レトロでハードな物語

レトロなゲーム機・マイコン・中古デバイスなどをArduinoやAVRで再活用する方法を模索しています。

AVR向けの汎用ディスプレイ装置をつくる その2

2019年08月22日 | 電子工作

前回ディスプレイ装置のハードが完成したので、次はスケッチです。今回作成するスケッチでは、以下の機能を実現しようと考えました。

・デバッグ表示に簡単に利用できるよう、シリアル接続で送られてきた文字列を表示する。
・標準でシリアル接続ピンを持っていないATtiny13Aなどからも簡単に表示できるような仕組みをつくる。
・電圧計など特定用途向けに作成したデバイス専用の表示機能も後から追加出来るようにする。

これらを踏まえ作成したスケッチはこちらになります。

ATmega328Display.ino

このスケッチを書き込んでディスプレイ装置を起動すると、初期状態ではシリアル接続されたAVRなどから送られてくるキャラクタデータを画面に表示します。ただし表示に利用しているAdafruitのライブラリは、display()メソッドを呼び出すまで表示内容が更新されません。1文字画面に書き込むごとにdisplay()メソッドを呼び出しているとパフォーマンスが悪いので、改行コード0x0Aが送られてきた時に表示内容を更新するようにしました。
また、このライブラリには縦スクロールの機能がないので、最下行まで表示されたら次の表示の前に2秒ほどウェイトした後、全画面を消去して最初の行から表示を行います。ちょっと手抜きな仕様です。

ATtiny13Aなどのシリアル接続用のピンのないAVRから文字表示を行いたいときは、ディスプレイ装置にコマンドを送って動作モードをシリアル接続から変更し、独自の方法で文字データを送ることになります。
具体的にはディスプレイ装置の2番ピン(物理的なピン番号は4)をコマンド送信のトリガーのピンにしてあり、送信したいコマンド(1バイト)の0ビット目を4番ピン(物理的なピン番号は6)にセットしてから2番ピンをLOWにすると、ディスプレイ装置が0ビット目の値を受け取ります。2番ピンをHIGHに戻してから、この操作を繰り返して0〜7ビットまでの1バイトのコマンドを送ります。するとディスプレイ装置はコマンドで指定された表示動作に切り替わります。

次に表示したいデータを送ります。今度はディスプレイ装置の3番ピン(物理的なピン番号は5)がデータ送信用のピンになっていて、送信したいデータを上記と同様に4番ピンにセットして、3番ピンをLOWにすることでデータを1ビット送りその後3番ピンをHIGHに戻します。これを8回繰り返して1バイトのデータを送ります。
あとは表示したい文字データをこの方法で送り続けるだけです。

ディスプレイ装置の2番ピンと3番ピンはプルアップしてあり、外部からLOWにセットされた時に割り込み(INT0, INT1)がかかって4番ピンの状態を読み取りにいきます。

動作モードは今回のスケッチではコマンド0がデフォルトのシリアル接続によるキャラクタ表示、1が上記の割り込みによるキャラクタ表示、2が前に作成した電圧計の表示となっています。

ATtiny13Aによるコマンド1のキャラクタ表示のテストスケッチは次のようになります。

ATtiny13DisplayClient.ino

テストはブレッドボード上のATtiny13Aをディスプレイ装置につなげて行い、配線は以下のようにしました。

ディスプレイ装置 − ATtiny13A
2 − 0
3 − 1
4 − 2

このスケッチを実行するとひたすら文字列を表示し続けます。



ところでATtiny13Aの問題だとは思うのですが、電源投入直後にATtiny13Aからディスプレイ装置にコマンドを送ると、0ビット目が必ず0(LOW)になるという現象が発生しました。原因はノイズなのか何なんのかよく分かりません。ディスプレイ装置やATtiny13Aにウェイトなどを入れて調整してみても現象は収まりませんでした。仕方がないので一度ダミーでコマンド0を送ってから、改めてコマンド1を送っています。2回目のコマンドは問題なく送信できているのでとりあえずこの問題はそのまま放置してあります。

つぎにコマンド2の電圧計の表示機能のテストです。

以前に作成した電圧計のスケッチは、そのままでは使えませんので新しく書き直しました。

Attiny13Voltmeter.ino

配線は上記と同じです。
実行すると画面にアナログ(っぽい)メーターと電圧の数値が表示されます。今回グラフィカルな画面表示を行ってみたかったので、文字表示のパフォーマンスはイマイチでもAdafruitのライブラリを採用したのです。


バッテリーは基板の裏に貼り付けたのでスッキリしました。

ところでこの電圧計は以前は5Vで動作させていたのですが、今回3.3V動作に変更したので計測できる電圧の最大値が15Vから9.9Vになってしまいました。回路の抵抗を替えるのも面倒ですし、普段は1.5Vか5Vを計測することが多いのでこのままでいいやということにしました。
入力電圧が変わったので電圧の計算パラメーターも変更する必要があります。今回の三端子レギュレーターの出力電圧は測ってみると3.29Vだったので、パラメーターにこれを3倍にしたものを使うのですが、そうするとテスターによる実測値と最大0.02V位の誤差が生じました。そこでパラメーター値を微調整して実測値と0.01V以下の誤差になるようにしてあります。
アナログメーターの上限値はスケッチ前方の #define RANGE で定義しています。



このスケッチではコマンド1のときのように、最初にダミーのコマンドを送らなくても正常に動作しました。ただし、このスケッチが完成するまでは初回のコマンドの値がおかしくなる現象が発生していました。最終的に問題が発生しなくなったのが何故なのかまったく分かりません。
それと関係するのかどうか分かりませんが、時々計測する電圧の誤差が通常より+0.01V位大きくなったりすることがあります。まあ、電源投入後にATtiny13Aにつけたリセットボタンを押せば誤差が0.01V以内に戻るので、あまり深くは追求していません。きちんと検証したわけではないのですが、三端子レギュレーターに入れる電源をバッテリーではなくACアダプターにするとこのような問題が起きにくいような気はします。

ATtiny13Aに限らずAVRのアナログ入力はノイズに弱いそうで、アナログ入力の計測中にCPUの動作を止めるとノイズが減るような情報もありましたが、具体的な方法は今のところ不明です。ただこの辺のことを調べているうちにAVRの動作を定期的に停止して省エネで動作させるという情報を得ることが出来ました。作成した電圧計は長時間連続使用することはあまりないので省エネ化する意味はありませんが、勉強のためにスケッチに組み込んでみました。
スケッチAttiny13Voltmeter.inoで先頭の //#define SLEEPMODE のコメントを外すと省エネ動作になると思います。(ロードテストのようなことは行っていないので確認は取れていませんが)
スケッチ中loop()の中で1秒間ウェイトしていたのを、1秒間パワーダウンさせています。ただし、見た目は何も変わりません。

今後この手法を何かに利用できればいいですね。




最新の画像もっと見る

コメントを投稿