tone() の解説と実装リファレンス
【概要】
tone() 関数は、Arduino環境において指定したデジタルピンから特定の周波数の矩形波(スクエア波)を生成するための関数である。主に圧電ブザーやスピーカーを駆動し、特定の音程の音を鳴らすために利用される。この関数は、内部的なタイマー割り込みを利用して波形を生成するため、関数呼び出しの直後もメインループの処理を継続できる非ブロッキングな特性を持つ。
【仕様】
関数シグネチャ
void tone(uint8_t pin, uint16_t frequency, uint16_t duration = 0);
void noTone(uint8_t pin);
引数
- pin: 出力に使用するデジタルピンの番号。
- frequency: 生成する矩形波の周波数(Hz)。1Hz以上の値を指定する。
- duration (任意): 音を維持する時間(ミリ秒)。デフォルトは0であり、0の場合は
noTone()が呼び出されるまで音が継続する。
戻り値
void(戻り値なし)。
初期状態
tone()を呼び出す前、またはnoTone()を実行した後は、指定したピンの出力は停止する。
【技術的特徴】
- 非ブロッキング動作:
delay()関数と異なり、tone()は実行中にプログラムの進行を停止させない。これは、Arduinoが内部タイマーをバックグラウンドで利用して波形を生成するためである。 - 矩形波の特性:
tone()はデューティ比50%の矩形波を出力する。これはanalogWrite()(PWM:パルス幅変調)が「平均電圧」を変化させるのに対し、tone()は「周波数(音程)」を変化させるものである。 - ハードウェアタイマーの利用: プラットフォーム(Uno, Mega, Nano等)により使用されるタイマーが異なる。そのため、他のタイマー依存ライブラリ(例:
Servoライブラリや一部のmillis()関連機能)と競合が発生し、特定の機能が停止する可能性がある。
【注意点】
- 同時生成の制限: ほとんどのArduino実装において、
tone()は同時に複数のピンで異なる周波数を生成することができない。一度tone()を呼び出すと、以前のtone()出力が上書きまたは停止される仕様となっている。 - タイマー競合: 特定のタイマーを
tone()が占有するため、それを使用する他の機能(例:millis()の精度低下やServoの動作不良)に影響を与えることがある。実装環境のデータシートを確認し、使用可能なタイマーを把握することが重要である。 - 解像度: 周波数の精度はマイコンのタイマークロックに依存する。非常に高い周波数や非常に低い周波数では、量子化誤差により正確な周波数が得られない場合がある。
- 音量制御:
tone()関数自体には音量を制御する引数はない。音量は、回路構成(抵抗値、アンプの使用有無)によって物理的に決定される。
【サンプルコード】
/*
* 簡易的なブザーの動作確認用コード
* 指定したピン(8番)に440Hz(ラ)の音を鳴らし、
* 1秒後に停止させる。
*/
const int buzzerPin = 8;
void setup() {
// 初期設定は不要(tone()内部でピン設定が行われる)
}
void loop() {
// 440Hzの音を500ミリ秒間鳴らす
tone(buzzerPin, 440, 500);
// 1秒間の待機(この間もtone()はバックグラウンドで動作する)
delay(1000);
// 880Hzの音を500ミリ秒間鳴らす
tone(buzzerPin, 880, 500);
delay(1000);
// 完全に停止させる
noTone(buzzerPin);
while(1); // 動作確認のため停止
}
【活用例】
- 警告アラーム: システム異常時に特定の周波数で警告音を鳴らす。
- UIフィードバック: ボタン操作時に短い「ビープ音」を鳴らし、ユーザーに操作を認識させる。
- メロディ再生: 周波数の配列を定義し、時間差で
tone()を呼び出すことで、簡易的なメロディを再生する。 - 状態通知: モーターの回転開始や充電の完了など、状態の変化を聴覚的に通知する。


コメント