気の向くままに辿るIT/ICT/IoT
IoT・電子工作

Arduinoで『オルゴールっぽいもの』を作る

ホーム前へ次へ
Arduinoって?

Arduinoで『オルゴールっぽいもの』を作る

Arduinoで『オルゴールっぽいもの』を作る

2017/12/24

 Arduinoを使って『オルゴールっぽいもの』を自作してみるページ。

 『っぽいもの』というのは、電子オルゴールというのもまた、構造からして、違う気がするため。

 また、家には、いくつかオルゴールがあるも、これを作るまで知らなかったのが、『オルゴール』とは、オランダ語やドイツ語の[orgel]に由来する和製造語で、英語では、[music box]とか、[musical box]と呼ぶということ。

 それは、さておき、オルゴールにもいろいろあってゼンマイを巻く機構ついでにメリーゴーラウンド(メリーゴーランド/merry-go-round/回転木馬)や観覧車、風車や扇風機が回ったりするものやゼンマイを巻いた後、引き出しや蓋を開けると鳴るものなどがあります。

 ここでは、スイッチを入れると「だるまさん」が回転し、ダルマだし、時節柄も、『お正月』を奏でるオルゴールちっくなものを作ることにします。

 季節的にといえば、今日はイブなのでクリスマスですが、回転体にも、いろいろ候補がある中、たまたま、ステップモータの軸と一緒に回る程度に、かつ、加工や固定することなく抜き差しできるものが、この達磨くらいで、ダルマとクリスマスソングじゃ微妙だよねということで正月ソングをチョイス。

 音階はネットで調べるといくつかあり、参考にしたものを結構、アレンジしてしまい音楽的にはいまいち...、それと自身が間違えて覚えているのか、「お正月には凧あげてー コマを回して遊びましょー」のメロディ部分が、記憶と違いますが、そこは妥協。

Arduino 2台で実装

『お正月』の曲にノってダルマが踊るオルゴール風のもの

 全体の構図は、簡単そのもの、ロッカスイッチをONすると圧電ブザー(パッシブブザー)モジュールで『お正月』のメロディを奏でつつ、ステッピングモータに載ったダルマが回るだけ。

 当初、Arduinoボード1つでいけるかと思いましたが、マルチタスクでないからでしょう、曲とステップでdelayが被ってるからか、どっちか一方のみ機能させれば、また、両方試すとメロディは流れますが、ステッピングモータが動かないという状態になり、Arduinoボードを2つ使うことにしました。

 2つ使うならTX/RX、I2Cなどで一方の状態の信号を送信、同時に動かせばよいだろうと思いましたが、一方のArduinoボードの電源から他方のArduinoボードの電源をとり、手抜きをしてステップモータも電源を共有することでロッカスイッチのON/OFFで連動するようにしました。

 が、これだとPCから電源をとらないと機能が安定しないかも...100均で買ったACコンセント接続USB充電器に挿すと電圧が安定しないのか、アダプタに起因して不足しているのか、モータは回るが、メロディが途切れたり、最初のフレーズだけ繰り返したりした...もう1個の同じアダプタでやってみたら数回はいけたが...また、不安定になる...もしかして、このアダプタの上限である電流1A超えてるのか!?でも、PCのUSB 2.0ポート(1ポートあたり500mA)で機能するんだから違うか...あ、延長コードのスイッチ付きコンセントとアダプタの間に噛ましてた電源分岐タップを外して直で延長コードにアダプタ付けたらいけた...タップの、しかも特定の接続口に起因するものだった模様...。

 本来は、電源を分けたり、整流ダイオードを入れたり、電池を使うなら尚更、省電力化を考慮してトランジスタの増幅機能(Arduinoボードのsleep機能は要らないか...)も入れるのが賢明、ステップモータの状態を変更し、停止含む動作にしたい場合、今回のスケッチだとステップモータ停止時も電流が流れるので変更が必要など、相応の工夫をする必要があるでしょう。

#define BEAT 500 // 音の長さを指定
#define PINNO 12 // 圧電スピーカを接続したピン番号
 
