カテゴリー「STM8S」の8件の記事

2013年4月26日 (金)

STM8Sでグラフィック液晶に漢字をスクロール表示する

ハングアップするSTM32F107の気圧計を修理する(4/13/2013)
 STM8Sでグラフィック液晶に日本語フォントを表示するプロジェクトは一段落したが、実は前から気になっていることがある。一年ほど前、O-Familyさんの掲示板で知ったのがきっかけで作ったグラフィック気圧計がまともに動かなくなってしまった。

 この気圧計のMPUはSTM32F107で気圧センサーは秋月のMPL115A2、Aitendoの2.4インチのカラーTFT液晶(YHY024006A)に2日間の気圧の変化をグラフィックに表示する。気圧データは、毎秒測定した気圧を1分ごとに平均化し、10分に一回、I2CのEEPROMに蓄積する。

 RTC(リアルタイマークロック)を内蔵しているので、実際の年月日を表示したグラフ枠に直近の2日間の気圧遷移が折れ線グラフで表示される。予報ロジックの組み込みや、ケースに実装する工程が残っているが、とりあえずここ数日の気圧の変化が一目で確認できるので、このままで結構重宝していた。

 当初この基板にはソケットの接触不良があって、長時間稼動させると(2~3日以上)、止まってしまう持病があったのだが、直接ピンとピンの間を別配線してしまうことなどで、トラブルは解消していた。ところが、最近になってまた止まるようになった。しかも動いている期間がどんどん短くなり、このところは数時間が限度である。これでは実用にならない。

 止まる要因で疑われるのは、TFT液晶の描画と、気圧センサーMPL115とフラッシュROMの読み書きに使っているI2Cインターフェースである。最初、液晶の描画ルーチンを疑っていたが、詳細にコードを調べて、このプロセスでは、少なくともMPU側にはループする要素が見当たらないことがわかった。

S_p4255844  とすると、残るはI2Cである。このI2Cのドライバーは、例の弁護士さんの書いた「STM32マイコン徹底入門」でも紹介されたSTマイクロの標準I2Cライブラリーを殆どそのまま使っている。久しぶりにEclipseを立ち上げて、ソースを見る。

 他のウェブや、この本にも書かれているとおり、このライブラリの信頼性は余り高くない。しかし、これに換わる適当なコードはないので、とりあえず仔細にソースコードをチェックする。何だ、何だ、ソースコードには、たくさんwhileでイベントが終わるのを待っているところがある。4箇所もある。しかも無限ループだ。これでは沢山のところでハングアップする可能性がある。

無限ループをやめて、エラーexitをつけたのに止まらなくなった(4/14/2013)
 回数を数えて、一定の回数以降はそのループを抜けるようにソースを書き換えた。ところが、MPL115が正しい値を返さないようになって測定値が乱れる。うーむ、1000回程度ではだめなのか。
クロックを計算してみたら数十μsだ。こりゃいかん。MPL115はまだ測定を終えていない。

 60000回以上(1ms近辺)でループを抜けるようにして、様子を見る。これが不思議なことに、何時間経っても、エラーexitもせず、しかも全く止まらなくなってしまった。2日間でも止まらない。???である。

 要するに少しソースに手を入れただけでタイムアウトもせず(エラーメッセージも出ず)、無限ループにも入らず直ってしまったのである。逆に、UARTの切断/接続でハングする。えー、UARTルーチンにイベントを待つプロセスなどはないぞ。これも謎である。暫く様子を見ることにする。

 それにしても最近の物忘れの程度は度を越えていて、自分でも笑ってしまうほどだ。STM32の開発手順を見事に忘れている。この気圧計の開発を盛んにやっていたのは、わずか1年前である。それが統合環境のEclipseでのソースのコンパイルはともかく、ファーム書き込みの具体的な手順が思い出せない。

 さすがに、どういうツールを使うか(中華製のシリアルローダーMCUISPを愛用している。他のプログラマーの出番なし)くらいは覚えているが、どういう手順でプログラムをロードするのかブートモードが0だったか1だったかも忘れている。見事なものだ。

 エラーが起きないので、これ以上のデバッグは出来ない。デバッグというより、I2Cがエラーで帰ってきたときにどうするかを考えておく方が合理的かもしれない。測定は毎秒やっているのでひとつくらい読めなくても大きな差は出ない。EEPROMの書き込みでも2日間のグラフなので、1回や2回データが欠けても大勢には影響がない。

ハードウェアのスクロールは難しい(4/15/2013)
  気圧計のエラー発生待ちで手が空いたので、いよいよSTM8Sの最後の課題、ハードのDisplay Startコマンドを使った漢字のスムーズスクロールを実装する作業に入った。

 問題は、縦64ラインある画面に12X12ドットの漢字を表示し、これをなるべく乱れなくスクロールしていくことである。これまでの検討では漢字フォントを分割して(画面の最下部と最上部に分けて)描画できればスムーズスクロールが出来るはずである。

S_p3285780  つまり、縦(Y軸)0ラインから、12ドットの漢字を5行表示し、余白になっている画面の60ラインから一字の4 ドット分描画し、画面の0ラインに戻って残りの8ドット分を描画する。さらに4ラインの空白を表示し、ここにハードウエアの描画開始アドレスを移動すれば、全体の漢字の位置は全くずれずに、1行分スクロールされることになる。

 このやりかたは、漢字描画の縦の物理スタートポイントが、決まった位置になく少しづつずれて行き(次の行の開始アドレスは12ではなく8。16回廻って一周)、スクロールのスタートアドレスも、それに合わせてずれるので、コーディングには細心の注意が必要だが、今のところ、この方法以上のやり方は見当たらない。複雑だがこれを実装することにする。

 まず、必要なのはフォントの分割表示のための、グラフィックライブラリの中の日本語フォント関数LcdChr_Kanji())への機能追加だ。これまでは画面の最下部にかかる文字の描画は、エラーリターンしていたのを、折り返して最上部に残りのフォントを描画するようにロジックを追加する。

 この改良は、相当厄介だろうと覚悟していたのだが、思いのほか追加するステップが少なく、簡単に完成した。Y方向(縦)のドットのアドレスを画面の最大幅になったときに0に戻すだけである。こんなにうまくいったのは、最初のプログラムの構造が良かったからだと自画自賛する(動いてから自慢するべきだろう)。

 実際にスクロールを制御するところは、ライブラリではなくmain.cの中である。SRAMが残り少なくなっているので、変数を増やすのは気を遣う。手持ちの変数を使いまわして、描画のスタートポイント、スクロール開始位置のシフトを考える。

 やっぱり一筋縄では動かない。擬似コードを何度もやりなおす。なんとかコーディングを終了した。いよいよテストである。苦労が多いほどこの瞬間はわくわくする。最初は連続ではなく、スペースバーを押すたびに、一字づつ表示するようにする。

 順調に画面の最上部から、漢字が出てくる。スクロールしないときの表示は順調だ。まあ、ここは前と変わっていないので表示されて当たり前なのだが、ついに画面の最後まできて、スクロールするところに来た。

 思い切って先へ進む。おお、画面全体が上に上がった。しかし文字は、表示されない。消し残しのようなラインが出るだけである。さらにキーを押して次の文字を出す。おっ、今度は文字が出た。コードを確かめる。出るべき正しい文字だ。スクロールした最初の文字だけが出ないが、分割したフォントは正しく文字になっている。良かった、この部分はうまく行っているようだ。

 さらに文字を出していく。何とかスクロールが動いているようだが、周辺にはゴミが出るし、行換えした直後の文字が出てこない。一字づつを止めて連続表示をしてみると、文字が乱れたりループしたりして不安定だ。しかし、とりあえずスクロールはしている。とはいえ完成にはまだ程遠い。

すこしづつスクロールが出来てくるが連続はまだ無理(4/16/2013)
 最初の文字が出ないのは、画面の更新をするときの領域の設定ミスとわかった。描画領域の定義は、仮想の描画スタートアドレスではなく、物理的なVRAMの範囲なので、分割して表示する時は結局、全部を描画領域にするしかない。

 これを直して、スクロール直後の文字もめでたく画面に表示された。しかし、スクロールの幅がおかしい。思ったように下の余白が止まっていない。表示が4ドット分上がったり下がったりするので、連続して表示するととてもスムーズなスクロールにはならない。それに画面にゴミが残って、それがスクロールに合わせて動く。

メモに図を描いては、画面の動きを確かめ、UARTにドットアドレスを表示したり、デバッグを進める。スクロールの幅は常に12ドット(文字フォントの幅)で良いはずだ。それなのに何故、4ドットの余白が移動するのだ。そのうち思い違いをしているのを発見した。

 ハードスクロールのスタートアドレスを新しく表示する文字のスタートアドレスに合わせている。ああ、これでは駄目だ。スクロールの開始アドレスは、0ラインから12ラインづつ動かしていけば良いのだ。このままでは空白は最上部に行ってしまう。まさしくプログラムは書いたようにしか動かない。

  面のゴミは原因不明だ。スクロールのあと、表示するまえに1行分全体を消去しているのだが、このあたりは並木算の世界である。0オリジンか1オリジンか、最後の部分は含むのか、含まないのか。画面の途中ならそう難しくはないが、折り返すところがどうしても計算が合わない。

ライン0を表示しないのは元の関数の仕様だった(4/17/2013)
 ゴミが出るのは、折り返しのところだけなのは間違いない。しかし、消去する幅や、起点を調整しても、ゴミがとれない。どうも今開発しているプログラムに誤りはなさそうだ。となると下部関数に何か不具合があるのではないかという疑いが出てきた。

 そら。さんから頂いたこのグラフィック液晶(GLCD)ライブラリのオリジナルは、外国でNOKIAの液晶用に開発されたようだ。グラフィックの部分は、このGLCDではコメントアウトされて使われていなかった。こちらが勝手にコメントをはずして動かしているので、このGLCDで動く保証はない。

 グラフィック関数は階層構造になっていて、新規に開発した特定の行を消去する関数、LcdFill()は、LcdLine()で直線を引き、LcdLine()はLcdPixel()という1ドットを描画する関数を使っている。

 LcdLine()から見ていく。特におかしいところはない。次は、LcdPixel()を調べる。あ、あ、あ、画面の0アドレス(Y軸)は何も処理せず帰っている。何だ、何だ。0ラインにはドットが描けないのか。スクロールは0ラインにもドットが描けなければ正しい字にならないのに。

 不具合でも何でもない。元からこういう仕様だったのだ。やれやれ大山鳴動鼠一匹である。もっと早くここを確認すべきだったのだ。0ラインも描画するようにして今まで汚かった画面は一掃された。漢字フォントだけが綺麗に表示される。一字づつ表示していくだけでは問題なく漢字が表示されて行く。よーし、大分進んだ。

 しかし、連続するとまだ途中でループしたり、画面の位置が変わったりする。まだ何かがおかしい。トラブルシューティングは終わらない。

連続してスクロールが出来ないのも大きな勘違いだった(4/19/2013)
  連続スクロールは、入力されたシフトJISの漢字コードに1バイトづつ足し上げ、漢字コードのときのみ(LcdChr_Kanji()は有効な漢字コードでないときはエラーで帰る)画面上に漢字を出すようになっている。

 待ち時間を入れないで連続表示させると、表示が速すぎて、画面全体が白くなり、字そのものが殆ど読めなくなってスクロールの意味がなくなるので、一字あたりに30ms程度の待ちを入れて表示する。

 ところが、連続しているうちにスクロールの位置が変わったり、ある時点でループに入ってしまう。 一字づつでは問題なく、連続してエラーが出るのは、ハードが疑われる。表示位置を変更するコマンドの前後に待ち時間を入れたり、表示そのものの関数にも待ちを入れたり、時間調整してみるが全く改善されない。

 GLCDのSPIインターフェースが早すぎてデータをとりこぼしているのかもしれない。現在のSPIクロックは、2MHzである。データシートを確かめてみる。何とこのGLCDは20MHzくらいまでサポートしており全く問題ない。

 そのうち一字づつ表示を続けているうち、全く同じところで表示が乱れることがわかった。うはあ、これはハードではない。ソフトだ。非漢字領域をスキップしているところで、どうもエラーが起きているようだ。

 漢字コードでないときのエラー処理がおかしい。念入りに調べる。あっあっあー、わかった。非漢字コードのときは、文字をずらすところをスキップしているのだが、肝腎のスクロール処理がこのループからはずれているではないか。これではたまたま表示が左端で非漢字コードが来た時、無意味なスクロールをしてしまう。

 何というお馬鹿なコードだ。非漢字領域のコードの描画が画面左端から始まるときのみ、おかしくなるので発生がランダムに見え、ハードを疑っていたが、何のことはない、単純なソフトのバグだった。今まで疑っていたGLCDさん大変失礼いたしました。悪いのは全部私です。

この解決で、グラフィック画面は、延々と漢字を表示し続ける。いやあ、良かった。良かった。これで動画が公開できる。この画面では、漢字一字に30msの待ちを入れて表示している(スクロールは待ちなし)。これより少ないと、表示が速すぎて液晶の残像で満足に字が見えなくなる。

これでSTM8SとGLCDの当面のテーマはすべて完了した。この日本語表示を何に使うかが今後の課題である。音声合成チップとあわせてネットワークを経由したメッセージボードのようなことが出来ると面白いかもしれない。

ここに例によって上記のソース一式をSTVDのプロジェクトごとzipファイルにしたものを置きます。STM8のライブラリはこれまでどおり同梱されていません。以前の記事を参考に所定のディレクトリに設定してビルドしてください。容量の関係でフルビルドが必要です。

「JCG12864_426.zip」をダウンロード

本格的なFETスイッチの実験(4/22/2013)
 このあいだ秋月から買ってきたMOSFET(FKV575)のスイッチの実験の続きである。ブレッドボードにCRとトランジスターの遅延回路を組み込んで、FETでLEDを1秒ほど遅らせて点灯する実験は成功した。しかし実際のスピーカー切り替え用の2つのFETを組み合わせた本格的なスイッチはまだ組んでいない。

S_p4235837  前回にも書いたように、2つのFETで構成されたスイッチの導通抵抗がどうも寄生ダイオードによってミリΩ台になっていないような気がする。ウェブを見ているとACのスイッチには、何と4つのFETでスイッチを構成しているものもあり、その回路図を探していたが見つからなかった。

 迷っていても仕方がない。現物があるのだから実際に試してみるのが手っ取り早いのではないか。まずは最初組んだFETひとつの回路に、オシロと秋月のファンクションジェネレーター(FG)で導通を調べてみることにした。

 FGの出力は、AC(±1V)なので、FETひとつなら、片側が半波整流のような波形になるはずである。ところが、これがおかしなことに、ACが完全に通るのである。所長のFETの知識は、トランジスターのアナロジーで、ドレイン(コレクタ)からソース(エミッタ)に流れる(N型のとき)電流をゲートが制御し、ソースからドレインには電流がそもそも流れないというものである。

 寄生ダイオードは、この逆電位のときに流れるもので(これはトランジスターにはない)、スイッチに使うときは、これが効かないよう、FETを背中合わせにするのだと思っていた。

 ところが、前回の記事に、久しぶりにkugaさんからコメントがあり、自分が勘違いしていることがわかった。FETはゲート電位が上がって導通状態になれば、たとえドレインがソースより電位が低くなっても(NMOSのとき)、寄生ダイオード以外のところでも電流が流れると言うのだ。

S_p4235830  どうも勘違いをしていたらしい。それなら本番用を実験してみよう。ブレッドボード上に背中合わせにFETをつけた回路を組む。たいした手間ではない。FGの出力を、このスイッチを通してオシロにつなぐ。導通は?うむ、全く問題ない。では、ゲートの電圧を0にする。ありゃあ、切れてないぞ。矩形波はサグの出る波形に、正弦波は殆ど減衰せずにそのまま出ている。

負荷抵抗を入れると切れた。うーむアナログは難しい(4/23/2013)

Fet  えー、どうして切れないのだ。良くわからない。ウェブで同じような実験をされているページの回路図を確認した。あ、そうか。負荷抵抗がいるのだ。微小電流ではFETは遮断できないらしい。

今ひとつ理屈はわからないが、本来はスピーカーという数Ωの負荷を切るスイッチである。この状態で調べるべきだろう。しかし、現在のFGは、内部抵抗が高く、とても数Ωの負荷抵抗をドライブすることは出来ない(出力は0になってしまう)。

S_p4235838  とりあえずFGが何とか出力を出す(0.5V)くらいの負荷抵抗、300Ωを入れてスイッチを調べてみた。よし、わずか脈流は残るが、出力は殆ど0になった。スイッチは機能したようだ。しかし、正弦波は切れたが、矩形波は立ち上がり(下がり)に鋭いパルスが残る。

 これは結局、実際の音で確かめるしかないか。使用を予定しているメインアンプの切り替えは少しおおごとなので、手元にあるカマデンデジタルアンプで試してみることにした。スピーカー端子は幸いこのあいだワンタッチの端子板に換えてあるので接続は簡単だ。

S_p4235826  これはFETが持つ内部寄生容量で一瞬導通するからではないかと思うが、これを解説しているところは見つけられない。この症状は0.01μFくらいのコンデンサーを負荷に並列に入れるとパルスはおさまり、何とかスイッチの役目を果したようだ。

 ブレッドボードからジャンパーを出し、念のためオシロもつないで片チャンネルだけスイッチをつける。問題なく入り切りができた。全くの無音になる。音は変化したか。この程度のスピーカーやアンプで、これを判別するのは無理と言うものだろう。

S_p4235824

 ウエブでも、機械リレー方式との音の違いを追及している人がいるが、まあスペックを信用するしかない。矩形波の残留パルスはMhzの世界で、少なくとも可聴周波数域での違いは全くないと言ってよいのではないか。

 ウェブをさまよった挙句、4つのFETを使ってスイッチする理由がわかったような気がする。FETのオン抵抗(Rds)が入力電圧(ゲートソース電圧)によって大きく違うので、レールツーレールにするため、P型とN型を並列にして特性を相殺しているためではないかと思われる。   http://www.analog.com/jp/content/cu_ad4505jp/fca.html
