Intel Edisonで超音波距離センサを使ってみる


電子工作は初心者ですが、これから色々作っていきたいと思います。

![DSC_0039.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/d1982e5a-5f7e-a49b-b1f2-2895d2ee40df.jpeg)

手元に超音波距離センサがあったので、これを使って見ようと思います。
ちょっと見た目がカッコいいのと、超音波って言葉に惹かれました。 :grin: 

今回は Intel Edison ＋ Node.js で距離を測ることが目標です。

# 組み立て
まずは、Intel Edison 本体を Intel Edison Board for Arduino に取り付けます。
![DSC_0008.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/7a68f6d9-2a9c-52d5-868a-fa07e881c4d4.jpeg)

簡単に取り付けられますね。
![DSC_0014.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/43006994-ecfa-9abc-f2fe-4ffb84ccc60a.jpeg)

次に Groveベースシールドを取り付けます。
![DSC_0040.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/70c6ac87-1bc8-9ad1-4bec-308d197411c6.jpeg)

# まずは Arduino で試す
センサの製品ページ（[Grove - Ultrasonic Ranger](http://www.seeedstudio.com/wiki/Grove_-_Ultrasonic_Ranger)）に Arduino のスケッチが載ってたので、
まずはこれを試してみようと思ったのですが、
[UltrasonicRanger Library](https://github.com/Seeed-Studio/Grove_Ultrasonic_Ranger) ってものを使っているみたいなので、その中のサンプルを試します。
![DSC_0041.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/cadeab64-95a2-52f4-6fc1-fe5eeb1ab6be.jpeg)

サンプルをそのまま動かしたのに、全然距離が測れない！！
![serial_output.png](https://qiita-image-store.s3.amazonaws.com/0/134613/1bd66212-bc59-050c-d0e8-b36943036a43.png)

センサのドキュメントも見てみましたが、よくわかりません。 :dizzy_face:
![Ultra-Sonic-seq.JPG](https://qiita-image-store.s3.amazonaws.com/0/134613/48d06003-c148-8c74-b0b9-9a3710b528ef.jpeg)

ライブラリのソースを読んでみたら、なんとなく理解できました。
簡単に言うと、シグナルPinを10マイクロ秒以上 **HIGH** にしてから，
**LOW** にすると40kHzのパルスを8回送信して Echo back されるらしい。
で、出力端子が **HIGH** になっている期間（マイクロ秒）の半分を音速で割れば距離を算出できる。

# 上手くいかなかったので Arduino UNO で試す
なぜ距離が取れないのかわからないので、Arduino UNO（互換ボード）で試してみます。
![DSC_0043.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/fd05bbf2-50d1-3a97-f42d-a837c9f8f00c.jpeg)

何の問題もないですね。
![serial_output2.png](https://qiita-image-store.s3.amazonaws.com/0/134613/795ed9bc-e22a-edf7-4b57-0a6f8cc7031d.png)

# 今度は HC-SR04 で試す
手元にHC-SR04もあったので、こっちで試してみます。
![DSC_0045.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/b3a383c6-d3dd-7482-abeb-cd536ea4476b.jpeg)
こっちのセンサはトリガーPin（Trig）とエコーPin（Echo）が分かれてます。
ドキュメントを見たところ、トリガーPinに入力してエコーPinから読み取ればいいみたい。
以下のように配線してみました。
![Arduino_HC-SC04_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/134613/08b031b3-2ab1-2ee8-2c0a-700fc2cefc47.png)

こんな感じになりました。なかなかいいですね！
![DSC_0046.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/7eb59115-6988-04af-b0e7-28bc48b92208.jpeg)

UltrasonicRanger Library のソースを参考にスケッチを作成しました。

```ino:ultrasonic.ino
#define echoPin 7 // Echo Pin
#define trigPin 8 // Trigger Pin

long duration, distance;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);

  // 距離を計算(cm)
  distance = duration / 29 / 2;

  if (distance > 0) {
    Serial.print(distance);
    Serial.println(" cm");
  }

  delay(500);
}
```
距離もちゃんと取れてます。
![serial_output3.png](https://qiita-image-store.s3.amazonaws.com/0/134613/1a31a6ab-4b05-83de-ad76-0b403841fa00.png)

# 再度 Intel Edison Board for Arduino で試す
Arduino UNOと同様に配線。
![Edison_HC-SC04_ブレッドボード.png](https://qiita-image-store.s3.amazonaws.com/0/134613/87768bd5-8972-7b65-58af-08a7fed2d310.png)

![DSC_0047.jpg](https://qiita-image-store.s3.amazonaws.com/0/134613/1b0060b7-4fd2-8e34-5959-0085de5cd1d0.jpeg)

今度は距離が取れました！
![serial_output4.png](https://qiita-image-store.s3.amazonaws.com/0/134613/15eaf112-de27-c9da-91ca-6fc093e85c63.png)

# Intel Edison ＋ Node.js で距離を測定してみる
先ほど作った ultrasonic.ino を元に Node.js 用ソースを作成。
pulseIn 関数がなかったので、適当に作ってみました。

```js:ultrasonic.js
var mraa = require('mraa');
var sleep = require('sleep');
var μs = require('microseconds');

// GPIO
// trigger pin: send trigger signal
var trigPin = new mraa.Gpio(8);
trigPin.dir(mraa.DIR_OUT);

// echo pin: receive echo from module
var echoPin = new mraa.Gpio(7);
echoPin.dir(mraa.DIR_IN);

var LOW  = 0;
var HIGH = 1;

function pulseIn(pin, value, timeout) {
    timeout = timeout || 1000000;

    var pulseOn, pulseOff;

    var start = μs.now();
    
    while (pin.read() != value) {
        if (μs.since(start) > timeout) {
            return 0;
        }
        pulseOn = μs.now();
    }
    while (pin.read() == value) {
        if (μs.since(start) > timeout) {
            return 0;
        }
        pulseOff = μs.now();
    }
    // duration[microsec]
    var duration = pulseOff - pulseOn;
    
    return duration;
}

setInterval( function () {
    // Send Trigger Signal to Module
    trigPin.write(LOW);
    sleep.usleep(2);
    trigPin.write(HIGH);
    sleep.usleep(5);
    trigPin.write(LOW);
    
    // Measure duration of echo pulse
    var duration = pulsein(echoPin, HIGH);

    // Calculate Distance from duration
    var distance = duration / 29 / 2;
    
    if (distance > 0) {
        // Show the distance on the console
        console.log(distance + ' cm');
    }
   
}, 100);
```

![xdk_console.png](https://qiita-image-store.s3.amazonaws.com/0/134613/e24b701c-2ad0-4bb1-12f3-69280d639f68.png)

# まとめ
Intel Edison ＋ Groveベースシールド + 超音波距離センサだと
どうして上手くいかなかったのか結局わかりませんでしたが、
何とか目標を達成することができてよかったです。

次は Raspberry Pi でやってみようかなぁ。