58曲メロディICをArduinoで制御する(2桁7セグメントLEDで曲数表示対応)
58曲のメロディが入った「M8058S」という超小型メロディICがあります。
SOP8パッケージということでかなり小型です。
僕の人差し指の先に乗せて撮ってみた写真がこれ。
高品質なメロディが58曲も入っていて、電子オルゴールとしてはかなり高機能で小型なものが作れます。しかも150円。
そのままサンプル回路通り結線しても楽しめるのですが、この回路では一曲ずつ選んで再生する機能しかなく、58曲目を聴くためにはかなりボタンを押しまくらないとたどり着くことができません。また、たくさんの曲の中から、何番目の曲を選択しているのか、状態を確認することができないのも悩みどころです。
このICには、マイコンからのシリアル入力でコマンドを送って選曲する機能もあるので、曲数表示とあわせてArduinoで制御してみることにします。
目次
- 目次
- まずは58曲メロディICの音楽を再生してみる
- Arduino pro miniで制御する
- 回路図
- Arduinoの各I/Oピンの使い方
- 58曲メロディIC「M8058S」をマイコンからコマンド制御する
- ボリューム型可変抵抗とボタン入力を一つのアナログ入力で読み込む
- 2桁7セグメントLEDで曲番号とメロディ再生状態を表示する
- まとめ
- 部材リスト
まずは58曲メロディICの音楽を再生してみる
最初に、ICのメロディと機能確認のために、リファレンス実装通りにブレッドボードで動かしてみました。
58曲メロディIC(M8058S)をサンプル回路通りにブレッドボードで実装して再生する
回路はaitendoさんのホームページにあります。
引用したのはこちら。
音色も良い感じです。
ただ、全部聴くのが大変・・・。
マイコン(Arduino)で状態表示と、コマンド制御することにします。
Arduino pro miniで制御する
58曲メロディICM8058SとArduino pro miniをブレッドボードで接続した様子がこちら。
Arduino pro miniで制御するための回路図とソースコードをgithubにて公開しました。
ここでは、各ポイントだけ解説していこうと思います。
- 7セグメントLEDに選曲番号を表示する
- 選曲はボリューム型の可変抵抗で行うようにする
- ボタンを押したら再生・停止が行えるようにする
- 小型・多機能オルゴールボックスを最終ゴールとするため、1ピンのアナログ入力と4ピンのデジタルIOのみで制御できるように制御ピンを最小化する
特に、4番がポイントです。
Arduinoだと十分な数のGPIOがあるので制御は容易ですが、このあと、小型化のためにATTiny85に移植します。ATTiny85では、5ピンしか制御ピンが無いので、ボタンそれぞれにGPIOを使ってると7セグメントLEDとメロディIC制御を行うためのピンが足りなくなります。今回、1つのアナログ入力で選曲用のボリューム可変抵抗の読み込みとボタンの状態読み込みをまとめて制御することにより、ATTiny85にも対応するようになっています。
回路図
接続の回路図です。
Arduinoの各I/Oピンの使い方
Arduinoの各I/Oピンの使い方は以下の通り。
- D2:メロディIC(M8058S)へのコマンド送信用。
メロディICの7番ピンに接続する。 - D3:7セグメントLED制御用(LATCH)。
シフトレジスタ(74HC595)のLATCHピンに接続する。 - D4:7セグメントLED制御用(シフトレジスタ用クロック)。
シフトレジスタ(74HC595)のRCLKピンに接続する。 - D5:7セグメントLED制御用(シリアル入力)。
シフトレジスタ(74HC595)のSER(シリアル入力)ピンに接続する。 - A0:入力状態判定用アナログ入力。
選曲用ボリューム可変抵抗とボタンで構成された複合抵抗を読み込んで入力判定するのに使用する。
58曲メロディIC「M8058S」をマイコンからコマンド制御する
M8058SのVOLボタンを接続してる7番ピンに、データシートのタイミングの通りにコマンドを送れば、メロディ選曲や音量調整、再生・停止、再生モードなどが可能です。ArduinoのD2ピンにつないで、データシートに記載されているタイミングでシリアルデータを送ります。
このコマンド送信のためのArduinoのソースコードはgithubを御覧ください。
void send_melody_command(int command) {
int i=0;// Initialize port
digitalWrite(PIN_MELODYIC_CTRL, LOW);// Send header to melody IC
digitalWrite(PIN_MELODYIC_CTRL, HIGH);
delay(6);
digitalWrite(PIN_MELODYIC_CTRL, LOW);// Send DATA
for(i=0;i<8;i++){
if( ((command>>i)&0x1) == 1){
delayMicroseconds(500);
digitalWrite(PIN_MELODYIC_CTRL, HIGH);
delayMicroseconds(1500);
} else {
delayMicroseconds(1500);
digitalWrite(PIN_MELODYIC_CTRL, HIGH);
delayMicroseconds(500);
}
digitalWrite(PIN_MELODYIC_CTRL, LOW);
}
return 0;
}
送信できるコマンドは次のとおりです。
<16進数コマンド>
・曲を指定する
0X00:メロディ1
0X01:メロディ2
...
0X3A:メロディ58・動作ステータス
0XE8:メロディ再生+LED点滅
0XE9:メロディ再生のみ
0XEA:LED点滅のみ
0XEB:メロディ再生+LED常時点灯・出力音量レベル設定
0XF0:音量レベル1
0XF1:音量レベル2
0XF2:音量レベル3
0XF3:音量レベル4
0XF4:音量レベル5
0XF5:音量レベル6
0XF6:音量レベル7
0XF7:音量レベル8
0XE8:音量レベル9・動作を制御する
0XFB:再生
0XFC:次の曲
0XFD:前の曲
0XFE:音量
0XFF:再生停止
ボリューム型可変抵抗とボタン入力を一つのアナログ入力で読み込む
Arduinoだと十分な数のGPIOがあるのでこんなことをやる必要は無かったのですが、このあと、小型化・省電力化(さらには低コスト化)のためにATTiny85に移植を行います。
ATTiny85では、5ピンしか制御ピンが無いので、ボタンそれぞれにGPIOを使ってると7セグメントLEDとメロディIC制御を行うためのピンが足りなくなります。今回、1つのアナログ入力で選曲用のボリューム可変抵抗の読み込みとボタンの状態読み込みをまとめて制御することにより、ATTiny85にも対応するようになっています。
今回、この複合入力抵抗を構成するために、次のような回路構成を組んでいます。
- Arduinoのアナログ入力ピンを2.2kΩでプルアップします。
- ボリューム型可変抵抗は最大10kΩのものを使用しています。これに2.2kΩの抵抗を直列につなぎ、最小抵抗2.2kΩ、最大抵抗12.2kΩのラインを構成します。
- 可変抵抗と並列に、押したら1kΩのラインとし、停止ボタン機能を割り振ります。
- 可変抵抗と並列に、押したら150Ωのラインとし、再生ボタン機能を割り振ります。
上記の回路構成により、可変抵抗の位置・ボタンの押下状況にあわせて、アナログ入力には次の値が得られることが算出できます。
結果、ボリューム可変抵抗の読み取り値と、ボタンの押下状況は、次のアナログ入力値によって判定が可能となります。
- ボリューム可変抵抗はアナログ読み込み値512~867の値を取る。(多少の誤差があるのでマージンをもつ必要はある。)これをメロディ曲数で割れば、選曲に使用できる。
- 再生ボタンを押したときは、65付近の値を取る。これで、再生ボタンが押されたかどうか判定できる。
- 停止ボタンを押したときは320あたりの値を取る。これで、停止ボタンが押されたかどうか判定できる。
githubのソースコードは、多少の抵抗のばらつきを考慮した値にチューニングしてあります。
2桁7セグメントLEDで曲番号とメロディ再生状態を表示する
今回、現在選曲している曲番号の表示は小型の2桁7セグメントLED(アノードコモン)を使用しました。ここでも、ピンの節約を工夫しています。
マイコン側は5ピンの制約で設計しているため、上述のメロディICの制御で1ピン、キー入力・選曲で1ピン使うと、残り3ピンとなります。今回使用する7セグメントLEDは10ピンあるため、8ビットのシフトレジスタを使っても2つ足りません。そこで、今回は次のポイントを工夫しています。
- マイコン(Arduino)から表示するのは、数値表示の7ビットとし、DP用のLEDは、メロディIC(M8058S)の再生状態表示LEDの表示場所として活用する。
- 7セグメントLEDの表示桁選択ピン(6番ピンと9番ピン)を、シフトレジスタに送るデータの最下位ビットに割り振り、この状態によって表示桁切り替えを行う。
1つめの工夫は、メロディICの再生状態表示LED用の8番ピンを、7セグメントLEDのDP表示用ピン(5番ピン)に接続すればOK。再生中は、7セグメントLEDのDP(小数点)の桁がチカチカして再生状態がわかるようになります。
2つ目の7セグメントLEDの表示桁を制御するために、8ビットシフトレジスタの出力最下位ビットの状態は、必ず次のような状態にする必要があります。
- 選曲番号の1の位を表示する(最下位ビットが0のとき):
7セグLEDの6番ピンにHIGHを出力、9番ピンにLOWを出力 - 選曲番号の10の位を表示する(最下位ビットが1のとき):
7セグLEDの6番ピンにLOWを出力、9番ピンにHIGを出力
つまり、7セグメントLEDの6番と論理が逆の信号を9番ピンに出力する必要があります。このため、シフトレジスタの最下位ビットは7セグメントLED6番ピンに接続する出力信号の他に、論理が逆の出力(NOT回路)を作って7セグメントLEDの9番ピンに接続しています。
回路図では、この部分になります。
この回路により、選曲番号表示は次のようなソースコードで制御しています。
void display_melody_num(int number) {
char num1, num2, dispnum;num1 = number / 10;
num2 = number % 10;if(led_digit == 0) {
dispnum = data[num1] | 0x01;
led_digit = 1;
} else {
dispnum = data[num2] & 0xFE;
led_digit = 0;
}
digitalWrite(PIN_LATCH, LOW);
shiftOut(PIN_SER, PIN_RCLK, LSBFIRST, dispnum);
digitalWrite(PIN_LATCH, HIGH);}
7セグメントLEDは各桁の表示処理しかできないので、表示処理が回ってくるごとに、表示桁を切り替えて、残像が見えることで全桁表示しているように見せています。
まとめ
Arduinoに書き込んで動作を確認している動画がこちら。
58曲メロディICをArduinoで制御する(2桁7セグメントLEDで曲数表示対応)
58曲のメロディを、ボリューム型のツマミで自由に選曲して再生させることができます。
開発用にArduinoで制御しましたが、最終的にはこのソースコードをATTiny85に移植して動作させます。Arduinoの豊富なI/Oを使えばいろいろな工夫は不要ですが、アナログ入力、シフトレジスタ、論理回路を使ったI/Oの節約制御は他にも活用できると思いますので、参考にしていただければと思います。
ATTiny85で動作させるための続きの記事は 次のブロクで記載します。
部材リスト
主要な部品リストです。
- 58曲メロディIC・M8058S
- Arduino pro mini互換ボード
- 小型7セグメントLED2桁表示・アノードコモン
- 8ビットシフトレジスタ・74HC595
- ダイナミックスピーカー
- ボリューム型可変抵抗(10kΩ)
- NPNトランジスタ
- 抵抗
- スイッチ