2019年3月7日木曜日

[Elegoo:10] 超音波センサモジュールで
楽器(テルミン)を作る


概要 (Overview)
  • 超音波センサについて学ぶ
  • 超音波センサモジュールで楽器(テルミン)を作る



使用する電子部品 (Component Required)
電子種別電子部品個数
マイコン Elegoo UNO R3 マイコンボード1
USBケーブル1
能動 超音波センサモジュール1
パッシブブザー1
機構 ジャンプワイヤ(赤)[オス-メス]1
ジャンプワイヤ(黒)[オス-メス]2
ジャンプワイヤ(青)[オス-メス]1
ジャンプワイヤ(緑)[オス-メス]1
ジャンプワイヤ(黄)[オス-メス]1



電子部品について (Component Introduction)

超音波センサモジュール HC-SR04


超音波距離センサモジュールは、モジュールに2つ取り付けられているうちの超音波スピーカーから40kHzの周波数を出力し、 物体に反射された音をもう片方の超音波マイクで受信する
超音波は「音」なので超音波を出力してから受信するまでの時間に音速を掛けることで距離を求める(測距)

《データシート》
動作電圧5V
測定可能距離2~400cm(精度3mm)
測定角度15度以下

《端子》
Vcc電源入力 (5V)
Trig超音波スピーカー:超音波信号を送信
Echo超音波マイク:超音波信号を受信
(デジタルINPUT-距離を測定するPWNピン)
GNDGND

《測距の流れ》
(1) 超音波スピーカーのTrigピンを10μs以上Highにする
(2) モジュールが自動的にTrigピンからパルス(40kHzの信号を8回)を送信する
(3) モジュールが測定物から反射したパルス信号を超音波マイクに受信する
(4) パルス信号の送信~受信までに掛かった時間分だけEchoピンがHighになる
(5) EchoピンがHighになった時間をμs単位で測定し、音速を掛けて距離を計算する

《測距の計算》
(HR-SR04ライブラリのDistance関数)
片道の距離[cm] = 時間[μs→msec→sec] × 音速[m/sec→cm/sec] ÷ 2[片道]
空気中の音速は公式「331.5 + 0.6 t (m/sec) tは摂氏温度」:一般的に340(m/sec)

片道の距離[cm] = (パルス送受信時間[μs] ÷ 1,000,000[μs→msec→sec])
                              × (340[m/s] × 100[m/s→cm/s])
                              ÷ 2[片道]
  => 片道の距離(cm)=パルス送受信時間[μs] × 0.017
 マイコンは小数計算しないほうが良いので 0.017=1/59 とすることもある
  => 片道の距離(cm)=パルス送受信時間[μs] ÷ 59[cm/μs]




電子回路 (Electronic Circuit)
回路図 (Schematic)





実体配線図 (Wiring Diagram)





実践 (To Practice)
配線写真 (Example Picture)

拡大           全体

プログラム (Code)

HR-SR04ライブラリ
書式引数説明
SR04::SR04(int echoPin, int triggerPin) echoPin:超音波を受信
triggerPin:超音波を送信
SR04にピンに割り当てる
long SR04::Distance() 対象物までの距離を測る(cm)
long SR04::DistanceAvg(int wait, int count) wait :待機遅延  [ms]
count:計測回数 []
指定計測回数分計数を行い、
平均を計算する(cm)

HR-SR04ライブラリを使用しない場合は《測距の流れ》に従って
①直接Trigピンから10μs間超音波を出力し
②PulseIn関数でechoピンのHIGH→LOWのパルスの長さ(パルス送受信時間)を受信して
③測距の計算を行う
《測距の計算》片道の距離(cm)=パルス送受信時間[μs] ÷ 59[cm/μs]

音階(ドレミ)の周波数(Hz)
pitches.h


/*************************************************/
/* 音階(NOTE_B0 - DS8)の周波数(Hz)を定義           */
/* https://www.arduino.cc/en/Tutorial/ToneMelody */
/*************************************************/

#define NOTE_B0    31
#define NOTE_C1    33
#define NOTE_CS1   35
    …
#define NOTE_CS8   4435
#define NOTE_D8    4699
#define NOTE_DS8   4978

スケッチ
/**********************************************/
/* 【 Elegoo:10 】超音波センサモジュール       */
/*    超音波センサモジュールで                  */
/*    楽器のテルミンを作る                     */
/* ※※ 音階の周波数と間隔距離(cm)を任意で設定   */
/**********************************************/

/*--------------------------------------------*/
/* SR04ライブラリの作成                        */
/*--------------------------------------------*/
#include <SR04.h>
#define PIN_TRIG    12  // D12 : 超音波スピーカー
#define PIN_ECHO    11  // D11 : 超音波マイク

// SR04オブジェクトの作成
SR04 objSr04 = SR04( PIN_ECHO, PIN_TRIG );

/*-------------------------------------------*/
/* ブザーと音階                               */
/*-------------------------------------------*/
#define PIN_BUZZER  13  // D13 : ブザー

// 音階(ドレミ)の周波数(Hz):NOTE_B0 - DS8     ※※
#include "pitches.h"
int aryNote[] = {
    NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4,
    NOTE_G4, NOTE_A4, NOTE_B4, 
    NOTE_C5
};
#define NOTE_STEP    3  // 音階の間隔距離(cm)  ※※
int intNoteCM;          // 音階全長(cm)


/*********/
/* setup */
/*********/
void setup() {

  // --------------------------------------------------
  // ブザーpinの設定
  // --------------------------------------------------
  pinMode( PIN_BUZZER,  OUTPUT );

  // --------------------------------------------------
  // 音階の数と間隔距離から音階全長を設定
  // --------------------------------------------------
  intNoteCM = ( sizeof(aryNote) / sizeof(aryNote[0]) ) * NOTE_STEP;

  // --------------------------------------------------
  // シリアルモニタ開始
  // --------------------------------------------------
  Serial.begin( 9600 );

  delay( 1000 );
}

/********/
/* loop */
/********/
void loop() {

  // 対象物までの距離を測る(cm)
  // 不安定解消のため、計数後(ms, 回数)平均を算出
  long lngDistance = objSr04.DistanceAvg( 10, 10 );   

  // --------------------------------------------------
  // 測定可能距離の範囲内:2~400cm(精度3mm)
  // --------------------------------------------------
  if( 2 <= lngDistance && lngDistance <= 402 ){

    // 対象物までの距離 - 測定可能開始距離(2cm)
    lngDistance -= 2;

    // --------------------------------------------------
    // 対象物までの距離別にブザーから音(周波数)を出力
    // --------------------------------------------------
    // 音階全長(cm)以内
    if( lngDistance <  intNoteCM ) {

      // 出力する音の決定
      int intCnt = lngDistance / NOTE_STEP; 

      // シリアルモニタに表示
      Serial.print( lngDistance ); Serial.print("cm : ");
      Serial.println( intCnt );

      // 音の周波数を出力
      tone( PIN_BUZZER, aryNote[intCnt] );

    // 音階全長(cm)以外
    } else {
      // 周波数の出力を停止
      noTone( PIN_BUZZER );
    }

  // --------------------------------------------------
  // 測定可能距離の範囲外
  // --------------------------------------------------
  }else{
      // 周波数の出力を停止
      noTone( PIN_BUZZER );
  }

  delay( 100 ); 
}

結果(動画)・モニタリング

動画

モニタリング