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()