Mira&Luna's nursery lab

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

Happy Halloween🎉🎃 2021 和装の仮装「狐と狸の化けくらべ」🍂

f:id:miraluna:20211011111801j:plain

Happy
 Halloween
🎃


今年の仮装は「和装」です。
私たちが化けたのは。いえ、もしかしたらミラルナに化けているのかもしれませんよ。


f:id:miraluna:20211011111810j:plain


ルナ)練習でこの化粧をしたときは二人とも笑いが止まらなかったの。
ミラ)初めは控えめでかわいい感じだったんだけど、だんだんエスカレートして。
ルナ)最後は二人とも狐でも狸でもない新しい妖怪になってたね。
ミラ)ハロウィン本番よりもあの時が一番面白かったかも。

ルナミラTrick or Treat? Happy Halloween🎃

f:id:miraluna:20201223185301j:plain




2020年は「アナ&エルサ」
miraluna.hatenablog.com

日本版GPS「みちびき」初号機がバトンタッチ🚀 自作GPSロガーの受信精度も上がるかな🥕

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

準天頂衛星みちびき」の後継機が、今日打ち上げられました🚀

「みちびき」は位置情報などを知るのに使われているGPS(グローバル ポジショニング システム)の日本版。アメリカのGPSを補完する形で使われるから生粋の日本っ子ではないけど、準天頂衛星といって日本付近(オーストラリアのほうまで)のエリアだけをぐるぐる周回する"日本のための"衛星なの。今までに4機の「みちびき」が打ち上げられて4機体制で運用されてたんだけど、その初号機が交代の時期になったので後継ぎとなる後継機を打ち上げたの。それが今日。
みちびきの打ち上げに使われたロケット[H-ⅡA]はもう44機目なんだって。そんなにたくさんロケットを打ち上げてたなんて知らなかった。びっくりです。
2023年からは4機体制ではなくて、7機体制での運用が始まるそうですよ。楽しみ。

さてさてこのニュースが私となんの関係があるかというと、私の作ったGPSロガーは「みちびき」からの情報を受信できる子なんです。だからみちびきが7機体制になったり、グレードアップした新しい機体になったりすると、受信できるログデータがより精密になるんじゃないかと楽しみなの。
話によると誤差数センチメートルだそうよ。それってすごく精確🍅

こちらは ↓ 内閣府準天頂衛星システムみちびきの特設サイト。今日の打ち上げのニュースも載っています。
qzss.go.jp


そしてこちら ↓ は私が自作したGPSロガーの作り方の記事。の目次。
miraluna.hatenablog.com

今でもお出かけの時とかに持って行って、道のりのログを取るのに活躍しています。ルナがヨーロッパの自転車旅の時に使うために作ったの。   🎀 ルナの部屋へ 🎀


🌌 自作のGPSロガー
f:id:miraluna:20180111120123j:plain:w290 f:id:miraluna:20180111120142j:plain:w290


もしご興味があれば、GPSロガー自作の記事、見ていってくださいね。
f:id:miraluna:20181215104752j:plain:w200 ミラでした。   🍎 ミラの部屋へ 🍎

2つ目のトラブル🦇 tone関数で制御できる音符数が足りない😢

    Mira
 外付けEEPROMにデータを書き込み、tone関数で音楽を鳴らす電子メロディの作製🍑


<第5回>
「2つ目のトラブル🦇
  tone関数ではすべての音符を鳴らせない🐸」


目次

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



🌷 ATmega328p(蓄音機)と24LC64(レコード盤)の配線
f:id:miraluna:20210920085347p:plain

EEPROMと、ArduinoマイコンATmega328pを使って電子オルゴールを自作する電子工作をしています。

前回は、EEPROMに一曲分の楽譜データを書き込もうとしたところ、書き込む側のArduinoのRAMが足りなかったの。容量に対してデータが多かったのね。そこで曲をA~Eパートに分割してEEPROMに書き込むことにしました。
今回はその続きです。


書込み用プログラム分割
📝 Arduinoから外付けEEPROMへの書き込み
f:id:miraluna:20210920085453p:plain:w300:left
大仕事が終わった。『Onenight』一曲分のすべての音符の音階と長さのデータをプログラムに書きました。次はその楽譜データをEEPROMに書き込むことで、『OneNight』レコード盤が完成します。
前回はArduinoのRAMが足りなかったけれど、今回は曲を5つのパートに分けて、3回にわたって(AとB、DとEはいっしょにしました)書き込みます。
さあ、うまくいくかな?

