公開日:2019/01/03
title.png

3rd Season


#3-7 ブザーとサウンドセンサ

 アクティブブザーとパッシブブザーの外観です。

ar37_buzzer.jpg

 表からでは見分けが付きません。アクティブブザーの方は裏側が樹脂でコーティングされており、パッシブブザーは基板がむき出しになっているので、かろうじて見分けることができます(他には、アクティブブザーの方が少し背が高い)。
 評価回路はいたってシンプルです。最後のサウンドセンサまで含めた回路図となっています。

ar37_schem.png

※後日更新(Rev.2):パッシブブザーのデータシートを見たところ、ドライバの端子保護のため、直列に1〜2[kΩ]抵抗を付けるか、並列にダイオードを挿入するよう記載がありました。ダイオードは挿入しませんでしたが、抵抗を挿入することとしました。ただし、1〜2[kΩ]では音が小さすぎたため、抵抗値は小さくしてあります。

 LED(D1)は、サウンドセンサ出力を視覚的にわかるようにするためのものです。UNOのオンボードLEDを使っても良いです。

アクティブブザー

 まずはアクティブブザーから鳴らしてみます。アクティブブザーは、ブザー内部で波形を作ってくれるらしいので、「+」端子にHIGHを印加するだけで音が鳴ります。

  const int pin_ABUZ=4;
  void setup (void)
  {
    // initialize
    digitalWrite (pin_ABUZ, LOW);
    pinMode (pin_ABUZ, OUTPUT);

    // buzzer
    digitalWrite (pin_ABUZ, HIGH);
    delay (500);
    digitalWrite (pin_ABUZ, LOW);
  }


 うるさいです。耳につきます。なので、0.5秒にしておきました。長く鳴らすときは周りに注意してください。

 少し長めに鳴らして、スマホのボイスレコーダで録音しました。Windowsにデータ(WAV)を転送し、「SoundEngine Free」というソフトウェアで周波数を解析したところ、3kHz弱辺り(2.7kHz付近?)にピークがありました。

ar37_abuz.jpg

 このスケールだと、正確な周波数が読み取れないので定かではありませんが、音階で言うと、「ミ〜ファ」の音(「鍵盤ハモニカで演奏する」を参照)に当たるでしょうか?ただし、440Hzラ音を含むオクターブより、3オクターブほど高い音です。
 甲高い音で音量も大きいので、長く鳴り続けると、かなり耳障りです。

パッシブブザー

 パッシブブザーは、ArduinoのI/OポートからHIGHをドライブしても鳴りません。HIGH→LOW、LOW→HIGHの変化時に「プツッ」と、かすかな音がしますが、それだけ。パッシブブザーを鳴らすには、自分で矩形波を作って入力してやる必要があります。
 ここからは、テストプログラム(test_buz_snd.ino)を使って評価を進めます。いつものように、コンパイルして起動すると、シリアルモニタからコマンドを受け付けるようになっています。
 【buz】コマンドを使って、周波数を変化しながら鳴らしてみます。長時間、ブザーが鳴り続けるので、注意してください。

  実行サンプル:【 】内はシリアルモニタからの送信データ
  【buz,10000,300,3000】 …… 10秒かけて、300Hz→3,000Hzへ変化させる。
  OK: buzzer 10000[ms], 300->3000[Hz]

 同じ様に、スマホで録音して周波数を解析してみました。横軸が時間の推移、縦軸が周波数だと思われます。

ar37_pbuz.jpg

 う〜ん、何とも言えませんね。300Hzから3,000Hzまで、片対数軸でリニアになるように周波数を変化させたので、図中、白線で示したような位置にピークが来て良さそうなものですが……。そもそも、リニアに変化する周波数帯は見当たらなくて、階段状に変化しています。入力波形が矩形波だからなのか、高調波成分が沢山出ていて、かえってそちらの方が音量が大きく見えます。
 途中から2.3kHz付近に強いピークが出て、実際に音量も大きくなったように聞こえました。各モジュールに固有の振動数があるはずなので、大きな音が出る周波数には差があるのかもしれませんね。また、この結果を見る限り、入力する矩形波の周波数と、鳴る音の周波数とは、あまり関係ない様です。

