« 2008年8月24日 - 2008年8月30日 | トップページ | 2008年9月7日 - 2008年9月13日 »

2008年8月31日 - 2008年9月6日の8件の記事

2008年9月 6日 (土)

美咲フォントの高速アクセス

任意の漢字フォントの表示に成功(6/21/08)
 SDカードに入っている美咲フォントのBDFフォントファイルは、ANK(半角1バイトコード)は20Kバイトそこそこだが、2バイトコードの漢字フォントファイルは400Kを越す。このフォントの実用性を確認するには、色々な漢字フォントを表示させて調べたいのだが、シーケンシャルに読んでいるだけでは効率が悪い。コードを入力するかターミナルから任意の漢字を送って表示させたい。

 しかしFatFSはMega168を継承しているので、TinyFatFSがベースであり、速度が遅く、ブロックで読むときは結構早いが、ちまちまと読んでいると、20Kを読むのに5 秒近くかかり、400Kだと2分近くかかってしまう。ただ、上位のFatFSでどれだけ速くなるかわからないので、更新をする気にはならない。

 はじめ、コンソールからPCが使っているシフトJIS漢字を直接送って表示させようとしたが、BDFファイルの漢字コードはJISで、シフトJISからJIS漢字への変換は、そう簡単でないことを知る。フォントを調べるのが目的なので、最初は開発しやすいコード入力で表示させることにする。

 これが結構面倒なのである。1バイトコードの方は、入力文字からコードを生成してサーチしており、2バイトコードと入力ルーチンを同じにしたので、その区別が難しい。C言語の文字列と配列の取り扱いが微妙に違い、関数によっては、文字列の最後にNULLだけでなく改行コードが入っていたりする。しかも16進のキャラクタ表示は、aとAではコードが違うので逆変換のときは気を使う。BDFファイルが小文字で全部書かれていることを信じて開発を進める。Ws000000

 数時間かけてやっと、コンソールからJISコードを入力すれば漢字が表示されるようになった。しかし、頭から読んでいるので、後半の第二水準の漢字ひとつをだすのにやはり1分以上かかることがわかる。こうなると意地でも何とかしてやろうと、こだわってしまうのが悪い癖だ。電光掲示板に漢字を表示させるのが目的なのだが、全然別の方向にエネルギーを使ってしまう。まあこれが楽しみでやっているようなものだから、暫く時間を費ってみた。

 思いついたロジックは、昔で言う、インデックスシーケンシャル方式(ISAM)である。頭から読むのでなく、コード番号とファイルのポインタのテーブルを作り、ファイルを途中から読んで目的のフォントに辿りつこうというものである。構造体を定義して、早速テーブルを作る。昔取った杵柄(きねづか)である。参考書は20年前のPCのC言語の参考書。

 くどいけれど、プログラムは考えたようには動いてくれない。構造体のテーブルの中の定数宣言も、昔のことで自信がない。こんな感じだったかなと手探りでコーディングする。恐る恐るコンパイルしてみた。これが不思議なことに一発で通る。調子に乗って動かしてみた。

 おお、想定どおり動いている。ファイルポインタの数もちゃんと関数に入っているようだ。用心してテストステートメントを詳しく入れてあったのでデバッグはすぐ済んで、第二水準の漢字まで、5秒以内に表示されるようになった。素晴らしい。成功の余韻にひたる。

 うむ、腕は落ちていないようだな。でも出来上がったものは、単にコードをキャラクタで入力すれば、その漢字が表示されるだけで、次のステップに進めるものではない。冒険物語はこれからが勝負だ。

漢字ファイルの高速化(6/29/08)
 先週、シフトJISとJIS漢字の変換ロジックをWebで偶然発見した。 20年近く前、パソコン通信が始まった頃、同じようなプログラムを組んだ記憶があるが当然資料など残っていない。判じ物のようなロジックだったが正直にコーディングしたら見事に変換した。それにしてもWebの情報はありがたい。これで残っているのは、連続した1バイト、2バイトコードが混在したテキストの表示である。これが最終ゴールに近い。

 次の朝、コーヒーを飲みながら構想を固め、コーディングを開始する。文字列とポインタの操作に慣れてきたので、コーディングが早い。かみさんの買い物につきあって帰ってきた午後遅くから夕食までの数時間で完成した。調子の良いときはこういうものである。一発で通る。漢字かな混じりの長文の文章でもフォントが次々に表示される。

 見ていた次女が、薔薇(ばら)、顰蹙(ひんしゅく)などの複雑な漢字のフォントを表示させて大笑いしている。まあ殆ど読めないが、8ビットフォントでこれだけ雰囲気が出てくるのはたいしたものだ。文脈があれば、難しい漢字でなければそこそこ読めることがわかった。これなら電光掲示板にしても大丈夫なようだ。

 これでほぼ予定していた必要な機能が実現した。あとはこれにLEDマトリックスのプログラムを合わせてやれば、任意のテキストを表示する電光掲示板が完成する。

 と、気楽に書いていたのが数日前。 しかし、これがかなり手強いのである。現在のフォントファイルは500Kバイト近いテキストベースの漢字フォントファイルで、インデックスをつけていくら早くなったとしても一字取り出すのに数秒かかる。従って、手順としては、これをフォントデータ(グリフというのだそうだ)だけのバイナリに変換し(元のファイルはグリフもキャラクタ)、漢字コードによるダイレクトアクセスでそのフォントが得られるファイルにしないと実用にならない(やや本気)。

 そのとき同時に、LEDマトリックスのダイナミック表示のために、通常、横方向に入っているフォントデータを、縦方向に変換して収容しておきたい。この行列の転置プロセスが一筋縄ではいかないのである。

 かなり考えた挙句のロジックなのだが思い通りの結果が出ない。仕方がないので、ひとつひとつUARTで途中経過を表示させてみて初めて、大きな勘違いをしていることに気がついた。ロジックに自信を持って疑いもしていなかった自分に恥じ入る。思い込みというものは恐ろしいものである。行から列に変換するのだから、各行のデータはその列のデータを足しこんでいくだけで出来ると考えていた。あとから考えればそんな簡単なことではなく、各列の位置に応じたマスクをかけてひとつひとつ拾って行かないと正しいフォントグリフにならないのだが、これに気づいていなかった。

 8ビットのマスクデータを移動させるロジックを追加しやっと横方向のフォントが縦に見えるようになった。勢いに乗って1バイトコードだけはEEPROMに全部入れてしまう。これはこれまでのロジックを活用して簡単に出来上がった。矢のように表示されるANKコードを見て満足する。

 最後の2バイトの漢字ファイル変換も難関だった。7000字もあるのでとりあえず100文字程度のデータを変換するプログラムを作る。しかし、SDカードの書き込みがうまくいかない。最初、リターンコードを勘違いして(FatFSの1文字書き込み関数は今までの関数と違ってリターンコードに書いた文字データが返ってくる)、悩んでいたがそれを直しても動かない。書く文字は1バイト単位なのに型はint(2バイト)というのが良く分からない。文字列ならどうだと文字列関数を試すがこれも動かない。ソースを良く見てみたら動かないと悩んでいる一文字関数を使っているので全くの無駄であることを知る。

 書き込みは前に動いていることを確認しているので、結局この関数を使うことを諦め、元の原始関数の方でやってみたら、不思議なことに一発で動いてしまった。これで半日はつぶれてしまった。動いた勢いで、表示部を仕上げて、「あいうえお」と入力し、正しくフォントが出てくることを確認した。表示速度も前のキャラクタファイルをちまちま順次読んでいたのに比べ圧倒的な速さでEEPROM並みである。コンソールの前で思わずガッツポーズしてしまう。

 勢い込んで、7000文字の変換に移る。1分少々で全部終了。これで終了と鼻を高くしたが、少し不安になり念のため漢字かな交じり文を表示させてみる。やっぱり、そうは問屋はおろさなかった。目茶目茶なフォントが入っている。途中でおかしくなってくるようだ。がっくり肩が落ちる。

 いちから出直しである。相手は7000字。気の遠くなるような数字である。気持ちを強く持ってバイナリエディタなどを持ち出して少しづつ調べ始める。正しい位置に所定のデータが入っているところもある。ロジックはもう間違ってはいないようだ。そうだとするとファイルの位置を決めるポインターがオーバーフローして上書きしている可能性が高い。

 しかしファイルポインタは4バイトもとってあり、この程度のファイルサイズでは超えるわけはない(32ビットは4ギガ、40億バイト)。他のところもみな2バイト(3万から6万)で問題ないはずだ。

 Ws000001 登録文字数を少しづつ増やして中身を表示させることにした。1500字を越えたところで、ファイルポインタが64540から1104になることを発見する。やった。これが原因だ。しかし、どうして4バイトもあるのにオーバーフローする? すぐ原因がわかった。2バイトデータを上へ8ビットシフトして4バイトに入れているのだが、シフトするときはデータをあらかじめ4バイトに入れておかないといけないようである。

 正しくポインターが増えていき、これで全部正しく入ったと喜んだのも束の間、調べていく間にデータがおかしい文字を発見、再びがっくりする。しかし、バイナリエディタで見るとデータは正しい場所に入っている。今度の容疑者はシフトJISからの変換ロジックである。しかし、見たところ間違っていない。このあたりで本日の根が尽きる。

 まあ、殆どの漢字は正しく表示されるので、じっくりバグをつぶしていこう。あせってデバッグして上手くいった例(ためし)はない。

