Mira&Luna's nursery lab

旅乙女と発明娘の子供部屋

EEPROMに楽譜を記録する♬ ♪ ♬ Tiny蓄音機レコード仕様プロジェクト2 [EEPROMレコード盤作り]

f:id:miraluna:20180806220931j:plain:w200 Mira

自作電子工作🧸
Arduino外付けEEPROMを使った電子オルゴールTiny蓄音機レコード仕様」を作ろう🍩


<第2回>
EEPROM楽譜記録♬ "レコード盤作り"」



目次
   🍩 Tiny蓄音機レコード仕様を作ろう 🍩
🍩1回目「 構想とEEPROMについてと曲紹介
🍩2回目「EEPROMに楽譜を記録♬ "レコード盤作り"」(この記事)
🍩3回目「EEPROMから楽譜を読み取って演奏するプログラム
🍩4回目「トラブル1🐉 ArduinoのRAMが足りない..p_q..💦
🍩5回目「[トラブル2🦇 tone関数ではすべての音符を鳴らせない
🍩6回目「"ちびやっこ"意気消沈。お姉ちゃんの"みつは"は超オンチに🦆
🍩7回目「Tiny蓄音機レコード仕様、実装します。& 動画🎬
🍩8回目「Tiny蓄音機レコード仕様🎶 作り方まとめっ♬

~これから何回かに分けて書いていきます。書いたら目次も増やしていきます。~



⛅ イメージ図 🦄
f:id:miraluna:20210926165439j:plain

"Tiny蓄音機レコード仕様"のイメージはこんな感じです。
蓄音機には "ATmega328" AVRマイコン(みつは)を、
レコードには "24LC64" EEPROM( "24FC64" その他でもO.K.)を使う予定です。

[24LC64]が記憶媒体のEEPROM。I²C接続なら、他のEEPROMも使えます。
ここに曲を入れて、いろんなレコード盤を作る予定なの🍅


EEPROMの使い方
Arduinoを使って外付けEEPROMを使う方法は以前の記事に書いたので、電子オルゴールとは関係なくEEPROMへの読み書きの方法を知りたい方はこちらを読んでみてね。
miraluna.hatenablog.com


楽譜の再生にはtone関数を使う

EEPROMへの読み書きができるようになったら、そのデータをtone関数で再生します。
「tone関数」というのはArduinoにもともと備わっているスケッチ(プログラム)で、それを使えばブザーとかスピーカで簡単にメロディを鳴らすことができるの。
スケッチは「toneMelody」という名前。Arduino IDEを開いて、「ファイル」→「スケッチ例」→「02.Digital」→「toneMelody」の場所にありす。(ねぇアリス、"ま"が抜けてるわよ。それじゃあまるであなたが......)

ここですよ🍎
f:id:miraluna:20210926181547p:plain

tone関数を使って曲を流したときのプログラムの例はこちら 👇 の記事にあります。
miraluna.hatenablog.com


tone関数では音符の音階[Melody]と、音符の長さ[noteDurations]の2つのデータを組み合わせることで音を出します。「8分音符のド」とか。だから2種類の情報をEEPROMに記憶させておく必要がありますね。私の場合、記憶する番地の前半に音階データを、後半に長さデータを入れました。

ここで1つ問題が発生。tone関数は音符データの他に、曲の音符の総数と、曲の速度という2つの情報も必要です。この情報は再生するプログラムに書かなくてはいけません。でもそれって曲ごとに違う🐧。これでは蓄音機(みつは)のプログラムも曲ごとに書き換えなくちゃいけなくなる。それじゃ「Tiny蓄音機レコード仕様」にならないよ~💦
そこで発明少女ミラヒェン f:id:miraluna:20210106121707j:plain:w30 の工夫が光ります✨(自分で言うな)🍘

工夫音符の数と曲の速度の2つのデータをEEPROM(レコード盤)に収めておいて、蓄音機のプログラムでそのデータも読み取るようにしちゃおう(∂, ∂🎀y
そんなわけでEEPROMの
0番地には曲の音符の総数を、
1番地には曲の速度を、
書き込むことにしました。

さあ、それでは音符データをプログラムしていきましょう、とはりきっていたら、また問題が発生。音符の音階データは、その音の「周波数」を入れるんだけど、EEPROMの1つの番地(1つのデータを書き込める場所)は容量が1バイト。1バイトは0と1の情報(ビット)が8つ集まったものだから、2進法で8桁、つまり0~255の値しか表現できないの。音階の周波数には500とか800とかいう高い音のものもある。これじゃ低い音しか表現できないよ..p_q..💦
そこで🌟 またまた発明少女ミラヒェン f:id:miraluna:20210106121720j:plain:w30 の工夫がきらっと輝きます✨(ドヤ顔すな)🍙

工夫周波数の値を4分の1の大きさでEEPROMに格納して、蓄音機で読みだしたときに4倍する。曲の速度も1700とか5000とかだから、100分の1にして読むときに100倍する。
ほら、ジュースの濃縮果汁還元ってあるでしょ? あれよあれ(∂_∂🎀y ドヤァ



EEPROMに楽譜を書き込むためのプログラム
tone関数を使うための下準備が整ったので、EEPROMに楽譜(音符の音階と長さのデータ)を書き込むためのプログラムを作ります。『OneNight』は私にとって大作なので、まずは短い曲で作ってみましょう。ジョージ・ウィンストンさんの『あこがれ/愛』のサビのところです。

🍎 EEPROMへ楽譜を書き込むためのスケッチ 🍎

//EEPROMへ書込むためのツールスケッチ
//使用時に曲に合わせて書き換えが必要
//『あこがれ』

#include<Wire.h>

 int melody[] = {    //音符の音階(周波数)
  330,440,523, 659,523,440, 587,494,392, 523,494,440,330,
  440,494,523, 330,523,330, 494,294,494,294, 440,262,165,220,  //Akogare
 };
 int durations[] = {    //音符の長さ(16→16分音符)
 16,16,16, 8,16,16, 8,16,16, 16,16,16,8,  //13(音符の数)
 16,16,8,16,16,16, 16,16,16,16, 16,16,16,8,  //14  
 };                                     //音符総数 : 27
    
void eep_write(int device_add, unsigned int eep_add, int data){
  Wire.beginTransmission(device_add);//対象デバイスへ移動
  Wire.write((int)(eep_add >> 8));
  Wire.write((int)(eep_add & 0xff));
  Wire.write(data);
  Wire.endTransmission();
}

void setup() {
  Wire.begin();
    for(int n=2; n < 27+2; n++){        //要書換「音符の数」  2番地から書き込み
              //[あこがれ:27音符]
      eep_write(0x50,n,melody[n-2]/4);  //デバイス[0x50]  4分の1に濃縮
        delay(5);//書き込み待ち
      eep_write(0x50,n+27,durations[n-2]);    //要書換「音符の数」
        delay(5);//書込み待ち
    }
      eep_write(0x50,0,27);  //要書換「音符数」 0番地に音符数格納
        delay(5);
      eep_write(0x50,1,50);  //要書換「曲の速度」 1番地に曲の速度格納(100分の1で書く)
              //速度[あこがれ:5000]
        delay(5);
}

void loop() {

}

EEPROMをArduinoにつなぐ配線

プログラムができあがったら、EEPROMに楽譜を書き込みます。
書き込みを行う装置はArduino。だからArduinoとEEPROMを配線しなきゃいけないわね。

配線方法はこちらです。
f:id:miraluna:20210920085453p:plain
                           「24LC64」の pin配置図
f:id:miraluna:20210929195228p:plain:w200:right  Arduino     EEPROM
  5v      (赤)     Vcc
  GND     (黒)     GND(Vss)
  SCL      (黄)     SCL
  SDA  (緑) 2kΩ分岐    SDA
  5v           分岐した2kΩ
  GND    (水色)     WP
  GND     (橙)     A0
  GND     (橙)     A1
  GND     (橙)     A2

※WPはGNDにつなぐと書き込み可。5vにつなぐと書き込み不可。
※橙のA0~A2はデバイスアドレス用チップセレクト。全部GNDならアドレスは[0x50]。
※SDAの2kΩはプルアップ用。厳密に2kΩでなくてもO.K.(2.2kとか4.7kとか)。


配線完了(∂. < 🎀/

この状態で Arduinoに上の楽譜書き込み用プログラムを書き込めば、
EEPROMの0番地には音符数の「27」が、
1番地には曲の速度(100分の1)の「50」が、
2番地~28番地には音符の音階「melody」が、
29番地~55番地には音符の長さ「durations」が格納されるはず。

つまり楽譜をEEPROMに記憶させたわけだから、
EEPROM🍩レコード盤の完成 f:id:miraluna:20191015184121j:plain:w100


次回はEEPROMレコード盤から楽譜を読み取って、実際に曲を鳴らすプログラムスケッチを紹介します。
ミラでした。またね(∂, ∂🎀ノシ
f:id:miraluna:20180127173159j:plain:w200 🧸ミラの部屋へ🧸



目次   🍩 Tiny蓄音機レコード仕様を作ろう 🍩
🍩1回目「 構想とEEPROMについてと曲紹介
🍩2回目「EEPROMに楽譜を記録♬ "レコード盤作り"」(この記事)
[次回]🍩3回目「EEPROMから楽譜を読み取って演奏するプログラム
🍩4回目「トラブル1🐉 ArduinoのRAMが足りない..p_q..💦
🍩5回目「[トラブル2🦇 tone関数ではすべての音符を鳴らせない
🍩6回目「"ちびやっこ"意気消沈。お姉ちゃんの"みつは"は超オンチに🦆
🍩7回目「Tiny蓄音機レコード仕様、実装します。& 動画🎬
🍩8回目「Tiny蓄音機レコード仕様🎶 作り方まとめっ♬