※アクティブブザー(〜2.7kHz)とパッシブブザー(〜2.3kHz)のピーク周波数が異なることからも明らかな様に、音色も異なって聞こえます。自発的に鳴るかどうかの差だけで、同じ物かと思っていましたが、ずいぶん違うみたいです。

 さて、【buz】コマンドは、loop()関数内でブロックせずに鳴らしてみたのですが、この方法だと、loop()内の処理量によっては、高い周波数を出力できなくなってきます。処理が間に合わなくなって、高速に矩形波を出力できなくなるためです。そこで、【bbz】コマンドを追加しておきました。このコマンドは、音が鳴り終わるまで、処理をブロック(他の処理が進められない)します。代わりに、高い周波数まで出力することができます。

 他にも、特定の周波数固定で良ければ、analogWrite(128)を使用する方法もあります。通常のPWM端子だと、約480Hz、高速PWM端子で約980Hzの矩形波を出力可能で、かつ、タイマ出力を使っていますので、処理をブロックされることもなく、パッシブブザーを鳴らすことが可能です。

※筆者の所では、パッシブブザーがあまり大きな音で鳴らなくて、「ん?」と思っていたのですが、ブザーの穴の部分を軽く指で押さえたところ、音が大きくなりました。理由は明確には分かりませんが……(1^^;)。なので、指の代わりに単三乾電池をブザーの上に置いて実験しました。

アラーム音

 せめて、パッシブブザーがもう少し、綺麗な音階で鳴ってくれるなら良いのですが、所詮は方形波なので、どこまで行ってもブザーですよね。なので、この後は、鳴らしやすいアクティブブザーを使います。
 アクティブブザーは、ON(鳴る)/OFF(鳴らない)の2状態ですので、「ONの状態をX1秒、OFFの状態をX2秒、ONの状態をX3秒、……」という配列データで表現して、アラームのパタンを定義することとします。通常状態では、アラームは停止しているものと考え、配列データを0から数えて偶数番目がON(鳴る)時間[ms]、奇数番目がOFF(鳴らない)時間[ms]、偶奇にかかわらず時間0が見つかると、パタン終了と見なすことにします。

  const uint alm_ptn1[ ]=  // alarm pattern #1
  {
    50,50, 50,50, 50,750,
    50,50, 50,50, 50,750, 0
  };


 さて、上のパタンは、どのような音が鳴るでしょうか?答えはこちら(↓)。

  実行サンプル:【 】内はシリアルモニタからの送信データ
  【alm,1】
  OK: alarm #1

  録音した音データ:ar37_alarm.wav

  

 筆者には、とてもなじみの深い音です。毎朝、枕元で鳴る目覚まし時計のアラーム音。
 他にもいくつかアラーム音を用意しておきました。完成版プログラム(test_buz_snd.ino)を実行して確かめてみてください。

 【alm】コマンドで鳴るアラーム音は、ブロックせずにloop()関数内で時間を管理しながら鳴らしています。つまり、アラームを鳴らしながら、loop()内で別な処理を進められるようになっています。2秒とか3秒とか、アラームが鳴っている間、他の処理が進まないようだと困りますからね。

  void loop (void)
  {
    :
    // alarm pattern
    ulong msec;
    msec=millis ();
    if (alm_play!=NULL)
    {
      if (msec - msec_alm<alm_play[alm_idx])
      {
        // stay
        digitalWrite (pin_ABUZ, (alm_idx%2==0)? HIGH: LOW);
      }
      else
      {
        // next index
        alm_idx++;
        msec_alm=msec;
        if (alm_play[alm_idx]<=0)
        {
          // end of pattern
          digitalWrite (pin_ABUZ, LOW);
          alm_play=NULL;
        }
      }
    }
    :
  }


 順番が逆になってしまいましたが、完成版のプログラムをリンクしておきます。

  完成プログラム:test_buz_snd.ino

 以下のコマンドを実装してあります。

 ブザーが長く鳴り続けると耳障りでしかありませんが、ON/OFFパタンによってアラームにすると、少しはマシになると思いませんか?