デバッグの醍醐味(6/30/08)
 仕事は週2日やることにしていて、今日は出番の日。お客さんが来たり、打ち合わせの準備をしたり、会合の司会をしたりして久しぶりに忙しかった。今日のお客さんは昔勤めていたITベンチャー企業の友人で偶然にもインドの組み込みコンピューター会社の売り込みで話が弾む。私が趣味で組み込み系にはまっていると聞いて彼らは大笑い。ホビーの需要を市場は将来期待していると聞き大いに意を強くする。

 そうなのだ。この面白さは私だけではもったいない。もう少し広がってもおかしくない世界だと思う。これだけ驚異的に進歩した技術の恩恵はアマチュアでも享受すべきだと思うし、それが可能になってきた、などと風呂敷を広げているのは、ほかでもない、昨日あんなに悩んだ問題があっさり片付いたからである。深夜なのでヘッドフォンでお気に入りのクラシックを聞きながら、満足感にひたってこの記録を書いている。

 漢字ファイルをバイナリに変換して表示するプログラムは一応データが全部入ってそれらしい表示が出来るようになったが、依然として一部の漢字が化けて頭を抱えていた。こういうときは基本からひとつひとつ検証して調べていくしかない。気を取り直し、別のプログラムからファイルを読んでみようと、以前コード入力で正常に動いていたプログラムにバイナリファイルのアクセスを追加して調べることにした。

 ところが、元のコードを新しいプログラムへコピー&ペーストをしているときに思いがけないものを発見した。何と何と、データの読み込みのアドレス計算のところはオーバフローの修正がされていない。やれやれ、読み込みのところの修正をすっかり忘れている。これでは折角正しい位置にデータを入れても正しく読めないのは当たり前だ。意気込んでとりかかったけれどあっというまに解決してしまった。

 これを修正して漢字ファイルの高速アクセスは完全に実現した。時間を測ってみる。1字あたり2ms台、キャラクタベースのアクセスの秒レベルとは比較にならない。いや、素晴らしい。デバッグの醍醐味は問題が解決したときである。頂上を極めた登山家や、42キロを完走したマラソンランナーの幸福感と同じである。本当に安い娯楽である。

| | コメント (0) | トラックバック (0)

2008年9月 5日 (金)

雑誌付録の32ビットプロセッサー

32ビットARMプロセッサーの登場(6/20/08)
 書店でふと手に取った雑誌(デザインウエーブ)にSDカードに動画を記録する特集が出ていた。将来的にはこの方向に行きたいと思っていたので、買って読んでみたら、記事で使っているプロセッサーが、数ヶ月前、この雑誌の付録についていた32ビットのプロセッサー(ARMのCortexM3)であることを知った。Wiiで有名になった加速度センサーもついた基板が付録になっていて、\2,480だと言う。フラッシュは128Kだが、クロックは76MHzの高性能チップだ。

 目の前のプロジェクトがうまく進まないときに限って別のものに手を出す悪い癖がある。立て続けにAVRチップ2つを壊したとき、衝動買いした16ビットのH8ですらまだまともに使っていない。狙っていた漢字フォントが8×8では使い物にならないかも知れないと気分が落ち込んでいるときにこれである。 これ以上、間口を広げてどうするという理性も強いが、欲しいなと思ったらなかなかそれをとめることが出来ない。

 値段の安さもさることながら、こういうものは単品ではこの機会を逃したら、恐らくアマチュアには絶対手に入らないものだと、自分に言い聞かせ、仕事の次の休みの日、車を駆って新宿の紀伊国屋に付録のついているバックナンバーを探しに行った。本店の方が、技術系の本の種類が豊富だ。店員に聞いたら即座に10冊以上並んだバックナンバー(2008年5月号)の棚を教えてくれた。

 なんだ、慌てて来なくてもまだ沢山在庫がありそうだ。2冊買うのはさすがにやめる。帰って早速、CDROMより少し厚いボール紙の綴じ込みから取り出し、USBケーブルを取り付ける。ターミナルソフトを起動させて雑誌の指示通り、*を入れると、おお、LEDが点き、加速度センサーの数値が出た。蛙が跳ぶソフトもセキュリティの解除(何故自分のところでアプリを動かすのにこんなにうるさいのか)に手間取ったが、ちゃんと蛙も跳んだ。

 買ってあったSDカードソケットは残念ながらヒロセのでなくこの基板には合わなかったが、これで秋葉に行く用事が出来た。ひとわたり触ってみて少し感慨にふける。このあいだから調べているFPGAと云い、がた老研究所も8ビットから始まっていよいよ組み込み系の先端のところまで辿りついた感じがする。雑誌の付録ごときで大げさと言えば大げさだが、とりあえずは2軍のファームから、1軍のキャンプに参加を許された選手の心境であろうか。

 JTAGとかバウンダリスキャンとかFPGAだのVerilogなどの最近技術とは全く無縁の世界から、少し関連するレベルに達したということだ。FPGAで往年のパソコン全部のロジックを組み、動かしたと言う記事を見つけて素直に嬉しくなる。そうか、こういうことが可能になる時代なのだ。今まで、大資本下のハードの技術者に独占されてきたハードウエアがアマチュアの手に戻ってくる時代が来る予感がする。

 ただ、雑誌の記事にでていたミックスドオシロスコープの値段が80万と知って少し暗くなる。まあ、メーカーには数百、数千万円する測定器はごろごろしているからな。一万円のロジアナで感激しているなんて可愛いもんだ。

ハード工作は順調(6/24/08)
 昨日久しぶりに秋葉原に出かけ、通り魔事件の現場を遠目にみながら必要な部品を買い集めた。まず、雑誌付録のSTM32F基板につけるSDカードソケットをラジオデパートの西川電子で求める。生意気な店員で、いきなりソケットを差し出すので型番を確かめて付録の基板に合うものか問うたが、はっきり答えない。末尾の番号が合っていたので「これだと思う。何種類もあるからね」と言ったら、「何十種類もあります」とのたまわった。喧嘩しても始まらないので無視して次の店へ急ぐ。

 次の目的は、Mega128とSDカードソケットをブレッドボードから正式な基板に組むときの3Vロジック(SDカード)と5Vロジック(AVR)を接続するバッファーICだ。手持ちの74HC126は5Vトラレントでなく、3VのVccより高い入力電圧では、出力がVccを超えてICがこわれる可能性があるし、そもそも3.6Vが限界のSDカードに4V近い電圧がかかるのはさすがにまずい。Webの情報で、74VHCシリーズがこういうためのものらしいので千石に寄る。秋月の品揃えには癖があり、こうした汎用ICは置いていない(その後、秋月で同種のバッファーを見つけた。5ヶで¥100!失礼しました)。

 しかし、千石でもVHCシリーズはあるものの目的のVHC126はなかった。頼みの鈴商は定休日。隣のマルツを試しに覗いてみると、あった。マルツもなかなかの品揃えで感心する。\168と少々高いが(あとでWebで調べたら通販のサトー電気では半値の\84)、感心した勢いで2つも買ってしまった。VHC シリーズはDIPではなく、表面実装の1.27ピッチのSOPだが、もうひるむ必要はない。変換基板という強い味方がいる。かねて調べてあったダイセン工業の安い変換基板が千石で売り出したのを知っていたので、再び千石に戻り、5枚組で\500のSOP変換基板を入手した。

 こいつは一枚の単価が100円の上に、表が1.27ミリ、裏が0.65ミリピッチでどちらか16ピンのSOPチップがつけられ、このあいだ買ったアイテムラボのSOP28ピンの変換基板より汎用性が高い。ついでにUARTの高速化のため、7.3728MHzという周波数の水晶発信子を買おうと思ったら、ケースの中は空っぽで品切れ。仕方なくこの倍の14.76MHzの石にする。UARTは高速になるとボーレートの倍数にあたる半端な周波数の発信子でないと誤差が出てつながらないのである。AVRでVccが3Vでも動く10MHz以下が欲しかったのだがやむを得ない。

 全部合わせて2000円もしない買い物だけれど、目的のものA6301331がほぼ揃い、充実した気分で家路に着く。帰ってから早速久しぶりのハード工作を楽しんだ。まず付録のCPU基板にSDカードソケットと20Pのピンヘッダーをつける。大分基板らしくなる。アイテムラボから送料単価減少のため1000ピンも買ったピンヘッダーが活躍する。何と言っても1ピンあたりたったの1円50銭、80ピンつけても\120である。次にSOP変換基板にチップをつける。このあいだの0.65ミリに比べれば、1.27ミリは鼻歌まじりでつけられる大きさである。この基板にもピンヘッダーをとりつけこれでブレッドボードへの対応がすんだ。A6301332

 いや、気分が良い。Webをみてみたら、私と全く同じダイセン工業の基板を使っている人がいて苦笑する。調子に乗って14.76MHzのUARTのテストもやった。3Vベースなので心配したが、115Kbpsも、230Kbpsも簡単に動いた。いや早いの何の、ターミナル(TeraTerm)の画面一杯のデータが一瞬で表示される。満足、満足である。

 74VHC126のバッファーもピンをつけて動かしてみる。ブレッドボードのスペースがもう残り少なく、少し離れてつけたため、ジャンパーコードがうず高く盛り上がってしまったが、問題なく動いた。電圧を測ってみた、ところが3.3Vでなく、まだ3.5Vを超えている。何故だ。良く分からない。最大定格の3.6V以内とはいえ気持ちが悪い。ひとつひとつ配線を抜いて原因を調べているうち、いつのまにか、3.26Vという元の電源電圧に戻った。???である。発振でもしていたのだろうか。そういえばこの石にパスコンはつけていない。とりあえずコンデンサをつけて様子を見ることにする。

 やれやれ、最後に少しみそをつけてしまったけれど、ここ数日の作業は怖いくらいに順調である。

