できること

Arduinoで距離計を自作しよう! スピーカーをつなげば楽器にも早変わり

超音波センサは、その名の通り、超音波を使用して、物体が近づいたり遠ざかったりすることを検出するデバイスです。
Arduinoのようなマイコンボードに接続すれば、体の動きを認識したり、誰かの侵入を検知したりできます。

どのようにして超音波で物体を検出するか、不思議ではありませんか? 本記事では、Arduino Unoに超音波センサとスピーカーをつなげて、超音波センサの動作を音で表現できる、距離計としても使える楽器を作成します。

arduino-distance-measurement-01

Arduino Unoの外観

 

目次

  1. 準備
  2. Arduinoと超音波センサでアイデアが広がる
  3. スケッチ全体
  4. スケッチのポイント解説 Arduinoで音を作る?
  5. 楽器だけではもったいない! 超音波距離計に改造してみよう
  6. まとめ

 

1. 準備

本記事では次のものを使用します。

Arduino Uno

arduino-distance-measurement-02

 

超音波センサモジュール

本記事ではHC-SR05を使用します。他製品を使用する場合は、ピンの配置に注意してください。

arduino-distance-measurement-03

 

Arduino IDE

arduino-distance-measurement-04

 

上記に加えて、USBケーブルとスピーカーを用意してください。スピーカーは、どの様なものでも構いません。本記事ではシンプルなモノラル密閉型スピーカーを使用します。

まだ、Arduino IDEをインストールしていない場合は、はじめての電子工作! Arduinoを触ってみよう(ソフトウェア編)を参照してください。

 

2. Arduinoと超音波センサでアイデアが広がる

本記事では、超音波センサにHC-SR05を使用します。
超音波センサは、さまざまな製品が販売されていますが、どれも構造は似ています。ピンの配置に注意すれば、ほかの超音波センサでも同じように使用できます。

一般的な超音波センサは、2つの円柱形の筒を備えています。筒の一つは超音波の発信器、もう一つは受信器です。
発信器から送出された超音波は、物体に反射して返ってきます。それを受信器がキャッチし、この「送出」から「キャッチ」までの時間を測定することで、距離を算出できます。

ほかにも「何かがある」ことを検出するセンサには、焦電型赤外線センサ(PIR: Passive Infrared Ray)などがありますが、距離の測定は苦手としています。
超音波センサは、超音波による距離の検出ができるので、その「何か」が、近くにあるのか、遠くにあるのかの判別を得意としています。

本記事では、Arduinoが物体までの距離認識を利用して楽器を作ります。この楽器は、ピアノのように鍵盤を押して演奏するのではなく、センサの前に手をかざし、その手を遠ざけたり近付けたりすることで音階が変わります。
Arduinoが距離を認識できるようになることで、さまざまなアイデアが生まれませんか? 超音波センサは、Arduinoを使った電子工作の可能性を広げてくれるデバイスです。

 

3. スケッチ全体

Arduino Unoに転送するスケッチは以下の通りです。

void setup() {
    pinMode (6,OUTPUT); // Insert HC-SR-05 with VCC in pin 6
    pinMode (5, INPUT); // Assign pin 5 to Echo
    pinMode (4,OUTPUT); // Assign pin 4 to Trig
    pinMode (2,OUTPUT); // Assign pin 2 to GND.
    Serial.begin(9600); // This will allow you to read how far away your sensor is later
}

void loop()
{
    long duration, cm; // Initialize variables for duration and cm
    digitalWrite(6, HIGH); // Power the sensor
    digitalWrite(4, LOW); // Clear pulse before sending a 10 microsecond ping,
    delayMicroseconds(2);
    digitalWrite(4, HIGH);
    delayMicroseconds(10);
    digitalWrite(4, LOW);
    
    duration = pulseIn(5, HIGH); // Detect pulse length from the Echo pin, measured in microseconds
    
    cm = (duration/2)/29.155; // Divide duration in half (due to round trip), then convert distance to centimeters (1cm per 29.155 microseconds), assign to cm variable
    
    Serial.print(cm); // Print distance in cm to serial monitor
    Serial.print("cm");
    Serial.println();
    
    delay(100); // Delay
    
    int note = 0; // Assign note based on distance, spacing notes per 6cm
    
    if(cm<=48&&cm>42) {
        note = 523;
    } else if(cm<=42&&cm>36) {
        note = 493;
    } else if(cm<=36&&cm>30) {
        note = 440;
    } else if(cm<=30&&cm>24) {
        note = 392;
    } else if(cm<=24&&cm>18) {
        note = 349;
    } else if(cm<=18&&cm>12) {
        note = 329;
    } else if(cm<=12&&cm>6) {
        note = 294;
    } else if(cm<=6) {
        note = 261;
    }
    
    if (note == 0) { // If distance isn't within 48cm, play nothing
        noTone(9);
    } else {
        tone(9, note, 200); // Play assigned note for 200 milliseconds
    }
    delay(10); // Brief pause
}