上の図のように配線をして、Arduinoの書き込み用プログラム(→ プログラム例はこちら)に分割したデータを入れて、EEPROMに書き込みを行います。このときに書き込み用プログラムの中の音符数や書き込み番地も、パートに合わせて書き換えが必要です。


📓 例:) Cパートの書き込み用プログラム

/*EEPROMへ「OneNight」の「ABパート」を書き込んだ後に
「Cパート」を書込むためのツールスケッチ*/
#include<Wire.h>
#include "tone_def.h"

 int melody[] = {
  /*C*/o,ru,ru,0,s,s,s,l,s, s,o,m,o,o,l,f,r,l,o, ru,ru,ru,ru,ruh,s,l,s,  //27
  o,o,l,l,s,o,f,o,f,m,r, m,0,m,s,f,m,f,o, o,l,s,0,s,s,s,  //26
  du,s,s,s,du,s,s,s,du,l,s,  //11
  /*C①*/ru,fuh,su, ou,fuh,ou,su,su,fuh,mu,fuh,ru,s,ru,  //14
  mu,ru,mu,ou,ru,0,du,s, du,du,du,du,mu,ou,fuh,ou,fuh,ru,ru, s,l,l,s,ru,s,0,fuh,  //27
  ou,fuh,ou,su,su,fuh,mu,fuh,ru,ru, mu,fuh,ou,lu,su,0,mu,ou, 0,mu,fuh,0,ru,mu,mu, ou,su,muu,0,  //29
  ou,fu,mu,ru,s,s,ru, mu,ru,mu,o,ru,du,s, du,o,o,r,l,o,l,s,s, fh,s,mu,ou,   //27
  su,lu,ou,fuh,lu,ou,fuh,ru, ou,lu,su,mu,ou, mu,fuh,ru,mu,mu, ou,su,muu,0,  //22
  /*C*/o,ru,ru,0,s,s,s,l,s, s,o,m,o,o,l,f,r,l,o, ru,ru,ru,ru,ruh,s,l,s,  //27
  o,o,l,l,s,o,f,o,f,m,r, m,0,m,s,f,m,f,o, o,l,s,0,s,s,s,  //26
  du,s,s,s,du,s,s,s,du,l,s,  //11
  /*C②*/s,s, du,du,fu,ou,  //6
  };
 int durations[] = {
  /*C*/8,16,3.2,5.33,16,16,16,16,16, 8,16,5.33,16,16,8,16,8,8,3.2, 16,16,16,16,8,8,8,8,  //27
  8,16,8,16,16,16,4,16,16,16,16, 4,16,16,16,3.2,16,8,2.66, 16,16,3.2,16,16,16,16,  //26
  8,16,4,16,16,16,16,8,16,16,2.28,  //11
  /*C①*/32,32,16, 8,16,8,8,16,8,16,8,16,16,16,  //14 
  8,16,5.33,16,3.2,8,16,16, 8,16,8,16,16,16,8,16,8,8,16, 8,16,16,8,16,3.2,5.33,16,  //27
  8,16,8,8,16,8,16,8,8,16, 8,16,5.33,16,3.2,8,16,3.2, 8,16,3.2,8,16,2,4, 32,32,16,8,  //29
  8,16,8,8,3.2,8,8, 8,16,8,8,3.2,8,8, 8,16,3.2,8,8,8,16,16, 2,8,8,8,8,  //27
  8,16,8,5.33,8,16,8,5.33, 4,4,2.66,16,2.28, 16,2.28,16,2,4, 32,32,16,16,  //22
  /*C*/8,16,3.2,5.33,16,16,16,16,16, 8,16,5.33,16,16,8,16,8,8,3.2, 16,16,16,16,8,8,8,8,  //27
  8,16,8,16,16,16,4,16,16,16,16, 4,16,16,16,3.2,16,8,2.66, 16,16,3.2,16,16,16,16,  //26
  8,16,4,16,16,16,16,8,16,16,4,  //11
  /*C②*/4,2, 2,4,8,8,  //6
  };
    
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() {
  Serial.begin(9600);
  Wire.begin();
    for(int n=210; n < 253+210; n++){  
        //音符の数  210番地から書き込み 210~462番地まで書き込む
        //[210:ABパートの格納済み番地が208。209にはCパートの音符数格納。]
      eep_write(0x50,n,melody[n-210]/4);
        //濃縮[÷4:OneNight] nは210から210+253まで
        //eepに高音域(256以上)を格納できないので、÷4や-100の濃縮還元
        delay(5);//書き込み待ち
      eep_write(0x50,n+719-3,durations[n-210]);
        //719+207(AB音符数)番地から253個書き込む
        delay(5);//書込み待ち
    }
      eep_write(0x50,209,253);  //209番地にCの音符数格納
        delay(5);
}