| | コメント (0) | トラックバック (0)

Mega128で漢字フォント表示

フラッグシップMega128の登場(6/11/08)
 LEDマトリックスのお遊びに止め処がなくなって、とうとう、当がた老AVR研究所の旗艦チップ、Mega128の出番がやってきた。性能から言えば、このあいだ衝動買いしたH8/3069Fの方が16ビット機で、上だが、こいつは、表面実装の20Mhzクリスタルをおまけについていた25Mhzに取換えようと悪戦苦闘し、結局はずすことが出来なかったこともあって少し嫌気がさし、放置してある。それに秋月のこのAKI-H8/3069-LANボードは、512KのROMだけでなく、2MのSRAMが始めから付いている。 SDカードやLEDだけに使うのはもったいない。

 Mega128の方は、このあいだ変換基板を載せたCPU基板を作り、準備が済んでいる。始めは168あたりでLEDとSDカードをつけようと思ったが、SDカードだけですでにフラッシュを14Kも使っており漢字フォントの処理でメモリ不足に悩まされそうなので、どうせブレッドボードで遊ぶのだから出し惜しみすることはないと早々と出番を決めた。Mega128

 CPU基板に20本余りのピンヘッダーをつけたのだが、チップはTQFPで64本もピンがあって何を引き出してよいのかわからない。SDカード用とLEDマトリックスにしぼってピンアサインをしていったが、2段になったピンの順番の数え方が難しい。表と裏でどうしても混乱する。 しかし、Tiny2313からのコードを単に移植しただけのLEDマトリックスのプログラムは最初全く動かなかった。

 Webの情報を参考にセットアップして(ISPのピンが違う、ヒューズビットを互換モードから変える、クロックの設定を外部にする)、AVRispで動くことは確認されているので、落ち着いて間違いを捜していく。タイマのレジスタの名前が変わっていたり、UARTの割込みベクタやレジスタの定義変更見落とし、出力ピンの定義間違いなど下らないミスが見つかった。その結果、何とかLEDが点くところまで行ったが、トランジスタアレイをパラレルにドライブするところが半分しか表示されないバグにはてこずった。 何度も配線を確認するが間違いはない。

 データシートをよくよく調べていたら、トランジスタアレイをドライブしているPORTFはJTAGポートを兼ねているという記述があり表示されない部分が正しくその部分である。あれえWebにヒューズビットのデフォルトはJTAG無効になっていると書いてあったはずだがな、と念のためヒューズビットを調べてみたら確かにJTAG経由のデバッグは無効になっている。ところがヒューズビットを見ているうち別のビットにJTAG禁止/許可ビットというのを見つけた。ここではJTAG許可になっている。こいつかもしれない。このビットを念のため禁止にして動かしてみたら「あたり」であった。JTAG無効にするだけでは駄目だったのである。

 やれやれ、動かすのに丸々1日かかった。フラッシュサイズは2313の限度2Kのままなので、使用率はわずか1.5%、目の眩むような広大な敷地が残されている。楽しみである。当面はこれも4KもあるEEPROMを使ってANKのキャラクタを入れてテストする予定だ。

Web情報を頭から信じてはいけない(6/14/08)
 Mega128のフラッシュは128キロバイトもある。フォントファイルを入れたSDカードを読むプログラムを入れる前に、LEDのフォントをEEPROMに少し手入力し、電光掲示板の準備をしておこうと、新しいフォントをEEPROMに書くプログラムを追加したのだが、これが動かない。

 Webの情報を元に、EEPROMのルーチンを書くが、全く思うところにデータが入っていかない。とにかく盛大な「ポインタ変数に整数を入れるな」という警告メッセージが出る。ポインターのキャストがうまく行っていないのかと警告のところを直すと、別のところで文句を言われる。変数定義を、始めからポインタにしてうまく行ったかと思うと、今度は「ポインターとポインターを足し算してはいけない」と今度は警告ではなくエラーになってバイナリを作ってくれない。LEDをまとめて発光させているので、スクロールさせるには2つのアドレスを足す必要があるのだ。ここにさらにキャストを入れれば直るのだろうが、余りキャストで一杯になるのも見にくいソースになってしまう。

 EEPROMに関しては、キャストの警告を無視してもこれまで問題がなかったので、これが動かない原因とは思えないがとにかく、書かれる場所もでたらめなら、入っているデータもでたらめ。eeprom_write_block() というまとめてデータを所定のアドレスのEEPROMに書き込む関数が言うことを聞いてくれない。

 思いあぐねていたとき思い当たったことがある。このWebサイトの情報は前にも間違っていてひどい目にあったことがある(UARTのレジスタ)。もしかするとこの関数の定義が間違っているのかもしれない。別のサイトで確認してみた。何と別のサイトの定義では、受け側と送り側の引数の順番が逆になっているではないか。しかし、このままではどちらが正しいのか分からないので逆にして動かしてみる。

 やれやれ、最初のWebの情報がやはり間違っていた。プログラムは所定の場所に正しいフォントデータを記録するようになった。頭から信じた俺が悪かった。まあ、この関数の定義が通常とは違う順番(左から右、普通は右から左)になっているのもおかしいのだけれど、こういう肝心のところを間違えているのは頂けない。気を取り直し、せっせと数字をエディタで作り登録する。

 我がLEDマトリックスは、UARTのキーボードから数字を入力するとそれを表示する電光掲示板となった。赤と緑は途中で色変更文字$を挿入すると変わるようにする。$を表示したければ$$と入れると$が表示されるようにもした。いや楽しい。数字以外のフォントも入れて遊ぶ。

 しかし、重大な課題があることに気づく。プログラムを簡単にするためすべてのフォントは同じ幅(等幅)にしているが、数字や、Iのような文字を表示すると間延びしてしまう。いわゆるカーニングをしないと見栄えが悪い。フォントデータエリアをアドレスで操作すれば出来る理屈だが、Tiny2313からMega128に移植するときプログラムをすっきりさせるため、わざわざアドレスから配列でデータを処理するよう直したばかりだ。今さら前にもどすのも大変だし、まだ先にやることがあるので先の楽しみに残すことにする。とにかく、次々にやりたいことが増えていく。

SDカードから8ビットフォントが出た(6/17/08)
 ここ数日は、Mega168に移植していたSDカードアクセスのプログラムを本来のMega128に戻し、これまでのLEDマトリックスのプログラムに合わせる作業をしている。SDカードに入った日本語フォント(美咲フォント)をLEDに使おうという計画である。これで今まで別々に開発していた機能が統合される。フォントは連続して表示することを考え、8×8のエリサフォントでなく、7×7の美咲フォントを選んだ。いずれもWeb上で公開され太っ腹なことに個人、商業目的にかかわらずすべてフリーである(9/06/08修正)。

 コメントアウトしていたMega128のステートメントを戻し、ブレッドボードにSDカード基板を移して順調にSDカードが読めるところまで行った。これまでの開発では、一画面分で画面表示が止まり、何らかのキーを押せば次のテキストファイルが表示されるようになっている。シフトJISの漢字なら、日本語テキストも見える。フォントファイルの中からフォントデータを抽出するロジックをこれから開発する。ところが暫く読んでいるうち、プログラムが暴走を始め表示が止まらなくなった。あわてて電源を切り、もう一度入れなおしたら今度は動かなくなってしまった。

 この日はもう深夜も2時を過ぎていたので、あれこれ考えながら床に就いた。その翌日、もしかしたら直っているかもしれないと再度動かしたが、やはり同じ。読んでいくだけでデータがこわれることは考えられない。別のSDカードも読めない。ソースを調べるが前と変わったところはない。大体、最初は動いていたのだ。何がおかしくなったのだろう。ピンを配線していないのでライトプロテクトとカード検出の結線はせずにソフトで常にOKにしている。これがいけないのだろうか。しかし何も変えていない。どうも初期化に失敗しているようだがわからない。遂にどこも調べるところがなくなり、仕方なく、ロジックアナライザーを持ち出した。

 出てきた波形を見て驚いた。クロックは出ているが、信号が何も出ていない。こりゃあハードだ。ブレッドボードの配線を確かめる。ちゃんとみんな刺さっている。あれ、SDカードの6番ピンはGNDなのに何かが結線されている。何だ何だ、これはSPIの出力ではないか。隣の7番から移動してしまっている。

 原因がわかった。暴走してあわててスイッチに手をかけたときジャンパーコードに触れて線がはずれそうになりつけ直したとき隣に差してしまったのだ。線に余裕がなく斜めになってささっていたので間違えたようだ。わかってしまえば何でもないお馬鹿なミス。正しいピンに接続して、SDカードは何事もなく作動する。やれやれ、ブレッドボードは便利だが、こういう危険がある。Misakilog

 フォントファイルはBDF形式といって、すべてがキャラクタなので操作がしやすい。夕方からロジックをメモに書き出し、フォントデータをUARTのコンソールに順次表示するコードを書く。久しぶりにC言語のライブラリで昔の参考書をひっぱりだしてstrcmpなどのなつかしい関数を組み込む。フラッシュはたっぷりある。何を組み込んでも余裕である。chaN氏のFatFSはいたれりつくせりの関数が用意されていて、簡単に組み上げられた。

 最初、strcmpで文字列を比較して合わない、合わないと悩んでいたが、長さを揃えて調べないと一致しないことがわかり(strncmpを使う)、それからあとの進捗は早かった。

 しかし、表示してみて、危惧したとおり、アルファベットやひらがな程度なら問題ないが、やはり漢字を8×8で表示するのは苦しい。しかもスクロールしながらでは余計わかりにくいだろう。折角、ここまできたが、ちょっと先行きが暗くなってきた。

