SDカードプレーヤーの演奏中の時間表示に成功
昨年初めから取り組んでいた、SDカードを使った8ビットマイコンAVRによるリニアPCMプレーヤーは、ついに、演奏中にLCD(液晶ディスプレイ)へ経過時間を表示できるところまで成長した。
OSは使っていない。タスクを3段構造にし、SDカード読み込みのバッファー空き待ち時間を利用して、LCDに残り時間と、プログレスバー(もどき)を表示する。
今年のお正月は近親に不幸があったりして、気分が暗かったが、これですっかり明るさを取り戻した。典型的な躁鬱質なので今は意気軒昂、矢でも鉄砲でも持って来いという爽快な気分である(落ち込むのも早いが)。
OlimexからPOフォームが来た。ドリルサイズの割り増しをとられる(1/6/10)
年末にボードファイルを送ったOlimexのプリント基板のPO(購入依頼)フォームが届いた。営業日数から言えば4日しかかかっていない。優秀である。Tsvetan君にちょっといやみなことを書いたので心配していたけれど、ちゃんと送られてきた。
しかし、POフォームを見ると、規格外のドリルサイズを使ったということで1ユーロの割り増しがついている。何い、そんなわけないぞ。あわててEAGLEを開いて、例のドリルサイズをチェックするコマンドを入れる(run drillcfg)。うむ、大丈夫なはずなのにどうして?
念のため、ウェブを開いてOlimexがサポートするドリルサイズを再確認。ありゃあ、32milは駄目なんだ。そうだ、EAGLEのライブラリは、大抵の部品のドリルサイズが32milで、パッケージにするとき修正しまくったことを思い出した。
違反の32milのドリルサイズは予想通り、新しく入れたパスコンのパッケージファイルだった。修正もれだ。やれやれ。ドリルサイズは、発送前にチェックしたが、32は大丈夫だとばっかり勘違いしていた。まあ1ユーロだから\140程度、たいしたペナルティではない。でも何となく腹が立つ。
PDFファイルになったPOフォームを印刷し、カード番号を記入して早速ファックスした。2回目なので発注作業は、10分もかからない。これは楽だ。最近、ブログのメールにEAGLEを使っている人を対象に、「Olimexより安く基板を作ります。試しませんか」というメールが届いている。しかし、Webサイトもなく、メールだけというのが少し気味が悪い。それと少しでもOlimexに慣れてしまうと他に移りたくない気持ちもある。誰か試した人がいたら状況をWebに上げてもらいたいものだ。
ファックスの次の日、例のfax receivedの2語メールが届いた。こいつはいつも恐ろしく早い。このまま行くと、1月下旬には基板が送られてくるだろう。そろそろ年末に成功したマルチタスクにしたソフトの仕上げを急がねばなるまい。
リニアPCMプレーヤーは、ついに経過時間を表示するようになった(1/8/10)
前記事でマルチタスクが出来たと書いたが、出来ているのは読み出したセクターの数を表示しているだけである。このセクターの数から、時間表示にしなければいけない。それにプログレス(進捗)バーのようなものも出したい。
LCDは、たったの2行16文字のキャラクターディスプレイである。しかも相当遅い。そのうえSRAMがもうぎりぎりだ。いつスタックのオーバーフローが起きるか分からない状況だ。フラッシュの方はまだ余裕があるが、メモリを消費しないコードにする必要がある。
このミニLCDは、一般の5VドライブのLCDに較べると明らかに表示速度が遅く、コマンドを立て続けに送ると全く表示されなくなってしまう。少なくとも100ms以上間隔をあける必要があり、それでも薄くなる。この待ち時間のロジックも組まなければならない。結構面倒である。
それに、今度のプレーヤーは、WAVファイルの沢山の形式に対応している(サンプリング周波数44.1、22.05、16.0khz、ステレオ、モノ、データ長16、8ビット)ので、
セクター数だけで時間が決まらない。あらかじめ計算しておかないといけない。
SRAMを増やさないコードにするため、慎重にロジックを考える。プログレスバーは、時間を表示したあとの10キャラクター分を#や>などの文字で表示していけば、それらしい感じになるだろう。全体の演奏時間は、ファイルをオープンしたときにファイルサイズを取得しているので、ここから換算できる。10で割った数を基準にして1つづつ増やしていけば進捗が表せる。
問題は、表示するタイミングである。バックグラウンドタスクは、ファイルがEOFになるまでループしつづける。的確なタイミングで表示間隔を明けていかないと、LCDは真っ白になってしまう。
さらに、ファイルサイズはバイト数なので、下手をすると8桁台(数百万バイト)である。一方、セクター(512バイト)をDACが処理する時間はミリセカンドオーダー、この両極端な数字を使って、正確な分、秒にもどすのは神経を遣う。4バイトのデータは8ビットマイコンには荷が重い。うっかりすると有効数字が消えてしまうのは周波数カウンターのとき経験済みである。
色々考えているうち、ふとアイデアを思いついた。進捗の単位をすべて表示する秒まで求めてこれに統一し、この数値が変わったときのみ表示すれば、表示間隔を気にする必要がない。そのためには一旦、表示した時の値はセーブしておいて、これが変わったときのみ次のデータを表示する。これだと表示は秒1回、または進捗が10%増えた時だけしか表示しない。これはうまいぞ。
このアイデアを思いついてからは早かった。タイマーなどは必要ない。念入りにロジックを検討したお陰で、実際のコーディングはすぐ済んだ。表示部だけなら、わずか7行、初期設定を入れて全体でも10行余りの追加におさまった。
秒まで出てくれば、分に直すのは60で割るだけである。最初、経過時間を表示しようとしたが、残りの演奏時間を表示する方が情報量が多いので、こちらにする。
わくわくしながらファームに書き込み、早速テスト。おおお、出た出た。市販のCDプレーヤーと同じように時間がカウントダウンしていき、プログレスバーの文字が少しづつ増えていく。嬉しい。単位を、#にしたり>にしたりしてチェックする。いやあ、もうこれは完全なプレーヤーだ。今の表示ディバイス(キャラクタLCD)ではこれ以上のことは望めない。
22khz、8bitのWAVファイルや、短いファイルを入れてテストする。22khzは問題なかったが、短いファイルはプログレスバーが止まらない。暴走する。考えてみたら、演奏が終わっても表示の処理が残り、際限なくバーが延びていくためである。対症療法だが、ストッパーをつけて止める。
昔から「段取り8分」という。計画を万全に立てたら80%は出来たも同じという意味だ。慎重に検討したお陰でプログラムはあっという間に動いてしまい、意気込んでいた肩の力がすっかり抜けてしまった。力が余ってしまって、ついでに前の5VのLCDを入れた1号機まで改修してしまう。これも問題なく動いた。いやいや今回はあまり楽しめなかったな。
2号機の一台目は、娘がユーザーだ。こいつもバージョンアップしてやる。娘が喜んでくれた。こちらの苦労も知らないで今度は、「早送り」の機能もつけろと言われる。うーむ、出来ないことはないけれど、もっと他にやりたいこともあるからなあ。
ここに、演奏の経過表示をするリニアPCMプレーヤー2号機(ストロベリーリナックスのミニLCD使用)と、1号機(秋月などの定番LCDを使用)のソースコードを、AVRstudioのフォルダーをzipにして置きます。
1号機は、SDPCM328V4.zip 2号機は、mLPCM328V4.zip です。
ソフトのバージョンはV4です。回路図等は、以前の記事を参照してください。なお、1号機の回路図には音量調整のVRがついていません。フォンジャックの直前につけてください。
| 固定リンク
「AVR」カテゴリの記事
- ソフトI2Cはクロックストレッチまで手を出してあえなく沈没(2017.09.02)
- オシロのテストどころかソフト開発で大はまり(2017.07.26)
- 超音波方式の人感センサーI2C化と新しいオシロ(2017.06.29)
- motionの動体検知はRaspi3の電源が安定しない(2017.04.16)
- 赤外線学習リモコンはデータ再現で挫折したまま進まず(2016.07.21)
コメント
ARIさん
遅くなりましたが、ご要望のパラレル(秋月)LCD版のソースコード一式を10/01/27付けの記事「量産を目指したリニアPCMプレーヤー3号機完成」におきました。ここに置かなかったのは整理上の都合です。ご了承ください。
投稿: がた老 | 2010年2月 6日 (土) 19時09分
はじめまして
SDPCM328v4作成させていただきました.
秋月LCDのバージョンの回路図ですが、2009年2月16日の回路図とSDPCM328v4.cファイル内の接続図で、DAC周りが異なっているようでした..cファイル内の接続図通りに配線するとちゃんと音がでました.
記事の内容は難しすぎてコメントできませんが、楽しみに拝見させて頂いております.
もしv4.1の秋月LCD版もありましたら、公開していただければ、作ってみたいと思っています.
すばらしいものをありがとうございました.
投稿: ARI | 2010年1月30日 (土) 23時16分
kugaさんお久しぶりです。今度も有力な情報をありがとうございました。コンペアマッチのタイマーにこんな(比較出力がトグル出来る)機能があるとは知りませんでした。これはLRCKそのままに使えますね。今のルーチンはわざわざ、割込みの最初でLRCKを切り替えるステートメントを入れている。これがいらなくなるわけだ。すごい。
ピンアサインはTIMER0なら空いているピンです(PD6)。わずかな修正で使えそうです。ありがとうございました。
ジッターは実測して、サンプリング3000~4000回に1回、100nsほど遅れる(次の間隔が短くなる)ことがわかり、まあ実際の影響は少なそうですが、これなら0ですね。大威張りです。
投稿: がた老 | 2010年1月12日 (火) 21時58分
ご無沙汰しています。
割り込みのジッタに対しては、DACのLRCKをポート叩きで生成せず
コンペアマッチでの比較出力選択(トグル)を使えばソフトでのジッタは完全に無視できるようになりませんか
(同割込みでデータの転送)
#ピンアサインが変わってしまうか
投稿: kuga | 2010年1月12日 (火) 10時09分
そらさん コメントありがとうございました。
はっはっは、グラフィックLCDですか。それも良いですが、そらさんに勧められて買ったTFTディスプレイがまだぶらぶらしているので、こちらが先ですかねえ。
それはともかく、今年もどうぞよろしく。
投稿: がた老 | 2010年1月 9日 (土) 12時55分
演奏中の時間表示成功おめでとうございます。
こうなってくると、グラフィックLCDにしたくなりますねぇ。
本年もどうぞよろしくお願いいたします。
投稿: そら。 | 2010年1月 9日 (土) 06時48分