このサイトはMacを使って Arduino Uno の動作や活用法を学びます。

24 Arduino 電子オルゴールで曲を演奏

この記事では、Arduino で電子オルゴールのスケッチを作り曲を演奏させようと思います。以前の記事 圧電スピーカーを接続 では、Arduino で「ドレミ」の音階を発生させました。また、PICマイコンでは既に記事 オルゴール [6] 楽譜の演奏プログラム で曲を演奏するプログラムを作成しています。

今回は、これら今まで学習してきたことの応用で、Arduino でも電子オルゴールのスケッチを作ります、

 

使用するハードウエア

ハードウエアは。 圧電スピーカーを接続 で使用したものです

圧電スピーカーは、Arduino ピン8 - GND 間に取り付けています。

 

楽譜ファイルの作成

Arduino で「ドレミ」の音階を発生させた時は、発音の順にその音階の周波数を調べスケッチ内の配列に記入していました。この方法だと、演奏曲を変更するたびにスケッチを変更しなければなりません。

今回は、楽譜データだけを独立したファイル、gakufu.h に分けることでこの点を改善します。

音の高さ

音の高さを周波数で列記するのはやめ、音符の名称「ドレミ...」を整数値に置き換えて記録する方法に変更します。この「ドレミ...」を整数値に置き換える方法は、音楽関連員インターフェースの「MIDIフォーマット」で採用されており、このスケッチでも中心の「ド」の音をMIDIと同様に、「60」にします。

この値を読み込みスケッチ本体で、対応する周波数に変換します。

音の長さ

「ドレミ」の音階を発生させた記事では、音の長さは500msで一定でした。しかし曲を演奏するには、音符の種類により音の長さを変更する必要があります。音符は、二分音符、四分音符、八分音符、十六分音符 と順にその長さが、半分ずつになります。基準単位を設けて、四分音符は8単位、八分音符は4単位・・・とすれば良さそうです。

楽譜の独自フォーマット

以上の音の高さ長さの考察から、音階を、16bits (1 word) で表現し、MSB 8 bitが音の高さ、 LSB 8 bitが音の長さを表します。

   | 76543210| 76543210|

   |    高さ     |   長さ     |

 

楽譜の情報は、"gakufu.h" に、ある、unsigned int 配列 「p1gkf」に記述します。

"gakufu.h" の例 

const unsigned int p1gkf[] = {
    96, // ハッピーバースデイー
    0x4304,0x4304,0x4508,0x4308,0x4808,0x4710,0x4304,0x4304,
    0x4508,0x4308,0x4A08,0x4810,0x4304,0x4304,0x4F08,0x4C08,
    0x4808,0x4708,0x4508,0x4D04,0x4D04,0x4C08,0x4808,0x4A08,
    0x4810,
    0xFFFF,
    0xFFFF,
};

 

スケッチ内容

「musicBox」というスケッチを作成しました。以下に内容を示します。

このスケッチで、圧電スピーカーから楽譜ファイルに記録された曲を演奏させます。

"musicBox.ino"

//  電子オルゴールで曲を演奏
// 2021-6-18

#include "gakufu.h"     // 楽譜

// 音階周波数一覧   262Hz(index 37) が中心のド(60 0x3C)
const uint16_t dW_tbl[] = {
//  Do, Do#,  Re, Re#,  Mi,  Fa, Fa#,  So, So#,  Ra, Ra#,  Si,
     0,
    33,  35,  37,  39,  41,  44,  46,  49,  52,  55,  58,  62,  // 1-12
    65,  69,  73,  78,  82,  87,  92,  98, 104, 110, 117, 123,  //13-24
   131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,  //25-36
   262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,  //37-48
   523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,  //49-60
  1047,1109,1175,1245,1319,1397,1480,1568,1661,1760,1865,1976   //61-72
};

int PBuzzer = 8;      // 圧電スピーカー接続pin
int buttonApin = 14;  // A0 pinをデジタルで使用

void setup() {

}

void loop() {
  int tempo = 7500/p1gkf[0];    // テンポ曲の速さを取得
  int thisNote = 1;
  while(p1gkf[thisNote] != 0xFFFF){         // 楽譜を順にし手と取得
    int duration = p1gkf[thisNote] & 0xFF;  // 音符の長さ取得
        duration = duration * tempo;        // 音符の長さ計算
    int freq = p1gkf[thisNote] >> 8;        // 音の高さ取得
    if(freq){                               // 休符でないなら
      freq = dW_tbl[freq - 24];             // 音の周波数計算
      tone(PBuzzer, freq, duration);        // 音符演奏
    }
    delay(duration+20);     // 音符休符の演奏時間
    thisNote++;             // 音符位置を進める
  }
  while(1);                 // Stop
}

 

スケッチの実行手順

電子オルゴールで曲を演奏するスケッチの実行手順の一例を示します。

  1. Arduinoアプリを起動し、上記 "musicBox.ino" の内容をコピーして新規ファイルに貼り付けます。
  2. Arduinoアプリのメニュー -> ファイル -> 名を付けて保存 を選択してスケッチを保存します。
    この例では、Arduinoディレクトリに "musicBox"との名称で保存します。
  3. テキストエディターで新規ファイルを作成し、上記 "gakufu.h" の内容をコピーして、そのファイル名を "gakufu.h" とし、 "musicBox"が保存されている Arduinoディレクトリに保存します。
     Arduino
      ┗ musicBox
         ┣ gakufu.h
         ┗ musicBox.ino
  4. 以上で準備完了です。Arduinoアプリの書き込みボタンをクリックしてスケッチを実行してください。

これで、ハピバースデーの歌が演奏されます。

 


 

次回は、このスケッチで演奏できる楽譜データを簡単に作成する方法を紹介します。