| | コメント (6) | トラックバック (0)

2008年9月 3日 (水)

スタック領域とSRAM変数

遂に真犯人をつきとめた(6/2/08)
 これまで、がた老研究所を悩ましてきたトラブルの原因が外部の支援でほぼ特定でき、とても嬉しい気持ちでこの記事を書いている。 LEDマトリックスでUARTバッファーを小さくしたら一気にトラブルが解消したため、これまでの色々なトラブルも含めてまとめてAVRWikiに「WINAVRの外部変数の不具合?」というタイトルで投稿したらすぐ反応があった。最初のレスポンスは少し違っだが、さすが経験者揃いのメンバーである。私が見落としていた問題点をすぐ明らかにしてくれた。いやいや仲間と言うのは持つべきものである。本当にありがたい。

 そうなのだ。限られたSRAMスペースにスタック領域がとられていることをすっかり見落としていた。このあいだは定義したバッファーサイズと実際のSRAMサイズが合わないことを不審には思ったけれど、それ以上の追求はしなかった。冷静に考えていれば、今度のTiny2313などSRAMはわずか128バイト、80バイトものUARTバッファーをとれば、残りは40 数バイトしかなく、ちょっと沢山pushをしてレジスタを待避させているプログラムなどであっというまに届いてしまう。それに早く気づくべきだった。

 大型機育ちなので、メモリバイオレーションには敏感ではない。大型機だと、あっというまに異常終了してプログラムそのものが通らないしかけが出来ているのでプログラマーは余り心配しないですむ(起きてから考える。ただし自分のプログラムのなかで自らのエリアをつぶすとわからない)。これまでTiny26やTiny2313(SRAMが128バイト) で起きて、Tiny861(512バイト)で起きなかったこと、I2Cインタフェースが72 バイトの送受信バッファーを半分にしてトラブルが解消したこと、データの破壊がUARTなどの割込みプログラムのあとで起きること、すべてがこのことを裏付ける。

 このブログでこれまでコンパイラーのバグだと言っていたのは、ほぼすべてが、このレジスタ値の待避などのスタックデータがSRAM変数域に被ったことが原因だったと思われる。WinAVRコンパイラーのみなさん、リンカーのみなさん、疑ってごめんなさい。

 AVRWikiでのやりとりでは、メモリマップの取り方をついでに質問をしたら、これも直ちに教えてもらった。 AVRstudioで出力されるlinkmapは実体のアドレスマップではないが、ELFファイルをavr-nmコマンドにかけると、実際のメモリーアロケーションが得られることがわかった。 これでビクビクしながらメモリを定義するのでなく事前に確認して予防ができる。寿命がきたとされたTiny26はまだ動く可能性が高くなってきた(LCD基板は2313に換えてしまったので確認できない)。

 LEDマトリックスは順調だ。わずか128バイトだけどEEPROMを利用して、自分の名前の漢字フォントをLED上で作り登録した。16ヶ登録できる。8×8のエリサフォントでも結構視認性が高い。携帯のムービーで動画を記録する。 こういうと叱られるが、みんながまあ愚にもつかないLEDマトリックスではまる理由がわかる気がしてきた。

 何度も書くように、始めは何の反応もしないLEDや、IC、抵抗などの部品が集められ半田付けされ、チップにプログラムが書かれると、生き生きと点灯して意味あるメッセージを送り出す。それが単なる点滅でも楽しいのに、自分の名前がLED面の上を流れるのを見ていると何故か嬉しくてたまらない。まあ、これは作ったものにしか分からないかもしれないが。

 ただ、Tiny2313はフォントのエディターまで作ったら、フラッシュがもう満杯になった。残念だけれど、861かMega168に移行せざるを得ない。今日は仕事の帰り、調子に乗ってLEDマトリックスをさらに2つ買い足してしまった。これで8×32の本格的な電光掲示板になる。

3色でLEDマトリックスが動いた(6/6/08)A6061329
 勢いで、というより、秋月の商品棚に2色のLEDマトリックスが2つしか残っていなかったのであせって買い込んだようなものなのだが(案の定その後は欠品)、よく考えてみたらまだ単色でしか動いていない。せっかく赤と緑のLEDがついているのだから、赤だけでなく緑もつけてみたい。同時に光らせるとオレンジか黄色の計3色でドットが表示できる。基板にはもう1色用のシフトレジスタのスペースもつけアートワークも出来ている。

 マトリックスを追加する前にその配線をすることにした。予想通り追加の配線は厳しい。UEW線での基板上の交差はしないで、基板の表にジャンパー線を回すという決まりを作っていたのだが、これを守ることが出来ず、いくつかの交差を許してしまった。まあ、UEW線の絶縁性は高そうで、ウェブにはこれを接着剤でかためて配線している例もあるのでそう心配はしていない。

 2色となると配線だけでなくプログラミングも難しい。ダイナミック表示をどうするかが問題だ。HC595はラッチがついているので、相当な長いデータをシフトレジスタに送り込んでも表示切替には気を使わなくてすむのはありがたい。しかし、2313はもう数十バイトしかフラッシュが残されていないので、プログラムがなかなかうまく組み込めない。

 今まであった4ヶのバッファーの2つづつを赤と緑のフォントエリアにして、それを同時にスキャンする方法によって2313で3色表示のスクロールが可能になった。と、簡単に書いたけれど、これを思いついて実際に動くようになるまではやはり2日ほどかかった。

 まあ、これが楽しいのだ。プログラムはまさしく考えたようには動かず、書いたようにしか動かない。最初、色コードのようなことを考えたが、各ドット単位に色を変えるところまで考えると断然この方法のほうがわかりやすい。ただ、シフトレジスタへのデータ送り込みと、各列へのダイナミックな動き、さらにそれ全体をリングバッファーのように折り返す動きを考えながら2色発光させるロジックはちょっとしたパズルである。それだけに思い通りに動いたときの満足感は、人のソースで動いたときのものとは比べ物にならない。

 ウェブには予想通り沢山、実験記があげられていてソースも掲載されているようだが、今度はなるべくこれを見ないようにしている。SDカードから文字フォントを読み込んで、長いテキストが電光掲示できるようになってからソースを見比べてどちらが優雅か比較してみようと思っている。
 前記事にuploadしたプログラムはこの3色を表示するTiny2313の最新のプログラムです。ソースをご覧になればわかるように、UARTのコマンドのいくつかはフラッシュメモリ不足でコメントアウトされています。

| | コメント (0) | トラックバック (0)

2008年9月 2日 (火)

LEDマトリックスで遊ぶ

