スポンサーリンク
ものづくり・DIY

Arduinoでブザーを鳴らす|アクティブとパッシブの見分け方、tone()の使い方と音階の周波数、メロディの組み方

音階の周波数を求める

基準は「ラ」の440Hz

メロディを作るには、ドレミの音それぞれの周波数を知る必要があります。現在の多くの楽器では、ピアノの中央付近の「ラ(A4)」を440Hzに合わせるのが一般的です。

スポンサーリンク

音が1オクターブ上がると、周波数はちょうど2倍になります。1オクターブの中には半音が12個あり、ピアノなどで使われる平均律では、半音上がるごとに周波数が約1.0595倍(2の12乗根)になります。この関係を使うと、ラの440Hzから、すべての音の周波数を計算できます。

音名 記号 周波数(目安)
ド C4 262Hz
レ D4 294Hz
ミ E4 330Hz
ファ F4 349Hz
ソ G4 392Hz
ラ A4 440Hz
シ B4 494Hz
高いド C5 523Hz

tone() には整数で周波数を渡すため、小数点以下は四捨五入した値で十分です。1オクターブ上の音は表の値を2倍、1オクターブ下は半分にすれば求められます。

計算式で求める

ラ(A4)から半音いくつ離れているかを n とすると、周波数は次の式で求められます。

float freq = 440.0 * pow(2.0, n / 12.0);

たとえば、ドの C5 はラから3半音上なので、n に3を入れると約523Hzになります。この式を使えば、表にない音や、半音(シャープ・フラット)の周波数も計算できます。

圧電ブザーの響きやすい音域

圧電ブザーには、特によく響く周波数(共振周波数)があります。多くは2000Hzから4000Hz程度の高めの範囲にあり、その近くの音は大きく、離れた低い音は小さく聞こえます。

表の C4 から C5 あたりのメロディを鳴らすと、思ったより音が小さく感じることがあります。その場合は、すべての音を2倍にして1オクターブ上げると、聞き取りやすくなることがあります。部品のデータシートに共振周波数が載っていれば、それも参考にしましょう。

配列でメロディを組む

音と長さを配列にする

いくつもの音を順番に鳴らすときは、音の周波数と長さを配列に入れておき、for 文で順に取り出すと、スケッチが見やすくなります。

const int buzzerPin = 8;

// 周波数(0は休符)
const int melody[] = { 262, 294, 330, 349, 392, 0, 392, 330 };
// 長さ(ミリ秒)
const int durations[] = { 300, 300, 300, 300, 600, 200, 300, 600 };

const int noteCount = sizeof(melody) / sizeof(melody[0]);

void setup() {
  for (int i = 0; i < noteCount; i++) {
    if (melody[i] == 0) {
      noTone(buzzerPin);           // 休符
    } else {
      tone(buzzerPin, melody[i], durations[i]);
    }
    delay(durations[i] * 1.2);     // 少し間をあける
  }
  noTone(buzzerPin);
}

void loop() {
}

周波数を0にした要素を休符として扱い、その間は noTone() で音を止めています。delay() に長さの1.2倍の値を渡して、音と音の間に少し隙間を作っています。この倍率を変えると、なめらかに続く演奏か、一音ずつ切れる演奏かを調整できます。

スポンサーリンク

音名で書けるようにする

周波数を数字のまま並べると、どの音か分かりにくくなります。冒頭で音名を定数として決めておくと、楽譜を見ながら入力しやすくなります。

const int NOTE_C4 = 262;
const int NOTE_D4 = 294;
const int NOTE_E4 = 330;
const int REST = 0;

Arduino IDE のサンプルスケッチには、こうした音名の定数をまとめたファイルが付属しているものもあります。慣れてきたら、そうした定義を利用すると手早く書けます。

テンポで長さを決める

音の長さをミリ秒で直接書く代わりに、四分音符の長さを決めて、そこから計算する方法もあります。たとえば1分間に120拍のテンポなら、四分音符は500ミリ秒です。八分音符はその半分、二分音符は2倍と計算すれば、楽譜のリズムをそのまま移しやすくなります。

ボタンと組み合わせて確認音を作る

押したときだけ短く鳴らす

ブザーは、ボタンの入力と組み合わせると、操作した手応えを返す部品として役立ちます。ボタンを押した瞬間だけ、短い確認音を鳴らす例です。

const int buttonPin = 2;
const int buzzerPin = 8;
int lastState = HIGH;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  int state = digitalRead(buttonPin);
  if (lastState == HIGH && state == LOW) {
    tone(buzzerPin, 2000, 50);   // 短い高めの音
  }
  lastState = state;
  delay(10);
}

ここでは、ボタンを INPUT_PULLUP で読み、HIGH から LOW に変わった瞬間だけを検出しています。押しっぱなしにしても、鳴るのは一度だけです。プルアップの考え方や、押した瞬間の検出、チャタリング対策については、Arduinoでタクトスイッチを読むで詳しく説明しています。

音の使い分け

確認音、エラー音、完了音などを鳴らし分けると、画面のない作品でも状態が伝わりやすくなります。

  • 確認音:高めの音を短く1回
  • エラー音:低めの音を2回
  • 完了音:低い音から高い音へ、2〜3音で上がる

音の意味を決めておくと、自分で作った装置でも、使う人が迷いにくくなります。

次のページへうまく鳴らないときの原因と対処
スポンサーリンク
  1. 秋の戸口に並ぶかぼちゃの明かりとかぶ、麦束
  2. 資料を手に落ち着いて話し合う二人
  3. ノートパソコンと資料、外付け記憶装置がある机
  4. 冬の木で越冬する卵のうやミノムシ、テントウムシ
  5. 青い折り鶴と三角に折った紙、無地の折り紙