息抜きに赤外線リモコン電子ボリュームを作っている
DE0が到着したというのに、なぜかここへきて急にフォトフレームもFPGAも制作意欲を失ってしまった。DE0は、あまりにも沢山の玩具を見て足がすくんでしまった子供のように、どうにも動けない。それでも開発環境はインストールしたが(QuartusはLatticeと違ってCドライブでなくても動いた)、気力はそこまで。先へ進まなくなった。
JPEGはJPEGで、ライブラリのインストール手順をこと細かに解説した(UNIX上だが)とてもわかりやすいサイトが見つかった途端、先に進む意欲を失った。昔から道筋がついてしまうと急に安心してしまって、やる気がなくなる癖がある。
JPEGが進まないのは他にも理由がある。JPEGファイルには、必ずオリジナルのピクセルサイズがあり、デコードでこれを可変にできないことがわかった。ということは、このフォトフレームに入れるJPEGファイルは常に640×480ドットの画像でないと、正しく表示されない。
それは困る。多種多様なJPEGファイルを放り込んでも、それとなく表示できなければフォトフレームとは言えない。しかし、そうするためには、デコードしたあとのビットマップデータをプロセッサーで処理してサイズを合わせてから、FPGAに送るという手順が必要になる。
画質を落とさないリサイズやリサンプリングは結構、厄介な作業である。ユーザーインターフェースを良くするためには相当な開発が必要なことがわかった。どの程度まで踏み込むか簡単には判断がつかない。これが先に進めなくなった大きな原因だ。
というので、このあいだから少しづつ準備していた赤外線リモコンによる電子ボリュームのプロジェクトを立ち上げ、少し気分を変えて意欲が回復するのを待つことにする。
赤外線リモコンの全体構成を考える(11/10/2010)
おりしも、エッジの取替え修理に出していた30年もののタンノイスピーカー(Berkeley)が工場から戻ってきた。送料を入れると費用は2本で軽く3万円を越したが、気のせいではなく明らかにスピーカーは生き返った。今までの何となくしまらない(響きが悪い)音から、きっちりしたメリハリのある音に戻った。これでまた暫くこのセットで音が楽しめる。
赤外線リモコンはこのオーディオセットの音量調整に使うつもりである。以前からこのオーディオセットのリモコン化が懸案だった。昔々LPレコードのHiFi(これは死語か)オートチェンジャー(これもか)を探し回って馴染みのオーディオショップの店主から叱られたことを思い出す。
時代は変わった。音量調整用の電子ボリュームICは既に買ってある。TI社のPGA2311である。FPGA評価ボードDE0を買う時に一緒にDigiKeyで買った(¥1,080)。市場には、沢山の電子ボリュームICが出回っているが、スペックによるとこの石の性能(高調波歪だけだが)は他と較べて群を抜いて高い(そのぶん値段も高い)。高級オーディオ装置向けのようだ。
ウェブにも沢山制作例が出ている。しかし、キットや既製品が多く、この世界は組み込み系というより、オーディオの世界なのでプログラムやロジックの詳しいサイトは少ない。この石の電子ボリュームだけで¥20,000を超える高級既製品もある。
一方、赤外線リモコンの方は「赤外線 リモコン」で検索すると、あるわ、あるわ、沢山の人がこのしかけを調べ、解析し、自作している。こちらはラジコン、工作関係の人のサイトが多い。自分が作ろうとしている電子ボリュームリモコンの記事もある。自作、キット、既製品いくらでもある。今さら、ここで制作記を書いてもあまり喜ばれないかもしれない。
まあ、売り物にするわけではない。あくまでも自分の実用のためだ。気にすることはない。今のところ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)
最初に、赤外線の受信部を作る。赤外線の受信モジュール(PL-IRM0101-3)は大分前に秋月で入手し簡単なテストは済んでいる(前記事9/11/2010「フォトフレーム: デジタル液晶を動かす準備」)。
赤外線信号のフォーマットは多種多様で機器によって全部違う。オーディオなどのAV機器には、いくつかの業界統一フォーマットがあるようだが、外国製品(QUAD)は全く違うし、エアコンなどは数十ビット以上のコードで何が何やらわからない。変調方式はなぜかみなパルス位置変調PPM(Pulse Position 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からデータを読もうとしていた。入力はPINだ。これも最初の頃やって大はまり。
・タイマーの割り込み先を定義していなくて暴走する。コンペアマッチなのにオーバーフローのエントリを定義して、暴走しリセットを繰り返していた。ソースコードの使いまわしをするとこういうミスが出る。
・フラグがたたずに必要な処理を素通りする。ローカル変数に同じ名前を定義していた。
いずれも、以前にやったミスばかり。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のレジスターを叩いて、割り込みを止めている。そうだよな。これしかない。割り込みの開始は、新たな送信要求のときに設定する。ここは何度繰り返しても問題ない。
改良版が出来た。途中経過が暴れる時もあるが、12ビットの赤外線データは、ほぼ100%正しくデコードされた。 最初は安定しなかったが丁寧に閾値を調整すると100発100中になった。これもUARTでパルスの幅を調整できたお陰だ。その後途中経過が暴れる不具合もリングバッファー終点の計算間違いが発見され解決した。
よーし、赤外線リモコンの部分は完全だ。送信割り込みのUARTも前々から気になっていたが、これで安心して高速なところにUARTを使える。赤外線データの解析はフォーマットが多種多様なのでこれ以上深入りせず、次の電子ボリュームの制御の方に開発の方向を移した。
ソフトSPI(マスター)を作った(11/16/2010)
電子ボリュームPGA2311の入力インターフェースはSPIである。Tiny2313にはSPIはない。USIを使っても良いが、こいつは癖があって簡単には動かない。速さも量も求められていないし、GPIOで作るほうが簡単なように思えた。というのでGPIO(汎用ピン)でソフトSPI(マスター)を作ってみた。
この開発には、このあいだ買ったZeroPlusのロジックアナライザーが大活躍した。プロトコルアナライザーがついているので、SPIのデータもいちいち波形を数えて調べる必要がない。UARTも簡単にデコードしてくれる。とても楽だ。
ほぼ出来上がったが、送信したビットがどうしても1ビットずれて送信されてしまう。簡単なロジックなのにどこが悪いのか、いくら調べても解決できない。諦めてもう寝ようと風呂に入っているとき気がついた。
赤外線のデータをSPIに送るとき、データを左シフトさせながらMSBを取り出し、8回ループして送信データを作る。あっあっあっ、こりゃ、だめだ。最後の1ビットのあとに次の(不要な)シフトをして見事に1ビット欠けた送信データを作っている。Whileではなく、do{..}whileでないといけないケースである。
しかし、風呂に入らないと、この程度のバグも見つけられないというのは困ったものだ。これを直して、基本的な開発は完成した。あとは、電子ボリュームの値をどう保存し、表示を7セグLEDかLCDにするか、付加機能をどこまでつけるかなどの細かい仕様が残っているが、開発の峠は越したようだ。
ブレッドボードでは完成(11/20/2010)
実際のケースに実装する前に、ブレッドボードにPGA2311を載せ、音源を先のLPCMプレーヤー(テスト用にブレッドボードに常駐)にして動作テストをした。7セグLEDはFPGAで使った基板を流用し、その2ヶ分をTiny2313につなぐ。ピンを全部使い切った。受信確認用のLEDはつけられない。まあ、これはデバッグ用のUARTをはずしたときにつけられる。
そろそろフラッシュも一杯になってきた。ChaNさんの便利なxprintfはもう入らない。7セグLEDが動くまではUARTが欲しいので自前の十進変換ルーチンを使ってしのぐ。ブレッドボードなので配線はすぐ終わった。7セグの開発はあとまわしにして、まずPGA2311の動作を確認する。
ありゃあ、動かない。データを送ると、「ポソポソ」という小さいノイズは聞こえるので信号がPGA2311まで行っているのは間違いないが、肝腎の音が出ない。ロジアナで見る限り、SPIは完全に仕様どおり音量データ(0~255のバイナリ)を両チャンネル分送っている。電源配線も間違いない。MUTEという音を止めるピンは負論理なので関係ないはずだ。念のためこれをpull upしてみるが当然何の変わりもない。
困った。これ以上調べるところがない。やることがなくなって、さっきは動かなかったMUTEピンを最初からpull upして動かしてみた。何ということだ、これで動いたのである。MUTEは浮かせておくと動かないのだ。しかもSPIでデータを一回は送らないと音が出ない。それならそうとデータシートに、はっきり書いておいて欲しい。
動いたときの気分はいつも爽快このうえない。ブレッドボードではあるがリモコンで自由に音量が変えられる。暫く音を上下させて遊ぶ。ご満悦である。音の変化は、PCのスピーカー程度では全くわからない。音量変化のときのノイズも全くない。好調である。
勢いに乗って7セグLEDと音量値のEEPROMへの記録機能(5回ごとに値が異なれば記録する)を一気に書き上げる。良かった。フラッシュ消費は全部で1700バイトどまりだ。UARTを入れてもフラッシュにまだ余裕がある。
これらの機能も一部を除いて順調に動いた。一時不調だったのは7セグLEDである。FPGAのときのトランジスタアレイを使った7セグLED基板を流用したのだが、どうもLEDが薄くピンによって明るさが違う。色々調べた結果、トランジスタアレイのドライブには適切なプルアップ抵抗が必要なことがわかった。10KではAVRのピンのドライブが不足(プルアップされすぎて点灯しっぱなし)で、47Kにするとちょうど良くなった。意外に微妙なものである。
このところソフトを公開していないので、今回のブレッドボードで動いている赤外線リモコンのテストベンチのソースコードを公開することにする。ソフトSPIとバッファードUART(送信割り込みを使って高速出力が可能)のライブラリ、それに7セグLEDの表示コードが入っている。
回路図はまだ試作中なので完成してから公開することにする。おおよその結線はソースコードにコメントがある。それぞれの部品の標準接続で特に問題なく動いている。
UARTの部分は実装では不要だが、高速送信の出来るUARTは他に有用だと思うのであえてUARTを残した。何かの開発の参考になると嬉しい。現在のソフトでは、UARTに赤外線リモコン(Sony限定)の送信コードを行単位に出力し、キーボードから音量の上下の指示と音量値の表示が出来る。
ここに例によってAVRStudioのプロジェクトフォルダーとして固めたソースを置きます。時間がなく乱雑なコードになっていることはご容赦ください。uart2313.cとUART2313.hが目玉です。2313だけでなく標準UARTを持つAVRチップで殆ど共通に使えます。
11/22に公開したバージョンにはEEPROM関連にバグがありました(最初の書き込みのときボリュームが最大になってしまう)。以前のバージョンをダウンロードした方は破棄し、以下の修正版をダウンロードし直してください。
| 固定リンク
| コメント (6)
| トラックバック (0)
最近のコメント