LEDマトリックスにはまる その1 (5/28/08)
 この1週間、お遊びのLEDマトリックスに夢中になっている(まあ、電子工作自体がお遊びだが)。 二色の8×8のLEDマトリックスは、秋月で見つけ、安い(\200)こともあって、大分前に、つい目的もないのに2つ買ってしまってある。ダイナミック表示とか、シフトレジスタで線をへらすテクニックなどは、昔、時計の針を刻む歯車に何故か心がわくわくしたのと同じような、工作心(ごころ)を刺激する。今までロガーとか電源制御とか実用的なことばかりやってきたので息抜きということもある。ちょっと遊んでみた。いや、単に作りたかっただけだけど。

 ところが、これが難物だったのである。最初軽く考えて、どうせなら一つでなく、電光掲示板のように2つ並べてスクロールさせてやろうと欲張ったのがいけない。赤緑の2色とも配線するのはとても大変になることがわかった。

 一応シフトレジスタの74HC595は4つ買ってあり(マルツが一番安く\94だった)、小さな基板にも一応そのスペースはぎりぎりとったが、最初は1色だけ実装することにした。LEDはスクロールを考えて、ピンを少し曲げて境目なくピッタリつけて固定する。LEDのドライブは、定番のトランジスタアレイ(TD62083)で、ダイナミック表示なら2色の8×8マトリックスを3つくらいまで1ヶでドライブ出来そうだ。

 石はとりあえず、ポートが8本連続しているTiny2313にした。これがうまく行ったら、フォントデータをSDカードに入れてMegaクラスで8ビットの、昔のPDAで流行っていた、エリサフォントなどで漢字の電光掲示板にしてやろうというのが最終的な計画である。

 実装は、UEW線でも良いが、UEW線を交叉させて配線するのに抵抗があったので、もうひとつのジュンフロン線を試してみた。これで、これまで買いたいのを我慢していた、Engineer製のワイヤストリッパーが買える。秋葉原駅前のラジオストアの入り口の工具店が意外に安く\2760で手に入った。それでも最近買った工具では電動工具を除けば一番の値段だ。これまでのニッパーとは格段の生産性で面白いように被覆がむける。細い線の皮むきにはやはり必須の工具であることがわかった。

 工具のおかげもあって配線は順調に終わり、早速ブレッドボードにヘッダーピンで直結する。 ソフトは下書きもしないで気楽に、これまでの部品ソフトを寄せ集めて3ms単位で8バイトのフォントデータをシフトレジスタに流し込むプログラムを組んだ。スクロールさせる必要があるので、少し本格的に、昔を思い出しながら構造体(struct)にフォントデータを入れた。

 動かしてみたら、これが全くうんともすんとも言わない。まあ、こういうのには慣れている。プログラムにはUARTが組んであるのでデバッグは簡単だと考えていたら、これが暴走するのである。原因はわからない。LEDは全く光もしない。ハードは組み込む前、すべてテストでLEDが点くことを確認してあるのにどこも光らない。

 UARTが暴走するのは、構造体のポインタの不正の疑いが強い。単なる変数ではなく、構造体はポインタを多用するのでデバッグが済んでいないときはどうしようもない。泣く泣く、構造体をやめて8バイトの配列に戻す。何とかUARTの暴走は止まった。

 ところがそれでもLEDは全く点灯しない。途方に暮れてロジックアナライザーで出力を確かめる。何とピンの出力は全く問題なく見事に出ている。8ビットクロックとともにデータを出し、最後にラッチパルスを出し、コモンのトランジスタアレイのドライブはちゃんと切り替わっている。こりゃあ、ハードだ。ここで深夜も3時をまわったので心残りだが追及を諦めた。

 次の朝、事務所に出かける電車の中でもLEDマトリックスのことが頭から離れない。昨夜のテストの思い出したくない光景が目に浮かぶ。トランジスタアレイのソース側に試しにVccをかけたときに一瞬電源のパイロットランプがわりにしているLEDが暗くなったのが気になってならない。また、こわしてしまったのだろうか。いやいや大丈夫だ。ウェブにはシフトレジスタのリセットピンにはVccをかけた回路図が商品になっている。

 あっ、そう言えば、確かリセットピンはグランドにつないで半田付けしたぞ。ああー、反対にOE(output enable)にはVccをかけて配線した。ここはすべて負論理だ。アートワークのときからそうなっていた。やれやれ、これではシフトレジスタは動きようがない。二重に止まっている。ICはこわれていないのだ。良かった。全部、こちらのせいだ。

 仕事を終えて帰宅し、食事もそこそこに配線のやり直し。点いた。喜んだのも束の間、
このあとも泥沼が続いたのである。A5301302

LEDマトリックスにはまる その2 (5/30/08)
 点灯したLEDは何とも不可思議な動きで全く安定しない。これはこれで見ていて飽きないが、目的は文字をダイナミック表示で固定して出すことである。ソースを何度も調べるが、こんなランダムな動きになるようなところは見当たらない。頭を抱える。気に入らないのは、コードを少し換えるだけでまたUARTが暴走したりする。

 タイマーがおかしいのかと間隔を変えるが全く変化がない。念のためロジアナで調べてみたら、パラメータを変えても時間間隔が変わっていないことがわかる。外部変数のスイッチが機能していない。これは例の外部変数がこわれるトラブルがここでも発生しているようだ。場所を換えたり、コンパイルオプションを換えて、何とか用意したアルファベットのAとBが表示できるようになった。しかし、後半のフォントビットがどうしても設定どおりの位置におさまらない。フォントデータは内部変数域にあり、あのトラブルとは関係ないはずだ。

 一日を無駄に過ごして、次の日、気持ちを新たに解決に取り組む。タイマでダイナミック表示をしているから解析が難しいことに気づく。デバッガーのようにタイマを止めて1ステップづつ調べていけば良い。幸い、きめられた時間にやらないとまずい処理はシフトレジスタにシリアルにデータを送るときだけだ。

 タイマの代わりに、コマンドで進むコードの改修はわずかで済んだ。やってみる。おお、これは便利だ。タイマのときは入れられなかったテストステートメントがいくらでも入れられる。LEDも一列づつ律義に表示されわかりやすい。

 テストステートメントで変数の表示をして行って驚くべき事実が明らかになった。外部変数だけでなく、内部変数までいたるところでデータが破壊されている。これでは暴走するはずである。AVRのサイト(AVRWiki)に外部変数だけだと書いたけれどそれどころではない。犯人を追跡する刑事の気分で、地道にひとつづつ破壊しているところを追及する。

 たどり着いたところは、Tiny2313の標準UARTの受信部分で、受信レジスタからデータをユーザー側に受け取るところである。これはもうどうしようもない。標準UARTが使っているSRAMデータとユーザーデータがぶつかっているのだ。コンパイラのバグである。

 ただ、前から気になることがある。コンパイルの出力結果が示すSRAMの消費量が、配列で確保したバッファ量より小さいことである。こいつ、定義した分だけデータをとっていないのかもしれない。もしかしたらと半信半疑で、バッファの大きさ80バイトを半分の40バイトにしてテストしてみた。

 やった。これまでのすべてのトラブルはうそのように消えて別人のように正確にLEDは表示された。急いでタイマを戻しダイナミック表示にする。ピタリとあらかじめ作ってあったA、Bの文字が表示される。いやあ嬉しい。1ドットづつ点けたり消したりするコマンドもきれいに動く。解決したときの喜びは今までの苦労が多ければ多いほどそれだけ大きくなる。75才でエベレストに登った三浦雄一郎の気持ちと同じだ。

 勢いに乗って、これまでの配列から構造体に変更し、スクロールに挑戦する。リングバッファーのロジックと同じでこれは簡単にコードが書けた。まだAとBしかキャラクタがないが、それらしく横スクロールする文字を眺めてひとり悦に入る。

LEDマトリックスにはまる その3 (5/31/08)
 いや、スクロールも手強かった。前にスクロールできたと書いたが、実は1文字づつ独立してスクロールするだけで文字が2文字分流れていく電光掲示板の形ではスクロールできていない。シフトレジスタは2段にカスケードになっていて、16ビットで2文字の縦データを送る。横データはトランジスタアレイ一つで同時に2つのLEDマトリックスの同じ列が点灯するようになっている。

 これで2文字分のスクロールをするのは結構大変である。しかし、これがプログラミングの醍醐味である。人のソースコードを見れば簡単だろうが、このところ人のコードを頼りにしすぎる。久しぶりにメモを書き散らしてロジックに頭を捻った。年をとっても直感的な分析力は落ちていないが、こういう解析力は確実に落ちているのを痛感する。集中が効かない。あるところまで論理をつめていくと最初の前提条件を忘れてしまって論理が閉じていかないのだ。

 まあ、年齢相応に色々なアプローチの手法だけは山ほど知っているので、そう悲観はしていないが、思い通り動かないと最後はソースリストの前で、定数を足したり引いたりする不毛なデバッグになり、暫くお休みをとるという繰り返しである。

 こういうときは気分転換が一番である。風呂などが一番良い。行き詰ってもう寝ようと風呂に入ったとき、はっと気がついてうまく行ったことが何度もある。このときもそうだった。トランジスタアレイが並行して点灯していくことに気を取られ、その順番と最後まで行ったときの処理をあれこれ考えていたが、黙ってそれぞれの点灯すべきアドレスだけ計算していけばそれでスクロールができることに気づく。そのために配列は並んでいるはずだ。アドレスが表示データを越えれば素直に最初のアドレスに戻ればよい。

 風呂に入ったのが午前3時近く、今さらまたデバッグするのも何なので寝たが、夢にまでVccだグランドだと基板配線の光景がでてきて夢の中で苦笑する。やることがあるときの朝の目覚めは早い。朝食もそこそこにPCの開発環境を立ち上げる。

 これで決まりと考えたロジックは最初動かなかった。がっくりくる。スクロールの指定もしていないのにそもそも文字が静止しない。あれこれいじるが改善しない。ミリセカンドのオーダーで表示を繰り返し、なおかつ少しづつその表示をずらすというのは確かにそう簡単ではない。

 これも一休みして原因が判明した。ポインターを止めて別の変数で8バイト分ダイナミック表示をしているときにポインタそのものも動かしていたのである。これでは静止しないはずである。ステートメントでいえば、++の記号をひとつはずすだけ。これでLEDマトリックスは完全に想定どおりのスクロールを開始した。万歳。A5311316

 表示フィールドを大きくして少し電光掲示板風にしてみる。家族に自慢する(いつも馬鹿にされるのだけれど吹聴せずにはおられない)。ウェブデザインをバイトにしている次女だけが、「すごい」と驚いてくれた。お世辞でも嬉しい。まあ、次女はよく大学まで車で送ってやっているからな。

 LEDマトリックスの次の目標は文字フォントの導入である。これでこのあいだのSDカードのプロジェクトと合体する。

ここにTiny2313を使ったLEDマトリックスをドライブするプログラムを置きます。回路図がないので読みにくいと思いますが、ソースにコメントがありますので、ダイナミック表示やスクロールの参考にしてください。EEPROMにフォントを溜めて16字まで表示できます。なお、本格的な8ビット漢字を表示する電光掲示板(Mega128)のソースはこのあと公開します。

「MATRIX2313.lzh」をダウンロード


| | コメント (0) | トラックバック (0)

今度はフォトカプラ2つが犠牲