まあ、ここまで心配ならリレーを使えば良いと思うけれど。

 実験はそろそろ良いだろう。これを実装する工程が待っている。いずれにしても、スピーカーのミュートスイッチは、一般のFETのスイッチング特性とは全く別の世界(スイッチング周波数は全く無関係)なので参考になるウェブサイトは意外に少ない。以下は、スピーカーのFETスイッチに関して参考になったサイトのURLである。ご参考まで(勝手リンクご容赦)。

そもそもフォトボル型カプラーを知ってFETスイッチを作ろうとしたきっかけのサイト。
http://easyaudiokit.hobby-web.net/bekkan/MOSFETrelay/MOSFETRELAY.html

スピーカーのミュートをリレーからFETにしたときの考察。切れていたら()内のホームから。
http://members2.jcom.home.ne.jp/2060bl/21review/18ftrly/01vrfctn/vrfctn1.html
http://members.jcom.home.ne.jp/4120blaudio/index.html

マルツのFETスイッチの基礎的な解説。FETの一覧表もある。わかりやすい。
http://www.marutsu.co.jp/user/fet_3.php#mos-fet3

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

2013年4月14日 (日)

STM8Sとモノクログラフィック液晶を基板に実装する

 今年の正月以来取り組んできたSTM8Sでの日本語フォント表示に、やっとのことで成功し、重い荷を肩から下ろしたときのように、暫く力が抜けて前へ進む気力を失った。記念すべきブログ200本めの記事なのだが、焦点が定まらない。

 当初、このSTM8Sとモノクログラフィック液晶(GLCD)の組み合わせは、電波時計のプラットホームにするつもりだった。しかし、これだけ日本語フォントの表示に苦労したのに、時計は日本語テキストを殆ど使わないというのは、いかにも勿体ない気がする。

 ハードウエアも、まだバラックである。GLCD(JCG12864A37)のインタフェースはブレッドボードで動くように自作のピンソケットをつけたものの、STM8S-Discoveryとの接続は基板のソケットからのジャンパーコードを差しただけで移動することもままならない。

S_p3265778_200top バラックで実験していたのは、電波時計でない他の適当なアプリケーションが見つからなかったためである。しかし、だからといって簡単にばらしてしまうのは、これだけ長い間付き合ったセットに何か薄情のような気もする。使うあてがないにしても、少しはまともな形でSTM8SとGLCDを動く形に残しておくことにした。

秋月の新商品パワーFET(FKV757)を買ってきた(4/1/2013)
 実装するとは決めたが急に方針が決まるわけでもない。手を動かしていないと落ち着かない性分になっている。手は勝手に、このあいだのMOS-FETスイッチ制作の続きに移った。

 念願のサトー電気からフォトボル型カプラー(TLP590B)は手に入れたが、スイッチに使えるようなパワーFETの手持ちがない。部品箱を漁っていたら、2年前のガイガーカウンターづくりのときに秋月で買った高圧用のFET、FQPF3N90(900V 2A)が出てきた。S_p4135804 GM管(SBM-20)やパルストランスなど自作のための高圧パーツはあのとき全部揃えたのだが、あれからガイガーカウンター制作熱はすっかり下がったままである。

 このFETはデータシートを見るとオン抵抗は数オーム近くありスイッチ用には適さない。それでもフォトカプラーを試したくて、ブレッドボードに組んでみた。導通テストは普通のマルチテスターの導通モードで確かめる。ブレッドボードなので組むのに10分もかからない。

 単三を3つ並べた4.5Vを入力側に入れてテストする。おお、無限大を差していた抵抗値が、一気に0Ω近くに下がる。LEDのON/OFFも問題ない。調子に乗って、1.5Vのモーターの入り切りをやってみる。これはさすがに動かなかった。

 やはりオン抵抗の低いFETが欲しい。ウェブ上で色々物色していたら、おあつらえのように秋月電子からサンケン電気のMOS-FET、FKV575が新商品として売り出された。DS間の最大電圧と電流が60V 75Aで導通時のDS間の抵抗が何と8mオーム、しかも値段が¥120と安い。久しぶりに仕事の帰り、秋月に寄った。

 新商品なので、陳列棚には出ていなかった。今日は月曜日。秋月は、月、木はバーコードのついた商品しか売らないということでカウンターのウインドウケースには白いシーツがかかっている。でも、店員に商品名を言えば出してくれることがある。まあ、急ぐものではないが折角ここまで来たのだがらと、だめもとで店員に聞いてみた。

 最初、ないようなことを言っていたが、事情通の別の店員が、奥からリールに入った現物を出してくれ無事手に入れることが出来た。とりあえず4つ買う。帰って夕食もそこそこにわくわくしながらテストに入る。実に安上がりな娯楽だ。

S_p4135810 例のフォトボル型カプラー(TLP590B)をゲートにつないでまずテスターで導通テスト。おお、このあいだのFETは数オームだったが、今度は測定限度の0オーム。1.5ボルトのモーターは快調に廻る。

MOSFETのスイッチ回路と遅延回路(4/5/2013)
 MOSFETスイッチの目的は、オーディオアンプとスピーカーの間に入れて電源投入時のポップノイズを避ける遅延スイッチである。フォトカプラーやFETの部品は揃ったが、回路をどうするかが悩ましい。スピーカーに流れる電流は交流なので、単純なスイッチでは動かない。

 ウェブなどを見ていると、オーディオ製品のこうしたソフトスイッチは、結構おおがかりで、回路がどうなっているかわからないがFETを4つも使って一回路を切ったりしている製品もある。

 こちらは、そんな大げさにするつもりはない。フォトボル型カプラーのおかげでFETをドライブする部分は非常に簡単になったのだが、スピーカーの接続を遅らせる遅延回路と、実際のスピーカー回路に入れるFETの組み合わせになかなか良い回路例が見当たらない。

 FETを対称に並べるスイッチは、片側のFETは寄生ダイオードを利用して導通している。寄生ダイオード(ボディダイオード)の順電圧降下はデータシートによれば、1V以上で、折角、片側がミリオーム台でも、トータルとしては結構な損失になる。

 仮に100Wの最大電力がスピーカー負荷(8Ω)にかかったときの電流は、3.5Aで、このときの損失は順電圧降下が1Vとすると3.5W、ヒートシンクが必要になるレベルになってしまう。

 片側をボディダイオードで導通させない回路を探しているが見つからない。FETを4つ使ったスイッチは恐らく、ボディダイオードを使わない方式だとは思うけれど、どうして実現するのかあれこれメモに書いては見るがうまくいかない。ここも奥が深い。S_p4135805

 遅延回路の方は、最初からCR時定数で組むつもりをしていたが、フォトカプラーの入力電流をCRで遅延させるのは、大容量のコンデンサーが必要で何か資源の無駄のような気がする。トランジスタをかませばもっと簡単になることに気が付いた。電流の少ないベース側にCRを入れコレクター負荷でフォトカプラーをドライブする。

 早速、ブレッドボードに組み込む。定番の2SC1815でベースに4KΩ、220μFの遅延回路を入れて0.8秒程度の遅延時間が得られた。こういう、ちまちました実験も楽しい。

STM8Sとモノクログラフィック液晶を実装する(4/7/2013)
 FETスイッチはさておき、そろそろ本来のプロジェクトに戻ろう。これまでブレッドボードにジャンパーでつながれていたSTM8S-Discovery基板とAitendoのGLCD(JCG12864A37)を基板に固定する工作を始めた。

 まだ何に使うか決まっていない。とりあえずは、STM8S-DiscoveryのST-LINKの部分も切り取らず、秋月の両面C基板の上下に液晶とCPU基板をソケットでつけることにする。STM8S-DiscoveryのCPU周りには、2X6のピンヘッダーが4つ出ており、C基板には、それぞれそれに見合うソケットをつけて固定する。

S_p4135822 GLCDは四隅のビス穴とスペーサーで固定する。インターフェースケーブルにはブレッドボード用のmilピッチのピンをつけてあるので、これを基板にハンダ付けしてしまう。抜き差しは、前々回に紹介したリード線のソケットで出来る(あまりやりたくないが)。忘れずにSPIの逆流防止のSBD(ショットキーダイオード)の1S4もつける。

 UARTは例によって、3ピンソケットでUART線をUSBアダプターにつなぎ、アダプターは共用する。久しぶりのハンダ付けが楽しい。目的がはっきりしているときの作業は捗る。テニスから帰って風呂に入ったあと、少し根を詰めて作業に熱中し、終わった時はさすがに腰が痛くなっていた。

 チェックもそこそこに通電した。よっしゃー、全く誤配線なしでWelcome画面が出た。苦労したあとの成功も嬉しいが、こういう一発で動くというのも爽快なものだ。ただ、これを何に使うかということが決まっていないと言うのがつらいところである。S_p4135820

SPIの不具合再発とその解決(4/9/2013)
  ところが一発で動いた後、思わぬトラブルに巻き込まれた。このあいだのフラッシュメモリの読み出しエラーが再発したのである。ブレッドボードではSBDをGLCDとフラッシュメモリの間にはさんで直ったのだが、今度はSBDが入っていても直結のときと同じようなエラーがでる。

 エラーの状況は、どこかで、SPIのクロックの1ビット程度が抜け(または余分に入る)、それ以降がすべて狂う。フォントデータだと少しずれるだけで済むが、漢字だとフォントデータに辿りつくデータブロックアドレスが目茶目茶になるので全く字にならないゴミが表示される。これでは使い物にならない。

 配線が長くなったからなのだろうか。どこかと干渉しているのだろうか。UEW線で結線した配線の長さが特に大きくなったわけでもない。ブレッドボードよりハンダ付けなので明らかに抵抗値は下がっているはずだ。

 ダイオードをとりかえてみても駄目。配線の位置を変えても駄目。オシロで波形を見る。確かに、GLCDのSPIのクロック線は、フラッシュを読みに行く時にわずかな波形が出ている。このSPIのクロックは、CPUクロックの1/2の8Mhzである。トランジスターや、普通のフォトカプラーでは高速すぎて分離できない。

 ここで、サトー電気で高速フォトカプラーTLP552を買ってあったのを思い出した。おお、先見の明があった。買ってきたのが無駄にならなかったぞ。早速使ってみた。しかし、こいつは10mA以上を入力側に流す必要があり、つないだだけでSPIそのものが動かなくなった。まあ、考えてみたらこんなことに¥200以上する高速フォトカプラーを使うのは明らかに資源の無駄遣いだ。

S_p4105801 それにしても、何故ブレッドボードで動いて、実装するとおかしくなるのだろう。何が悪さをしているのかわからない。こんな些細なことでも上手く行かないと言うのは、不愉快なものである。SPIを複数ディバイスで共用するときのノウハウをウェブで探すが、そういう話はどこにもない。

 そのうち、Vccの違いを吸収するレベルシフターICを使えば、ハード的な干渉を避けられるような気がしてきた。いわゆるバスバッファーICというやつである。こういうICは出力側をHiZ(ハイインピーダンス)にして完全に接続を切ることもできる。

 バスバッファーのICならFPGAのドングルを作ったときの予備のTC74VHC244がピッチ変換基板に取り付けたまま残っている。ブレッドボードにつけて、ジャンパーピンを実装面に無理やりハンダ付けし、空中配線でテストしてみた。

ビンゴ!であった。フラッシュメモリは全くエラーなく読み出せるようになった。今のプログラムのUARTはテスト用に、日本語フォントのフォントブロックテーブルをコンソールに表示するコマンドがあるのだが('q')、これがいくら繰り返しても、全く同じデータを表示する。

Kanjicodeblock ANK文字表示('d')も、今までは、どこかしら字が欠けていたのだが、全く変わらない。いやいや嬉しい。今までの鬱陶しい気分がすかっと抜けて気分は日本晴れだ。達成感で体が軽い。はい、完全に中毒にかかっていますな。

 バスバッファーで問題は解決した。しかし、8チャンネルもある3ステートバスバッファーを使うまでもない話だ。世の中には、1チャンネルだけのバスバッファー(74LVC1G125GW)もあるようだが(Digiで¥15)、これだけ買うわけにもいかない(共立電子の通販でも発見。2ヶ¥60)。

 実際の実装には、昔々、電子工作を始めて最初にChaNさんのシリアルプログラマーを作ったときの予備、74HC126を使うことにする。この石は4回路をチャンネルごとにHiZ(ハイインピーダンス)に出来る。特にHiZにする必要はなさそうだ。enableのままで問題なく動いた。

 1回路しか使っていないけれど、16ピンDIPくらいならあっても邪魔にならない。基板にハンダ付けする。これでやっと実装版が完動した。

ZAZ(ザーズ)にはまる(4/10/2013)
 全く電子工作とは違う話題でちょっと失礼。珍しく感動したことがあって記録を残しておくことにする。この世界に詳しい人には旧聞に属すると思うが、NHK-BSの番組(再放送らしい)でパリのストリートミュージシャンから一気にフランスで大評判の歌手になったZAZという女性歌手(正式名 イザベル・ジュフロワ)を知った。

 所長は音楽と言えばクラシックしか聴かないのだが、これが、このあいだのポルトガルのファドと同じように、何故か心を引き込まれてしまったのである。ジャンルは、シャンソン、ジャズの範囲に入るのだろうか。

 声は美声ではない。むしろハスキーで、メジャーになって本式の伴奏がついたものより、ギターとベースだけのストリート時代の録音の方が訴える力が強い。伝説的なシャンソン歌手、エディットピアフの再来と言われている。日本にも1回来たようだ。

 歌詞(彼女は作詞作曲もする)は、放送の時は字幕がついていて、結構、歌詞でも引き込まれるのだが、不思議なことに全く理解できないフランス語だけのときでも気持ちが伝わってくる。ファドの時と同じだ。PCの前で例の雑誌付録のUSB-AUDIOからYouTubeの音をカマデンのデジタルアンプで再生する。

Zaz  良い時代になったものだ。CDを買ってこなくてもとりあえず自由に音楽が聴ける。ファドと違って気分が落ち込まないのが良い。音楽を聴きながら、このブログの原稿を書いたり、電子工作の資料を検索したりする。至福の時間である。

ハードウエアのスクロールを研究する(4/12/2013)
 大分前に、この液晶のコントローラーST7565のデータシートに画面をハード的にスクロールできるDisplay Start Command(0x40でlowerアドレスが位置アドレス)という命令があることを知り(データシートP26とP42)、いつかそのテストをしたいものだとブログに書いた。

 実は、前回発表したソースコードには既にこのコマンドを動かす機能が入っている。UARTモニターの「s」というコマンドがそれで、sn(nは1桁の数字)とやると、nドット分ずれて画面が表示されるようになっている。

 実装はコントローラーのコマンドたったのひとつで、VRAMのY軸(縦)1ドット単位に任意の場所を画面の最初に持って行くことが出来る。残りの画は巻絵のように上に折り返して表示される。ハードなので表示の切り替えは一瞬である。

 ただ、これを使って、12ドットの漢字をスクロールさせようとコードを入れてみたが、全くうまくいかなかった。液晶がFSTNで残像が大きく、100ms以上の待ちを入れないとちゃんと絵がでないということもあるが、うまくいかなかった理由はそれだけではない。

 このGLCDの縦のサイズは64ドットで、12ドットの漢字を5行表示すると、下に4ドットの余りが出来る。これを単純に12ドット単位にスクロールさせると、この4ドットの余白がずれて動くので、文字が無駄に動いてスクロールしたように見えなくなるのだ。

 理屈はわかったが、これをどうやって解消してスムーズなスクロールに出来るかうまい方法が見つからない。画面下の4ドットの余白を残しながら、画面60ドット分だけをスクロールさせるのは、簡単なロジックでは実現できない。

 ということで、スクロール機能は放ってあったが、実装が一段落したので、これも何とか実現させてみようと取り組んでみた。少し考えれば出来るだろうと思っていたのだが、これが思いのほか手強い。

S_p4135823 どうも、フォントを画面の下段から上段にかけて分離して描画しないと、余白をなくすことは出来なさそうだ。そうなると相当基本的な部分まで手を入れないとスムーズなスクロールは出来ない。しかし、問題が難しいとわかると、余計燃え上がるのが性分である。

 ブログの原稿を書きながら、ロジックに頭をひねる。擬似コーディング以前に考え方を整理しておく必要がある。メモに図を描きながら、何度も発想を換えて一番合理的な方法を研究する。

 その結果、やはり当初のやりかた通り、文字フォントの描画、画面の領域(レクタングル)のクリアなどの関数を、Y軸についてシームレス(最大幅まで来たら折り返して0に戻る)に動くようにすれば、画面のスクロールの部分は単純な演算だけ(フォントを書き出すVRAMアドレスは16回も変わって元へ戻るが)で、表示できることを擬似コーディングで確かめた。

 実装はこれからで、文字フォント描画関数がはたしてシームレスに動くように改装できるか確認できないが、とりあえず何とか動きそうな感じである。ささやかだがこういうときも達成感がある。本当は動いてから報告するべきだが、ちょっと時間がかかりそうなので、このあたりでブログに上げることにする。動いたかどうかは次記事をお楽しみに。

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

2013年3月30日 (土)

STM8Sでグラフィック液晶に日本語文字が表示できた

 LPCMプレーヤーでばデバッグの醍醐味を味わって大いに意気が上がったというのに、本来のSTM8Sによるモノクログラフィック液晶(JCG12864A37)への日本語フォント表示の開発の意欲は依然として高まらない。

 進まない理由は前にも書いたように、具体的な目標が決まっていないからである。目的があいまいなので、仕様の選択肢が多くなりすぎ、迷うばかりで先に進まない。何か決めても心配になってまた元へ戻るという堂々巡りになっている。システム開発で良くある失敗プロジェクトのパターンだ。

