RaspberryPiで超音波を使った距離測定
利用する部品
配線
左図(クリックして拡大)のように、超音波を利用するための温度補正用にI2C 12ビットデジタル温度センサ ADT7410も併用する。
pythonスクリプト
次のコードは上記写真のように結線した超音波距離センサとデジタル温度センサを使って、音速の温度補正を施しながら、温度と曲を表示するスクリプトである。。
[参考] Using an Ultrasonic Sensor (HC-SR04) on a Raspberry Pi with Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# HC-SR04 ultrasonic range sensor
# with ADT7410 temperature sensor for sonic velocity correction
# ultrasonic
# GPIO 17 output = "Trig"
# GPIO 27 input = "Echo"
import time
import RPi.GPIO as GPIO
import smbus
# prepare for ADT7410 temperature sensor
bus = smbus.SMBus(1)
address_adt7410 = 0x48
register_adt7410 = 0x00
# prepare for HC-SR04 ultrasonic sensor
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.OUT)
GPIO.setup(27,GPIO.IN)
# detect temperature in C
def read_adt7410():
word_data = bus.read_word_data(address_adt7410, register_adt7410)
data = (word_data & 0xff00)>>8 | (word_data & 0xff)<<8
data = data>>3 # 13ビットデータ
if data & 0x1000 == 0: # 温度が正または0の場合
temperature = data*0.0625
else: # 温度が負の場合、 絶対値を取ってからマイナスをかける
temperature = ( (~data&0x1fff) + 1)*-0.0625
return temperature
def reading_sonic(sensor, temp):
if sensor == 0:
GPIO.output(17, GPIO.LOW)
time.sleep(0.3)
# send a 10us plus to Trigger
GPIO.output(17, True)
time.sleep(0.00001)
GPIO.output(17, False)
# detect TTL level signal on Echo
while GPIO.input(27) == 0:
signaloff = time.time()
while GPIO.input(27) == 1:
signalon = time.time()
# calculate the time interval
timepassed = signalon - signaloff
# we now have our distance but it's not in a useful unit of
# measurement. So now we convert this distance into centimetres
distance = timepassed * (331.50 + 0.606681 * temp)* 100/2
# return the distance of an object in front of the sensor in cm
return distance
# we're no longer using the GPIO, so tell software we're done
GPIO.cleanup()
else:
print "Incorrect usonic() function varible."
try:
while True:
temp = read_adt7410()
print "temperature[C] =", round(temp,1)
print "\tdistance to obstcle = ", round(reading_sonic(0,temp),1), "[cm]"
time.sleep(0.5)
except KeyboardInterrupt:
pass
GPIO.cleanup()