気が滅入る(5/22/08)
 このあいだRTCモジュールを電源逆差しで失ったのもつかの間、今度はフォトカプラを2つも壊してしまい気分が滅入っている。ひとつ¥20もしない安いフォトカプラなのだけど、このまえの100V接触のような事故と違って、ここに書くのも恥ずかしいお馬鹿なミスが原因だったことが余計悔しい。まあ、聞いてください。

 SDカードの試作ボードは一応機嫌よく動いているが、面倒なことが残っていた。UARTをUSBシリアルモジュールで接続しているため、本体の電源を切っても、USBのUART側の電圧で(UARTは負論理)、送受信ピンを通じて電流が流れて本体のMCUのVccに電圧が上がり(1V近く)、パワーオンリセットがかからない。前のチップからこの問題は起きており、このときは1V以上出て、MCUが動作したままだった。

 USBケーブルを抜けばシリアルモジュールの電圧はなくなり問題ないのだが、差し込みの度にUSBが初期化されPC側のターミナルソフトの再立ち上げが必要になる。これでは何度もリセットを繰り返して開発するとき、不便でたまらない。MCUのリセットピンをアースしてリセットすれば良いが、電源を切ってもMCUが何となく動いているのは気持ちが悪い。このあいだから、これを解決しようと、フォトカプラを持ち出してあれこれやっていた。

 ここで徹底的な勘違いをしていたのだが、フォトカプラ入力のLEDの電流制限抵抗は内蔵されているものだと頭から思い込み、入力をそのままUARTの出力につないで動かない、動かないと思い悩んでいた。あろうことかVccの5V にもつないでみた。

 テスターを持ち出してフォトカプラが壊れていることに気づき、10年近くも前に買ったフォトカプラだから前に壊したのを忘れていたのかと気楽に、もうひとつのフォトカプラをとりだして、しかもこのときはテスタをつけて壊れていくさまを目撃したと言うお粗末。

 始め、電圧が上がっていてそのうち0になってしまい頭を捻っていたら、はっと気がつき呆然となった。そのときは既に2回路フォトカプラ2つの3回路分が犠牲になったあとであった。子供が親の目の前で車にはねられたようなもので可哀想でしかたがない。

 何とか気を取り直し、残りの1回路に制限抵抗を入れテストをしてみる。Vccは見事0V近くまでさがり絶縁の目的は果たされた。UARTを動かしてみる。うーむ、データの受信は少し出来ているようだが、データシートのとおり、38.4kbpsのシリアルデータ、1クロック25μsではパルス遅延が5μs程度の汎用フォトカプラでは苦しい。半分くらいデータをミスする。予想通りだった。元々はこれを確かめるためで、こんなことなら始めから実験などしなければ良かったのである。

 高速フォトカプラは沢山市販されているが値段は結構するし(\200以上)、まあこれをつけるほどのものでもない。出来ないとなると何とかやってやろうといういつものへそ曲がりの癖がでてあれこれ考えてみる。3ステートバッファも大げさすぎる。このあいだうまくいったインバーターを通した方法は、何故か順論理(NANDを2つカスケード)にしたら74HC00の電源を切ってもダメだった。

 それでは普通のトランジスタではどうだろう。ICそのものがトランジスタの集合体だからうまく行くとは思えなかったが、だめもとで古い2SC945を持ち出してエミッタフォロワで接続してみた。これがうまく行ったのである。UARTが5V、Vccが3.3Vでベースに直列に10Kエミッタに1Kの抵抗を入れ、コレクタ電流が3mA程度でポート出力は3Vちょうどにおさまった。Vccも電源を切ると、0.4Vに下がる。いやいや昔に比べればハードの設計技術は長足の進歩である。晴れない気分に光が差し込む感じがする。

 2SC945のスイッチングスピードを念のため調べてみる。データシートによれば、立ち上がりはPict0720早い(50ns)のだが、立下りは400nsと非常に遅い。しかし、100kbps程度のUARTではまだ10倍以上のマージンがあるので問題なさそうだ。

 ついでに、ブレッドボード用に、基板の切れ端の上にトランジスタとヘッダーピン、ピンソケットをつけ、回線をアイソレーションするミニ基板をでっちあげた。 こういうものを作っているときは、気が紛れていやなことを忘れる。これで実験のたびに回路を組む手間が省けるというものだ。

| | コメント (0) | トラックバック (0)

2008年8月31日 (日)

LCDを待ち時間なしで動かす

電源逆差しでRTCがお亡くなり(5/11/08)
 SDカードのプロジェクトが一段落したので、工作室を整理しながら、今までやり残していた作業を少しづつ始めている。電力ロガーのセンサーの出力がACであることがわかっていたので、ブリッジダイオードでDCにして手元にある電気機器を測定したり(これが意外に直線性が悪く補正が必要か)、遊びに買ったLEDマトリックスのトランジスタアレイ(TP62083)の定格を調べて、基板の構成を考えたりしていた(最終的には4文字くらいの電光掲示板にしたい)。

 先の話はともかく、前から気になっていたのが、I2Cを使ったLCDドライバーで表示しているデジタルクロックである。1秒タイムアウトですっかり丈夫になったドライバーだが、一晩置くと、表示が止まっていたり、2行ダブって表示されたり、まだ実用レベルとは言いがたい状況である。LCDの表示がダメなのか、I2Cが空振りしているのかわからない。

 UARTをつなぐと何事もなく表示が始まるので、デバッグの手段が見つからず放置してあった。懸案が片付いたこともあってアイデアが浮かんだ。そうだEEPROMにログを記録しておき、それを後から見れば良い。幸いメインチップはTiny861なのでフラッシュは余裕があるし、EEPROMは512バイトもある。節目でデータを書きタイムスタンプを書き込んでおけば直前の状況がつかめる。

 思いついたら実行に移さないと気がすまない性分である。早速、奥に置いてあったLCDデジタルクロックのブレッドボードを取り出し、秋月で買った3個めのRTCモジュールを差して久しぶりに動かす。問題なく動く。AVRstudioのプロジェクトをLCDのメインに移し、eepromのルーチンを組み込み始める。

 組み込み始めてから、LCDドライバーの方も換える必要がでてきて結局ドライバー側もファームウエアを書き換える。ISPケーブルが2つのボードを行き来し神経を遣う。何とか双方のファームを書き直し、データの取り出し部まで書かずにとりあえず動かし見る。

 これが、動かないのである。まあ、すぐ動かないのには慣れている。少しづつこれまでのルーチンを入れながら動かすことにする。まず、LCDドライバのケーブルをはずし、これまでのステップを全部コメントアウトしRTC部分だけ動かしてみる。なに!これも動かない。そんな馬鹿な。念のためRTCモジュールをSDカードのボードに差してみると問題なく動く。

 少し考えて原因がわかった。LCDドライバーへのコマンドをコメントアウトしていないので、ここでI2Cがハングしている。モジュールが原因でないので元のモジュールを戻し、LCD関係をスキップするファームを書き換えて電源ON。

 まだ、動かない。えー、どうしてとモジュールを見たら、何と逆に差している。大抵のICはたすきがけの位置にVccピンとGNDピンがあるから逆ざしは致命的だ。この間10数秒。慌てて電源を切り、元へ戻すが遅かった。レジスタは読めるが書き込めない。そのうちreadも出来なくなった。

 ちょうど車の物損事故のときの気分と良く似ている。怪我をしたり、たいしたお金を失ったわけでもないのに、無性に自分が腹立たしく気分が納まらない。車と違って外見は全く変わりがないので余計口惜しさがつのる。 やれやれ、また秋月に行って買ってこよう。いや余り早く行くとまた必要もないものを買ってしまいそうである。もうすこし後にしよう。

LCDのビジーフラッグの問題が解決(5/14/08)
 電源逆ざしでICを失い気分が滅入っていたが、久しぶりのクリーンヒットが出て気分は最高である。今年の正月から奥歯にものが挟まったように気になっていた問題が遂に解決された。LCD表示のビジーフラッグを調べて表示するロジックの実装である。

 LCD表示は、AVRを始めてすぐ取り組み、豊富なWebの情報をもとに動かせるようになった。I2Cを使ったLCDドライバーまで作ったが、長時間表示させると調子がおかしい。表示が止まっていたり、2重に表示される。これを解明するためEEPROMを使ったトレースの仕掛けを作ったのだが、これがまだハングするのである。EEPROMには何にも残されていない。I2Cがおかしければ必ず何か証拠が残るようにしてある。こうなると原因はI2CではなくLCDの表示そのものである。

 LCDがハングする原因はLCDの制御が終わらないうちに次のコマンドを送ってしまっている可能性が高い。さらに待ち時間を増やしてみたが同じ。しかし、待ち時間を調整して動かすのは余り嬉しくない。確かに1本信号線は節約できるが、本来のLCDの能力を生かしていないことになる。しかし、LCDのREADを使ってビジーフラグを見る方法は、さんざん試したが、どうやっても動かず、諦めてみんながやっているように時間を待って書くコードにしてしまった。

 データシートによれば、コマンドの処理時間はたかだか60μsなのに、待ち時間は1ms以上必要で、それ以下ではハングアップしてしまう。理屈に合わないが、それだけの待ちを入れれば動いたのでそのままになっていた。

 ハングアップとは直接関係ないが、ちょうど良い機会なので、少し念入りに調べてみた。Webを漁ったが、どのソースも待ち時間を入れているだけで本格的なビジーフラグを見るコードを探し当てることが出来ない。諦めきれず、「LCD」「待ち時間」などのキーワードで調べているうち、あるサイトにLCDを使った製品のPDFがあり、そこには待ち時間ではなく、LCDのビジーフラッグを調べているフローチャートが掲載されていた。このプログラムはビジーを見るために2回READをしている。えー、頭のbit7(busy flag)を調べるだけで良いのに何故2回も読む必要があるのだと思った瞬間、頭を電撃が走った。これだ。LCDの初期化で散々4ビットモードにするロジックを研究したはずなのに、フラグを見るREADを一回しかしていない。

 あとから考えれば、何でもない話だけれど、全くこれに気がついていなかった。そのWeb
