ロボットに四個の距離センサーをつけたい。四方の距離をいつでも測りたいというわけだ。US-015は、音波を発信してその跳ね返り時間で距離を測る。音を出すトリガとエコーを受け取る2つのgpioを消費する。八個のgpioを直接ラズパイのポートから取るというのは勿体なさすぎる。そこで、spiモジュールを使って、ラズパイのgpioを拡張してそこから取りたい。これが目標だ。
モーターの回転数をMCP23S17経由で取るというのは成功した。しかも、JAVAのpi4jを使って。これは先に書いた。
距離センサーは、同じようにpi4jでやろうとしたのだが、うまくいかない。超音波の発信と受信は、微妙な時間のタイミングで行われるので、どうもpi4jのライブラリとの相性が悪いと思った。
そこで止むを得ず、CのWiringPiライブラリで動かすことにした。まあ、動いた。
https://youtu.be/1zhjbX62gA8
ただ、問題はある。モータ制御との整合性だ。モーターは、JAVAで、距離センサーは、Cというのは、何しろ一つのMCP23S17なので、見るからにうまくいきそうにない。
両方Cで書くしかないが、モータの方はピンの値の変化をpi4jの割り込みで取っているので、それを割り込みを使わないでやれるようなCのプログラムを書かなければならない。それが面倒だ
距離センサのプログラムを以下に掲載しておく。
http://nopnop2002.webcrow.jp/HC-SR04/HC-SR04-1.html
と、wiringPiのMCP23S17サンプルを参考にさせていただいた
わかりやすく言うと、その二つを融合しただけである
#include <stdio.h> #include <wiringPi.h> #include <mcp23s17.h> #include <sys/time.h> #include <unistd.h> #define BASE 123 // トリガピンとエコーピンは、MCP23S17のピン番号である // 8ピンは、B0 // 7ピンは、A7 である #define trigPin 8 #define echoPin 7 int pulseIn(int pin, int level, int timeout) { struct timeval tn, t0, t1; long micros; gettimeofday(&t0, NULL); micros = 0; while (digitalRead(pin) != level) { gettimeofday(&tn, NULL); if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0; micros += (tn.tv_usec - t0.tv_usec); if (micros > timeout) return 0; } gettimeofday(&t1, NULL); while (digitalRead(pin) == level) { gettimeofday(&tn, NULL); if (tn.tv_sec > t0.tv_sec) micros = 1000000L; else micros = 0; micros = micros + (tn.tv_usec - t0.tv_usec); if (micros > timeout) return 0; } if (tn.tv_sec > t1.tv_sec) micros = 1000000L; else micros = 0; micros = micros + (tn.tv_usec - t1.tv_usec); return micros; } int main (void) { int i, bit ; int j,k,l,m; long duration, distance; wiringPiSetup () ; mcp23s17Setup (BASE, 0, 0) ; printf ("距離センサーテスト with Raspberry Pi - MCP23S17\n") ; pinMode (BASE + trigPin, OUTPUT) ; pinMode (BASE + echoPin, INPUT) ; pullUpDnControl (BASE + echoPin, PUD_UP) ; for(i=0;i<100;i++){ digitalWrite(BASE + trigPin, LOW); // Added this line delayMicroseconds(2); // Added this line digitalWrite(BASE + trigPin, HIGH); delayMicroseconds(10); // Added this line digitalWrite(BASE + trigPin, LOW); duration = pulseIn(BASE+echoPin, HIGH, 1000000); //printf("duration=%d ",duration); distance = (duration/2) / 29.1; printf("距離 = %d cm\n",distance); sleep(1); } return 0 ; }