void setup(){
}
 
void loop(){
  melody();
  delay(3000);
}
 
void melody() {
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,440,BEAT); // ラ
  delay(BEAT);
  tone(PINNO,440,BEAT); // ラ
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,392,BEAT); // ソ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
 
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,330,BEAT); // ミ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,294,BEAT); // レ
  delay(BEAT);
  delay(BEAT);
  tone(PINNO,262,BEAT); // ド
  delay(BEAT);
  delay(BEAT);
}

 圧電ブザー担当のArduinoボードのスケッチは、これです。

 回路は、パッシブブザーモジュールのS、-(マイナス)をそれぞれArduinoボードのD12、GNDにつなぐだけ(中央のプラスは5V/3.3Vにつないでもつながなくても可)。

int motorPin1 = 8;
int motorPin2 = 9;
int motorPin3 = 10;
int motorPin4 = 11;
 
int motorSpeed = 2300;  // 速度。数値が小さいほど速くなる。2000以下は脱調が起きる。
int count = 0;          // ステップのカウンタ
int countsperrev = 512; // 1周した時のステップ数
int lookup[4] = {B01000, B00100, B00010, B00001};  //1-1相
 
void setup() {
  //declare the motor pins as outputs
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);
  Serial.begin(9600);
}
 
void loop(){
  if(count < countsperrev ) {
    clockwise();
  } else if (count == countsperrev * 2) {
    count = 0;
  } else {
    anticlockwise();
  }
  count++;
}
 
void anticlockwise()    //反時計回り
{
  for(int i = 0; i < 4; i++)
  {
    setOutput(i);
    delayMicroseconds(motorSpeed);
  }
}
 
void clockwise()    //時計回り
{
  for(int i = 3; i >= 0; i--)
  {
    setOutput(i);
    delayMicroseconds(motorSpeed);
  }
}
 
void setOutput(int out)
{
  digitalWrite(motorPin1, bitRead(lookup[out], 0));
  digitalWrite(motorPin2, bitRead(lookup[out], 1));
  digitalWrite(motorPin3, bitRead(lookup[out], 2));
  digitalWrite(motorPin4, bitRead(lookup[out], 3));
}

 ステッピングモータ担当のArduinoボードのスケッチは、ステッピングモータ 28BYJ をarduinoで動かしてみる(http://hp.hana-neko.com/archives/693からURL変わったらしい、httpだったけどhttpsもでいけたので書き換え)の「1-1相励磁」バージョン(どちらのバージョンでもよいと思います。)をそのまま使わせて頂きました。

 回路は、モータドライバ上のIN1〜IN4をArduinoボードのD8〜D11へ、プラスを5V、マイナスをGNDに繋ぐだけ。

 今回、ロッカスイッチは、ステッピングモータを担うArduinoボードの5Vに挟みました。

 この時、電源は、今回、普通のUSBケーブルを直接Arduinoボードに接続したため、ロッカスイッチをOFFしても電源入力側のArduinoボードの電源はONのままですが、自作含むON/OFFスイッチ付きのUSBケーブルを使うとか、電源を電池ボックスからとれば、電池ボックス側にロッカスイッチやスライドスイッチ、トグルスイッチなど何らかのスイッチを繋ぐことで回路全体の電源をOFFにすることもできるでしょう。

 Arduinoボードを共にNanoやPro Miniにすれば、100均の比較的小ぶりなケースなどにも収まるでしょうし、電源もモバイル充電器や電池にしてもよいでしょう。

 予算としては、Amazonマーケットプレイス激安店価格なら、Arduino Nanoボード2個として約580円(EasyWordMall/KKHMF 10個入り単価約290円)、ステッピングモータ・ドライバセット単価約220円、パッシブブザー単価約18円、400穴ブレッドボード単価約108円、ロッカスイッチ単価約20円、ワニグチクリップケーブルやジャンパワイヤが約60円、ケースを100円ショップで調達すれば、ダルマなど載っけるもの+載っける方法は別として材料費は締めて約1200円内外でいけるかと。

ホーム前へ次へ