上記のソースコードをArduino IDEにコピー&ペーストしてください。

 

4. スケッチのポイント解説 Arduinoで音を作る?

スケッチの重要な部分を、超音波センサの動作の仕組みや、調整のポイントと合わせて解説します。
Arduinoボードに転送する前に確認しましょう。

digitalWrite(6, HIGH); // Power the sensor
digitalWrite(4, LOW); // Clear pulse before sending a 10 microsecond ping,
delayMicroseconds(2);
digitalWrite(4, HIGH);
delayMicroseconds(10);
digitalWrite(4, LOW);
duration = pulseIn(5, HIGH); // Detect pulse length from the Echo pin, measured in microseconds
cm = (duration/2)/29.155; // Divide duration in half (due to round trip), then convert distance to centimeters (1cm per 29.155 microseconds), assign to cm variable

この部分は、スケッチの中でも重要な部分です。
ここでは、超音波を送出し、跳ね返ってくるまでの時間を計測しています。

今回使用した超音波センサは、トリガーピンに電圧をかけると超音波を送出し、超音波を受信するとエコーピンに電圧を出力します。

4行目で、デジタル入出力ピンの「4番」に接続されたトリガーピンをONし、40KHzの超音波を送出しています。

受信の判定にはpulseIn()関数を使います。
この関数は「パルス幅」を測定するためものであり、引数に指定されたピン状態が「HIGH」か「LOW」になるまでの時間を計測します。「HIGH」か「LOW」のどちらに反応するかは、第二引数で指定します。
7行目で、デジタル入出力ピンの「5番」に接続されたエコーピンが、「LOW」から「HIGH」に変化するまでの時間を計測しています。

計測された時間は、超音波が物体に当たり返ってくるまでの往復時間です。必要なのは片道分の時間なので、2分の1にし、それを29.155で割ることで、物体までの距離(cm)を算出します。

ここで登場する数字、29.155とは超音波が1cm進む時間を表しています。
1秒間に音波が空気中を進む距離は、気温15℃で340m、室温18℃の環境だと約343mです。

pulseIn()関数で計測された時間の単位はマイクロ秒なので、1cm進む時間は
1,000,000[マイクロ秒] ÷ 34,300[cm] ≒ 29.155
となります。
1,000,000マイクロ秒は1秒です。

上記に続くソースコードの中で、Serial.で始まる行は、算出した距離(cm)を、シリアルポートを通して送信します。このデータは、シリアル通信に対応したパソコンやデバイスで受信します。
Arduino IDEの[Tools(ツール)]メニューから[Serial Monitor(シリアルモニタ)]を開くと、受信したデータを確認できます。
この、シリアル通信を通してデータを受信することは、Arduinoボードで何が起こっているのか把握するために有効なデバッグ方法です。

残りのソースコードは以下の通りです。

int note = 0; // Assign note based on distance, spacing notes per 6cm

if(cm<=48&&cm>42) {
    note = 523;
} else if(cm<=42&&cm>36) {
    note = 493;
} else if(cm<=36&&cm>30) {
    note = 440;
} else if(cm<=30&&cm>24) {
    note = 392;
} else if(cm<=24&&cm>18) {
    note = 349;
} else if(cm<=18&&cm>12) {
    note = 329;
} else if(cm<=12&&cm>6) {
    note = 294;
} else if(cm<=6) {
    note = 261;
}

if (note == 0) { // If distance isn't within 48cm, play nothing
    noTone(9);
} else {
    tone(9, note, 200); // Play assigned note for 200 milliseconds
}

この部分は「音」を作成しています。これまでのコードと比べると長く複雑ですが、見た目ほど難しくはありません。

