以前のリビジョンの文書です
ライントレーサーに載せてあるスピーカーを使っていきたいと思います。
ここまで来た人はタイマー割り込み(CMT)が理解できていますよね?
それではやっていきます。
音ってなんでしょう。皆さんなら波動であることは知っていますよね?スピーカーは電気的な波を受けることによって音波に変換してくれます
(構造は面白いので時間があったら調べてみるといいかも)
電気的な波を起こすには一定の時間ON,OFFを繰り返す必要があります。
一定の時間ということでCMT割り込みを使っていきます。
皆さんは1/1000秒(1ms)に一回割り込んでますね?
しかし音を鳴らすのにはもっと速く割り込んでもらわないといけません。
そこで25倍の速さ、1/25000秒(40μs)で割り込んでみてください。
LEDが1秒毎にON,OFFするはずのプログラムが
嫌になるような高速でチカチカするようになるはずです。
できましたか?ヒント;initCMTの割り込み周期を変えよう
音の周波数の基準値というのは440Hz(ふつうのラ)だそうです。
楽器を習ったことのある人は知っているかも
まず、割り込みの関数内で1ずつ加算される変数sound_countを作ってください。
次に440Hzの電気的な波、つまり1秒間に440回ON/OFFの波を送ってみてください。
とりあえずON,OFFのプログラムをwhile(1){}の中に入れてみましょう。
ヒント;(ONまたはOFFの時間)=(周期/2) 周期=(1/周波数)
上手くいかない人へ;カウントリセットを忘れていませんか?
出ました?といっても絶対音感の持ち主じゃなきゃわからないですよね?\\スマホのピアノ(鍵盤)アプリとかをダウンロードして、ラの音(これはわかるよね)を出してみてください。
1では永遠に「ラ」の音が出ているプログラムが書けましたね。
音程は周波数の部分を変えるだけです。それぞれの音の周波数はここで
好きな音、無ければドの音を出してみてください。
またメロディには休符(「そ」とか「皿」みたいなやつ)があります。みなさん知っているようにその期間だけ音を止めます
やり方はとても簡単です。ON/OFFをしているプログラムを止めればいいだけです。
次に長さを変えてみたいと思います。
いろいろと方法はありますが、一番簡単だと思われる方法でやっていきます。
sound_countと同じようにlength_countを用意してください。
while(1)の部分をwhile(length_count⇐流したい時間(ms)×25)にしてみましょう
またそれぞれの音の終わりには一瞬、休符を入れてみるといいです。
音楽チョー得意だぜって人はいいですが、そうでない人は下のをやってみてください
「ソ」200msを3回、「レ#」1000msを1回、「ファ」200msを3回、「レ」1000msを1回
きっと皆さんが知っている曲が流れると思います。
くれぐれもカウントリセットを忘れずに!!
音の長さは明確に決められている場合が多いです。曲によって違いますが一分間に四分音符が50~300くらいだそうです。
上でやってもらった曲では一分間に四分音符が168~216回だそうです。
ちなみにソとファは八分音符、レ#とレが四分音符×2.5です。
それを考慮して上の交響曲を流してみてください。
2では好きなメロディを流すことができるようになりましたね?
えっメロディ流したくても音がわからない?――音感がある人に耳コピしてもらいましょう。
人によっては知っているかもしれませんが、プログラムには定義文というものがあります。
定義文は次のように書くことが出来ます。
#define (定義名) プログラム
これはプログラムの一番最初に書いてください。
例えば #define ra0 440 のように書いてみます。
するとra0に440という数が”定義”されました
以降、「ふつうのラの周波数はえっーーーと440Hzだ」ではなく
「ふつうのラの周波数はra0」と調べたり思い出す時間、手間を省けます
他にもモーターを回す際にポートを調べたり、覚えたりする手間が省けます。その際は
#define Motor_Right_ON (PE.DRL.BIT.B0=1; PE.DRL.BIT.B1=0;)
のようにします。以降はMotor_Right_ON;とプログラムに入力するだけで
右のモーターが回ってくれます。なんか直感的でいいですよね?
注意:次の関数と違い#defineが書いてある一行しか定義されません。
3,4で音が簡単に流せるようになりましたね?たぶん人によっては5,6行でひとつの音が流せているかもしれません。
しかし、関数化することによってたった一行で音やメロディを流せるようになります。