今のところQUADのプリアンプ405とメインアンプ44の間のオーディオケーブルの間にはさんで音量調節をする。7セグLEDなどで現在音量値を表示し、電源を切ってもその値を記憶しておくようにする。大まかな仕様は出来た。PGA2311を調べ始める(11/12/2010)調べているうち、こいつはアナログアンプでもあることを知った。最大ボリュームでは、31.5dbも増幅する。ボリュームが増幅するというのはちょっと不安なので、0dbを上限にした方が使いやすいかもしれない。それでも192段階調整できる。データシートがあるので制作上の不安はない。PGA2311は正負両電源を必要とする(幸い±5V)。昔買ってあったトランスと7805、7905によるシリーズ電源にしたい。5Vの正負電源なら秋月のFG(ファンクションジェネレーター)のときに作ったDC-DCコンバータの予備があるが、ここはそれ気持ちの問題である。スイッチング電源でも殆ど問題ないと思われるが、高級品の電子ボリュームICの顔も立ててやりたい。それに買ったまま使っていない電源トランスの活用にもなる。PGA2311のデジタルインターフェースはSPIである。プロセッサーから8ビットづつの左右の音量値を受け取るだけである。プロセッサーにはEEPROMに設定値を覚え込ませておく。AVRのEEPROMは10万回くらい書き換えできるようだが、毎回変化するたびに記録するのではさすがに寿命が心配だ。電源を大容量キャパシタかなにかで保持し、EEPROMに記録した後、リセットICか何かで、このバックアップ電源もシャットダウンすれば、書き込み回数は最小になるが、ここまで凝ることもあるまい。5回に一回とか、一分に一回とかのタイミングでEEPROMに書いておけば十分だろう。いう工夫を考えるのも電子工作の楽しいところだ。久しぶりのAVRの開発(11/14/2010)最初に、赤外線の受信部を作る。デジタル液晶を動かす準備」)。赤外線信号のフォーマットは多種多様で機器によって全部違う。オーディオなどのAV機器には、いくつかの業界統一フォーマットがあるようだが、外国製品(QUAD)は全く違うし、エアコンなどは数十ビット以上のコードで何が何やらわからない。Modulation)である。この解析だけで沢山のページを使っているサイトもある。当研究所のモットーは「実用」である。役に立てばそれで良い。フォーマットに凝る趣味はない。みて、ビット数が少なく(12bits)、一番簡単な(自分にとって)Sonyのフォーマットを使うことにした。ターゲットはAVRである。AVRマイコンはここの研究所の名前どおり、当研究所の電子工作発祥の石である。このところFPGAとかARMとかに走っていたけれど、久しぶりにAVRStudioに戻ってきた。懐かしいふるさとに帰ってきたかのように気分が休まる。AVRStudioの新しいプロジェクトを作る。石は秋月で¥100のATTiny2313を選ぶ(7セグLEDまで入るか少し心配だが)。ブレッドボードに実装する。ソフトは前から擬似コーディングを片手間に始めており、PPMの信号をデコードするロジックは出来上がっている。印刷されたAVRのデータシートを久しぶりに開けてタイマーのところをおさらいした。このデータシートは2年以上前に日本語サイトからダウンロードしたものである。このサイトは一時、閉じていたが、最近、復活した。いくつかの電子パーツショップが協賛している。AVRの日本語データシートが自由にこれからも見られることは有難い限りだ。データシートを見ているうち、前から気になっていた、「捕獲入力」(キャプチャー入力のことだが、ちょっとおおげさな翻訳)機能のところで、はたと気がついた。これは今、自分がGPIOで普通のタイマーを使いながらやろうとしていることと全く同じではないか。パルスが入れば、タイマーを動かし、次のパルスでその間の時間を測る。この間隔の大きさの違いで、0か1を判断しようとしていた。赤外線リモコンのパルス位置変調(PPM)のデコードはこれで出来るはずだが、タイマーの設定と外部割り込みの2つの設定が必要である。これに対して、キャプチャー入力を使うとタイマーの設定だけで一発でデコードできるのだ。これは感動した(常識だったらごめんなさい)。おや、Tiny2313のキャプチャー入力は、片側のエッジでしか反応しない。ふーむ、ウェブでは両エッジで動く動作例が殆どだ。これは割り込みのたびに設定を換えてやればよいだけの話だ。赤外線を出す送信機は、昔々面白半分に買った汎用のリモコンを使う予定だ。こいつは設定ボタンで各社(10社以上)のリモコン信号を出力することが出来る。今回使うコマンドは、音量上下、それに無音(MUTE)の3つだけなので、これで十分である。うーむ、ロジアナで見ていると、赤外線リモコンというのは同じ信号を何回も出してしまうようだ(このリモコンだけではなかった)。音量アップの信号が多数回でるのはまずい。チャタリング防止のような感じでまとめる必要がある。同じようなミスを立て続け(11/15/2010)AVRで赤外線モジュールの信号をデコードし、UARTにビット列を0,1で表示するテストプログラムの開発が終わった。キャプチャー入力のパルス間隔を測り、所定(12ビット)のデータ量が来れば、UART出力ルーチンのゲートを開いて結果を出力する。たいしたコード量ではない(1KB少々)。動くと思ったけれど、やはり久しぶりのAVR開発は、バグだらけで思ったようにすんなりとは動いてくれなかった。いくつかあったバグをつぶしたあと、バグの原因をリストアップしてみて思わず苦笑いする。前にやったミスを忠実に繰り返しているのだ。生物は進化の過程を胚から胎児の間に再現する(個体発生は系統発生を再現する)という生物学の法則みたいだ。・まず、ポートレジスターのビット順の数え方を間違えていた。最初、赤外線モジュールの出力を入力ピンにつけるとデータが消えてしまうので大騒ぎした。これはピン順を間違えインピーダンスの低い出力ピンに入れていたためだった。前にADコンバータで同じ間違いをやったことを思い出す。・キャプチャー割り込みのピン(ICP)の状態が見えなくて苦労する。一生懸命、PORTからデータを読もうとしていた。これも最初の頃やって大はまり。・タイマーの割り込み先を定義していなくて暴走する。コンペアマッチなのにオーバーフローのエントリを定義して、暴走しリセットを繰り返していた。ソースコードの使いまわしをするとこういうミスが出る。・フラグがたたずに必要な処理を素通りする。ローカル変数に同じ名前を定義していた。いずれも、以前にやったミスばかり。FPGAと違って、LEDやprintfで途中経過が出せるので、すぐ解決したが、余りにも以前やったミスと同じことを繰り返す自分に感心してしまう。UARTのところは最後まで、てこずった。本番ではUARTは使わない。採集したパルス間隔の正確な閾値を求めるためには、UART出力が欠かせない。考えてみたら、赤外線リモコンのデータは、1ビット単位が、0.6~1.8ms、このあいだに悠長にUARTで出力をだしていたら(1バイト0.2msで3文字くらいをパルス単位に出す)、赤外線データの方を取りこぼしてしまう。今は、強力なロジアナが手に入ったので、パルス間隔を無理にUARTで測ることもないのだが、バグ続きで少し意地になっている。不具合の原因ははっきりしている。UART送信関数が、ハードウエアがデータを送り終わるまでループで待っているので、次の赤外線割り込みがそのあいだに入り前のデータを消してしまうからだ。これはUARTの送信関数にバッファーを設け、UART送信を割り込みで処理すれば解決する。ChaNさんのFATFsのモニターのUARTでも使われている方法だ。こちらに持ち込んでも良いが、せっかくなので自前で作ってみることにする。送信割り込みは、送るデータが空になると割り込みが上がり続けるので、ちょっとした工夫が必要だ。ChaNさんのソースを、そっとカンニングする。バッファーのポインターを監視していて、送るデータがなくなると、UARTのレジスターを叩いて、割り込みを止めている。