S_p3265774 こういうときは、少し強引でも、良い加減でもいいから、完成までの作業工程を可能な限り細分し、そのひとつづつを何も考えず、とにかくやってみるという少々乱暴だが効果的な打開策がある。で、今度もこれを応用してみることにした。

手順を分解して沢山の作業項目を作る(3/19/2013)
 ということで、STM8Sの日本語フォント表示計画は、次の5つの手順に分けて、とにかく先に進むこととした。

(1) フォント抽出と、フォント描画の機能の分離
 グラフィック液晶(GLCD)に文字フォントを描く手順は、大きくわけると、フラッシュから、所定の文字のフォントグリフ(フォントのビットマップスキャンデータ)を抽出してくるロジックと、GLCDメモリに、そのデータを移すロジックに分かれる。

 これまでに作った半角のANK文字表示関数と、日本語文字表示関数を分けるか、一緒にするかで悩んでいたが、GLCDの描画部分を共通にして、関数を2つに分けることにした。

(2) 漢字コードの入力
 UARTモニターからは任意の2バイト漢字コードが入力できないといけない。ハードコーディングした漢字コードのテストだけでは不完全である。この開発は、描画とは独立した機能なので、この部分だけでも進める。

(3) フォント構造体の統合とSRAMの構成見直し
 フォントデータを速度の遅いフラッシュに収容しているので、フォント属性だけは、SRAMにあるフォント構造体に収容している。日本語フォントは、FONTXフォーマットを使うとすると、さらに文字データをアドレスするデータブロックがSRAMに必要となり、この量は結構多い(バイナリエディターで調べたところでは蕨フォントで376バイト)。

 このため、ANKとは別の考え方をしないといけない。しかもSRAMは既に限界の2KB近くまで使い込んでいるので、このままではSRAMがオーバーするのは自明である。何とかしなければいけない。

(4) 2バイト日本語フォントデータ抽出関数の開発

 この部分は、ChaNさんのサイトの「FONTXの話」に、幸いソースコード付きで紹介されているので安心である。コードを読んでみると、自分が考えていた手法と殆ど同じで意を強くする。この手順だけで、あのばらばらのブロックに分かれたシフトJISコードがハンドリングできるのか、ちょっと信じられないのだが、彼のコードにぬかりがあるはずはない。

(5) フラッシュメモリの再構成
 フラッシュメモリへの書き込みが、なるべく単純作業で行えるようなメモリの構成とソースコードにしておきたい。そうでないと最初は良くても自分でもメンテナンス不能になる可能性がある。

 しかも今度のフラッシュの初期化の単位がセクター(64KB)ごとなので、今後のことを配慮したメモリ配置をしないといけない。とりあえず、0セクターをワーク用、1セクターをANKフォント、2セクター以降を日本語2バイトコードと割り振って、ソースにハードコーディングしておく。

達成感があるとやる気が出てくるものだ(3/20/2013)
 手順が出来たので、各個撃破のつもりで作業にとりかかった。まず、(1)の手順として、既存のフォント表示関数LcdChr_Ank関数から、フォントデータをLCDメモリに展開するだけの関数LcdPut_Font関数を切り出す。

 やってみると意外に簡単に分離することが出来た。早速、ここだけでテストする。いつもの逐次開発法である。よーし、分離してもこれまでのANK文字は問題なく表示された。これでこれから開発する2バイト漢字コードを表示する関数、LcdChr_Kanji()は、この切り出した関数を呼ぶことでコードの効率化が図れる。

 次に(2)のステップである。16進表示キャラクターから、実際の2バイトバイナリーをデコードするロジックは、AVRなどいくつかのところで実装済みである。このあたりを参考にUARTコマンドのコードを書く。これもそう手間をかけずに完成できた。既存のユーティリティで数値を確認する。

 沢山ある仕事もこうして細かい手順に分けて少しづつ完成させていくと、はずみがつくものだ。ちょっとでも達成感があると次のやる気が出てくる。不思議なものである。しかし、良いことばかりは続かない。(3)の手順で、つまづいた。SRAMのメモリーがなかなか減らないのである。

 フォント構造体の設計は、1バイトのANK系と2バイトの漢字コード系とはヘッダーの部分だけであとは全く別方式でやることにした。そこまでは良かったが、漢字コードのデータブロックに必要な300バイトあまりのSRAMの余剰はどうしても生まれない。

 STM8Sコンパイラーには、変数を、SRAMに置くか(予約語data)、フラッシュに置くか(予約語code)、指定できるようになっている。プログラムの中には、UARTのメッセージのように、固定された定数が多いので、これをcodeでフラッシュに移したつもりなのだが、これが全く効果がない。

 STVD(STマイクロ統合環境)には、出来上がったバイナリーの大きさを表示するsizeコマンドが入っていないので、.mapファイルをエディターで見ている。しかし、これが不思議なことにSRAMのサイズが考えたように減っていかない。変化が連続的でないのである。時々、がくっと減ったり増えたりする。謎である。

 暗礁に乗り上げた。余裕は精々30バイトくらいしかない。このままでは、所望の日本語のフォントデータにたどり着くまでに、何回もフラッシュを読まないといけなくなり速度が落ちてしまう。何とか切り抜ける方法はないがあれこれ考えるが、うまい解決策が思い当たらない。S_p3305790

気を紛らそうとハード工作の道草をする(3/21/2013)
 こういうときは、何か全く別のことで気を紛らわすのが一番だ。そのうち良いアイデアが湧いてくる。ということで前から気になっていたハード工作をすることにした。

 それは、オーディオセットのスピーカーの起動時のポップノイズを避ける遅延装置の作り直しである。LM380革命アンプをテストしていた時、この遅延回路を作って30年以上経っていることに気が付いた。

 この遅延装置の主要な部品は、30年以上前、職場の大型汎用コンピューター(IBM)のハードエンジニアから分けてもらった、大型のリレーとカンパッケージのトランジスターである。それに電源とケースをつけたして自作した。遅延はベースに入ったCR時定数で、電源が入った数秒後トランジスターがリレーをドライブしてスピーカー回路をONする。

S_p3305795  さすがにあの時代の電子計算機の部品である。作ってから全く何の問題なく動いているが、そろそろリレーの寿命が心配になってきた。ウェブなどを見ていると、最近のMOS-FETのオン抵抗は、下手なリレーより低い一桁のミリオーム台なのだそうだ。FETのスイッチングは大電流のところを派手に切るためのものと思っていたが、こういうところにも使われているとは知らなかった。

 ウェブで紹介されている回路を見て驚いた。FETのドライバーのフォトカプラーの2次側に電源線がない。スピーカーの端子を切るだけだからフォトカプラーの絶縁性は余り問題にならないが、2次側に電源が要らないと言うのは回路がとても簡単になる。

 こういうフォトカプラーはフォトボル型といって、1次側のLEDの光だけで、FETのドライブに必要な電圧を出せるのだそうだ。急に欲しくなった。いきつけの千石や、秋月では売っていない。DigiKeyにはさすがにあった(TLP590B、TLP190Bなど)が、これだけ買うわけにも行かない(最近はDigiKeyで欲しいものがない、というよりあらかた買ってしまった)。

 値段は、少々お高い。DigiKeyで¥200ばかりだ。諦めきれずにウェブでさらに探し回ると、例のサトー電気でTLP590Bを売っているのをつきとめた(¥252)。前々から一度は行ってみたいと思っていたサトー電気である。

Photo

川崎のサトー電気でフォトカプラーを手に入れる(3/22/2013)
 相当、古くからある電子部品の専門店である。Webの通販ページが手作り感満載の不調法なリスト一点張りのページだが、品揃えは中々侮りがたい。色々な逸話のあるお店である。ただ、お店が町田や川崎など遠方にあるので行く機会がなかった。

 ちょうと良い機会である。フォトカプラーだけというのもちょっと何だが、気晴らしに久しぶりに車を駆って川崎駅前まで出かけてみた。カーナビで目指すところに辿りつき、車をコインパークに入れて探したのだが、これが見つからない。

 場所は、駅近くの府中街道沿いの家内工場街といった感じのところで、看板が全くない。地図を見直して(印刷してきてよかった)、慎重に調べ直しやっと辿りついた。看板が出ていないのは、トラックに壊されて中に入れたままだったということをあとで聞いた。

 3間ほどの間口の店の中には所狭しと電子部品が積み上げられ、ちょっと壮観である。名物のおばさんは10年近くも前に亡くなったそうだ。親父さんはすこぶる元気らしい。川崎の店の息子さんらしい人は意外に愛想が良かった。

S_p3285787  問題のフォトボル型フォトカプラーTLP590Bを4ヶ、ついでに高速(10Mbit/s)フォトカプラーTL522を2ヶ買った。型番を調べてあったので、あっという間に品物が揃う。足が出ているので導電スポンジにつけて欲しいと言ったら、エアシートで包装してくれた。

 買って帰ると何となく安心して、遅延回路を作る意欲が薄れる。面白いものである。第一、まだオン抵抗の低いFETを入手していない。FETの型番はどういうことになっているのだろう、2SK,2SJ以外に多種多様な型番があって、何がなにやらさっぱりわからない。

 暫くは、FETを何にするかで楽しもう。出来合いのSSR(ソリッドステートリレー)を買ってしまうほうが、安くついて簡単なのだろうけど、こういうところにこだわれるのが自作の醍醐味だ。

SRAMのオーバーはやりたくなかったがUNION(共用体)で回避(3/23/2013)
 STM8Sの日本語フォント表示の開発に戻った。(3)が頓挫しているので、残りの(4)と(5)のステップを進めている。(4)はChaNさんのコードを参考に、LcdChr_Kanji()を少しづつ実装していく。SRAMが残り少ないので、なるべくワークを使わないように気を遣う。

 (5)のフラッシュデータの再構成である。これまでのデータはすべて破棄し、0セクターはテスト用に残し、1セクターをANK文字、2セクターを、日本語文字フォントに割り当てる。書き込みコマンドを書き直し、12ドットと10ドットのANKフォント、日本語フォントは12X12の蕨(わらび)フォントを入れ直す。

 あれえ、データ量が少ないなあ。ダンプリストで確認しようとした。あっ、こいつは32ビット対応になっていない。セクター1以降は、64K以上なのでアドレスはすべて32ビット対応にしておかねばならない。まずダンプリストのソースを修正する。

 ダンプリストが1セクター以降でも動き始めた。データがおかしい。ちゃんとデータが入っていないようだ。どうしたのだろう。ああ、なーんだ。ファイル転送をバイナリーモードにしていなかった。お馬鹿な話である。

 ファイルをもう一度、バイナリーモードで転送し直す。これでANKフォントは入ったようだ。テストし直す。これまでと全く変わりなくGLCDの表示が出来た。さらに日本語ファイルを入れる。時間はかかるが正常終了。サイズもピッタリだ。よーし、これで(5)はクリアした。

(4)の日本語フォント表示関数も、そろそろ完成に近づいた。残りは、懸案の(3)のSRAMのやりくりである。GLCDのVRAMに既に1KB以上取られている上、フラッシュ上にコンスタントを移せていないのでちょっとのことでは空きが出来そうにない。

 これまで構想はあったが、実装をためらっていた方策をやはり実行するしかないようだ。UARTバッファーとフラッシュのデータエリアをUNION(共同体)で流用する方法である。フォントデータをファイル転送するために、UARTはダブルバッファーで100バイト以上をとっている。転送してしまえば、UARTにこんな大きなバッファーはいらない。ここにフォントデータブロックのエリアを割り当てる。

 エリアを共用するので、プログラムの構成を良く考えておかないと、予測不能なバグが出る可能性がある。余りやりたくない方法である。しかし、もう背に腹は代えられない。変数名が長くならないように、共用体(union)の名前をなるべく短くして(uとか、tr)プログラムを書き直す。これでやっと全部のプログラムのSRAMを、2KB(2031バイト)内に納めることが出来た。

嬉しい。フラッシュメモリのエラーが直った(3/25/2013)
 ソフトはおおよそ出来上がったが、実はまだ解決しなければならない大きな問題が残っている。SPIフラッシュM25P40のreadエラーがとれないのである。

 単独では全くエラーが出ないのに、グラフィック液晶(SPIインターフェース)とSPIを共用するとデータエラーが頻発していた。当初は、フラッシュにパスコンを入れたり、接触不良を直したりしてエラーが出なくなっていたのだが、今度の漢字フォントのような大容量データを読み出すと再びエラーが起き始めた。

 漢字ブロックデータはアドレスなので1ビットでも間違いが起きれば、フォントのようにドットが欠けるくらいではすまない。エラーの出方がおかしい。単なるノイズでビットが時々乱れるのではなく、発生するときは、ある時点から連続的におかしくなる。止まっているはずのGLCDが時々動いてエラーを出しているような感じである。

 マスターのSPIから見れば、GLCDへは送信(MOSI)だけであり、フラッシュは殆ど受信(MISO)だけである。お互いに干渉しないはずなのにおかしい。GLCDそのものの結線をはずせば、全くエラーがなくなるので、GLCDによっておかしくなっていることは明白である。

 試しにGLCDの電源ラインを切ってみると、かえってエラーが増える。???である。しかも、液晶面には、電源を切っているのに、画像が出ている!GLCDのコントローラーは動いているのだ。クリアも有効である。謎は深まるばかりである。

 そこで、さらにCLK線をはずしてみた。おお、これでGLCDそのものをはずした時と同じようにエラーが出なくなった。GLCDの方も完全に止まっている。

 どうも、GLCDのクロックラインがフラッシュのSPIのクロックに悪さをしているようだ。両者の間に300Ωばかりのダンプ抵抗を入れてみる。ふむ、GLCDはこれでも動くが、フラッシュのエラーは改善されない。

 えーい、こんどはダイオードだ。小電力用のダイオードを入れる。だめだ。GLCDが動かなくなる。これは0.7V近く電圧降下するからか。では、SBD(ショットキーバリヤーダイオード)ではどうか。やった、やった。SBD(1S4)を入れてGLCDからの信号を遮断すると、GLCDは正常に動き、しかもフラッシュのエラーはきれいになくなった。何十回フォントデータを読み出してもエラーは起きない。

 いやあ、これで2バイトコードのデコード関数開発に心置きなく専念できる。これまでこのエラーが気がかりで中々先に進めなかったのだ。

S_p3265771 遂に日本語フォントの描画に成功(3/27/2013)
 長かったSTM8Sのプロジェクトが大詰めに近づいてきた。当面の目標であるグラフィック液晶への漢字表示である。2バイト日本語フォント表示関数が完成したのでテストに入る。

 漢字コードや、フラッシュのエントリーアドレスなどをUARTに表示するテストステートメントをびっしり入れたお陰で順調にバグがとれ、画面にそれらしい漢字データがあらわれた。あのデータブロックの計算はうまく行っているようだ。この部分は一発で通った。ちゃんと指定どおりの漢字が出る。

S_p3265777  嬉しくて何枚も記念撮影する。まだ、一字づつ16進コードを入れて漢字をひとつ表示するだけだが、表示の度にキーボードの前で何度もガッツポーズを作る。今回は特に感慨深い。とにかく時間がかかっているのだ。

 ブログの記事によれば、STM8Sを触り始めたのが、去年の11月、グラフィック液晶をつないだのが、2ヶ月前の1月、かれこれ5ヶ月近くこれにかかわっている。STM8SがAVRに比べて有利な点を持っているわけではない。情報も少ないし、余りメリットはないのだが、日本語が出るまでと意地になっていた。

 コードを追加して、エンドレスに漢字が表示されるようにする。おやあ、途中で文字が化けてしまう。どうしてだ。ファイル転送は、PCにおけるデータ数と同じ転送バイト数を示しているのでデータエラーは考えられない。ソフトか。うーむ、今までの高揚した気分が一気に落ち込む。

S_p3285780  文字化けし始める漢字コードを探し当てる。8C49「栗」というコードからおかしい。ふーむ、この文字のポインター(ファイルのエントリーからの)と、ひとつ前の8C48「粂」の違いは?あ、あ、あ、わかった。セクター消去を3セクターまでしかやっていない。「栗」からは4セクターに入るんだ。ダンプリストを作っておいて良かった。アドレスの違いが一目でわかった。

 あわてて、フラッシュメモリを7セクターまで消去し、フォントファイルを入れ直す。第二水準の一番最後の文字まで画面に出ることを確認した。これで完全だ。

 遂に、STM8Sの日本語フォント表示プロジェクトは大団円となったようである。次のテーマも良いが、長い間の付き合いでこのSTM8SとGLCDに妙に愛着が出てきた。ブレッドボードのバラックではなくて、ちゃんとした基板に実装してあげようか。

ここに作りかけのソースコードですが、以上の漢字が出力されるプログラムをSTVDプロジェクトの形で固めたものを置きます(フォントは入っています)。以前同様、ライブラリは入っていません。また、容量の関係で、ビルドは最初からやってください。UARTを接続し(38400bps N81)、プロンプトがでたら、kWXYZ でコードWXYZの漢字、kWXYZ- で、連続して漢字が表示されます。中断はスペースキー、終了はリターンキーです。

「JCG12864_330.zip」をダウンロード

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

2013年3月17日 (日)