void loop() {

}


ちょっとごちゃごちゃしていますが......。
プログラム下のほうの「void setup」のところを見てください。このプログラムはCパートの書込み用なので、EEPROMの書き込み先番地が210とか462とか大きな数になっています。これはABパートのデータがEEPROMの208番地まで書き込まれているから、その続きに書き込むため。音符数はCパートのみの音符数になっています。
プログラムの書き換えというのは、それら音符数や番地の数字のことです。

プログラム上のほうのmuやらruやらfuhは、音階のミやラやファ#のことです。ライブラリのようなものを作ったので、それら自作の名前が音階(周波数)を表しているんです。→ ライブラリを作る


外付けEEPROM内の番地図
EEPROM[24LC64]には0番地から8191番地まで、データを格納できる番地があります。『Onenight』の音符の数(私のプログラムでの音符数だけどね)は715音符。1つの音符には「音階データ」と「長さデータ」の2種類が必要。さらに各パートごとの音符数も記憶しなきゃいけない。こんがらがっちゃいそうだから、番地図を作りました。


番地名>            <格納データ

 0                ABパートの音符数
 1                曲全体のテンポ
 2~208              ABパート"音階" 207個
 209               Cパートの音符数
 210~462             Cパート"音階" 253個
 463               DEパートの音符数
 464~718             DEパート"音階" 255個

 719~925             ABパートの"長さ" 207個
 926~1178            Cパートの"長さ" 253個
 1179~1433            DEパートの"長さ" 255個
 

EEPROMの中はこんなふうにデータが収められていて、1433番地まで使っています。まだまだ空き地がいっぱいあるので、この5倍以上の長さの曲を入れたり、同じくらいの長さの曲を5曲入れるなんていうのもいいわね。

(この時点(トラブル前)での音符数の格納は、「0番地」に一曲の音符総数を格納するのみでした。上記のように各パートごとに音符数を格納しているのは、トラブル後の処理によるものです。)