を見たのは職場である。帰宅して夕食もそこそこにLCDの試作プロジェクトを立ち上げ、LCD表示基板から石をはずしてブレッドボードにLCDを取り付ける。お世話になったTiny26の余命をすごさせるLCD 表示基板には、こういうこともあろうかとLCD端子をそのまま引き出したソケットがつけてある。

 急いで色々なところからコードをかき集め、待ち時間ではないビジーを見る関数にENABLEをもう一回とデータレジスタを出力から入力、さらに出力に戻す修正を入れる。あれだけ頑固に動作を拒否していた仕掛けが何の問題なく動いた。心なしか速い感じがする。ハングアップする原因は明らかだ。次のREADで下半分が読み出され、関係ないビットをビジーフラグにみなして、それが0なら先に突っ込んでハングアップする確率は50%、奇数回にOKになれば、あとの処理は4ビットづつずれて目茶目茶になる。

 問題が解決したときの最高の気分を味わう。何度経験してもこの気分は何物にも替えがたい。長い間の懸案が片付いたのだ。今までの暗い気持ちが嘘のように晴れ天下をとった気分になる。山登りで頂上に着いたときと同じ爽快感である。

ここにビジーフラッグを見て表示するLCDのドライバーとヘッダーファイルを置きます。
表示速度ははるかに速くなりますが、RW線を所定のポートにつなぐ必要があります。

「NewLCD.lzh」をダウンロード

 今夜は旧友との飲み会でへろへろだったけれど、帰って来てすぐPCに向かう。やり残している仕事(?)がある。今まで文字を表示するたびに1msとか1.5ms待っていたルーチンとの性能比較だ。酔いで覚束ない手先でロジアナのプローブを接続し、LCDの最大の文字数32文字を表示させる。何と32文字表示するのに2msかかっていない。10倍以上の速さである。大量に出力すると見た目でもはっきり一気に表示されるのがわかる。今までは一呼吸かかっていた。LCDというのはそういうものだと思っていたが、申し訳ないことをした。LCDに謝らなくてはなるまい。

やることが多すぎる(5/20/08)
 難問が解決して、少し気が抜けてしまった。何しろやりたいことは山ほどあるので、何かやりだしても、他のことに気が散ってなかなか先に進まない。こういうときは手作業が一番落ち着く。アイテムラボから買った変換基板にMega128の実装を始めた。実は、変換基板をユニバーサル基板につけるピンヘッダーを1000ピン(\1500)も買ってある。

 なぜこんなに買ったかというと、秋葉原などで売っているICピンヘッダーは金メッキなどの高いものしかなく、Mega128の64ピンだけで\300以上かかり変換基板分を入れるとチップの値段に近づいてしまう。

 表面実装はやってみたいが、基板を自作しない限り安定した配線は望めない。それにブレッドボードがとても使い勝手が良いので、このボードを基本にすべての工作を進めて行きたい。で、変換基板なのだが、いくらなんでもチップの値段に近いところまでかけてやるのはいただけない。これだと64ピンでも\100以下ですむ。

 少し飲みに行けば\5000やそこらはあっという間に使ってしまうが、電子工作になると途端にみみっちくなるのは不思議だ。消費感覚と言うのは相対的なものなのだろう。0.8ミリピッチのTQFPの半田付けはこのあいだ大騒ぎして済ませてある(4/29)。ブレッドボードにつけるための小さなCPU基板に64ピン分のソケットをつけ、ここへ変換基板を差し込む。まだ用途の決まっていないときの基板の位置決めは難しい。QFPのピン配置に慣れていなく、しかもMega128は電源ピンが3組もあるので電源とファーム書き込みのISPピンの配線だけでも結構頭を捻る。ついでにパスコンにこのあいだ買ったチップコンデンサーをピンの間に半田付けし悦にいる。

 出来上がってチェックしたら、あろうことかチップコンデンサーをつけたところだけ1ピンずれていた。マーフィーの法則である。2ミリに満たないチップコンデンサーのとりはずしが簡単ではないことをいやというほど知らされる。ウェブでチップパーツの取り扱いに大げさな注意があったのを笑っていたが確かに笑い事ではない。くしゃみをすれば間違いなく部品はあっというまに吹き飛び、見つけることは殆ど不可能だ。

 半田まみれになりながら何とかチップコンデンサーの移動は終わった。テスターで容量が定格にあることを確認し胸をなでおろす。まあ、1ヶ\2なのだけど、部品を動かす前に壊してしまうと言うのは抵抗がある。生きとし生けるものというが、職人の感覚では道具、部品、材料すべてに命が宿っている気がする。無機質な要素を集め、工夫し、汗を流して、何か動く命があるかのようなものにすることが無性に楽しい。

 Mega128が動いた。Gataro研のフラグシップである。今のところSDカードとNICチップをつけてインターネットのマイクロサーバーのCPUになる予定である。A5211285

 手を動かしだすと止まらなくなった。やりかけになっていたボタン電池をつけたRTC基板もついでに完成させてしまう。これでブレッドボードにつける変換基板がらみの小さなユニットは、作り始めた順番に、DCアダプタ基板2ヶ、NIC基板、SDカード基板、RTC基板の5つになった(NIC基板は電源コントローラに実装済み)。これにMega128のCPU基板が間もなく加わる。

| | コメント (0) | トラックバック (0)

MMC(SDカード)をMega168で

Mega168を2つも失う悲劇(5/2/08)
 LANの電源コントローラが正式運用を始めて実験の中心は、SDカードアクセスの方に移った。chaN氏のFATファイルシステムの話は前から読んでやりたいと思って、Mega128を入手していたのだが、まだまだ先のプロジェクトになると思っていた。ところがこのあいだMega168でSDカードのTinyFSを動かしたという記事を読んで急にやる気になった。組み込みウェブサーバや、計画している電力ロガーの記録媒体に早く使いたいという事情もある。

 そんなこともあって、ソフトはスクラッチをあきらめ、chaN氏のソースを参考にMega168の環境に移し始めた。彼のコードはとても洗練されていて参考になる。しかし、これがなかなかコンパイルが通らないのだ。このプロジェクトのきっかけになったMega168を使った 記事は、ソースが公開されているが、肝腎のコードサイズを小さくする方法が全く書かれていない。このソースを使えば良いようなものだが、それでは前と同じで進歩がない。そこで勉強を兼ねてオリジナルをもとに、コードを解読しながら機能を減らしたり、バッファーサイズを縮めて何とか16Kぎりぎりに収めた。

 RTCとのインタフェースのI2Cはオリジナルでは何故か標準のハードを使わず、スタートコンディションから何から全部ソフトで作っている(これがシンプルで素晴らしい)。これを標準I2Cにして、秋月のエプソンのRTC(リアルタイマー)で動かすようにしたら、コードが200バイト近く減った。

 ここまでは順調だったが、悲劇が襲ったのはテストに入ってからである。UARTが動くところまで行ったが、それ以降はなかなか進まない。カードが入っていないという状態で完全な門前払いである。Mega168の記事ではこのあたりは全部省略され電源は常時ONで動かしているようだが、折角コントロールできる機構なのでつけてやりたい。しかし、ここのしかけが良く分からない。電源が入る前にポートでチェックしている。そんなことできるのか。

 何度かファームに書き込んで動かしているうち、書き込みエラーが起きた。ファーム書き込みのSPIとカードアクセスはピンが共通である。慌ててピンをはずして試みるが同じ。そのうちMCUを全く認識しなくなった。このチップは全くの新品でこんなに早く書き込めなくなることは考えられない。ライターの不具合かと他のボードのMCUを試すが問題ない。

 過電圧をかけたこともないし、熱も全く持っていない。Device Not Foundという冷たいメッセージが出るばかりである。チップの予備はもうない。初期故障なのかと諦め、あわててネットを開き以前Tiny861を買ったショップに注文する。次の日、車で入谷まででかけチップを手に入れた。約束の時間より早かったので、秋葉原の秋月に寄って、H8/3069Fというマイコンボードを買ってし
まった。どうも、何かが動かなくなると不安になって衝動買いしてしまうようだ。

 こいつはフラッシュが512Kもあり、NICチップもRTL8019という本格的なコントローラがついている。これが完成品で、たったの\3450である。実は以前買ったLAN電源コントローラの参考書にこれが詳しく出ていて、このあたりになると10年前に熱中したLinuxが動き本格的な組み込みシステムになる。欲しいセットだったのだ。ついでに千石で安いリードタイプのFET(2SJ325 \100)があったので買う。トランジスタでカードの電源を制御しているが、何となく不安だったからである。

 この不安は的中した。新しいチップをブレッドボードに挿し、実験を続けていたら、また同じ現象が起きたのである! 初期故障でもなんでもない。これは何かが起きている。Gataro研究所始まって以来の大事件である。立て続けに2つも心臓部のチップを失ったのだ。

