電子工作勉強会(まとめ)
see also: http://d.hatena.ne.jp/inajob/20090712, http://d.hatena.ne.jp/tgbt/20090713/1247500951, http://www16.atwiki.jp/tokoroten/pages/1166.html
id:tgbt, id:inajob, id:nyaxt, id:TOKOROTEN, masa-uらと電子工作祭りをした。
できたもの: http://www.youtube.com/watch?v=Segch217C0w
「とりあえず音の出るものを作ろう」だけしか決めてなかったんだけど、なんだかよくわからないうちに音源チップとやらを買うことになった。ヤマハ音源IC(YMZ294)500円。
Atmel AVRのAtmega168、FT232RL USBシリアル変換モジュール(950円)、ブレッドボードでとりあえず最初はArduino互換基盤を作るとことからスタート。ブレッドボードはパズルだった。
出来上がったので電源を通してテスト。動いた!AVRにはあらかじめ masa-u 先生によってArduinoのブートローダが焼き込んであったらしい。たぶん。
右上隅のがUSBシリアル変換回路で、そこからAVRに適切に配線をしてある。銀色の部品が水晶発信子で、AVRの9と10のXTAL(クリスタル)って足に入って行く。GNDとVCCはなぜか二つあるので両方に同じようにつなぐ。あと送受信用のTXD, RXDをUSBシリアル回路とつなぐ。
うまく動いたので次は開発環境とかを色々インストールする。まあArduinoの公式サイトにいってGetting Startedを読めば全部書いてあるので省略。
さっそくLEDを点滅するプログラムに書き換える。といっても点滅させるサンプルコードが載っているのでその通りにするだけ: Arduino - Blink
さて書き込み。しかし挙動に変化がない。さんざん悩んだ結果、配線が間違っていた罠。TXD, RXDあたりが1マスずれていて「すでに書き込んであるプログラムを電源供給を受けて実行することはできるが、新しいプログラムを書き込めない」という状態になっていた。修正。
LEDの点滅ができたので次はPWM(Pluse Width Modulation, パルス幅変調)に挑戦。というかドキュメントにきちんと書いてあるのでその通りにやるだけ。蛍みたいに点滅するLEDができました。
次は音を出すためにアンプを作る。LM368というチップらしい。「ぐぐってデータシートを読め。何が必要か申請せよ」といわれたので id:inajob と二人で読む。最小構成で十分らしいので250microF、0.05microF、10オームの3つの部品を申請する。もらった部品は220microF、0.1microF、抵抗はえっと茶緑黒金なので15オームかな。
上がドキュメントに書いてあったのに近い回路図。下が実際に組んだ形に近い回路図。
回路の写真。
さて、アンプができたので早速何かを流し込んでみよう。と、ここで「PWMで明るさ調節をしているこのLEDの信号を音の入力に入れたらいいんじゃないの」と試してみたらあっさり音がなった。
ここら辺で開始から3時間くらい経ってみんなおなかがすいてきたので片付けて晩ご飯。たくさん食べるうえのたんを眺める。
押しボタンスイッチを接続して「押している間だけ音が出る」というコードを書いてみたが、押してない間にも音が出る。押すと音が変わる。押されると開始するコードにすると押していないのに開始する。ノイズで押されている?などと思ったがスイッチをVccとの間に挟んだのが間違い(スイッチが切れている=開いている時には0だと思ったが違う。不定値)で、そういうのは「スイッチが押されるとGNDに繋がる」という回路にしておいてコードの方でプルアップをするものらしい。回路でプルアップすることもできるがArduinoでは1行書くだけで内部的にプルアップさせられる。
次は音源ICだ。音源ICを買っているのは僕一人だったので孤軍だ。読み方がよくわからない。なんだかすごく複雑だし!こんなの読んで理解しろって無理だ!とか思っていたけど、今になって思えば重要な情報は全部ここに書いてある。
φMにクロックの信号を入れて、4/6でクロックが4メガなのか6メガなのかを指定し、リセットはとりあえず使わないことにしてHにしておく(ここつまずいた!電子回路だとHがfalseでLがtrueになっていることが多い。プログラマの発送と逆)
写真では水晶の1が何かに結線されているけど開放でいい。
回路は正しくできたつもりだがなぜかうんともすんとも音が出ない。しばらく悩んだが眠くなったので寝る。
起きる。寝ている間に回路を調べてくれたらしくて「回路的には問題がない」と言われる。コードを見る。やるべきことは「チャンネルAをトーンの設定にする」「チャンネルAのボリュームを最大にする」「チャンネルAに0b000100011100 (=284。440Hz)を書き込む」の3つ。
ボリュームの設定で$08レジスタに0b11111を書き込んでいたが5番目のビットはエンベロープの設定なので0b1111にすべき。チャンネルAをトーンにするところで$07レジスタに0b000001を書き込んだのだけど、0がTrueで1がFalseなので0b111110と書き込むべきだった。ちゃんとドキュメントに書いてあるのに読み落とした。そしてこの「アドレスxにyを書き込む」って処理が具体的には「AD=Hでアドレスの値をD0-D7に出している状態でWRをLからHにし、次にAD=Lで値をD0-D7に出してWRをまたLからHにする」という処理で複雑なので書き込みよう関数を作ったのだがそれにバグがあってAD=Hで両方やってしまっていた。さらに、書き込もうとしいているデータが0b000100011100であるべきなのに0x000100011100だったので全然正しくない。
そんなこんなで大量のバグがあったけどようやく音が出るようになった。やったー。
てってってーてってっててーを無限再生する。
ボリュームをもう1個買ってあるので、これでテンポが変わるようにした。analogReadすればいいだけなのでとても簡単だった。ただ、割り込みしないスタイルで書いたので曲の最初で読み込んでセットするだけで、滑らかに動かしても滑らかに早くならない。
masa-uに「和音でしょ、やっぱ」と言われたので頑張る。頑張った。楽譜の読み方が間違っていて半音ずれた伴奏をならしたりした。
完成品の動画: http://www.youtube.com/watch?v=x8Z8at9PRDs
そんな感じかな。まだやっていないことはセンサー入力での割り込みとかセンサー入力をPC側に返してどうこうとか。
追記:楽譜はここからもらいました。 http://www.nicovideo.jp/watch/sm1237915