サウンドセンサ

  Iduinoスタータキットに以下のようなサウンドセンサが入っていました。

ar37_sound.jpg

 端子は4本、電源(+)、GND(G)と、アナログ出力(AO)、デジタル出力(DO)です。アナログ出力は、マイクの出力そのもの、でしょうかね……?どのような出力なのか調べてみたいところですが、今回は使いません。
 今回使うのはデジタル出力です。恐らく、一定の音量を超えた時に信号が出力されるようになっているのだと思います。基板に青いポテンシオメータがついているので、これで信号を出力するレベルを調整するのでしょう。

 最初に示した回路と、先ほどのテストプログラム(test_buz_snd.ino)は、既にサウンドセンサに対応してあります。一定の音量を超えた時に、LEDが光るようになっています。最初、マイクの近くで拍手をしてみたのですが、なかなか反応しませんでした。どうやら、ポテンシオメータの設定レベルが高すぎたようです。

出力レベルを調整する

 最初に、ポテンシオメータを回して出力レベルを調整します。ポテンシオメータの上に小さなねじがついていますので、これを回して調整します。時計回りに回すと反応レベルが高く(より大きな音にしか反応しなく)なり、反時計回りに回すと反応レベルが低く(より小さな音に反応するように)なります。
 サウンドセンサのデジタル出力に対応して光るようになっているLED(サウンドセンサで光っているLEDではなくて、上の実験用回路図に記したLED)を見ながら、以下の様に調整します。

 あ、音に反応するのですから、なるべく静かに、生活雑音だけが残っている状態で調整してください。搭載されているポテンシオメータは、精密な抵抗変化を調整できるタイプの物なので、結構ダイナミックに「クルクルクルクル〜」っと、回さないと、なかなか所望のレベルを設定できません。ですので、メガネのねじなどを締めるのに使うような、マイクロドライバ(マイナス)が必須です。

評価に戻る

 では、評価に戻りましょう。拍手したり、ちょっと大きな音を立ててみてください。その音に反応して、LEDがピカッと一瞬光ればOKです。
 ブザーの音にも反応するでしょうか?【alm,1】、【buz,1000,2000】などのコマンドに反応するか、確かめてみてください。

※筆者の環境では、ちょっと、パッシブブザーの音が小さいみたいなので、マイクを近づけても、ほとんど反応しませんでした。【alm】コマンドなど、アクティブブザーには反応して、LEDが点滅します。

  実行サンプル:




 サウンドセンサのデジタル出力波形を確認しておきましょう。Logiscopeを使います。

ar37_clap.png

 サウンドセンサを繋いで、拍手したときの波形です。このデジタル出力は通常時HIGHで、一定以上の音量が入ってきたときにLOWを出力するようになっているようです。

※後日追記:通常時HIGHになるか、LOWになるか?は、サウンドセンサのポテンシオメータで設定したレベル次第で変わるのだと思われます。今回はたまたま上の様に「通常時HIGH」となる設定で使った様です。

 一回の拍手だったのですが、複数回LOWレベルが出力されていますし、間隔や幅も様々です。loop()関数内でサンプリングする方法だと、取りこぼす可能性があるので、デジタル出力の立ち下がりエッジで割り込みをかけて検出する方法を取らざるを得ないでしょう。
 その場合に困るのが、以下の様なケース。