さあ、これで加賀谷玲さんの『Onenight』が1曲まるまるっと入ったEEPROMレコード盤の完成です!(∂, ∂🎀y

f:id:miraluna:20211013184449p:plain:w300:left


 レコード盤『Onenight』"EEPROM"オリジナルエディション。あの「銀河鉄道の夜」の感動を再び。加賀谷玲のオリジナル曲を電子工作娘ミラヒェンが電圧スピーカ用にオリジナルアレンジ。
~現代(いま)だからこそ味わいたいレトロロマンがある~大好評発売中!

(嘘です。非売品です🐈)




🍰 Tea Time
f:id:miraluna:20200223224106j:plain
                       Mira & Luna's nursery lab


トラブル発生
 tone関数で制御できる音符数には制限があった🦇>

ついにレコード盤としての曲を収めたEEPROMが完成したので、さっそく再生用プログラムをArduinoに書き込んで再生してみましょう🍅

📯 再生用プログラム

Arduino IDE の「マイコンボードに書き込む」をクリック。
「書き込みが完了しました」の文字。
そしてブザー(圧電スピーカ)から「Onenight」のメロディが......
♪ Dancing ♬ f:id:miraluna:20210117102243j:plain:w100 やったね🎶



・・・ってなる予定だったのに~f:id:miraluna:20200916184356j:plain:w100

流れてきたのは変なバグ音。
い゛や゛~~🐛
Mira Bitter 🦇f:id:miraluna:20180430190439j:plain:w200


ほんのちょっとだけお菓子をやけ食いしてからいろいろ試して調べたところ、tone関数でメロディを流すとき音符数が257以上だと変なバグ音が出ることがわかったの。よく見つけた私、えらい。で、256だと無音で、255以下だと正常に動作する。ミラアレンジの『Onenight』の音符数は715。さあ、どうしましょ。

もうちょびっとだけお菓子を食べて考えました。


Tiny蓄音機再生用プログラムを変える>

tone関数で鳴らせる音楽は音符数255個まで。これは変えられそうにない。だから音符255個以内の演奏を3回行うことにしたらどうかしら。書き込みを行ったときのように曲を3分割して、それを連続して流す。つまりtone関数のプログラムを3つ続けて書くのよ。

🍎 こんなふうに

// Tiny蓄音機実装用 [OneNight]専用
// 周波数を÷4で濃縮還元用
#include<Wire.h>

int eep_read(int device_add, unsigned int eep_add){
  Wire.beginTransmission(device_add);//対象デバイスへ移動
  Wire.write((int)(eep_add >> 8));
  Wire.write((int)(eep_add & 0xff));
  Wire.endTransmission();
  
  Wire.requestFrom(device_add,1);
  if(Wire.available()){}
  return Wire.read();
}

void setup() {
  Wire.begin();
}

void loop() {
  int onpu_ab = eep_read(0x50,0);  //0番地から音符数を読む ABパート分
  int sokudo = eep_read(0x50,1);//1番地から速度を読む(100分の1)
  
  for(int note = 0; note < onpu_ab; note++){       //ABパート再生
    int melody =eep_read(0x50,note+2);
    int duration = eep_read(0x50,note+719);     //719番地からduration格納してある
    int noteDuration = sokudo*100 / duration;   //速度を復元(x100)
    tone(3, melody*4, noteDuration);

    int note_hazama = noteDuration * 1.10;
    delay(note_hazama);
  }

  int onpu_c = eep_read(0x50,209);              //209番地にあるCの音符数を読む
    for(int note = 0; note < onpu_c; note++){   //Cパート再生
    int melody =eep_read(0x50,note+onpu_ab+3);
    int duration = eep_read(0x50,note+onpu_ab+719);
    int noteDuration = sokudo*100 / duration;   //速度を復元(x100)
    tone(3, melody*4, noteDuration);
    int note_hazama = noteDuration * 1.10;
    delay(note_hazama);
  }

  int onpu_de = eep_read(0x50,463);             //463番地にあるDEの音符数を読む
    for(int note = 0; note < onpu_de; note++){   //DEパート再生
    int melody =eep_read(0x50,note+onpu_ab+onpu_c+4);
    int duration = eep_read(0x50,note+onpu_ab+onpu_c+719);
    int noteDuration = sokudo*100 / duration;   //速度を復元(x100)
    tone(3, melody*4, noteDuration);
    int note_hazama = noteDuration * 1.10;
    delay(note_hazama);
  }
  delay(5000);  //余韻
}


「ABパート再生」「Cパート再生」「DEパート再生」という部分が3つの再生プログラムね。
こうすればEEPROM内の楽譜データすべてを演奏することができる。
でもそのためには音符数の情報を各パートごとに読み取れるようにしなきゃいけない。3つのプログラムそれぞれで音符数の情報が必要になるからね。
そんなわけで上述の番地図のように「AB」「C」「DE」それぞれの音符数も格納できるようにEEPROM内のデータを書き直しました。
そして再生すると、うまくいきました。(∂. <🎀y

でもね、このやり方だと1つ諦めなくちゃいけないことがあるの。それは再生用プログラムに「OneNight」用の数値を書き込んでしまったことによって、『Onenight』専用の蓄音機になってしまったこと。
これでレコード盤EEPROMを交換すれば音楽が流れる「Tiny蓄音機レコード仕様」にはならない。プログラムのリライトが必要ね。
でもまずはこのプログラムで「Tiny蓄音機レコード仕様」の作製を進めていきます。書き換えは後からでもできるもんね🐪


兎に角🐇これで「Tiny蓄音機レコード仕様」で『OneNight』を鳴らすことができそうです。やれやれ🍵


次回もトラブル続きです。
 ミラでした。




目次

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




<お買い物コーナー>
🌟「銀河鉄道の夜」楽譜   🌟 CD        🌟 DVD
        
加賀谷玲さんの音楽も、KAGAYAさんの映像も、どちらも素敵です🌠