まず、疑うべきは何故、オリジナルの記事の回路で、トランジスタをつかわずFETを使っていたかである。トランジスタはコレクタにカード電源の負荷がかかりベースがMCUのポートにつながっている。トランジスタがOFF状態でもプルアップ抵抗などを通じてカードを通してMCUに何らかの電流は流れる。しかしMCUの入力ポートは高インピーダンスでMCUを破壊することなど有り得ないはずである。

次に考えられる原因は、カードの電源電圧とMCUの電源電圧の違いである。しかし、これも論理判定で混乱する程度で、壊れるところまで行くとは考えられない。ネット上で色々キーワードを換えて調べてみたが、それらしい情報は見つからない。

 しかし、今の状態では、取り替えても3回目の悲劇が起きる可能性が高い。暫く途方に暮れていたが、結局、オリジナルの回路に忠実に戻すことにした。これなら問題ないはずである。幸いFETが手に入ったので、電源コントロールも組み込める。電源電圧も3.3Vに統一する。0.5Aのレギュレータだが何とかなるだろう。

明け方近くまでブレッドボードの配線を全面的に取り替えて次の朝(といっても昼近くだが)、起き掛けに突然ひらめいた。そうだ電源が入る前にカードが入ったか、ライトプロテクトがかかったかがわかるのは、スイッチが入っているからなのだ。chaN氏の回路図には出ていない。慌ててサンハヤトのソケット基板をテスタで調べる。この基板には記事には出ていない何本かの端子が出ており、シールドかなにかと思っていた端子と、カードインサートなどの端子が導通していた。これだ。

 ここを配線して、プロジェクトは少し前進した。SPIのコマンド送出まで動いた。もう10数回書き込みをやっているが、まだチップはこわれていない。オリジナルと全く同じ配線なのだから、これで壊れたら電波か宇宙線ということになる。それにしても、電源電圧の差で本当にチップはこわれるのだろうか。

何とかセクターまで読めた
(5/3/08)
 SDカードアクセスのプロジェクトは、やっとのことでSDカードの読み出しに成功した。動いてから考えてみれば、何でこんな間違いに気がつかなかったのだろうというケアレスミスの連続である。プログラムのデバッグというのはこういうものだ。動作環境が違うのだから、そこだけ目をつけておれば良いのだが、どうしてもロジックに目を奪われてどうでも良いところばかり疑ってみたりする。

 メインの初期化のところのポートの設定は、目を皿のようにチェックするが、カードの電源を入れるところでもう一回ポートの初期化を行っているのを見落とし、カードのチップセレクトのポートが入力になっているのに気がつかなかった。ロジアナでは、ちゃんとチップセレクトのCSがLow(1)になっていないのに気がついていたが、カードの初期化にはCSをHigh(0)にしたまま70クロック動かしてカードを始動させるという記述に惑わされていた。A5101280

 テストを始めて4日目にして、何とかセクタ単位のデータは吐き出してくれるようになった。FATレベルはまだ動かない。フラッシュサイズが一杯なので必要な関数を小出しに入れている。まだ足らないらしくシステムがリセットしてしまう。それとRTCがまだ動かない。まあ、これはテストステートメントを入れていけば何とかなるだろう。

 やれやれ、人のソースを見るのは疲れる。しかし、chaN氏のソースは非常に洗練されていてとても参考になる。「良い仕事してますねえ」と感心する。しかし、コードサイズは絞っても16K近くになる。Mega128クラスでないと、ちょっと他の応用はきついかもしれない。

 Mega168は順調に動いている。これも寝ながら思いついたのだが、Mega168急死の原因は、やはりトランジスタの電源制御の疑いが濃い。NPNのトランジスタ(2SC1213)なので、SDカード周りのグランドがコレクタにつながって浮いた状態がOFFである。これだと、カードの電源は接続されたままのSPIインタフェースを通して全て流れていく。これはまずい。

 以前、LCDのバックライトをトランジスタで切ったとき、切ったほうが動いているときより電流が多く流れる経験をしている。SDカードは数十mA近く流れると言うことだから、これがMega168のSPIピンに流れれば、壊れる可能性がある。

H8に浮気しそう(5/4/08)
 このあいだのAKI-H8/3069Fを動かしてみた。始め間違えて6VのDCアダプタを直結し、もうちょっとでまた悲劇が起きるところだったが、何とかOSをROMに書き込むことに成功した。これは2MのRAMを持っているので相当本格的なことが出来る。

 このRAMにロードするメディアとそれをドライブするROMのOSがあれば、フラッシュ100回までという制限なしに、自由にプログラムの開発が出来る。もちろんWindowsからもロードが出来るが、コンパイルはともかくプログラムの実行の度に、Windowsからロードするのは美しくない。このあたりが、一番やりたいところなので、SDカードのアクセスは是非実現しておきたいところなのだが、こいつが手強い。

 テニスから帰ってまた地下にこもり、開発に専念する。リアルタイマーは単純なミスが見つかり、クロックの移植は成功したのだが、論理的なファイルの状況表示がうまくいかない。システムがリセットされるのはメモリをオーバーランしているからだろう。その場所をみつけるため、LEDやテストステートメントを挿入するが中々特定できない。

 ファイル構造体の定義の中に512バイトという大きな数字を見つけ、これを減らしても状況は変わらない。このあいだのMega168で動かしたと言う記事のコードを見てみると実際のバッファーサイズが80バイトしかない。構造体が512なのにどうしてバッファーはこんなに小さいのか。ロジックが読みきれていないので試行錯誤でやるしかない。

 現在のこちらのバッファーサイズは256バイト。バッファーは大きければ大きいほど良いはずなのだが、試しに半分の128に減らしてみた。 これが何と、動いたのである。理由はわからない。ちゃんとディレクトリの位置、FATテーブルのセクタ、ファイルの数などが表示された。やれやれお疲れさんでした。 16MのSDカードがうまく出たので、128Mの方を試してみる。セクタ単位は問題ないが、論理ファイルの表示は途中でリセットがかかった。

 まだ完全ではないが、SDカードのプロジェクトもほぼゴールに近づいたようである。あとは、この応用だが、フラッシュ16KのMega168ではテストに精一杯でSDカードを使いこなすのは、やっぱりMega64クラスにならないと難しそうだ。H8なら全く問題がないが。

ほぼ完全にSDカード読み書き成功(5/10/08)
 CPUチップを2つ犠牲にしたが、SDカードアクセスは試作ボードで、想定の機能をほぼ満足し、実用に近づいた。128MのSDカードは最初読めなかったが、いくつかの関数を使わないようにしたら正常に読めるようになった。どうもメモリ管理を自分でやらないとリセットしたりハングするようだ。まだソースが読みきれていないのでこれは後の課題とする。

 ロガーなどの実装のときのためFETを使った電源制御とプルアップ抵抗などSDカードの回路をサンハヤトの変換基板に組み込みブレッドボード上を整理する。昨夜、酔っ払ってピンをひとつ間違えて差込んでVccをショートさせ、あやうくレギュレータを昇天させるところだったが、時間が短かったので何とか助かった。動かないので念のため部品を触っていて、レギュレータがやけどしそうになるほど熱いのを見つけ、あわてて止めた。このあと動かしたが、特に問題はなかった。いや結構丈夫なものだ。A5101274

 余裕が出来たので、ベンチマークをとってみた。8MのCPUクロックで128MのSDカードは、Readでは200KB/秒、Writeでは20KB/秒と、chaN氏のレポートの半分くらいの速さだが、フラッシュ16K、SRAM 1KのMega168でこの数字は立派なものだ。これでAVRマイコンの世界では破格の大容量記録装置を手に入れたことになる。

 ソースはオリジナルは消さずにすべてコメントアウトし、これからMega168クラスでFATシステムを動かす人のための参考になるようにしたが、オリジナルをコメントアウトしたソースを公開するのも気が引けるので、変更点をまとめておく。

  • 元のメインプログラムはすべての機能を試せるようにかなり大きいので、コマンドを半分以下に減らす(main.c)
  • バッファサイズを縮小  ファイルバッファは2048を128 UARTは120から40 (main.c)
  • 電源制御、チップセレクトなどのポートを変更。(mmc.c)
  • 10msのインタバルタイマーのタイマーレジスタ変更。(main.c)
  • RTCを秋月のRTCモジュール(エプソンRTC8564)で動くように変更。ついでにオリジナルのソフトIICをMega標準のIIC機能を利用。

 以上で、TinyFATFsを使いフラッシュサイズ16K以内(fw,frなどの性能テストコマンドを含む)の16,078バイト、SRAMが798バイトに収まっている。コードの内訳は、ttf.cが7キロ、SDカードをアクセスする下位ルーチンmmc.cが2キロ、リアルタイムクロックが1 キロ、その他UARTやXitoaなどの周辺ルーチンが1キロ程度で、残り5キロはメインのコードとコンスタントである。

 従って、電力ロガーなどのアプリは5キロ以内に収めれば、何とかMega168でSDカードに記録するロガーが出来そうである。

| | コメント (0) | トラックバック (0)

« 2008年8月24日 - 2008年8月30日 | トップページ | 2008年9月7日 - 2008年9月13日 »