ar37_alarm.png

 【alm】コマンドでアラームを鳴らしたときのサウンドセンサ出力波形です(ブザーを鳴らすための矩形波ではありません)。機械的な音だからでしょうか、今度は、一定期間毎にLOWレベルが連続して出力されます。このようなケースを割り込みで処理してしまうと、今度は割り込み処理にかかりっきりになってしまって、他の処理が追い付かなくなってしまう恐れがあります。
 一度、サウンドセンサの出力を検知したら、その処理が終了するまでdetachInterrupt()しておき、次の処理を受け付けられるようになった時に改めてattachInterrupt()するなど、工夫が必要になるかもしれません。


 ブザーとサウンドセンサを組み合わせると、モールス符号みたいな情報なら、やり取りできるようになりますね。可聴域無線通信??まあ、双方向で通信しようとすると、自分が鳴らした音を自分で検出してしまったり、混信したりするので、一方向通信が関の山ですが……(戯れ言でした、ホンキにしないで……)。


後日のアップデート

 「#5-8 MMLで音楽を奏でる」にて、CR回路を使って、イヤホンやスピーカなどに音階を出力する方法を紹介しました。現時点で、Arduinoを使って音階を奏でる方法としては、この方法が最善だと考えています。
 一方、インターネットを眺めていると、どうも、パッシブブザーを使って、音階を奏でている記事が散見されるのが気になっていて、今回、もう一度、パッシブブザーの評価をやり直してみました。

 「#5-8 MMLで音楽を奏でる」で作ったプログラム(play_mml.ino)をそのまま使います。使用方法については、「#5-8 MMLで音楽を奏でる」を参照してください。このプログラムに合わせて、以下の様な回路をArduino UNOに接続します。

Arduino UNO 接続 パッシブブザー
GND −端子(表示なし)
D9 抵抗を通して、+端子

 プログラム(play_mml.ino)をコンパイルして、UNOに転送したら、シリアルモニタを開いて、以下の様に実行します。

  実験サンプル:【 】内はシリアルモニタからの送信データ
  【,C44,D44,E44,F44,G44,A44,B44,C52】
  OK: short-cut (0)

 どうですか?一応、音階らしき音がなったハズです。本ページ上の方の評価では、出力したPWMの周波数に依存した音が出なかったのですが……、もしかして、上の評価プログラムを間違えているのか??

 まずは、「#5-8 MMLで音楽を奏でる」と同様に、スピーカで鳴らした音階と、パッシブブザーで鳴らした音階を聞き比べてみましょう。

 パッシブブザーの方は、何故だか、耳障りな感じがしますが、「音階」は奏でているようです。正しい周波数が出ているかどうかは、残念ながら絶対音感を持ち合わせていないのでわかりません。ここは機械の手を借りましょう。
 上のWAVファイルをSoundEngine Freeで解析してみました。

 周波数解析してみたら、一目瞭然でしたね。C4(約262Hz)→C5(約523Hz)の音階(ドレミ…)を演奏しているので、250〜500[Hz]辺りに階段状のピークが出るのが正解です。

※周波数と音階の関係については、「鍵盤ハモニカで演奏する」をご参照ください。

 スピーカで鳴らした方は期待通りですが、パッシブブザーで鳴らした方は、250〜500[Hz]のピークがうっすらと見えている程度です。2〜4[kHz]近辺の高調波成分の方に、より強いピークが出ているので、甲高い耳障りな音に聞こえるのでしょう。
 本ページ上の方の評価で、PWM周波数に対応した周波数成分が見えなかったのは、ピークが小さすぎて、視認できなかったせいだと推察できます。


 スピーカなどを使わず、簡易的に音階を鳴らしたいケースでは、パッシブブザーを使う手段も可能なことはわかりましたが、少しでもきれいな(耳障りにならない)音で鳴らしたい場合には、「#5-8 MMLで音楽を奏でる」で示した方法を使うのがベストみたいです。


btn_arduino.png

btn_prev.png btn_next.png

home