超音波距離センサー(HC-SR04)をJetson Nanoで使用してみました

2020.10.18

1 はじめに

CX事業本部の平内(SIN)です。

Jetson開発ボードでは、GPIOが利用可能で、RaspberryPiとピン互換になっています。
https://www.jetsonhacks.com/nvidia-jetson-tx2-j21-header-pinout/

今回は、こちらを利用して、Jetson Nanoで超音波距離センサー(HC-SR04)を使用してみました。

2 Jetson.GPIO

Jetson NanoでGPIOを扱うために、Jetson.GPIOというモジュールが公式に公開されています。
https://github.com/NVIDIA/jetson-gpio

$ pip3 install Jetson.GPIO

なお、デフォルトでは、一般ユーザーからGPIOにアクセスする権限が無いため、ユーザー(nvidia)にそれを付与します。

$ python3
>>> import RPi.GPIO as GPIO
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/nvidia/.local/lib/python3.6/site-packages/RPi/GPIO/__init__.py", line 1, in <module>
    from Jetson.GPIO import *
  File "/home/nvidia/.local/lib/python3.6/site-packages/Jetson/GPIO/__init__.py", line 1, in <module>
    from .gpio import *
  File "/home/nvidia/.local/lib/python3.6/site-packages/Jetson/GPIO/gpio.py", line 33, in <module>
    raise RuntimeError("The current user does not have permissions set to "
RuntimeError: The current user does not have permissions set to access the library functionalites. Please configure permissions or use the root user to run this

gpioグループを追加して、ユーザー(nvidia)を追加します。

$ sudo groupadd -f -r gpio
$ sudo usermod -a -G gpio nvidia

udevルールをコピーして、適応します。

$ sudo cp /opt/nvidia/jetson-gpio/etc/99-gpio.rules /etc/udev/rules.d/
$ sudo udevadm control --reload-rules && sudo udevadm trigger

再起動すると、ユーザー(nvidia)から利用可能になります。

$ python3
>>> import RPi.GPIO as GPIO

3 接続

超音波センサー(HC-SR04)は、Jetson NanoのGPIOに接続して使用しています。 TrigとEchoは、物理番号の19と21に接続しました。

4 コード

下記は、超音波センサーの制御用クラスを使用するコードです。

# -*- coding: utf-8 -*-
import time
import RPi.GPIO as GPIO

# 超音波センサー(HC-SR04)制御クラス
class Sensor():
    def __init__(self):
        self.__TRIG = 19 # 物理番号19
        self.__ECHO = 21 # 物理番号21
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD) # 物理ピン番号で指定
        GPIO.setup(self.__TRIG,GPIO.OUT)
        GPIO.setup(self.__ECHO,GPIO.IN)

    def getDistance(self):
        GPIO.output(self.__TRIG, GPIO.LOW)
        # TRIG = HIGH
        GPIO.output(self.__TRIG, True)
        # 0.01ms後に TRIG = LOW
        time.sleep(0.00001)        
        GPIO.output(self.__TRIG, False)

        signaloff=0
        signalon=0
        # 発射時間
        while GPIO.input(self.__ECHO) == 0:
            signaloff = time.time()
        # 到着時間
        while GPIO.input(self.__ECHO) == 1:
            signalon = time.time()
        # 距離計算
        return (signalon - signaloff) * 17000

    def __del__(self):
        GPIO.cleanup()


def main():

    sensor = Sensor()

    while True:
        distance = sensor.getDistance()
        print("{:.0f}cm".format(distance))

        time.sleep(0.1)
    del sensor

if __name__ == '__main__':
    main()

動作を確認している様子です。

5 最後に

充分ご承知だと思いますが・・・GPIO等に配線を行う場合は、基本、電源OFFで行うことを超お勧めします。 また、通電する際には、充分に配線を確認し、ちょっとでも異常を感じたら、すぐOFFにする感じで・・・

ちょっと火傷して、センサーが1つお亡くなりになりました・・・