はじめに
自作のProlog処理系(O-Prolog ver0.60以降)のラズパイバージョンで超音波距離センサモジュール HC-SR04を動作させることができました。そのことの覚書です。
HC-SR04
ラズパイとPrologで自律型のおもちゃロボットの製作をすすめています。扱いやすくて安価なセンサーはないかとハードの達人にお聞きしたところ、HC-SR04を教えていただきました。1個400円程度です。
扱いはとても簡単です。GCCとGNDはラズパイから5ボルトを与えます。トリガーとエコー端子にはGPIOを接続します。注意を要するのはエコーの出力は5ボルトだということです。抵抗をかませてラズパイの規格である3.3ボルトに落とす必要があります。5ボルトのまま与えるとラズパイを破損する可能性がありますので注意です。
Prologからの制御
WiringPIを利用した組み込み述語を使います。トリガーをONにして、10マイクロ秒以上待ってからエコーを読み取ります。エコーが1を出力している時間を計測して、所定の定数を掛けるとセンチメートル単位の距離が得られます。
repeat/0 述語を使います。O-Prologのrepeat/0はループにして実行していますので、信号を待ってもスタックオーバーフローになることはありません。通常、repeatは次のように再帰的に定義されると説明されています。
repeat.
repeat :- repeat.
しかし、O-Prologに限らず、通常、処理系は末尾再帰をループに変換しているようです。
タイマー
マイクロ秒単位での時間計測が必要となります。Prologの標準述語にはありませんので、独自拡張しました。timer/1です。 timer(on) で計測を開始し、timer(off)で終了します。変数を与えるとその間の時間(秒単位)を浮動小数点数で返す仕様にしました。
コード
Prologのコードは次のようになります。setup/0を実行し、measure(X)のように質問するとXにその距離を浮動小数点数としてunifyします。
setup :-
wiringpi_setup_gpio(X),
pin_mode(23,output),
pin_mode(24,input),
digital_write(23,0),
delay(1000).
measure(X) :-
digital_write(23,1),
delay_microseconds(11),
digital_write(23,0),
read_wait(1),
timer(on),
read_wait(0),
timer(off),
timer(T),
X is T * 34000 /2.
read_wait(X) :-
repeat,
digital_read(24,Y),
X == Y,!.