BEEP音の鳴らし方 | arduinoロボットプログラミング

2023年11月16日

Arduinoのtone関数を使い、CPUから単音(BEEP音)を鳴らすことで、昔のゲームに使われていたメロディーや効果音を簡単に自由に鳴らすことができます。Arduinoのデジタルピンからは、tone関数を利用し、BEEP音信号を指定した音の高さ(周波数)で出力しますが、それをそのままスピーカーにつないだだけではパワーが足りないので、オーディオアンプまたは圧電ブザーを使います。

クムクムロボット(ArduinoLeonardo)でBEEPを鳴らす

クムクムロボットにも、BEEP音発生機能があり、クムクムロボットではtone関数からのBEEP音信号をLM386というオーディオLSIによるオーディオアンプ回路で増幅しスピーカから鳴らします。
BEEP音の大きさはオーディオアンプ回路のボリュームによって簡単に変更できるので、一般のArduinoボードに比べ、余計な配線などは一切必要なく簡単にC言語でプログラムでクムクムロボットのスピーカーからBEEP音を鳴らすことができます。

クムクムロボットのメインボードの構成(アンプ接続図)

クムクム(入門モデル)のメインボードは、下記の図のように左側の上部のAMP(LM386によるオーディオアンプ)にCPUからBEEP陰陽の信号が出力され、その横のボリュームを通してスピーカに出力されています。
CPUからは単純にBEEP音を鳴らすためのポートに、ArduinoのC言語関数 toneによって制御するだけです。

ArduinoプログラムからBEEP音を制御するために

クムクムロボットのメインモードでは、BEEP音の出力はArduinoとしての(D12)ピンとなりオーディオアンプに接続されスピーカーへ到達します。
よって、プログラムからは(D12)をArduinoによるtone関数を使い、BEEP音の長さや高さをコントロールするプログラムを作ることによって効果音や楽曲を鳴らします

Arduinoとしてのポート
D12
関数
tone(D12,440,100) 指定した周波数のBEEP音を指定した長さで鳴らす
noTone(D12) BEEP音を止める

Arduinoのtone関数(クムクムロボット対応)

BEEP音を制御するArduinoのtone関数は標準に用意されている関数で、指定した出力ピンから、周波数(50%のデューティ・サイクル)の高さの音を出力時間(msec)鳴らします。
出力したBEEP音は、指定した出力時間が過ぎると自動で音は止まりますが、途中で強制的に出力を止めたいときにはnoTone()関数をコールします。
なお、出力時間(msec)を省略した場合は、出力を止める noTone()関数をコールするまでBEEP音はなり続けます。
また、tone関数によって指定できるPINは1つだけに限られますのでBEEP音は単音での発音となります。
※同時に複数のピンを指定して複数のBEEP音を同時に鳴らすことはできません。

void tone(出力PIN,周波数,出力時間)

出力PIN BEEP音に指定した出力PIN番号を指定します
周波数 出力するBEEP音の周波数を設定します
出力時間 BEEP音を何ミリ秒鳴らしたいかを設定します
型:unsigned long  0~4,294,967,295
戻り値 なし

発生できるBEEP音の周波数と可聴範囲は、アンプ・スピーカーの性能によって異なりますが、プログラム的には下記の値を指定することが可能です。

ボード 出力周波数
Uno,Mega,Leonardo,その他AVR系 31Hz~65535Hz
Zero 41Hz~275000Hz
Gemma,Due 実装なし

tone()関数はBEEP音発生のため内部でマイコンのタイマーを利用します。
そのため、マイコン内の同じタイマーを利用したPWMポートの一部が使えなくなったり、他のPWMポートで阻害されBEEP音が鳴らない場合が発生します。
その場合は、Arduinoのライブラリー内のソースコードないを変更しでタイマー割り込みの番号等を変更する必要があります。

※クムクムロボットでは、モータを7個使いPWMとToneが競合しているので、競合しないでBEEP音が鳴るようにTone側のタイマーを変更したプログラムを使っています。

ArduinoのnoTone関数

tone関数で出力したBEEP音を停止します。

void noTone(PIN番号)

PIN番号 BEEP陰陽にtoneを鳴らした出力PIN番号
戻り値 なし

BEEP音を音階配列で鳴らしてみる

ロボットとして、ちょっと面白くドレミを使ったBEEP音も鳴らしてみたいと思います。
曲を演奏するためのドレミファ音階の周波数を指定してBEEPを鳴らすこともできます。
以下の例では、ドレミファ音階を周波数テーブルとして配列で用意し発音しています。
鳴らしたBEEP音は、せっかく発音時間を設定していてもその時間分処理を止めないと、次のBEEP音で前の音を消してしまい意図した長さで発音させることができません。
そのため、tone で発音した後にArduinoのdelay関数によって次の処理までの時間を待つようにし音の長さを確保しています。


//---------------------------------------------------------------------------
// BEEP音階表現用周波数テーブル
//---------------------------------------------------------------------------
static int _NoteFreq[84] = {
  32, 35, 38, 39, 42, 44, 46, 49, 52, 56, 58, 62,
  66, 70, 74, 78, 82, 88, 94, 98, 104, 110, 118, 124,
  132, 140, 148, 156, 166, 176, 186, 196, 208, 220, 234, 248,
  262, 278, 294, 312, 330, 350, 370, 392, 416, 440, 466, 494,
  524, 554, 588, 622, 660, 698, 740, 784, 832, 880, 932, 988,
  1048, 1110, 1176, 1246, 1320, 1398, 1480, 1568, 1662, 1760, 1865, 1976,
  2094, 2218, 2350, 2490, 2638, 2794, 2960, 3136, 3322, 3520, 3730, 3952,
} ;

int BEEP_pin = 12;      
void setup() {
}
void loop() {
  for(int i=0;i<84;i++){
    tone(BEEP_pin,_NoteFreq[i],200) ;  // 
    delay(200) ;                  // 音がなっている間待機
  }
}

ArduinoLeonardoについて

Leonardo は、ATmega32u4 に USB 通信が組み込まれており、セカンダリ プロセッサが不要であるという点で、これまでのすべてのボードと異なります。これにより、Leonardo は、仮想 (CDC) シリアル / COM ポートに加えて、接続されたコンピュータにマウスとキーボードとして表示されるようになります。

Arduino Leonardo は、ATmega32u4 をベースにしたマイクロコントローラー ボードです。20 個のデジタル入出力ピン (そのうち 7 個は PWM 出力として使用可能、12 個はアナログ入力として使用可能)、16 MHz 水晶発振器、マイクロ USB 接続、電源ジャック、ICSP ヘッダー、およびリセット ボタンを備えています。これには、マイクロコントローラーをサポートするために必要なものがすべて含まれています。USB ケーブルでコンピューターに接続するか、AC-DC アダプターまたはバッテリーで電力を供給するだけで使用を開始できます。

出典 :https://docs.arduino.cc/hardware/leonardo

出典 :https://docs.arduino.cc/hardware/leonardo