Raspberry Pi Pico GPIO割り込みを使って超音波センサーHCSR04で距離を計測する

Raspberry Pi Pico

はじめに

Raspberry Pi Picoを使って超音波センサーHCSR04で対象物までの距離をを計測してみます。

超音波センサーHCSR04は、トリガー信号を出力した後に帰ってくるエコー信号を捉え、そのエコー信号のhighレベル時間からセンサーと対象物の距離を計測するというセンサーです。

今回は、エコー信号のhighレベル時間をRaspberry Pi PicoのGPIO割り込みを使って計算します。

HC-SR04 超音波距離センサーモジュール 距離測定モジュール トランスデューサI / Oトリガーセンサー UNO Mega2560/Raspberry Pi B/ロボット/ Arduino用

価格:980円
(2022/9/4 21:44時点)
感想(0件)

Raspberry Pi Pico

価格:807円
(2022/9/4 21:45時点)
感想(0件)

回路

超音波センサーのTrig信号をGPIO28、Echo信号をGPIO6に接続します。

センサー側は5Vで動作するのに対してRaspberry Pi Picoは3.3V動作なので、Raspberry Pi Picoに入力されるEcho信号ラインのGPIO6は分圧する形にします。分圧1:2となるようにEchoラインに5kΩ、EchoとGndラインに10kΩの抵抗を接続します。

センサーのVccには5V電源を接続し、Gndは接地します。

プロジェクトのディレクトリ作成

まず、作成するプロジェクトのディレクトリをつくっていきます。

ここでは、次のようなディレクトリ構成にしています。

C:¥prog¥pico¥DL

     ┗¥pico-sdk

     ┗¥ultrasonic_hcsr04

          ┗ \build

          ┗ ultrasonic_hcsr04.c

          ┗ CMakeLists.txt

          ┗ pico_sdk_import.cmake

pico-sdkディレクトリやpico_sdk_import.cmakeファイルに関しては、こちらの記事にまとめています。

SourceファイルとMakeファイルの作成

次にソースファイルとビルドファイルを準備します。

作成したプロジェクトディレクトリに移動します。(ここでは、ultrasonic_hcsr04ディレクトリ)

ultrasonic_hcsr04ディレクトリの中に実行するソースファイルultrasonic_hcsr04.cを作成します。

ultrasonic_hcsr04.cのファイルに次のようなプログラムを記述しました。

ultrasonic_hcsr04.cの中身は、次のようにしています。

main()関数にあるstdio_init_all()関数 は、printf()関数で結果を出力するために呼び出しています。printf()関数の出力は、Tera Termなどのソフトを使うことによって確認できます。

raspberry Pi Picoの28ピンをセンサーのトリガー信号用にGPIO出力として設定します。

また、6ピンをエコー信号用にGPIO入力設定にして、割り込みを使うため、gpio_set_irq_enabled_with_callback()関数で割り込み設定を行います。

この関数の仕様は、SDK Documentationに記載されています。

Page not found · GitHub Pages

第一引数は、使用するGPIOピン番号、第二引数は、イベントマスク、第三引数は、割り込みの許可、禁止の設定(trueまたはfalse)、第四引数は、割り込み発生時のコールバック関数指定になります。

第二引数のイベントマスク値は、次のうちの何れかを使用します。

enum  	gpio_irq_level { GPIO_IRQ_LEVEL_LOW = 0x1u , GPIO_IRQ_LEVEL_HIGH = 0x2u , GPIO_IRQ_EDGE_FALL = 0x4u , GPIO_IRQ_EDGE_RISE = 0x8u }

また、第四引数のコールバック関数は、void型の戻り値をもち、割り込みが発生したGPIOピン番号とイベントマスク値を引数にもつ形で定義します。

メインループでは、12[us]のトリガー信号(仕様上は、10[us]以上の出力)を出力し100[ms]ウェイト後、エコー信号のhigh時間が格納されているdtimeをチェックしています。

ここでは、センサーと対象物間の距離が10[cm] 未満の場合、エコー信号のhighレベル時間を出力するようにしています。距離[cm]は、エコー信号のhighレベル時間[us] / 58 で計算できます。

出力後は、5秒待った後に再度トリガー信号を出力するという流れです。

超音波センサーは、トリガー信号を受信後、エコー信号を送出します。Raspberry Pi Pico側では、そのエコー信号の立上がりと立下りを割り込みで捉えます。

立上り時の時間と立下り時の時間を取得し、その差をabsolute_time_diff_us()関数を使って算出し、dtimeという変数に代入しています。このdtimeの値をメインループ側でチェックするというプログラムです。

プログラムができたら、続いて、CMakeLists.txtを作成します。

CMakeLists.txtには次のように記述しておきます。

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(ultrasonic_hcsr04_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(ultrasonic_hcsr04
  ultrasonic_hcsr04.c
)

target_link_libraries(ultrasonic_hcsr04 pico_stdlib hardware_gpio)

pico_enable_stdio_usb(ultrasonic_hcsr04 1)
pico_enable_stdio_uart(ultrasonic_hcsr04 1)
pico_add_extra_outputs(ultrasonic_hcsr04)
target_link_libraries(ultrasonic_hcsr04 pico_stdlib)

さらに、pico-sdk¥externalディレクトリの中にあるpico_sdk_import.cmakeというファイルをコピーして保存します。

ビルド

プログラムをビルドします。

このとき、パス設定をしていなければ、次のコマンドを実行します。

C:\prog\pico\DL\ultrasonic_hcsr04\build>setx PICO_SDK_PATH "..\..\pico-sdk"

実行ファイルを生成するため、cmakeを実行し、その後、nmakeを実行するとビルドが開始されます。

C:\prog\pico\DL\ultrasonic_hcsr04\build>cmake -G "NMake Makefiles" ..
C:\prog\pico\DL\ultrasonic_hcsr04\build>nmake

実行

ビルドが正常に終了するとbuildディレクトリの中にultrasonic_hcsr04.uf2ファイルが作成されるので、このファイルをRaspberry Pi Picoに書き込みます。

書き込みは、Raspberry Pi Picoのリセットボタンを押しながらRaspberry Pi PicoにつないだUSBケーブルをPCに接続します。この実験環境では、DドライブとしてRPI-RP2が認識されました。

このDドライブ内にultrasonic_hcsr04.uf2ファイルをドラッグアンドドロップで入れ込みます。

ドロップ後、プログラムが自動的に実行されます。

ここで、Tera Termなどのソフトでシリアル通信を確認するとセンサーと対象物までの距離が10[cm]未満となったときにエコー信号のhighレベル時間が出力されます。

壁に向かっておおよそ9[cm]の位置にセンサーを設置して実験した結果が上の写真です。

オシロのCH2がエコー信号になります。507[us]のhighレベルが出力されています。

それに対して、プログラム上のprintf()関数から出力された結果も507前後となっています。

距離を算出すると、507 / 58 = 8.74[cm] となります。

厳密にセンサー位置を決めているわけではないので、誤差の検証はできませんが、おおよその距離算出はできていると思います。

まとめ

このブログではRaspberry Pi Picoで超音波センサーHCSR04を使い、対象物の距離計測をしてみました。距離を確認するためには、センサーのエコー信号のhighレベル時間を取得する必要があり、その時間取得のためにGPIO割り込みを使いました。

プログラムを作成し、プログラムから得られたセンサーのエコー出力値と実際の対象物とセンサーの距離におおよその一致が得られました。

コメント

タイトルとURLをコピーしました