リニアPCMプレーヤーのデバッグで電子工作に戻る

 前回の記事以来一ヶ月が経ってしまった。これほど更新が滞ったことはブログ開設以来始めてのことである。電子工作自体のモチベーションが下がってきたこともあるが、この時期、行事が立て続けに続いたことも大きな原因である。

 例年いつも2月から3月にかけては、所属する団体の全体集会の準備と実施、恒例のスキー合宿、確定申告と、毎年必ず決まっている行事で電子工作どころではないのだが、今年は特にそれに輪をかけて別の行事がいくつも重なって多忙を極めた(え、いや現役のときに較べれば、屁のような話ですが)。

 学生時代の友人の新年会が遅れに遅れて、雪見酒を楽しむ会になったことを含めて予定外の飲み会が3つ、さらに義理を欠いていた旧職場の同窓会に久しぶりに出たり、古い友人が突然電話してきて飲むことになったり、さらに長女の縁談で関係者が集まったりして、このあいだ数えたら1ヶ月たらずの間に、10いくつも行事が重なっていた。

 で、電子工作の方は、STM8Sという8ビットプロセッサーにフラッシュメモリをつけて、グラフィック液晶に文字フォントを描いたところで止まったままである。書く事がないとはいえ、備忘録を兼ねているこのブログを放置しておくわけにはいかない。

P3175746

 それに、昔のリニアPCMプレーヤーのトラブルの問い合わせがあり、全体集会(浜松)から帰って、行事が一段落したので久しぶりにこのトラブルシューティングにはまった。原因究明は結構、大変だったが何とか収束することができたので、これを合わせてブログをアップすることにした。(プレーヤーの件は、記事の最後に)。

ダンプリストコマンドは完成したが(2/15/2013)

 これまでのテーマ、STM8Sの話である。STM8S基板(STM8S-Discovery)にフラッシュメモリをつけてモノクログラフィック液晶(Aitendo JCG12864A37)に文字を出す開発は、前回までに1バイトの半角文字を表示するところまできた。フラッシュメモリは2Mバイトの大容量のメモリである。折角だから日本語フォントまで出してみようということになっている。

 日本語フォントデータは、半角に比べれば圧倒的に量が多く、その取り扱いは簡単ではない。今のところ想定している12X12ドットのフォントでも240KBもありコード体系も複雑だ。そのため、デバッグの効率を高めるため、フラッシュメモリ内のデータを16進で表示するユーティリティを作ることにした。

 こういう周到な環境整備が、結局は成功への早道になることが多い。ダンプリストが簡単に出るかでないかでデバッグの効率は全然違う、などと一人で能書きを垂れながら、せっせと、UARTに16進表示を出すコードを書いた。ChaNさんのFatFSのサンプルプログラムにも良い例がある。しかし、これは書式付出力関数を多用されているので余り参考にならない。

Stm8s_hex ほどなく、ダンプリストのユーティリティが完成した。UARTのコマンドに入れて、半角のフォントのエリアをキーボードのキーで表示を止めたり、再開させたりして遊ぶ。左側に16進、右側にANKコードが出る本格的なダンプリストである。

 環境整備は出来たが、肝腎の日本語2バイトコードの表示関数の開発は、まだ手が出ない。このSTM8Sでは、やり残していることがまだいくつかある。その一つがスクロールである。AVRでは動かしたが、STM8Sには移植していない。どうもやる気が起こらない。

 画面が小さくスクロールの見栄えが良くないので気が進まないのだ。128X64ドットの画面だと、小さな文字(5X10ドット)でも、たかだか5行、20文字程度しか表示できない。これでは、スクロールすると、あっと言う間に文字が見えなくなってしまう。苦労の割には効果が薄い。STM8Sでは先送りすることにした。

 それでも、日本語フォント実装に向けて、少しづつ作業を進めている。フォントは2つまで入れ、複数フォントの動作を確認した。日本語フォントは、12X12の蕨(わらび)フォントをダウンロードした。しかし、フラッシュメモリ上のこれまでの1バイト系と整合性のある仕様が決められないのでフラッシュに書き込むところまでは行っていない。

STM8SのUART立ち上がりハングは直ってしまった(2/18/2013)
 もうひとつのSTM8Sの問題は、UARTがハングすることである。STVD(STマイクロの統合開発環境)でコンパイルしテストする分には全く問題がないが、そこを経由せず、単に電源を入れて動かすと、PCコンソールとのUARTがハングアップする。

 つまり、単独では動かない。実用的に使おうというときには大問題になる。始め、STVDに何かオプションがあって、単独で使うときのバイナリーは、統合環境のときと違うものを作るのではないかと一生懸命探したが何もない。

 他の方々の使用例を調べてみても、こういうことは全く書いておらず、問題なく単独で動いているようだ。どうも良くわからない。そのうちいつのまにか動いたり、また動かなくなったり、わけのわからない状態になった。

 ダンプリスト開発が一段落したので、少し、本腰を入れて調べ始めた。ときどき動くと言うのが曲者である。ソフトではなくハードを疑う。GLCDの表示はうまく動いているし、UARTも何か送受信をしているが字化けだけが原因のようだ。

 UARTの初期化が疑われる。試しにボーレートを下げて設定してみたが変わらない。こんなことで変るわけはないとは思いながら、今度は、UARTの初期化ルーチンをプログラムのメインループの直前まで遅らせてみた。

 ところが、なんと、これで直ったのである。今までのトラブルがうそのように快調にUARTが動く。要するに、電源投入後、すぐにUARTを初期化すると、ハングすることがわかった。STVDでは最初デバッガーが動くので、十分な時間の余裕が生まれていたのだ。

 STM8SのUARTを動かす時は、スタートのあと100μsくらいの待ち時間をUARTの初期化の前に入れる。というのが教訓である。クロックがまだ安定していないのだろう。

画面描画で遊ぶ。円を描くのが結構難しい(2/22/2013)
 行事が重なってきて、まとまった時間を電子工作に割けなくなってきた。懸案の次のテーマ、日本語フォント表示に踏み込む時間の余裕がない。と言って全く時間がないわけでもない。こまぎれの時間ならいくらでもある。

 そういうときは、TVの前で時間をつぶさず(下らない番組を見ていると自分がどんどん馬鹿になる気がする)、なるべくPCでSTM8Sの開発画面に向かうようにした。まとまったコードは書けないので、気の付いた細かな、とりとめもない開発を少しづつやっては楽しむ。

 グラフィックディスプレイ(GLCD)の描画速度が気になっていたので、調べてみることにした。どれくらいの早さで画像が出せるのだろう。そら。さんから頂いたソースコードには、点と線の表示関数はあるが、それ以上の関数の用意はない。

 そこで、まず、直線を組み合わせて四角枠(レクタングル)を描画する関数を作って表示してみた。どうせなので、乱数を使う。感心にも、RaisonanceのCコンパイラーは、GNUのRand()を実装していた。フォトフレームで使ったSTM32の乱数関数を参考に、ランダムなレクタングルを画面に出してみる。

 描画速度は余り早くない。SPIで送られたデータ転送速度より明らかに描画が遅い。描画の間に待ち時間をはさまないと、残像で画面が見えなくなり、レクタングルはスムーズに移動しなくなる。

S_p2245695  こんどは、円を描画してみた。円を表示するには、本来なら実数で平方根を計算する必要がある。しかし、128X64ドットくらいのGLCDで、浮動小数演算をして座標を求めても表示する場所は整数単位なので意味がない。

 こういうときは、みなさんどうしているのだろう。整数型の平方根算出法をウェブで探してみた。ウェブの力はすごい。あっという間に沢山の解答例が出てきた。だいたいは、ニュートン法である。

 しかし、これでも大げさだ。これくらいの平方根はニュートンの近似式を使うまでもない。平方根の小数1位まで出せるように(四捨五入するため)、元の数を100倍して、それに近い冪を求めれば簡単に、小数一位までの平方根が得られる。

 ロジックは良かったが、なかなか数字が合わない。調べてみたら、このやり方では、26を超える平方根を出すだけでも16ビット(65534)を簡単にオーバーフローしてしまうことがわかった(26X26=676でこれを100倍すると67600)。あわてて32ビットにして事なきを得た。

 画面に円が出た。しかし整数計算した円は、単純に描画すると、急激に値が変わる部分は、空白になってしまう。つまり、円が立ち上がる最初と最後の部分は、値が飛ぶのでその間は描画できない。

Photo  そうか、ちゃんとした円を描くには、最初Y軸から描きはじめて、45°まで行ったら、今度は、X軸を増やしていって描画していく必要があるのだ(図参照)。

 何度か試行錯誤のあと、やっと、円らしい画像が描けた。ただ、このLCDの表示は遅い。ちょっと動画らしく動かしてみたが、全体が白っぽくなるだけでまるで動画にならない。やはりFSTNで動画は厳しいようだ。

 ここに、以上のダンプリスト、円などの描画が出来るSTM8SのソースリストをSTVDのプロジェクトの形で置きます。この前と同様、必要なライブラリは同梱されていませんので各自サイトから落としてリンクさせてください。試作プログラムなので当記事と違う描画をしているところがあります。ご了承ください。

「JCG12864_317.zip」をダウンロード

日本語フォント表示関数の検討に入る(2/26/2013)
 グラフィック画像の表示にもあきたので、いよいよ、日本語2バイトコードのデコードロジックを検討し始めた。検討だけならメモ用紙と筆記具さえあれば、どこでも出来る。スキーに行く時も一式を持っていったが、結局今回は、その時間がなかった。電子工作に熱中していた時は、行き帰りのバスの中でロジックを考え、良いアイデアが生まれた時もあったのだが。

 言い訳になってしまうが、STM8Sの開発の進捗が遅いのは、実はモチベーションが下がっているからではない。このSTM8Sの使用用途が決まっていないというのが一番の原因である。仕様を決めるときに「何に使うか」が明確でないので、色々迷ってなかなか決められないからである。

 今度の日本語フォント表示開発も同じことだ。JJYの標準時計にするなら、大げさな表示ルーチンは必要ない。大容量フラッシュメモリも必要ない。必要な日本語のビットマップデータを用意するだけで出来てしまうはずだ。

 日本語ファイル名や、テキストデータの表示という目的なら、本格的な日本語フォント表示関数を開発する意義があるのだが、あいにく、そういう用途は考えていない。

 まあ、あまり固いことを言っても始まらない。所詮アマチュアの工作だ。好きなように作れば良いというのが結論だが、つい昔の「問題解決」の癖が出て、「効率」を考えてしまう。

 それはともかく、日本語フォント表示関数の仕様である。シフトJISは、第1バイトで、このデータがシフトJISの1バイト目であることを識別できるので、フォント表示関数は、ANKの1バイトと共用にすることができる。

 こちらは、フォントグリフを縦から横に変換する処理(大抵のグラフィック液晶はこの処理が必要なようだ)が、かなりコードを喰うので、ANK(半角)も2バイト(日本語)コードも一緒の関数にしたいのだが、大抵のこのあたりのプログラムは、1バイトコードと2バイトコードのフォント出力関数は別のものを作っている。その理由がどうもわからない。

 入力を値参照にするかアドレス参照にするかも頭を悩ませる問題だ。1バイト関数でアドレス参照にしている例は殆どない。開発に手間がかかるだけに、このあたりの仕様は良く考えてから決めたい。そんなことで、中々検討が先に進まない。

 それと関数が出来上がって、GLCD上に日本語(漢字)データをどうやって画面上に見せていくかというのも何が良いか迷っている。やっぱりスクロールを生かして、画面上を移動させていくのが一番見栄えがするような気もする。うーむ、悩むだけで決まらないなあ。

LPCMプレーヤーの不具合を調べる(3/6/2013)
 そうこうする内に、3年前に作ったリニアPCMプレーヤーの不具合報告がコメントにあがった。こういう問い合わせは大抵、忙しい時に限ってくるものである。今度もそうだった。ステレオの音の左右のチャネルがばらけるのだという。

 最初、メディアによって違うと言うのでI/Oエラーか、リッピングのエラーだと答えておいたが、その後、詳しい調査報告があり、pause(一時停止)でも起きると言う。これは大変だ。ソフトの不具合の可能性が高い。

 いくらオープンソースとはいえ、発表したソフトに不具合があるのを放置しておくわけには行かない。久しぶりに3年前のリニアPCMプレーヤーのソースコードを開いて調べてみた。

 pauseは、DAC割り込みルーチンの割り込みをマスクすることによって、再生を止めている。ありゃあ、こりゃいかん。タイマーはpauseをかけても動きっぱなしで、LRのトグルはレジスターがコンペアマッチする度に動き続けている。

 V41、V42以前のバージョンのときはLRのトグルは割り込みルーチンの中の命令でやっていたので、割り込みを停止すればLRのトグルは止まるが、V41,V42ではハードでトグルをするようになっている。ジッターはなくなったのは良いが、pauseで再生を止めると、延々とトグルを続ける。

 このままでは、pauseのあとの次の再開が前の状態を保持して動く保証はない。50%の確率で左右が逆転する。生録(SL機関車の録音など)や、オペラなど、音の場所に敏感な音源を聞かない人にとって左右のチャネルの逆転は気づきにくい。それにしても、よくここまでわからなかったものだ。

 ただ、今は電子工作以外の事で忙しく、とてもこれに関わる余裕がない。調査してくださった、n_piezoさんにお断りのコメントを返すのが精一杯だった。折り返し、修正のお願いのコメントが返ってきた。まあ、半年も1年も放置する積もりはない。出来るだけ早く、pauseのバグだけでもとっておこう。

S_p3165741  スタート時点でのLR逆転はまだ原因は突き止められていない。ここも、LRのトグルはハードで行っているので(V41から)、もしかしたら、ソフトの可能性もありうる。しかし、時間がないので、そこまで調べるゆとりがない。

検証する音源データを作る(3/12/2013)
 全体集会の浜松出張から帰ってきて、やっと仕事が一段落した。早速、ブレッドボードに常備しているLPCMプレーヤーでデバッグを開始した。少なくともpauseの時のバグの修正方法はわかっている。コーディングに入る前にテストデータの作成にとりかかる。

 プログラムは考えたようには動かない。書いたようにしか動かない、というのが鉄則である。どんなに完全だと思っても、本当のテストデータで確認しないと安心できない。テストデータはデバッグの前に必ず作る。このあたりが長年ソフト開発をしてきた経験から生まれたノウハウである。

 数年前、音楽演奏の録音用に買ってあったRolandのデジタルレコーダーR-05を取り出した。最初、自分の声でレコーダーの前を歩きながら、「左です」「右です」などの声を入れたテストデータを作った。

 しかし、再生してみると内蔵マイクがちゃちなせいか、分離が悪くてどっちが左なのか右なのか全然使い物にならない。仕方がないのでPCで適当な音楽を鳴らし、PCのミクサーで左右チャネルを振り、ラインアウトを通してレコーダーに録音した。

S_p3165739  pauseの時の不具合修正は簡単である。割り込みのマスクではなく、単にタイマー(Timer0)をストップさせる(TCCR0B = 0)。ただし、このレジスターはプリスケールを決めるレジスターなので、再開のため、ソースの種類(ステレオ、モノラル、44.1/22.05khzなど)によって決まるプリスケール値を保存しておく必要がある。

 pauseで左右が逆転することは全くなくなった。この部分は解決した。しかし、起動時の左右逆転は、たまにどころか、かなりの頻度で起きていることがわかる。あわてて、再生直前に、トグルピンを初期化するコードを加える。

 これで、電源投入直後の再生は、全くぶれがなくなった。ところが、再生を中止したり、別の曲を再生して(ここが逆転しているかはわからないが)、テスト曲に戻ると、何回かの割合で左右が逆転する。トグルピンを初期化しているのにおかしい。

迷走している(3/13/2013)
 そもそも、V41からは、DACにデータを送る割り込みルーチン、SDカードを読むsystick割り込み、それにLCDに経過時間を表示するバックグラウンドタスクと3段のマルチタスクになっている。構造が複雑な上、曲の再生開始のタイミングも、曲データがバッファーにある程度貯まったところというクリティカルな条件がある。デバッグは容易ではない。

 電源を入れた直後はうまく行くのに、そのあとがうまくいかないというのが気に入らない。片っ端から電源投入直後の初期化コードを、繰り返し処理の中に入れてテストするが、改善されない。これはBU9480Fが悪いのかと疑い始めた時、AVRのリセットでも、うまく行くことがわかって、その疑いは晴れた。

 結局、再生開始直前のトグルピンの初期化がどうも、うまくされていないという仮説が一番有力になってきた。ロジアナを取り出して確認しようと準備し始めた頃、たまたまMega168のデータシートを見ていて、意外な記述を見つける。

「COM0A1~0ビットの1つまたは両方が1を書かれるとOC0A出力はそのI/Oピンの通常ポート機能を無効にし、そのI/Oピンに接続されます。」(p64 14.9.1. タイマ/カウンタ0制御レジスタA )

 うはあ、トグル出力にしているピンは、タイマーにつなぐと、外からはいじれないのだ。それならと、タイマーの定義、TCCR0A=0で、一旦ピンをタイマーからはずし、通常のPORTD=(1<<PD6)などで、ピンの値を固定した後、再度、タイマーのトグルピンとして(bit0=0, bi1=1)、TCCR0Aを設定する。これでトグルピンは初期化されたはずだ。さあ、どうだ。

 いや、やっぱり駄目だ。まだ左右がふらつく。どうもタイマーの方でトグルの情報を残していて、それが復活してしまうようだ。これ以上直すところがなくなった。暗礁に乗り上げる。2日間悩んでいた。前の記事以来もう一ヶ月が経とうとしている。そろそろ記事を上げたいが、この状態のまま経過報告するのもしゃくだ。何とかすっきりする結果にしてしまいたい。

考えれば智恵が出るものだ。やっと正しいチャンネルで再生成功(3/14/2013)
 デバッグに疲れると、他の事をやって気を紛らわす。メモにこれまでの経過を書きとめて、あれこれ仮説をたてる。しかし解決策は生まれてこない。そろそろ、あきらめてブログにこれまでの経過を報告し、完全に直せなかったことを謝ろうと文案を考え始めたころ、ふっと方法を思いついた。

 タイマーのトグルにしたピンを勝手にいじれないのなら、トグルをデコードとは分けて何回かまわし(要するに空振り)、所定の位置に揃えてから再生を始めれば良いのではないか。トグルするピンの状態は、PINを読めばわかるはずだ。

 何か、光が差してきた。コードはそれほど難しくない。DAC割り込み部に空振りするロジックを加え、再生開始の方ではトグルピンを見て左チャネル(最初)になったのを確かめて、空振りをやめて再生に入る。うむ、これはうまくいきそうだぞ。期待に胸が膨らむ。

 あせる手でコンパイルする。何十回とやったテストを始める。おおー、良いようだ。何度やってもチャネルはぶれない。今までなら4~5回で必ず逆になる状態が20回以上やっても同じだ。もう大丈夫だろう。