音には固有の周波数があります。特にドレミといった音階は、その周波数が決まっているので、Arduinoボードのデジタル入出力ピンに、作りたい音の周波数と同じ周期の波形を出力します。
この波が、ピンに接続されたスピーカーのコーン紙を振動することで、音が作り出されます。

ここでは、スピーカーから出す音の周波数を、物体までの距離に応じて設定しています。
Arduinoの公式ドキュメント、Melodyのページに、周波数と音階の対応表があります。例えば261[Hz]が「c(ド)」、294[Hz]が「d(レ)」に対応します。

測定した物体までの距離6cmごとに、「ドレミ・・・」と音階が変化するように、周波数をnoteに設定します。もし物体を検出しない場合、noteの値は0です。
今回は、1オクターブ(低いド〜高いド)の8音階を設定するので、48cmまでの距離を音で識別できます。

ifelse は、「if文」と呼ばれる、プログラムの基本的な制御構造の一つです。Arduino言語だけでなく、ほとんどのプログラム言語で対応する構文です。

上記のソースコードの最後の部分は、距離に応じて決定した周波数の値をtone()関数に指定します。tone()関数は、引数に指定された周波数の波(音)を、デジタル入出力ピンに出力します。
また、周波数の値が0の時はnoTone()関数を呼び出して、音を止めます。

loop()関数の末尾にあるdelay()関数は、超音波センサの反応が、ある程度安定するまでの待機時間です。この時間が短いと、スピーカーから綺麗に音が出ません。反対に長いと、超音波センサの反応が鈍く感じます。

 

5. 楽器だけではもったいない! 超音波距離計に改造してみよう

ソースコードの実装が終わり、スケッチが完成したらArduinoボードに転送しましょう。
その後、一旦、パソコンにつながっているUSBケーブルを取り外して、超音波センサなどを次の手順で配線してください。

  • 超音波センサ(HC-SR05)をデジタル入出力ピンの「2番」から「6番」に接続します。センサの「Vcc」が「6番」、「GND」が「2番」です。HC-SR05は、直接Arduinoボードのコネクタに接続でき、正しく取り付けられると、センサのオモテ面がArduinoボードの外側に向くはずです。
  • スピーカーの「+側」をデジタル入出力ピンの「9番」に接続します。一般的なスピーカーの「+側」は赤色のリード線です。
  • スピーカーの「-側」をArduinoボードの「GND」ピンに接続します。一般的なスピーカーの「-側」は黒色のリード線です。

arduino-distance-measurement-05

ブレッドボードを使って配線(写真はイメージ)

 

配線が終わったら、Arduinoボードを再びパソコンに接続します。
超音波センサの向いている前方50cmの範囲には何も置かないようにしてください。

いよいよ本番です。
手を超音波センサのすぐ前にかざしてみましょう。スピーカーから音が出るはずです。
次に、その手を少しずつセンサから離してください。音階が上がっていけば成功です。

音階がスムーズに変わらない場合は、delay()関数の引数を調整してください。

いかがでしょう。上手く動作しましたか?

このままでも、楽器として面白い電子工作ですが、構成や超音波センサの仕組みが理解できたら、もう一歩進んで、超音波距離計に改造してみましょう。
今回の楽器は、48cmまでの距離に反応するスケッチになっていますが、もう少し先まで測定できるようにしてもいいですね。ただし、超音波センサは、安定して測定できる距離があります。こうした改造を積み重ねていけば、超音波センサの理解もより一層深まるでしょう。

 

6. まとめ

今回はArduinoに合わせて設計された超音波センサを使用しました。超音波を使って距離を測定する基本的な原理は同じなので、ほかのメーカーが販売している超音波センサでも、ピンの配置に注意すれば同じように利用できます。

超音波センサによる距離測定は、市販の距離計にも使われています。例えば、車の後方にある、障害物を検出するセンサにも超音波が使われています。超音波センサは応用範囲が広い技術です。
Arduinoは、こうした技術を簡単に応用できる環境が整っています。今回の楽器のような、すぐに実用的なデバイスへ転用できるものを作ると、ますます、Arduinoに興味が出てくるのではないでしょうか。

アバター画像

エレクトロニクスやメカトロニクスを愛するみなさんに、深く愛されるサイトを目指してDevice Plusを運営中。

https://deviceplus.jp

RoboMaster 2019 参戦ファーストステップガイド