MCP23S17を使って、US-015の距離センサーを動かす

ロボットに四個の距離センサーをつけたい。四方の距離をいつでも測りたいというわけだ。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 ;
}