いやあ、久しぶりの爽快感に体中が満たされていく。気分の良いことこの上ない。難しいパズルを解いたときの達成感である。苦労が大きければ大きいほど、この解決した時の喜びは何ものにも替えがたい。

 単なるデバッグでバージョンを上げるのは少々気が引けるが、混乱をさけるためV43としてプログラムソースを公開することにする。V41以降をお使いの方は、是非、このV43を使っていただきたい(V41以前はトグルを自前でやっているので問題ないと思われる)。また、この微妙な不具合を発見、報告していただいたn_piezoさんに改めて御礼を申し上げる。

ここに例によって、AVRStudioのプロジェクトフォルダーを固めたソースコード一式を置きます。元の記事にも
リンクを貼る予定です。上段が2号機、3号機の小さな液晶をつかったタイプ、下段が1号機のソースコードですなお、双方とも、ソースファイル名は前と変わっていないので注意してください。

「mLPCM328V43.zip」をダウンロード

「SDPCM328V43.zip」をダウンロード


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

2013年2月14日 (木)

STM8Sでグラフィック液晶に文字を表示することに成功

 STM8Sで外付けフラッシュメモリーを読み書きするルーチンがひとまず動いた。このプロジェクトの当面の目標は、このフラッシュに文字フォントデータを入れて、STM8Sでグラフィック液晶に文字を表示することである。

 このモノクログラフィック液晶(AitendoのJCG12864A37 以降GLCD)を制御するソフトは、AVRで開発が済んでいる。STM8SではSPIのところを書き換えるだけで容易に動くはずだ。今度付けたフラッシュメモリは大容量(512KB)なので、日本語フォントを入れて表示することも出来る。

S_p2125686

 ここまでやれば、STM8Sの顔も立つだろう。漢字がLCDで表示できるとなると色々なアプリケーションに使える。他の用途も考えられるので、電波時計にするかを今決めてしまうこともない。

 GLCDを動かす前に、大事な作業工程が残っている。外付けフラッシュメモリにフォントデータを収容する手順である。当初はメモリをソケットから外して、SDカードが読めるAVRなどのマイコンで転送する予定だったが、途中で気が変わった。STM8SのUARTのファイル転送に挑戦する。

UARTからのファイル転送の仕様を考える(1/30/2013)
 そのきっかけは、常用のターミナルソフトであるTeraTermにファイル転送機能が標準でついていることに気づいたからである。そう言えば昔のパソコン通信全盛の頃はファイル転送は日常茶飯事のことだった。

 別のマイコンでSDカードからフォントデータを入れるにしても、そのマイコンには今のフラッシュの書き込みソフトを新たに開発しなければいけない。どうせ開発するなら難易度は少し高くなるがSTM8SでUARTのファイル転送ソフトを作ったほうが手間が省ける。

 フォントデータの大きさは、1バイトの半角フォント(6X12ドット)なら5KBほどだが、日本語フォントともなると、12ドットフォントでも240KBはある。STM8SのUARTで、この程度の規模のデータが安定して受け取れなければいけない。

 STM8S側のUART受信ソフトの開発は、厳しい信頼性(1バイトでもずれると後のデータは全滅)が求められる。しかし挑戦しがいのある開発テーマでもある。安定したファイル転送を実現するための仕様の検討に入った。

 UARTの信頼性はフロー制御をすれば飛躍的に高くなるが、ハードソフトとも、もうひと手間、複雑になるので余りやりたくない。とすると、UART受信は待ちを一切いれず一気に読み切る必要がある。

 この前の受信割り込みルーチンではフラグを立てるだけだったが、今度は、割り込みルーチンでしっかりバッファーに貯める方式に変える。読みながら、フラッシュにブロック単位に書いていくことになるので、必然的にバッファー2つを使うダブルバッファー方式ということになる。

 さらにバッファーからフラッシュへ書き込むSPIインターフェースは、必ず処理の途中でUARTから割り込まれる。処理が分断されても問題ないかどうかの確認が必要だ。それにフラッシュメモリの書き込み時間も問題である。

 STM8SはSRAMが2KBしかないのでバッファーサイズは、余り大きくは出来ない。小さくしていくと、フラッシュの書き込み時間とUARTの転送時間が近くなり、バッファーオーバーランの心配がある。

 ロジアナで見ると64バイト程度のフラッシュ書き込み(2Mbps)は2ms以下である。UARTの64バイト受信は13ms程度(38.4kbps)であるので、そう神経質になることはないが、念のため実測しておくことにした。セクター消去の時間がロジアナでは計測不能なのでこの時間も測っておきたい。

 LEDの点滅に使っているタイマーの1tick(10ms)を減らして1msとし、フラッシュ書き込みの両側にコードを入れて実際の速度を測る。最初、10ms近くあり慌てたが、UART送信時間を含めて測っていたことがわかり、書き込み直後の時間をワークに入れてやり直した。その結果、転送時間はスペックどおり1msであった。ロジアナの1.6msとも符合する。

 一方、フラッシュメモリの消去は、セクター単位(64KB)なので時間がかかる。スペックによれば全消去(512KB)が2秒なので、0.3秒程度のはずだが、実測の結果は0.6秒だった。まあ、これは、ファイル転送の前に手動でやっておけば良い話なので関係ない。

 またSPIが割り込みに耐えられるかは、STマイクロのライブラリのコードを確かめた。その結果、単にレジスターとのデータの出し入れだけで、いわゆるAtomicオペレーション(分割できない複数の命令の処理)はないことがわかった。これなら割り込みを受けても心配ない。

 安定したファイル転送のための要件は満足しているようだ。残るはオペレーション手順である。転送を指示するコマンドの入力で、PCからのUART送信をひたすら待ち(タイムアウトを設けるが)、ファイル転送が終わったあとは、暫く待って一定期間データが来なくなれば終了と判断する、というプロトコルである(これがあとで大紛糾するのだが、このときは露知らず)。

擬似コーディングでダブルバッファーシステムを設計する(2/1/2013)

 ブロックレコードの転送では定番のダブルバッファー方式である。この方式ならUARTとの衝突を心配する必要がない。バッファーを2つ用意し、片側のバッファーにUARTの受信データを貯めながら、もう一方のバッファーから余裕を持ってフラッシュに書き込んでゆく。

 ちょうど良い機会なので、擬似コーディングの始めから、少し忠実にメモに書き出してみた。以下、こんな感じである。

 ------ダブルバッファー処理の擬似コーディング開発メモ------

 バッファーの状態を 0...未使用  1...書き込み中 2...満杯で転送待ち とする。

 バッファーA、Bの状態遷移表(真理値表)は、
        A  |  B 
        -------
        0  |  0     初期状態。とりあえずAから書き始める
        1  |  0     バッファーAに書き始めたとき
        2  |  0     バッファーAが一杯になり書き込み先をBに変更
        2  |  1     バッファーBに切り替えて書き込み
        0  |  1     Aを外付けフラッシュに転送した。書き込みはBで変わらず
        0  |  2     バッファーBが満杯になった。Aに切り替え
        1  |  2     バッファーAに書いている。
        1  |  0     Bを外付けフラッシュに転送した。最初から2番目に戻る

上の条件を整理していくと、ifを使ったロジックが作れる。一旦作っておいて、条件の聞き方を工夫する。整理すると条件式を減せるときがある。

まず、UART受信割り込みルーチンでは、A、Bをバッファーのステイタスだとすると、
if(A == 0) {
    if(B == 1) バッファーBにデータを移す
    else バッファーAにデータを移す
  }
else {
    if(A == 1) バッファーAにデータを移す
    else バッファーBにデータを移す
 }

 これくらい抽象度が高いと、ソースコードで見るより一目瞭然でロジックを確認できる。バッファーが満杯になって、受信したデータの書き込み先を切り替えるところと、満杯になったデータをフラッシュに書き出すところとは、処理するところが別々でクリティカルなところなので十分動作を確かめておく。

 このあとの処理として、それぞれのバッファーのポインターの処理(満杯になれば、ポインターを0にもどし、ステイタスを2にする)もここで必要である。

 次に、メインルーチンでは、満杯になったバッファーデータをフラッシュに転送していくが、このロジックは、これより簡単になる。
if( A ==2){
バッファーAのデータをEEPROMに転送し、フラッシュアドレスを進める
バッファーステイタスAを0にする。

if( B == 2){
バッファーBのデータをEEPROMに転送し、フラッシュアドレスを進める
バッファーステイタスBを0にする。

 UART受信割り込みでは、もうひとつ重要な処理を忘れていた。ステイタス0から1にするときの処理である。バッファーAが0のときは、最初のifで判別できるので、バッファーAに移すときに、ステイタスを1にしてやればよい。

 バッファーBは、最後のバッファーBに移すif elseのところであらためて、ステイタスが0かを確認したうえで、1にする。もっとも、ここは真理値表を良く見れば、必ず0か1なので(ここのステイタスBが2ということは、オーバーランエラー)、ifで聞くくらいなら常に1にしておく方が早いかもしれない。

 最後にバッファーに満杯にならずにデータ受信が終了した時のバッファーに残った最終データの送出処理と、実際のファイル転送をやるときのオペレーションにあわせたロジックを考えておく必要がある。
           --------------開発メモ終了------------- 

念入りな擬似コーディングをしたところは完璧。他はボロボロ(2/4/2013)

 周到にロジックを考えたので、ソースコードの完成は早かった。意気揚々とファイル転送のソフトのテストに入った。とりあえず、データが来なかった時のタイムアウトは20秒、データが来たあと(ファイル転送終了)のタイムアウトは、PC側がファイル転送を中断することもありえるので5秒とした。

Dblbuf

 ところが、これが不安定なのである。うまく行く時もあるが、何故か途中でファイル転送が中断され、残ったデータが終了後のコマンドプロンプトに流れ込んでハングする。奇怪なのは、ロジアナを入れると転送が失敗することである。

 ロジアナのプローブは動いている時と止まっている時とはインピーダンスが違うのか?まさか。UART(TTL)にはプルアップ抵抗も何も入れていない。それが悪いのか。そんな馬鹿な。しかし、ロジアナを動かさない時はOKでも、動かすと駄目になることは間違いない。頭を抱えた。

Dbl_cons

 しばらく悩んだが何のことはない、こちらのミスだった。ファイル転送の開始が遅れると、5秒タイムアウトが効いてデータを受信した途端、転送終了とみなしていた。要するにロジアナを動かす時のオペレーションの単なる遅れの差だけだったのである。ロジアナさん疑って失礼しました。

 しかし、これが解決した後もしつこいトラブルに悩まされた。転送が終わったあとのUARTにゴミが出て正しく文字が出力されない。データは2KB近くまでOKになっているが、ときどき失敗し、UARTにゴミが残る。タイムアウトのタイマーは、フラッシュに書き込むときでなく、UARTのデータ受信の度にリセットするようにしたのだが、それでもうまく行かないときがある。

 擬似コーディングを念入りにやったおかげで、ダブルバッファーのロジックは完璧に動いている。うまく行く時は、2KB以上のデータを間違いなく転送するのに、うまく行かない時は、たかだか400バイト程度でも途中で転送が止まってしまう。

 原因がわからない。ファイル転送のあとのタイムアウトを5秒から10秒程度にすると少し改善されるが、それでも不安定である。ダブルバッファーのところは完全なのに、タイムアウトのリセットまわりは良い加減なロジックで組み立てたのでボロボロだ。

変数の宣言ミス。やっとのことで安定してファイル転送がOKになった(2/5/2013)
 原因究明を続けた結果、どうみても転送終了を決めるカウンターが割り込みルーチンとメインルーチンの間で正しく受け渡されていないような気がしてきた。 UART受信の度に、このカウンターは0に戻されるのだが、これがどうも0に戻っていないようである。

 ファイル転送のタイムアウトは5秒後で、もしこのカウンターを0にしていないという仮説を取り入れると、これまで起きている様々なトラブルの症状はすべて説明することができる。問題のカウンターは、外部変数のlap_cntという変数である。メインのmain.cで定義し、uart2.cのUART関数で外部参照している。コンパイラーはエラーも警告も出していない。

 ソースリストを見ていて気が付いた。メインでの変数宣言は、int16_t lap_cnt; で、uart2.cの外部参照宣言は、extern uint16_t lap_cnt; だ(傍線 筆者)。あれ、タイプが違う。ふーむ。普通は、同じ名前をつけるとエラーになるか少なくとも警告が出るが、今回は何も出ていない。

しかし、コンパイラーによっては、こういう外部変数の参照解決には甘い(厳密にチェックしない)ことがある。特にこのRaisonanceのCコンパイラーは以前もヘッダーファイルまわりで散々な目にあっている。もしかしたら、これが悪さをしているのかもしれない。

 こんなことで直るとは思えないが、タイプを揃えてテストしてみた。何と、何と、これですべてが解決したのである。タイムアウトぎりぎりに、どんな大きなファイル転送をしても問題ない。40KBを超えるファイルも1バイトの誤りもなく転送に成功した。

 要するに、UART受信の度にカウンターをリセットしているはずが、やっていなかったために、5秒以内にファイル転送を終えなければ必ず何らかの不具合が起きていたのだ。

 わかってしまえば、何ともお粗末な話である。同じ変数だと思っていたが、考えてみれば、コンパイラーにとっては、タイプが違うので全然別の変数で、外部参照宣言では同一変数名はチェックしようがないのだろう。コンパイラーを疑って悪いことをした(でも警告ぐらい出してよね、と恨み節)。

 UARTでゴミが出るのは、ターミナルソフト、PCハード、USB-UART(TTL)アダプターのどこかにハードのフロー制御がされていて、UARTの受信を途中で止めると、残っていたデータがファイル転送を終えたコマンドプロンプトに現れて字化けをしていたものと思われる。当初はUARTが壊れているかと疑っていた。UARTさん、ごめんなさい。

 いやあ反省、反省である。擬似コーディングを念入りにしたダブルバッファーのところは、ピタリと動いて、そうでないやっつけで書いたところはバグの出まくりである。いい加減なカットアンドトライでロジックを作ると碌(ろく)なことはない。今度の開発では、つくづくこのことを痛感した。

GLCDドライバーをSTM8Sに移植する(2/7/2013)
 いつもの大騒ぎながら何とかファイル転送は成功した。これでフォントデータはいつでもPCからファイル転送で、コマンド一発でフラッシュに収容することが出来る。200KB以上のデータも問題なく入り、ファイル比較ソフトで検証しても一字もエラーは出ない。好調である。

 勢いに乗って、いよいよ次の工程、AVRで開発したグラフィックLCDのドライバーST7565.cのSTM8Sへの移植にとりかかる。変更しなければならないところは、2つ。ひとつは、SPIの原始関数と、もうひとつはフォントデータの取り出し方である。

SPIの部分は機械的な変更だが、フォントの部分は少し厄介だ。オリジナルは、.oファイルでプログラムフラッシュ上に展開されているので、すべてのキャラクターのフォントデータは一発でリニアに辿り付けるが、今度はそうはいかない。

 外付けフラッシュ上のデータは、今度のメモリ(M25P40)ではリニアで読み込めるとしても、文字キャラクターを読む度に、その都度フラッシュから読み出す手順が加わる。それに複数のフォントの対応でフォントデータの属性を換えるときに、いちいちフラッシュに読みに行くことは避けたい。

 久しぶりの本格的な、C言語の開発である。フォントの属性を決めるフォント構造体を定義して、ここに各フォントの属性(縦横のフォントサイズ、フォントデータの始点フラッシュアドレスなど)を入れる。

 あらかじめ、Open_Font()のような関数でフラッシュからフォントファイルのヘッダーを読み込み、このポインターを各グラフィック関数に渡すことにした。これで、いちいちヘッダーを読み直すオーバーヘッドがなくなる。構造体のポインターはChaNさんのFatFSで盛大に使われている。時々、そのソースをカンニングしながら、せっせとコーディングに励んだ。

Stm8

SPIの移植はすぐ済んだが、フォントデータが出てくるまで一苦労(2/11/2013)
 SPIの方はすでにフラッシュメモリで動いているので、移植はGLCDのSPIの原始関数をSTM8S用に換えるだけである。GLCDの操作に必要なI/Oピンも一緒に定義する。

 フォントデータのハンドリングを含めて、ソースコードがあらかた出来上がった。ハードウエアの準備はブレッドボード上のGLCDのジャンパーを、つなぎかえるだけだから簡単に終わった。さあ、テストである。これまで書いてきたコードが思ったように動くか。わくわくどきどきの瞬間である。

 GLCDは、最初は文字ではなくグラフィックの直線が出るかのテストをする。文字フォントは画面に出す前に、UARTのコンソールにフォントデータを表示するテストルーチンを組み込んで、こちらで確認する。いつもの逐次開発法である。

 電源を入れてUARTからコマンドを打つ。画面は全く反応なし。うーむ、残念。鉄則に従って、直したところを重点的に調べる。問題なさそうだ。面倒だが、再びロジアナのプローブをつなぎ直して波形を見る。あ、あ、追加したGLCDのI/Oピンで動いていないところがある。

  ロジアナの威力は絶大である。リセットとコマンド/データ切り替えのポートの定義を忘れていた。ピンだけ定義しても動くわけはない。あわてて修正。よーし、画面に変化が出た。ゴミだらけの画面だが動いたことには変わりはない。

 フォントデータの出力はもう少し手間がかかった。最初は、読んできたフォントサイズのXYの値がでたらめで表示が出来ない。バイナリが表示できるターミナルソフトで読むと、.oファイルは、実際のファイルの前に、余分なヘッダーをつけていることがわかった。しかも、長さが実際のデータより短い。

Photo

 .oファイルでなく、.fntファイルを使えばソフトの変更はしないですむことに気づいた。長さが違うのは、ファイル転送がバイナリーモードでないため0x20以下の制御コードが無視されていた。考えてみれば、検証のときは200KBが通ったと言っても全部テキストファイルだった。やれやれ。

GLCDにグラフィックは出たが文字が乱れる。ハードエラーだった(2/12/2013)

 画面に少しづつ画が出始めてきた。画面の汚れは、初期化のミスだった。フォントのハンドリングも細かい不具合がとれて文字らしくなってきた。しかし、読むたびにフォントデータがずれる。フラッシュメモリだけのときは、こんなに不正確ではなかった。

S_p2125683

 その日は画面の記念撮影をしただけで店仕舞いする。寝ながら色々原因を考える。GLCDとSPIを共用してからのエラーだ。原因はハードくさい。はっと気づいたことがある。フラッシュメモリには、電源にパスコン(0.1μF)を入れていない。これだ。

 次の日、久しぶりにハンダごてに火を入れて、フラッシュメモリ(M25P40)にコンデンサーをハンダ付けする。さあ、どうだ。おおお、良いぞ。フォントが正しく表示される。うーむ、まだ、たまにキャラクターがずれる(その後、ブレッドボードの接触不良がわかり、ほぼ完全になった)。

 フォントが少し乱れるが、何とかSTM8SでGLCDに文字フォントを出すことには成功したようだ。達成感で胸がふくらむ。SPIにプルアップ抵抗を追加すれば、もっと正確になるかもしれない。とりあえず、このあたりで一段落することにする。ソースと回路図を公開することにしよう。

 ただ、ソースコードは、まだ開発途上の半かけで、回路図もブレッドボードを使った、あくまでも暫定的な回路図であることをお断りしておく。STM8Sの公開ソースが少なそうなので、とりあえず少しでもお役にたてたらという気持ちである。

Glcd_stm8s

 使用SRAMは、1800バイトでほぼ満杯だが(ファイル転送ルーチンを別にすればもっと下がる)、フラッシュは17KBとまだ半分しか消費していないのでアプリケーションには余裕がある。

  これからSTM8Sで開発される方の参考までに、所長がこれまでに、このRaisonanceのCコンパイラーとリンカーで遭遇した注意点(不具合の可能性もあり)をまとめておく(前回の分も含む)。

  • ヘッダーファイルを使った関数のプロトタイプ宣言で、エラーが出たり警告が出て別ファイルにした関数の引数渡しがおかしくなることがある(原因不明。当該関数をひとつのファイルにまとめて回避)。警告は同一ソースを変更せず2回コンパイルすると、なくなってしまうので注意。
  • 外部変数と外部参照宣言はタイプが違うと同じ名前にしても警告にもエラーにならない。当然別の変数として取り扱われるので大はまりとなる。これはもしかして他のコンパイラーもそうかもしれないが、重複名の定義は確かリンカーで警告を出してくれたような。
  • dataという変数名は予約語である。SRAM上に定義する変数の識別子のひとつだそうだ。エラーの説明が実態と全く違うので最初は気づかずにはまった。
  • memcpyなどの標準関数が、<string.h>などとしても正常に組み込まれていない。エラーにもならない。最初GLCDの画面が汚れていたのはこれが原因(自前でクリアする手順をつけて回避)。

 以下にSTVD(STMicro Visual Develop)のプロジェクトフォルダーを固めたものを置きます。ライブラリのリンクは、ご自分の環境に合わせて必要なファイルをプロジェクトに入れてください。(STM8S_StdPeriph_Lib_V2.1.0を使っています) STVDの環境で、glcd.stwを開けば一式が読み込まれます。Buildは最初からやってください。

「JCG12864.zip」をダウンロード

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

2013年2月 1日 (金)

STM8Sにフォントデータを入れる外部フラッシュメモリをつける

 販促基板のUSBローダー部ばかりが注目されて本体は不遇な8ビットマイコンSTM8Sに同情して始めたプロジェクトは、次はこれに外部メモリをつけてSPIで動かそうというところまで進んだ。

 前回の記事では、モノクログラフィックLCD(以降GLCD)をAVRで動かしたが、本来はこのSTM8Sで動かすためのものである。今度の外部メモリをつけるというのも、風が吹けば桶屋が儲かるという諺に近い話で少し説明がいる。

 GLCDに文字を出したいが、STM8SはGNUコンパイラーがないのでフォントファイルをフラッシュに埋め込めない。それなら外部メモリにフォントデータを入れればよい。どうせなら、いっそのこと日本語まで出ると面白いだろう、という脱線に近いプロジェクト進行である。

 しかけはSTM8SのSPIインターフェースに外部メモリをつなぐだけである。コーディング例は、例の平坂氏のSTM8SサイトにSDカード(SPI接続)を直か読みするサンプルソースにある。簡単に動くだろうと気楽に始めた。

  ところがこれがはまったのである。このブログは、ときどき「波乱万丈」と褒めていただくが、今回も、実はここに書くのも恥ずかしい思い違いをいくつかやって、見方によってはドラマチックな展開になってしまった。

 はたから見れば、何でまた、こんなくだらないことに血道をあげるのだろうと思われることばかりだが、負けず嫌いの当人にとっては、大げさに言えば自分の存在を賭けるくらいの入れ込みようになる。うまくいかないときは、率直に言って人生が暗い。生きていることがつらくて、来し方行く末をあれこれ考えるくらい落ち込む。

S_p1315669 しかし、問題が解決したとなると、暗い気持ちが一挙に吹き飛んで、まるで天下をとったような気分になる。山の頂上を極めたり、マラソンを完走したときと同じような快感だ。こういう快楽のときに分泌されるというドーパミン中毒に間違いなくかかっている。

M25P40という4メガビットメモリーをSTM8S-discovery基板につける(1/21/2013)
  このM25P40という8ピン外付けメモリーは、以前LatticeのFPGA XP2に載せるつもりで買ってあったが、XP2本体のメモリで用が足りたので使わずに置いてあったものである。SPIインターフェースで、サイズは512KBもあるから、12ドットの日本語フォントファイル(240KB)でも余裕で入る。書き込みは遅いが、読み出し速度は速い(この石は25Mbit)。

 ただ、SPIはGLCDで使う予定だ。SPIはCS(チップセレクト)で複数のディバイスを一本のSPIでつなげるとはいえ、プログラムは複雑になる。最初は、独立したI2CのEEPROMにするつもりだった。しかしI2C EEPROMの手持ちは最大が1Mビットで128KBしか入らない。それに速度がせいぜい1Mbitなのでちょっとかったるい。

 少し迷ったが、結局、M25P40を外付けメモリに使うことにした。STM8S-Discoveryの試作スペースにM25P40を実装することにした。久しぶりの基板の半田付けである。STM8S-Discoveryには、基板の一部にユニバーサル基板的な蛇の目パターンがあって、真ん中には表面実装の8ピンPSOCパターンまで用意されている。

 最初、このパターンに吸い寄せられるように、嬉々として、M25P40(PSOC 8ピン)をパターンにハンダ付けして、はたと気づいた。M25P40へのデータ移動は、SDカードをつけたマシンを経由しようと考えている。ソケットで着脱できるようにしておかねばならない。お馬鹿な話である。

S_p1305662 例の低温ハンダ(ストロベリーリナックスの低温ハンダが安い。¥1575)で取り外し、DIP用の変換基板(秋月の8ピン用¥11)に載せ換える。このM25P40の1番ピンがわかりにくい。データシートにはチップの文字が表記されていないが、正順に置かれているとして左下を1番としたが不安である。電源とグランドが、たすきがけの配置なので間違えれば一発でお陀仏になる。

 ソケットをつけたあと、UEW線で本体との配線をすませる。SPIなので3本をつなぐだけだ。電源とグランドを合わせて5本のハンダ付けである。ハードの準備はあっけなく終わった。さあ、次はソフト開発である。

STM8SのSPIはSDカードアクセスのサンプルソースを利用する(1/23/2013)
 平坂氏のサイトのSDカードのプログラムは、STマイクロ社のSDカードのサンプルコードが大元になっているようだ。 SDカードのアクセスは、ChaNさんのFatFSを移植する予定なので、SPIをドライブする基本関数部分だけを利用させて貰う。

 同時にM25P40のデータシートを読んでアクセス手順を勉強する。EEPROMは、STM32で気圧計に実装したり、AVRでも使っているので理解が早い。読み込みはページ区切り(256バイト)を無視して連続して読めるようだ。ただし、書き込みは、どこからでも書き込めるが、256バイトのページ単位で折り返される。

S_p1305656

 読み出しを止めるのは、チップセレクトだ。書き込みは送信をやめるだけで止まる。擬似コーディングを始めて、ドライバーの構成がかたまってきた。いつものように、ソースコードは3階層に分ける。

 最初のSPIのところは、GLCDと共用になることを意識して変数名を考える。ここでやることは、SPIの初期化と、1バイトの送受信関数だけである。2段目は、EEPROMのアクセスルーチンで、データ書き込み/読み込みシーケンスの基本(共通)部分をここで作る。3段目がアプリケーションレベルで、ここが実際のデータの書き込み/読み込み関数となる。

 当初、フォントデータの書き込みは、SDカードを持った別のマイコンに、このEEPROMをつないで、そこからオブジェクトファイルをEEPROMに流すつもりだった。そのために、STM8Sの基板に最初ハンダ付けでつけたEEPROMをわざわざ剥がして、ソケット付きにとりかえている。

 しかし、開発を進めていくうち、STM8SのUARTでファイル転送を使えば、そんな手間は要らないことに気づいた。データはバイナリーデータだし、送受信とも1バイトも取りこぼしが許されないので、UARTにはダブルバッファーを設定するなど、少し難しいロジックになるが、これはこれで挑戦しがいのあるプログラムだ。楽しみになってきた。

RaisonanceのCコンパイラーのエラーメッセージに惑わされる(1/25/2013)
  ソースコードはそれほど苦労せずに出来たのだが、わけのわからないコンパイルエラーが連続して、なかなか先に進まない。このRaisonanceのCコンパイラーは、無償だからあまり文句は言えないが、このコンパイラーのエラーメッセージが奇怪で、その対応に一日つぶれてしまった。

 何でもない関数のところで、わけのわからないコンパイルエラーが出る。しかも容易に解決しない。キャストが裸になっているのを括弧で閉じたり、ifの中の演算の括弧を増やしたりするといつのまにか直ってしまう。だいたいエラーメッセージが、実体を反映していない。

 エラーの大元は、
 void M25_Write_Page( uint32_t adr, uint8_t *buf, uint16_t leng)
という、adrで示されるEEPROMアドレスに、lengの長さの、bufにあるデータを書き込む関数である。全く同じ形式のM25_Read_Str(略)は、エラーにならないのに、こいつだけが通らない。全く不審である。

 しかも、出てくるエラーコードが Invalid parameter declarationになったり、syntax errorだったり不定で、funcdef requires ANSI-parameter listというわけのわからないものや、なかには、警告だが、'?' decleared. but not used.などという全く身に覚えのないメッセージが出たりする。

 そのうえ、プロトタイプ宣言をヘッダーファイルですると Invalid parameter declarationというエラーになるのに、プロトタイプ宣言をソースに持ち込むとエラーでなくなる(警告)。全くもって何のことかさっぱり見当が付かない。

 ソースをだましだまし調整して、コンパイルはやっとNO ERRORになった。大したステップ数でもないのに、およそ一日かかってしまった。先が思いやられる。

コンパイラーのご機嫌が悪い。いんちきな引数渡しをしている(1/26/2013)
 コンパイルが通った(少し警告が残るが)ので、いよいよテストに入る。テストのやり方は、UARTモニターから文字列を適当なEEPROMアドレスに送り込み、それを読み出しコマンドでUARTにデータを戻して確かめる方法である。いつもの定番のテスト方法である。

 ただ、この方法では、うまく動かなかったときのデバッグは不可能である。送信が悪いのか、受信がまずいのか、それともEEPROMがおかしいのかを簡単に特定することが出来ないからである。心配なので、最初からロジックアナライザーをプローブさせて送受信の様子をみながらテストすることとした。

S_p1305655 テストを始める。懸念したとおりいきなりハングするだけで全く動かない。ロジアナで見ると送信から動いていないことがわかる。やれやれ。今度は、UARTの出力関数を入れて最初からチェックして行く。いわゆるprintfデバッグである。あれえ、SPIの送信関数の引数がでたらめな数字になっている。なぜだ。

 関数を呼ぶ前と、関数内の引数の値が明らかに違うことを確認した。どうも警告を無視してコンパイルした結果がまずいようだ。プロトタイプ宣言をヘッダーファイルに定義すると、エラーになって、main.cに持ち込むと警告になった例の関数である。

 正しく引数が渡されていないのは明らかだ。同じような引数構成の他の関数は通っているのに、こいつだけがおかしくなる。コンパイラーの不具合の疑いが濃厚だけど、こればかりに時間をかけているわけにはいかない。

 対症療法を考える。ヘッダーファイルがらみでエラーが起きているようなので、この関数をmain.cの中に入れてしまって、1ファイルとしてコンパイルしてみた。なんだ。警告もなくなった。やっぱり関数の表記が悪いのではなかった。

 テストしてみる。うむ、パラメーターは正しく関数に送られている。ロジアナの波形も、とりあえずもっともらしい送信シーケンスになったようだ。しかし、まだ正しいデータは戻ってこない。

SPIのマスター受信って送信しないと動かないのね(1/27/2013)
 ロジアナで見る限り、正しい命令、正しいアドレスでEEPROMにデータを送っていることが確認された。しかし、受信をしても全くデータは受信できない。SPIに対する読み込み命令は正しくEEPROMに送信されている。しかしクロックパルスが出てこない。

 正しく送られているといっても、これは単にSTM8SからEEPROMに送ったというだけで、EEPROMがこれを正しく受け取ったかどうかの確認はできない。送信シーケンスのあとデータが書かれたことを確認するRead Status Registerという命令を送ってもStatus Registerが帰ってこない。もしかするとEEPROMを逆差して、壊してしまったのかもしれない。

 もういちどルーペを取り出して何度もチェックする。刻印はないが、印刷の方向はデータシートと同じで問題なさそうだ。電圧も正しくかかっている。調べるところがなくなった。状況は暗い。気分が落ち込む。しかし、こんなことくらいで引き下がるわけにはいかない。

 基本的なところから確認していくしかない。受信のとき、クロックパルスが出ないのはなぜだろうと考えていて最も基本的なことに気づいた。クロックパルスはスレーブ側のEEPROMが出すのではないのだ。あくまでもマスターのSTM8S側が出すものだ。うはあ、わかったぞ。このあいだサンプルソースの受信関数から不審な送信コマンドをコメントアウトしたことを思い出した。

 このサンプルソースは送信するときも、受信バッファーに入ったデータを受け取って呼んだルーチンに返している。てっきり全二重通信のために、受信のときも送信しているのだと思い、今度のような半二重通信には不要と考えて削除してしまっていた。

 そう言えば、これまで開発したSPIインターフェースはすべてマスター送信だけで、SPIのマスター受信というのはやったことがない。受信関数のサンプルソースに送信コマンドが入っているのは、受信クロックパルスを作るためだったのだ!何というお馬鹿な勘違い。

 I2Cのように、スレーブ側も何らかのパルスを出して交信しているのだとばっかり思っていた。SPIのスレーブというのは、クロックパルスを受けてデータを送ることしかやっていないのである。いやいや思い込みというのは恐ろしいものである。

 あわてて、受信関数にもダミーバイトを送信するコマンドを入れて、テストする。無事、ロジアナには受信パルスが復活した。ReadStatusRegsterコマンドのあとにもStatusRegisterのデータが出るようになった。

 しかし、受信したデータは意味のあるデータではなかった。StatusRegisterの値も、ロジアナではちゃんとしたデータがでているのに、受信関数を通した値は、全く違う値だ。書き込み完了が終わらず延々とループする。先はまだ遠い。

Ws000000 しかし、ロジアナのお陰で、全体の動きが完全に把握できている。もし、これがなかったらここでのデバッグは全くお手上げだっただろう。測定器の有難さをつくづく感じる。トラブルシューティングを続ける。

M25P40はEEPROMでなくフラッシュメモリーだった(1/29/2013)
 最後のオチが、ここに書くのもためらわれるお恥ずかしい思い込みだった。SPIの受信コマンドがまともに動いて、ロジアナで見る限り、受信シーケンスはちゃんと想定どおりのデータストリームとなった。しかし、送り込んだデータと似ても似つかぬデタラメなデータしか出てこない。

 データが送り込まれているらしいことは、受信するデータが少しづつ変化しているので、全く動いていないわけではなさそうだ。送ったデータより先のエリアは、0xFFで埋められているので、何らかのデータが書き込まれ、それを読んでいることは確かだ。

 ただ、データはでたらめである。もうデバッグすることがなくなった。解決を求めウェブをさ迷う。しかし検索するにも適当なキーワードが見つからないので有力な情報に行き当たらない。STM8Sのエラータ情報にSPIに関連するのが1件あるが、どうみてもそれとは関係ない。

 万策が尽きて、印刷したM25P40のデータシートを最初から少し丁寧に読み返し始めたときである。書き込みコマンドのところで妙な記述に目が止まった。

Page Program instruction allows bytes to be programmed in the memory(changing bits from 1 to 0).
 「ページ書き込み命令は、メモリのビットを1から0に変えてプログラムします。」

 なんで、わざわざ、1から0と断っているのだろう。ここで明かりが点った。あ、あ、あ、もしかして、このメモリーはこれまでのEEPROMと違って、フラッシュメモリーなのか。てっきりEEPROMだとばかり思っていたが、違うようだ。

 何のことはない。M25P40のデータシートにもちゃんとSerial Flash Memoryと書いてあり、EEPROMとは書いていない。大慌てで、改めてウェブで、EEPROM、フラッシュメモリ、NANDメモリ、NORメモリなどの外付けメモリの違いについて調べ直す(ここが詳しい)。

 大きな誤解をしていた。フラッシュメモリは、EEPROMといわれるメモリと違ってデータの書き込みでは、0から1には出来ないのだ。書き込むときは一旦、eraseで全体を0xFFにしてからでないと正しいデータにならない。

 そうか、だんだん書かれた内容が0になっていくのはそういうことだったのだ。間違いない。謎が解けた。あわてて、データシートのセクターイレーズ(Sector Erase)のコマンドを使って、メモリーを消去する手順を加える。

 テストする。はい、おめでとうございます。やっと思うようなデータが入り、それが出てきた。少し長い2バイトコードの漢字も入れてみる。問題なく日本語が戻ってきた。いやあ嬉しい。暗かった気分がすっかり晴れる。心が充実感で満たされる。周りを余裕を持って眺められるようになった。

Ws000001

 しかし、それにしても今度は長かったな。解決に少なくとも4日はかかっている。外付けメモリについて、いい加減な覚え方をしていてひどい目にあった。

 さあ、次は、UARTを使ったファイル転送だ。まだソースコードはデバッグのためのテストステートメントが山盛りになっており、機能的にはまだテストプログラムにすぎないが、とりあえずは一山を越した。ソースコードの公開は次のファイル転送を実現してからまとめてやることとしたい。今度はドジを踏まないぞ。

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

2012年12月 9日 (日)

STM8Sの開発環境を整備する

STマイクロ純正の開発環境に移行するのに苦労する(12/1/2012)
 販促基板のUSBローダーの部分だけが脚光を浴び、本体は見捨てられて不遇な境遇にあるSTM8Sプロセッサーに少しでも日を当ててやろうと、このところSTM8S-Discovery基板の開発環境を整備している。

 前回の記事ではフラッシュ32KBまで無償のRaisonanceのCコンパイラーと一緒にIDE(統合開発環境)であるRide7をインストールしたことをご報告した。しかし、どうもRide7だけではSTM8Sにプログラムを書き込めないようだ。プラグインのような形で別のプログラマーを組み込む必要がある。面倒なことになってきた。

 あらためて、いくつかのSTM8S関連のサイトを見渡す。みなさん素直にSTマイクロの純正の開発環境をインストールされている。こちらの開発環境はSTVDとSTVPという2つの系に分かれており、使いにくそうなので敬遠していたのだが、Ride7のプラグインを探すより、正規の環境でやる方が安全だ。あまりこだわるのはやめて、みんなの方法に従うことにした。

 ところがいざプログラムをダウンロードしようとしたら、開発用ソフトのzipファイルsttoolset.exeが見つからない。サイトの情報が古くなっていて所定のURLにはもうファイルがない。みなさんが使っているCosmicのCコンパイラーも無償提供が終わっている。考えてみれば、話題になってからもう3年近く経っているのだ。

 STマイクロのサイトは、STM32の頃、欲しいものが見つからないと散々悪態をついていたが、今度も大苦戦だ。色んなところを探し回って、やっと見つけた。実は、一番最近のこのサイトにはちゃんとダウンロードの仕方が書いてあったのだが見落としていた。

 サイトのネストが深いのである。いくつかリンクしてSTVDの紹介ページに辿りつくのだが、ここでも更にDesign Supportのタグを押さないとリンクが出てこないようになっていた。やれやれ慌て者だから、こういうミスが多い。

 さらに混乱したのは、必要なファームウエアライブラリの名前が参考にしていたな主なサイト(さっきの平坂氏のサイトとここ)で変わっていて、最初は2つあるのかと勘違いしていた。旧の名前は、_fwlibで、新は_StdPeriph_Libになっており中身は同じである。

 こういう開発環境の整備は、余り好きではない(人の言う通りに素直に動くのが嫌い)。しかし、ここを通らなければ何も進まないので仕方がない。AVRにしておけば何も苦労することはないのだが、乗りかかった船だ。降りるわけには行かない。黙々とディレクトリチェーンを作る。

Ws000000 STVD(ST Visual Develop)は、AVRStudioと開発したところが同じと見えて外観が似ており、アイコンなどは全く同じなのが面白い。ファームウエアライブラリを少し見てみる。8ビットマシンだけれど、生意気に結構、大層なライブラリー構成だ。

 ほどなく、最初のサイトから頂いたLEDチカチカプログラムは一つのエラーをコメント化して(full_assertのチェックルーチンのエラー、stm8s_conf.sで#define USE_FULL_ASSERTをコメントにしてソースから削除。とりあえず不必要)無事に稼動した。

 STM8S-Discoveryのボードは、デモ用にタッチパッドでLEDを制御するプログラムが元々焼かれている。開発環境のテストを兼ねて、このプログラムへの復元をやってみた。これは、もっと楽だった。落としてきたUM0834アプリケーションノートをそっくりプロジェクトにしてコンパイルし直したら、そのまま簡単に動いた。

 さて、とりあえず、STM8Sは動いたようだ。次はUARTに行こう。

UARTを作り替えようとしてはまる(12/3/2012)
 UARTはこうした組み込み系の開発にはモニター機能として欠かせない機能で、当研究所ではどんなチップでも、まずこれを動かすことを開発の基本にしている。UARTを使わないアプリケーションでも、フラッシュがある限り必ずつけて、本番のときとりはずす(メモリがあればデバッグ用に残す)。

 STM8Sでも当然のように、UARTの組み込みを始めた。LEDチカチカのソースを頂いたサイトにはもちろんUARTのサンプルソースもある。ありがたく参考にさせてもらう。ソースコードをコピー&ペーストで簡単に取り込んだ。割り込みを使った本格的なUARTだ。

S_pc095488 ハードは定番の秋月のUSB-UARTモジュールを使ってPCとつなぐ。モジュールはブレッドボードに差し、ジャンパーで接続する。ハードの準備はあっという間である。早速テストする。苦もなく動いた。

 次にやることは、このUARTプログラムを、PCからUARTを経由してコマンドを受け入れ、色々なことをさせるモニターに仕立てることである。デバッグの強力なツールになる。ソースを本格的に読み始めた。

 ふーむ、このUARTのソースは、割り込みルーチンに、殆どのアプリケーション処理が入っている。どうも馴染めない。まあ、この程度の規模のソースでは目くじらたてることでもないし、参考にさせて貰ってこういうことを言うのも少し気が引けるが、普通はこういう書き方はしない。

 速度の速くない、メモリの少ない組み込み系プログラムでは、割り込みルーチンはなるべく身軽にしておき、メインルーチンに処理を集めるのが鉄則である。そういう習慣をつけておくとあとあとの開発が楽になる。

 なぜ、割り込みルーチンに処理を入れてはいけないかと言うと、普通、割り込み中は別の割り込みを禁止しているので、余り長い間ひとつの割り込みルーチンに居ると、別の割り込みを待たせることになり、同時性が失われたり、動作がおかしくなる可能性がある(多重割り込みは処理がはるかに複雑になるので余程の時以外は使わない)。

 さらに、割り込みとは現在の処理を強引に中断して別の処理を始めることなので、そのときのレジスターを全てどこかに保存してから、帰るときに元へ戻す余分なコードを必要とする。割り込みルーチンにはなるべく処理(たくさんのレジスターを使う処理)を入れないほうが良い。

 フラッシュの少ないマイコンではプログラムが(無駄に)大きくなるだけでなく、C言語を使うと、このレジスターのsave/restoreだけで(無駄な)数十ステップを使い、このオーバーヘッドは無視できない性能の低下をきたす。

 それならどうするかと言うと、一番簡便な方法は、割り込みルーチンにはフラグを立てるだけの処理などにしてなるべく身軽に作る。そしてメインルーチンのループで、このフラグをキーに割り込みでやりたかった処理を行う。こうすることで様々なメリットが生まれる。

 まず、フラグを立てるだけなので、セイブすべきレジスターを最小限にでき、オーバーヘッドを減らせる(Cコンパイラーの最適化も効く)。さらに、フラグをテストする順番を工夫(短いウェイトやsleepを入れるなど)すれば、メインルーチンで複数の割り込みの優先順位をつけることも出来る。別々の割り込みルーチンだとこういう芸当はできない。

 それにメインルーチンの中にアプリケーションがすべて入ってくるので、何をやっているのか一望できるメリットも大きい。ソースコードの一覧性というのは、みんなが思っているより重要な要素で、メンテナンスしやすいプログラムの大きな条件のひとつである。

 もちろん、良いことばかりではない。フラグでメインに処理を持ち込む方法は、時間にシビアな処理(いわゆるリアルタイム処理)には使えない。音声のデコードや、周波数の測定などに、これを使うことは無意味である。また、メインの中での処理は結局は順序処理になるので厳密な同時処理は難しい。OSを使った多重割り込み機能が必要になってくる。

 てな、うんちくを垂れながら、鼻歌まじりでソースコードを入れ替えた。ついでにUARTからのコマンドで、タイマーを使ったLEDの点滅の入り切りが出来るようにする。STM8Sのペリフェラルライブラリーの書式は、STM32にそっくりなので進行が早い。タイマーや、GPIOの制御も簡単に書けた。

 テストする。これが動かないのである。送信は問題ない(変えてないのだから当然だ)が、UARTの受信が出来ない。STVDは、単にプログラムを走らせることは出来なくて、必ずデバッガーを経由するのだが、このステップ実行では、受信割り込みルーチンを抜けてメインに来てもフラグが立っておらず、受信データがないことになっている。

 サンプルソースにある割り込みルーチンの書式が良くわからない。このあたりはコンパイラーの独自仕様なので、Raisonanceのコンパイラー仕様をネットで探すが見つからない。この割り込みは何を契機に起きているのか資料が見つからないのである。

 オリジナルのソースコードを見ると割り込みルーチンに来てから、さらにUARTのレジスターの受信フラグを調べている。それなら、この割り込みは何なのだ。他の割り込みというのはあるのか。ここは受信割り込みだけのルーチンのはずだが。

またお粗末な勘違いだった。UART動く(12/5/2012)
 少しづつステートメントをメイン側から割り込み側に戻して様子を見る。デバッガーにもう少し慣れれば、もっと楽に原因究明ができるのだろうが、こういうタイムディペンダント(UARTのキー入力)な処理のデバッグは容易ではない。

Ws000001  UARTの受信関数を割り込みルーチンに入れれば、動くことは確認できた。とりあえず受信だけさせておいて、フラグを立てて受信バッファーをメインで処理すれば、正常に動く。コマンドも受け付ける。しかし、何かやっていることが重複している感じで美しくない。

 フラグだけにすると、全く動かなくなる。フラグが換わらなくなる。おかしい。色々なところにテスト出力をUARTにさせて原因を探る。一文字出力関数で'*'を割り込み関数の頭に入れてみる。おおー、画面一杯に*が埋め尽くされる。ふーむ、受信割り込み以外にも、何か割り込みが起きているのか。

 一文字出力を、受信割り込みを特定してからのプロセスにも入れてみる。ありゃりゃー、変わらない、同じように画面が*で一杯になった。わかった、わかったぞー、このSTM8Sの割り込みルーチンは、割り込みフラグは明示的にクリアしないと、割り込みルーチンに飛んできただけでは解除されないのだ。

 このままでは、割り込みから抜ける度に、また割り込みが入って延々とループを続ける。割り込みルーチンの中で、データ受信をすれば、このとき割り込みフラグがクリアされるので問題ない。全くの基本的なミスだ。情けない。

 デバッガーではわからなかった。本来なら割り込みルーチンにへばりつくべきだが、実際には、メインルーチンの一定の場所(割り込みが起きたところ)に止まったままだった。まあ、これもデバッガーの指定で換えられるのかもしれないので、使えないと結論するのは早いかもしれない。

 AVRのUART受信割り込みは、割り込みルーチンに来た時に自動的に割り込みフラグはクリアされるので他のマイコンもそうだとばかり思っていた。STM8Sのデータシートには、「受信割り込みフラグは明示的にクリアするか、受信データレジスターをアクセスするとクリアされる」とちゃんと書いてあった。はい、はい、悪いのは私でした。

 原因がわかれば、対処は簡単だ。割り込みルーチンで、受信割り込みなら受信割り込みフラグをクリアするステートメントUART2_ClearFlag(UART2_FLAG_RXNE); を追加するだけである。

 これで割り込みをフラグだけにしたUARTプログラムは、無事、正常に動作した。これは今後のプロジェクトでモニタープログラムとして活躍してくれるコアプログラムである。

 こちらにソースコードの中身の参考のため、このUARTモニタープログラムのmain.cを置きます。ただし、これだけではライブラリをincludeしていないのでコンパイルエラーになります。リンクしたサイトを参考にライブラリを所定のディレクトリに配置してビルドしてください。

「main.c」をダウンロード

 余裕が出来たので、STマイクロの開発環境のもう一つの系STVP(ST Visual Programmer)を試してみる。これは、単なるSTLinkを介した独立のプログラムローダーだ。STVDにもプログラミング環境があるのだが、立ち上がりが遅い上、やたらとハングする。STVPの方が少し早そうだ。

焦電型人感センサーの修理に成功。基本的な間違いだった(12/7/2012)
 階段の照明制御に使っている人感センサーの誤動作がまた目立ってきた。人も居ないのに頻繁に作動し、役に立たない。修理しようと電源を切って工作机に置いていたら、家族から「あら、もう壊れたの」と言われてしまった。

S_pc065478 へー、頼りにしていたんだ(階段の照明は別にあるのだが、便利なようだ)。今までに何も言われなかったが、こういう反応は予想外である。ちょっと嬉しい。でも復旧へのプレッシャーは強くなったように思う。早く直さなきゃ。

 STM8Sが予想外に早く進展したので、ちょっとお休みし、こちらの方の修理に入る。症状は、オペアンプの無入力の時の電圧がマイコンの入力ピンの閾値に近いので、オペアンプのドリフトで感知してしまうというものである。

 以前も同様な状態になり、入力ピンにプルアップ抵抗をつけて電圧を閾値以上に引き上げた経緯がある。ケースをはずして抵抗値を確かめると22KΩだった。これを半分の10KΩにしてみる。心配したとおり、今度はセンサーが反応した(->0V)ときでも2V以下に下がらず、失敗である。

 そのうち見るともなしに配線図を見ていて、2段目のオペアンプの入力の一方が、同じ抵抗2本でVccの半分の電圧であることに気づいた。あーっ、わかったぞ。センサーがドリフトしているのではない。このオペアンプは交流増幅なのだ。2.5Vの中位電圧にしてセンサーの出力を上下に振っているだけなのだ。

 完全に勘違いをしていた。この部分は、秋月の回路のアナログコンパレーターの部分をマイコンにしたところで、HighのVccが無入力、Lowの0Vがセンサー感知というTTL出力だとばかり頭から信じ込んでいた。2.5Vになるのはドリフトではなくもともとの仕様だったのである。

S_pc065475 理屈がわかれば解決法は早い。この中位電圧をマイコンの閾値に近い2.5Vより、もう少し高い3V近辺にしておけばオペアンプのドリフトくらいで反応することはない。人が近づいた時の反応は、0VからVccまで派手に振れるので中位電圧は高い方が安定する。

 制御部からプルアップ抵抗を外し、焦電センサーのオペアンプの分圧抵抗を、4.7k×4.7kの組み合わせから、2.7k×3.9kに換えた。オシロで確かめる。オペアンプの定常出力は、3.1Vになった。これにより焦電センサーは完全に安定した。このあいだの電源のふらつきによるディップも、こうしておけば何の問題もなかったのだ。

 ついでに、センサー基板の固定部分の一部を改善する。何回か前のブログ記事で、基板をアクリルケースに固定する簡便な方法をみなさんにお聞きしたところ、何人かの方がコメントでアイデアを提供してくださった。

 このうち、そら。さんから頂いたアイデアを実行する。やることは非常に簡単で、切片つまりストッパーをアクリル板に固定してしまう方法である。とりはずしは、ケースの剛性で行う。

S_pc065477 ケースは2つに分かれており、組みあがっているときはたわみが少ないので、この方法はとれないが、アクリルは剛性に富んでいるので、パーツに分解した時は楽にミゾに基板は入り込む。実にコロンブスの卵的解決である。

 切片に接着剤をつけ、完全に乾くのを待つ(慌てて付けてとれなくなると悲劇)。基板をはめてみる。問題なく入った。いやあ、あれこれ迷って、ガイドを切って切片を削ったり、色々苦労したことがうそのような解決だ。そら。さん、ありがとう。

 いくつもの課題が一気に解決して、すこぶる気分が良い。記事の量は少ないが気分の良いうちにブログに報告しておこう。

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

2012年11月29日 (木)

次のテーマが見つからない。細かい工作を続けている

 親戚の不幸で関西に帰ったり、珍しくこの時期に仕事が立て込んだりして、まとまった時間が電子工作にかけられない。このところ夢中になれるような大きなテーマが見つかっていないこともある。ペンライトの制作記事以来もう20日以上経つが書くことが少ない。

 考えてみれば電子工作という趣味を始めて、まもなくちょうど5年になる。見回してみると、周囲には自作の工作品が溢れている。ひとつひとつは滅多に故障しないが何しろ数が多い。このお世話だけでも結構やることがある。

 PCの横には、FPGAを使ったデジタルフォトフレームが納まり、階段の下には人感センサーと気圧計、それにLANによるプリンター電源制御ユニットが常時動いている。後ろを振り返ると、本棚には腕時計のぜんまい自動巻き機、2台のLPCMプレーヤーにLM380革命アンプ、ガイガーカウンター(1台はとうとう友人に無期限貸与した)、あれからバラックのままになっているXbeeラジコン車など。

 洗面所に行けば、このあいだのLEDペンライト、工作室の棚のガラスケースには、使っていない温度ロガーやXbee電力ロガー、メトロノームの時間間隔を測定するリズムキャプチャー、自作CPU基板や小物まで含めると、もうその数は、数え切れない。

 当研究所のモットーは「実用品」を作ることだから、工作品が身の回りに溢れるのは当然と言えば当然だ。新しいテーマが見つからないと言うのも、身の回りで欲しいというものをあらかた作ってしまったということがあるのかもしれない。

S_pb295473

グラフィック気圧計が時々ハングする(11/4/2012)
 このあいだは、ガイガーカウンターを修理したが、今度は、常時稼動させている気圧センサーMPL115A2を使ったグラフィック気圧計が、時々止まるようになった。電源を入れなおせば何事もなく起動するが、また2日くらいで止まる。1週間動く時もあるが、半日で止まる時もある。

 RTCは動いているので、電源を入れなおせば正しい時刻が出る。何らかの原因でCPUがハングしているようだ。何が原因か、EEPROMにトレースデータを入れて、どこでハングするか調べようと、少し本気になり、基板をいじっているうちに直ってしまった(また再発したが)。

 状況から見ると、TFT液晶のコネクターの接触不良が可能性として一番高い。コードの中でイベントが終わるのを待つプロセスは考えてみたら、ディスプレイドライバー以外にはない。

 そういえば、このコネクターは開発初期に、接触不良に悩まされ、主なピンにハンダを薄く盛って問題解決したことを思い出した。そうか、そこがまた酸化したのだろう。まあ、これも気象データを記録しているわけでもない。いずれ、接点を磨くか、もう一度ハンダを盛ってやろう。

 この気圧計は、予報ロジックが未実装で、O-Familyさんからはケースに入れるよう勧められているが、今ひとつ気力が湧かずそのままになっている。気圧の推移をグラフで見ているだけで結構予報できるので実用性は十分ある。それより文字をもう少し大きくしたいのだが、これをやるのはまた大変でそう簡単にはいかない。

GPSレシーバーのUART電圧改善(11/5/2012)
先日、受信に成功したGPSレシーバーPA6Cである。回路図をみているうち、USBブリッジCP2102のTTL-UART部分は5V出力であることに気づいた。GPSレシーバーのVccは3.3Vである。これはまずいのではないか。

 あわてて測定してみる。USBブリッジからのUART TXはやはり5V近かった。これは危ない、早く手当てせねば。あわててネットで対策法を調べる。レベルシフターのICを使うほどのこともない。みんなどうしているのだろう。

 典型的な、3.3->5V、5V->3.3Vの電圧変換なら、時々掲示板でおみかけするgomisaiさんのネガティブログが詳しい。いつも参考にさせてもらっている。今度も早速、このサイトを訪れて回路を検討した。

 このなかから一番、簡便な方法、抵抗一本で下げる方法を選ぶ。USBのTXに10KΩをはさむだけ。分圧もしない。内部抵抗的にこれだけで良いような感じだ。念のためオシロで送受信波形を確認する。

 よーし、PA6CのRX(USB側のTX)は3Vに下がった。ちゃんとPCのユーティリティから送信信号を受信してPA6Cは反応している。壊れていなかったようだ。ほっと胸をなでおろす。

 GPSロガーを作らなければならないが、GPSレシーバーが具体的に何をやっているのかまだ何も知らない。泥縄に近いがGPSレシーバーそのものの仕様を勉強し始める。レシーバーが出すNMEAフォーマットもまだ何もわかっていない。レシーバーそのものにはログデータを蓄積する機能はないはずだ。

 やっぱりそうだ。ログデータは必ず外に溜めなければならない。他の人はどうしているのだろう。ChaNさんのはマイクロSDカードに蓄積し、ログをPCに取り込むときは、マイクロSDカードを取り出しているようだ。こいつはとても小さくて、制作心を刺激する。CPUはAVRだ。

 一方、ねむいさんのは、STM32Primer2のケースを応用して内蔵のSDカードに蓄積し、USBのマスストレージクラスを動かして、PCにデータを渡している。あのマイクロSDカードは余りにも小さくて取り扱いが面倒なので、こちらの方が魅力的だが形は大きくなってしまう。

 折角作るのだから、何か新機軸を出したいものだ。このあたり、あれこれ妄想するのが電子工作の醍醐味のひとつでもある。ただ、具体的にこれを使うシーンが想像できない。まあ、最初はビル街に持ち込んで、準天頂の効果を確認することだけど。

すごいソフト発見。JAXA製のGPS衛星の周回シミュレーション(11/6/2012)
 あまりにもGPSに不勉強なので、少し基本から勉強した。衛星からの電波の周波数は1.2GHz帯のUHFである(3GHzから上のsバンドも使っているがこれは衛星テレメトリー用)。今、地球には70個近いGPS衛星が廻っていて、日本の上空にも常時6個程度の衛星が周回してくる。これらの電波を複数受けることで測地点の正確な緯度、経度、高度を測定する。

 沢山あっても衛星が上空の角度の低いところにあると、市街地や、森林地帯では見えなくなるので、測定精度が下がる。この難点を克服するのが、「準」天頂衛星という衛星だ。QZSSというのが略称である。日本ではJAXAが、2年前に打ち上げ、「みちびき」という名前がつけられて去年からテスト運用が始まっている。

「準」がついているのは、通信衛星や放送衛星で御馴染みの静止衛星と違って、上空の同じ場所に止まっていないからだ。上空に止まるために、静止衛星は地球の自転と同期する軌道、つまり赤道面に軌道がある。日本は赤道から35度ほど北にあるので、静止衛星を天頂に持って来ることはできない。日本の放送衛星のパラボラの角度が、かなり低いのはそのせいである。

 しかし、衛星軌道の角度と、高度を工夫すると、みかけの衛星軌道が、長い間天の高いところにあるようにすることが出来る。これが「準」天頂衛星だ。

 常に天頂付近にいるのだと最初思っていたが、このあいだブログに上げた衛星図には、「みちびき」がいなかった(193が識別番号)。どうしてだろうと調べ始めて、その面白さに引き込まれる。地球の自転と衛星の軌道をうまく調整している。

 日本では、夜中の0時ごろから、4時ごろまで一旦南の空に隠れるが、朝の5時ごろから23時ごろまで渦を巻いて天頂付近に存在する。見掛けの軌道は8の字型で上の丸の部分が天頂を囲むように周回する。見事なものである。

 以上の動きは、JAXAのサイトで、任意の日本の地点の上空のGPS衛星のシミュレーションをしてくれるPCソフトでわかったことだ。JAXAのサイトにある準天頂衛星の周回軌道の絵は何度見ても良くわからなかったが、このソフトで良く理解できた。

 このソフトQZ_Radarはすごい。観測点の緯度と経度と時刻を入力すると、その地点のすべてのGPS衛星の位置を正確に表示してくれる。時間間隔を指定して、その間の動きを画面上でシミュレーションできるようにもなっている。素晴らしい。

Ws000001 しかも、このソフトは無料である。JAXAだから税金で作られているのだろう。納税者として始めて得をしたような気分になった(確定申告用のソフトは腹が立つことばかりだったけれど)。ただし、JAXAのサイトから、このソフトをダウンロードするのは極めて難しい。

Ws000000  まずJAXAのホームページは、情報が余りにも多すぎて「みちびき」すら見つからない。「JAXA みちびき」のキーワードで、やっと「みちびき」のサイトに辿り付けるが、ここにはダウンロードのリンクはない。画面右上の「みちびきデータ公開サイトQZ_Vision」をクリックし、さらに出てくる、劇画風のポップなバナーの「USE」をクリックして始めてQZレーダーなるPCソフトのダウンロードのリンクが現れる。

Ws000002  「USE」のところのキャッチフレーズが、「使うみちびき! QZSS+GPSデータダウンロード」
では、事情を知っていなければとても辿りつけない。プロモーションとしては、「PLAY」のQZ_Visionみちびき3Dの方が金がかかってそうで、こちらを強調したかったのだろうけれど勿体ない話だ。

準天頂衛星の勉強をするうち宇宙の凄さに感動(11/8/2012)
 色々勉強するうちに、地球や月、人工衛星の実際の位置関係を正確に知りたくなり(昔、本で読んだがうろ覚え)、調べてみた。もう半世紀近くも前の子供のころ、夢中になって読んだ宇宙旅行の本の復習である。

 地球の大きさを直径1.2センチ(パチンコ球くらい)とすると、月は正露丸(3.5ミリ)くらいの小ささで、月は地球の周りの38センチの軌道を周っている。人工衛星の軌道は、静止衛星がいくら離れていると言っても、1.2センチのパチンコだまの外周3.5センチのところにへばりついているだけで、宇宙といってもほんの入り口にすぎない。太陽の大きさはこの縮尺だと、直径1.39メートルの球(運動会の大玉ころがしくらいか)の大きさである。このあたりまでならまだ驚かない。

 しかし、ここからが驚くのが、地球と太陽の距離だ。何と149.5メートルもある。郊外電車の一両の長さが20メートル程度なので、7両か8両の電車編成の長さに相当する。えー、郊外電車のホームの先頭にパチンコだまを置いて、一番後ろに運動会の大玉を置いて、間に正露丸を置いて、これで日食が出来る。しかも、地球から見た、見かけの大きさが同じという太陽がちょうど月に隠れる皆既日食って、これ奇跡としか言いようがない。すごいことだと思う(軌道面が同じというのも不思議)。

 さらに恐れ入るのが、恒星(太陽系)と恒星の間の距離である。一番近いので4光年というから、4×10^12(10の12乗)キロは、この縮尺でいくと4000キロメートルに相当する。ほぼ日本から赤道直下のインドネシアあたり(曲線だけど)なのだ。宇宙空間では1.4メートルの玉(恒星)の一番近い玉まで4000キロ行かないとめぐり合わない。

 銀河系というのは、こうした星が、これだけ離れながら2000億個以上集まっていて、しかも、これが宇宙のほんの一部分に過ぎないことを考えると、考えるだけで気が遠くなっていく。こういうことが想像できる人間の叡智と、それを遥かに超える宇宙の悠久さに、ただ、ただ感動するだけである。

STM8Sを生き返らせるために苦労する(11/11/2012)
 それはともかく、電子工作の続きである。手持ちの電子パーツを整理しているうち、秋月で買ったマイコンの評価キットSTM8S-Discovery(¥750)というのが出てきた。一時ネットで評判になり、所長も何となくひとつ手に入れていた。このSTM8Sは、ARMプロセッサーで有名なSTマイクロが出したプロセッサーだが、ARMではない。

S_pb275461  奇妙なことに本体が8ビットマイコンなのに、STlinkという付属のUSBローダーには32ビットARMプロセッサーが使われているというおかしな構成である。恐らくSTマイクロの新作の8ビットマイコンの販拡のための価格設定だと思うが、手練れの電子工作マニアの中では、本体の8ビットマイコンをそのままにして、このローダー部分だけを切り取り、別のJTAGドングルに改造することが一時大流行した。

 しかし、本体の8ビットマイコンの方は、ARMでもない独自のSTマイクロのプロセッサーなのでGNU環境がない上に、日本語の情報が極めて少なく、日本のアマチュアの中では、殆ど省みられることがなかった(STマイクロの意図は見事にはずれた)。

 所長は、へそ曲がりな性格なら誰にも負けない。この評価キットを見ているうち、せっかく、はなばなしく登場したのに、ローダーの方ばかりが注目を浴びて、本体は捨てられるSTM8Sが急に不憫に見えてきた。みんながやらないというのなら使ってやろうではないか。

 へそ曲がりは私以外にもいると見えて、最近、ぼつぼつSTM8Sを応用した例が出てきた。特に、ここのサイトは充実している。このサイトは、ソニーをやめた回路設計エンジニアが開いているサイトで、話の展開が独特で面白いので所長の定期購読サイトのひとつであるが、STM8Sをこんなに詳しく研究されているとは気がつかなかった。

 STM8SにはGNUの環境は揃っていない。始め、無償期間限定の有料Cコンパイラーしかないと思っていたが(買えば10万円以上する)、良く調べてみると、Raisonanceの方のSTM8Sのコンパイラーはフラッシュサイズが32KB以内なら無料で手に入ることがわかった(期間無制限)。

 大体この販促用のチップのフラッシュは32KBであり、STM8Sも現在のラインナップの最大フラッシュは64KBしかない(その後、128Kまで増えたようだ)。そこで、この無償版を手に入れて、開発環境だけでも作ってみることにした。Ws000003

 ユーザーの登録、ライセンスコードの取得、アクティベーションコードと、やたらに面倒くさい手続きを経て、何とか、Ride7というIDE(開発環境)とコンパイラーを手に入れた。しかし、何をするためにインストールしたのか決めていなかったことに気づき、愕然とする。

 そう、これも部品箱に眠っている、64×128のモノクログラフィック液晶(Aitendo)を動かすために使うことにしたい。ああ、これも手段で目的でないな。まあ、目標は、JJYデコード環境(最終的には電波時計)、GPSロガーとしておこう。

ケースまで買ったが、革命アンプの同一基板上の電源は失敗だった(11/18/2012)
 LM380革命アンプの続きである。電源はスイッチング電源のままだ。ここはオーディオなのでまともなシリーズ電源にしたい。ただその前に、音が、どうも低音と高音が弱く中音ばかりが強調されているような気がしてきた。入力ケーブル(フォンケーブル)を換えたり色々調べる。

 結果としては、やはりブレッドボード上のテスト用LPCMプレーヤーが良くないようだ。フォンケーブルを短いものに換え、LPCMプレーヤー1号機から入力すると良い音に戻った(ように思う)。

S_pb275446  シリーズ電源の制作を始めた。仕事の帰り、久しぶりに秋葉に寄り、千石で普通の6V-0-6V電源トランス(¥880)、ケース(リードPS1 100X50X85 ¥640)などの部品を買ってきた。電源部を基板の残りスペースに入れてしまおうというのである。

 うまく行けば、この小さなケースに入ったアンプが作れる。、ただ、トランスの漏洩磁束が心配だったので、とりあえずトランスだけ固定し、100V部分を仮配線して、ハムが出ないか通電してみた。

S_pb185313  うーむ、明らかにハム音が増える。スピーカーから1メートル離れて、電源を入り切りしたときの音がわかるのでは、せっかくの良い音も台無しだ。やっぱりトランスが近すぎる。まあ、HiFiオーディオがすべてトロイダルトランスを愛用しているわけがようやく理解できた。

 しかし、どんなに小さいトロイダルトランスでも¥2000以上するのでちょっと手が出せない。どうしようか。少し離せばよいのかもしれないが、とりあえず買ってきたケースの中に入れることは出来なくなった。せっかく、基板の大きさにぴったりあうケースを見つけて上機嫌でいたのに残念である。

リップルはとれないし、電圧は17Vもある。スイッチング電源に戻る(11/20/2012)

 このままにしておくわけにもいかない。思い切って基板を分割する。コンデンサーをはずし強引にサーキュラーソーで半分に切る。幸い何も傷つけず切ることに成功した。早速、試す。よし、10センチも離せばハム音は消えた。勢いに乗って、電源部の完成を急ぐ。

S_pb215325  ハンダ付けは殆ど問題なし。平滑コンデンサーの大きさは迷った。10000μF以上は突入電流が心配だ。回路図を見ていると6000~8000μFほどが多いようだ。

 2200μFを3つつけることにする。電源を、このシリーズ電源に切り替える。うーむ、だめだ。またハム音がし始めた。スピーカーに耳を当てないと聞こえない程度だが、明らかにスイッチング電源の時に較べると大きい。

 オシロで調べてみた。ありゃあ、17Vもあるぞ。全波整流ではこれくらいになるのか。まあ、定格内だから良いとして、やはり120Hzくらいのリップルが出ている。余分に買ってあった2200μFをもうひとつつけて8800μFにする。

S_pb275455

 少し、ハム音は小さくなったが、リップルの程度は、オシロで見る限り、明らかにスイッチング電源に負けている。やはり10000μF以上が必要なのだろうか。今の容量でも、電源を切っても延々と電圧は下がらないし、突入電流は半端な量ではないはずだ。トランスや、ダイオードを痛めているのではないかと心配になる。

 あらたにセメント抵抗(5W)を買ってきて、電源品質を本格的に調べ始めた。電源トランス(12V)の電圧が定格より高いのは負荷が小さいためで、定格の300mA近く流すと、11Vまで下がった。しかし、これは負荷によって電圧が上下するということで音質には決して良い影響を与えないはずだ。

S_pb275456

 一方、スイッチング電源はオシロの波形で見る限り、とても好調なのである。オシロをACモードにして、感度を上げる(200mV/目盛り)と、シリーズ電源のリップルは派手に出るのに対し、スイッチング電源はきわめて優秀である。細かいパルスノイズも同程度で遜色ない。

S_pb275450

 試しに、以前買ってきてノイズの出た12Vアダプターを測ってみた。オシロを最大感度の50mVに上げる。この感度だと、何も測定しないプローブから、20mV近いノイズが出るのだが、このスイッチング電源は明らかにノイズが多い。とても派手なパルスノイズだ。これは不良品と言ってもおかしくない電源品質だ。

 この電源はともかく、スイッチング電源の品質は思ったより高いということがわかった。少なくとも、当研究所のオシロでは、リップルもないしパルスノイズもシリーズ電源と全く変わらない。スイッチング電源を今まで毛嫌いしていたけれど、このアンプでしばらく使ってみることにする。

S_pb275458_2

S_pb275457

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