さえきさんの ホームページ  -  Linux 導入での奮闘メモのページ -


その4 - Armadilloに 専用リモート操作装置  -


 Armadillo組み込みLinuxカードの活用を コツコツ とすすめてきました
その3 - "Armadillo" : 組み込みLinuxカード で 紹介したように 拡張I/Oが
Armadilloは、PC/104規格に準拠していて 組込み機器開発に 大変重宝です

HT2020-P24 Opt-Isolated 24bit出力カードを Armadilloとあわせて購入し 実験で使用しましたが 
例えば 特定のパターンに従って LED群を個々に点灯制御する応用で 開発中は そのパターン登録
や確認動作などの 人間とのインターフェイスに Webサーバ機能も立ち上げ CGI活用のページを作成し
LAN接続されたパソコンのブラウザにて 画面上の表示を見ながら マウスボタンで対話操作していました

さて いろいろ勉強しながらですが 機能としては動作するようになりまして パソコンを経由せずに 直接
Armdillo Linuxカードに付帯した 専用の操作装置の実現が 具体的に求められる レベルに達しました

そこで 手掛けましたのが PICマイコン採用、20文字x4行のLCD表示、操作ボタン
ロータリエンコーダつまみも備えた 9600bpsシリアル通信接続の専用の操作装置
 です

なかなかの仕上がりでしたので その作品の紹介をさせていただきます:

A. まずは 回路図を示します  (見難いようでしたら 図をクリックして大きなのを表示させて下さい)




・ パーツを一式そろえるのに 秋月の ”PIC16F84使用 シリアル制御 液晶表示モジュールキット”
 @3000円で購入 追加で [P-00292] ロータリーエンコーダやつまみ、プッシュスイッチなども揃えます

・ このキットに付属のソフトはそれなりに楽しめますが ロータリエンコーダの入力処理などに
 結構なプログラム処理を要しますので タイマ割り込みの通信処理にしてゆくことと相成りました

そのために まず キットの回路改造 パターンカットなど をする必要が生じました
内容としては 以下のとおり:

・PICマイコン、16F84のRA4は TMROのクロック入力ポートにもなっているので
 ここを232C、Rx受信のトランジスタからの接続にします

 (9600bpsのシリアル通信のデータ送信、受信とも ソフトウェアにて
 カウンタタイマ満了のタイミングでの割り込み処理で行ないます そして とくに
 いつ来るか分からない本体側装置からのデータ受信を待ち受けて スタートビット開始と同時に
 いつでも受信処理を開始できるような仕掛けに タイマクロックを外部入力出来る機能を
 活用しております タイマは満了直前の値でセットされていて スタートビット開始を示す
 レベル変化を そのタイマの外部クロック入力として受け取って その変化エッジで
 カウンタ満了となって 割り込み処理開始
 ↑をクリック その部分のソフトをご覧下さい
 その後 各ビット値の読み取りのための内部クロック使用の待ちタイマ割り込み式に 切り替えています
 このようにタイマの外部クロック入力機能がRA4ポートに仕掛けが施されているのを利用した次第です)

・LCDモジュールとのデータやり取りは双方向にはなっていますが R/Wポートを切り替えてまでの
 読み出しをさせないことにしました  LCDモジュールへのコマンドの中には 2ミリ秒近くの
 処理時間を要するものもあり モジュールからの完了合図のビジーフラッグを監視するのが
 双方向通信本来かとは思いましたが ソフトを組む際 分かっていることですのでその分待ちを
 挿入して混乱を避けています  また ほとんどのデータ転送では 40μ秒弱で済みますので
 モジュールからの完了合図のビジーフラッグのマイコンでの入力監視はせず 40μ秒固定のソフトで
 対応のディレイを挿入することとしました (元々のキットでも ビジーの監視は無しでした)

 ということで  R/Wポートは ロー固定で  LCDモジュールへのコマンドライトのみです

・この結果 LCDモジュールへのデータバス、DB7〜4は 入力モードの固定になります
 また LCDモジュールへのデータ書き込みは 4ビットモードの転送を採用しました
  
・PICマイコン,16F84のRB3〜0の4つのポートを出力モードでLCDモジュールへのデータライトに使用し
 そして 同時に 入力モードでは 4つのプッシュスイッチからのステイタス入力にも使用しています
 (LCDモジュールへのライト出力時の干渉防止に各スイッチはシリーズの抵抗を挿入してます)
  PICマイコンの限られたポート数のなか かなりの効率的な活用です

・RS232規格正規のドライブICを使用しない(このキットのやり方の)簡易式を採用  そして 
 通信接続される本体、Linux装置側RS232ポートのCTSがイネーブルでハイ、
 +5〜10Vとなることを期待してこの操作装置の電源に流用しております

 (Armadilloには第2のシリアルポートがあって この装置の接続には この独立の第2ポートを使用する
 ことにしました その第2のRS232ポートはフル規格ではなく このCTSポートは NCでしたので10Vライン
 を接続するちょっとした改造をしました  よって 第一のシリアルポートはコンソール用のままです)

・ Linux本体装置との接続には RS232ストレートケーブルを使用とし Dsub9pinメスコネクタでRx,Txクロス
 させました   電源を別に接続せずに済み 大変スマートな外部制御装置になりましてHappyです

・LCDでの文字表示とは別に LED点灯のシグナルも操作の上で 便利そうでしたので 
 上記のようなPICマイコンのI/Oポート節約で空いた RA1をこれに使用しました それでもなお
 RB5,4の2つが将来拡張用に残せました  ボタンや表示LEDに? もう一つREを かな?

・ところで ここで使用したロータリエンコーダは 価格は200円という大変にリーズナブルなのですが
 メカニカル式というのでしょうか 接点のオンオフ時にチャタリングの現象が伴います
 つまみを廻していって 順次カウントアップしている途中で 突然値が跳ぶのは 操作上 大問題です
 僅かな時間ずらして2度読みして同じであることを条件に 入力として採用するというようなソフト
 対応で 素早いつまみの回転時に たまに スリップしたかな? 位の感じで逃げられたようです


B: さて つぎは PIC16F84マイコンに書き込んだ 新たなプログラムについて触れましょう

・ ロータリエンコーダは 2つの接点を持ったロータリスイッチのような構成で つまみの回転にしたがって
 位相差90度ずれながら 各接点がオンオフします  回転方向によって+と−の位相差ですので これを
 ソフトで判定しながらパルスの数をカウントする ということです  その部分の原型のプログラムを示します
テーブル参照でやってますが  elm-chan.orgのHPhobby-elec.orgのHP も参考にされると良いでしょう

 (詳しく 全プログラムをご覧になりたければ 図をクリックして 大きなもので どうぞ)




・ ところで PIC 16F84マイコンは 最大動作周波数,10MHz プログラム用とデータ用のメモリが
 独立した 一風変わった構成で 1Kワード(14ビット巾)のフラッシュプログラムメモリ と 68バイトの
RAM/64バイトのEEPROMのデータメモリを持ち、タイマモジュール(TMR0)や4種の割り込みソース そして
13本のI/Oピンを備えています  18ピンというコンパクトながら 結構気の利いた いいマイコンです

ブロックダイアグラムを示しておきます  (ここでも 見難かったら 図をクリックし 大きなので どうぞ)



・ 先ほど触れましたように RA4ポートは タイマ/カウンタのクロック入力として選択できる構成です
 キットのPCB基板で切った貼ったをやった理由は この特徴を利用したかったから という次第です
シリアル通信のソフトについては  自らを”ラジオ少年だった子供のころから、電子工作の趣味を楽しんで
いるうちに50才を過ぎてしまった万年青年です”と 小生と同じようなことを言って居られる某御方の作品

参考にさせて頂きました 感謝!!です  (プログラムリストにも引用元を明記しておきました)

・ 20文字x4行のLCD表示について触れます  本体LINUX装置との通信内容についても絡んできます
使用しましたLCDモジュールについて その解説は SPECTRUM 電子工作のHP が 分かり易くていいでしょう

すでに 全体ソフトをご覧頂きましたが 大部分がこの関係のプログラムになっています 
 つまり Linux本体装置専用の制御操作装置として 本論は ここからということです

・ 制御操作は 1.本体応用ソフトで 20文字4行のLCD表示用のメニューを用意して送ってくる
2.その表示を見ながら ボタンやロータリつまみの操作で応答する
3.本体側はその応答結果の処理を進める  必要に応じ 再び 1〜3を繰り返す

という感じです  この間の通信の様子も 本体主導で 表示のデータはLCDに送り
表示データとは別のコード- 00h〜1Fh -を受けたときには そのコード毎に決められた-
例えば ボタンデータを送出するとか LEDを点灯/消灯する あるいは LCD表示で
改行やカーソル位置セットとか をします   組み込んだコマンドは次図のとおりです




・ 各コマンドでの処理についてはは それぞれのJUMP先のソフト部分をご覧頂ければ と思いますが
 ロータリエンコーダデータの送出について ちょっと 解説を試みましょう  結構 苦労したところです

 このJUMPテーブルの飛び先では それまでに処理された最新の 20h〜7Fhの間の96種の1バイトデータを
送り出すだけなんですが 本体とのシリアル通信の1文字分の送信や受信に要する(9600bpsで)約1ミリ秒
位の単位時間毎に一度は かつ 受信待ちの間も自走のループで怠りなく エンコーダ接点のステイタスを
読み取るループの処理が繰り返されています (のつもりですが 特殊コード処理のあとで抜けがあるかも?)
先程示しましたチャタ対策の2度同じを確認して 回転方向に従って加算、減算させ その上で 20hと7Fhの
コードがつながった感じの循環のコードの一つを採るように更新させています 数百hzのレートになるのかな

比較の意味で もう一つの応答型のステイタス送信、4つのプッシュSWについて 触れましょう これらのボタン
 ステイタスは 本体側からの要求コマンドを受信してから 常時はLCDへのデータ出力のポートを にわかに
そのときだけ入力に切り替えて 読み取って 応答しています  コンマ数秒のレートで 問題ないわけです

ところが ロータリエンコーダの方はそうは行かないですよね  本体側が ボタンを読み出すレートとは
比較にならないくらい早いレートで つまり 数百Hzで応答せよと要求してくるようでは それだけで目一杯で
LCD表示データの受信や そのデータのLCDモジュールへの引渡しも出来なくなります  ということで
ロータリエンコーダの方は PICマイコンサイドで自立的にループ監視の上 処理済データに纏め上げるのです

もう ひとつ苦労したところだけに このロータリデータ処理との関連で 改行コードの扱いの例に触れましょう
本体側で 20文字4行のLCD表示を考えながら 表示データを送ってくるようには出来ますが 例えば 改行コード
で どうするのがいいでしょうか  LCDモジュールには表示せよと届けられたデータは1画面分、つまり 20x4の
80文字分データをメモリにキープしていますので 改行コード受信でカーソル移動だけでは 行末までのデータが
書き替えられず スペースで埋める手配が必要です プログラムリストをご覧頂きたいところですが  このとき
最大で 19文字分のスペースコードをマイコンから主体的にLCDモジュールに渡します これが大体1ミリ秒くらい
の所要時間です このスペース文字列を送る前と 送った直後に ロータリエンコーダステイタスデータを読み取る
という処理を入れて という 気配りしながら 怠りなく という例です  どこかに まだ 抜けがあるかもですが

さて 通信上 Linux本体側で制御コードと扱われるのを避けた 20h〜7Fhの間の96種のコードとしました 初めは
4ビット、つまり 16種の循環コードでやってみたのですが 本体側での処理作業の都合によっては素早いロータリ
の回転で 前回との差が -8〜+7 のつもりでやると 読み誤るため 96種の長い周期のコードにした という経緯

ちなみに 採用したロータリエンコーダは1回転で24カウントパルスで 本体側での読み出し間隔で
2回転以内までなら 値を間違えない充分なものとなっています  もっとも そんなにゆっくりと読み
出されたのでは 人間との対話で反応が鈍いなぁということになりますので 実際は もっと早い間隔で
本体側プログラムを作ることにはなります  本体側はなんといっても能力はずっと上です スクリプトの
ソフトでは遅いなら Cで書いてコンパイルする方法などで対処します  後程 実績例を示します


C. つぎは 応用ソフトへの橋渡しの役割りをする Linux本体側での プログラムモジュールについて

まずは 真面目に 対話テストプログラムを作成しました  Linuxコンソールの対話画面は 次図にお示すとおりです
(この図を クリックしますと テストプログラムのリストを ご覧頂けます  スクリプト言語で dialogを利用してます



LinuxカードのArmadilloのttyS1は 第2のRS232通信ポートでして そのポートに接続した操作装置宛に
コンソールキーボードからの文字列やコマンドを送出し また 応答を得て 表示させる という
 対話型のシンプルなテストプログラムです   図では ","、カンマを送って "K"というデータ応答を
得た ところが示されています(last_keyinに, StatuRead->にK)    プログラムの方を見て頂くと
カンマでは ロータリエンコーダのステイタス応答を要求する ^R というコマンドコードを送信している
のが分かります このテストプログラムで PICマイコンの処理内容を更新しては 確認を繰り返しました


ところで 上記のプログラム内のコメントにもあるように Linux本体側には 同じディレクトリに
onebyoneR1 ,S1など置いておくよう指定してます  これらについて 簡単に説明をします
上の色違いをクリックして プログラムリストを見て下さい Cで書かれたプログラムで 一文字の
コード,^R をttyS1から送信し また 一文字分のコードが受信されるのを待って拾うというプログラム
です   Linuxではすべてのポートについてもファイルに読み書きすると同じ手続きを取ります
ttyポートにつては標準でドライバソフトが組み込まれておりますが 通常の通信では 一行分の
文字列のあと 改行(エンター)キーまでを単位にして 送信,受信が行われています  ここでは
そのドライバに対し 一時的に 一文字だけの入出力を扱うように また 無用なエコーバックも
要りません などと設定し そして 終わる前に 元に戻しています    onebyoneS1は 送り出す
文字を ^S にしただけの同形のプログラムモジュールで 4つのボタンの状況を伝えさせるものです
(色の変わったところをクリックされますと それらのCベースのプログラムリストをご覧頂けます)

このように 個々に作ったモジュールを積み上げて大きな処理をさせる という手法をとっています
応用ソフトへの橋渡しの役割りをする部分を 利用し易い形でモジュールにしておくように心掛けました
ちなみに  onebyoneS1は そのまま あとで紹介する応用プログラムの実行でも使っています  
ロータリエンコーダの R1 の方は 応用ソフトで使い易いように 受け取った生データのままではなく
さらに細工を加えたプログラムモジュールに含めました  つぎは そのプログラムを説明しましょう:




re_checkと名付けたのは RotaryEncoder状況をCheckする という意味合いでして 総合的なREの処理の
まとまりで ボリュームのあるものになってます   上の図をクリックしますと リストを御覧頂けます
その道のプロの方から見れば ひどい代物かとは思いますが 赤面しつつ 紹介します  上図で示すように
このプログラムは そのなかで 先程触れたようにtty1に^Rを送出して RE応答データを受け取るほかに
引数付きで使用され その引数の内容次第で 幾通りかの処理をし そして 返り値を返してきます  

a=$(./re_check "$a") というのが基本です  つまみをまわして ある値を設定するという使い方ですので
Linux本体側の応用ソフトでは 人間との対話で違和感のないコンマ数秒毎に ループのなかでロータリEnc
の様子をチェックしています  先のチェックでの値も引数の一部にいれてコールすると 最新のREつまみの
回転変化に応じて 値を更新して返してくる という処理です  値そのもののほかに 設定中の部分を表す
のに 表示がチカチカと点滅する形が欲しかったので そのような表示用の文字列として 返り値に含めました

1:res 2:str_res(表示用/点滅) 3:old_re 4:new_re 5:n_min 6:n_max 7:n_step 8:str_choiseの順 tab区切り
の8項目に区切られたリスト形式の文字データにしてみました  設定する箇所が複数ある応用ソフトでは
ひとつのつまみで順々に設定することになりますので re_check "$a" -R (リセット) の形も用意しました
順番に設定することになると前にセットした時のつまみの位置とは違うところから再開することになるので
以前の通信で得た3:old_re 4:new_re の前後のデータとも現在のものにリセットする という使い方です

応用側で 初期値を決めて それからのつまみ回転で 値を上下したいとか つまみをどんどん廻されても
ある範囲だけの値に限るケースも必要でしょう そのような 初期設定は re_read 3 0 5 1 のmin max step式
そして 候補リストをセットし つまみでセレクトさせる場合の初期設定は re_check 3 List: a bb ccc のような
文字表現からのチョイスとなってます  その場合の現在値は リストの何番目という数値をホールドしています
応用ソフトで表示とは別に 必要なら使えます  チョイスでは端までゆくと頭にゆくような順番にしました
値のときは min,max で打ち止めと step:0 でリストと同じように循環する 両方可です  応用で楽が出来ます

一寸工夫した点に触れます  表示の点滅はつまみが回転していない時だけに限りました 廻している時は
どんどん値が変化しているので それを見ながらの方が設定し易いからです  つまみが早く廻されたとき
数字の設定では跳んだ値の表示であっても かえって 早く目的の値を設定できていい という感じですが
リストからのチョイスでは 数字の場合と違って 飛び飛びでは どんな候補があるのか分からないので
必ず 順番に一つずつ進むように表示させました   表示のブリンクは正規の表示と同じ長さの空白文字列を
つくってます  リストの場合も同様です  内部的にはスペースを _(アンダーバー)コードにしてます
応用ソフトサイドで disp_a=$(echo "$a"|awk '{print $2}'|sed -e 's/_/ /g') というやり方で 空白に
してもらいます  いろいろ事情があってと いうことです  記述の楽なシェルスクリプトで応用ソフトを
つくりますが ときとして空白文字を区切り文字扱いしてくれることもあり ちょっと 困ったからです
リストの文字列の内部的な区切りについても 図のように 空白コードが無い 長い一語の形で扱ってます


D. いよいよ 応用ソフトについて 幾つかの デモ要素を含んだ展開利用に役立つ形の実施例を挙げましょう

ボトムアップの紹介を続けてきましたが 構想としては トップダウンで こんな形のものにしたいなぁ と
イメージ先行で 取り掛かった経緯があります  このご説明ページで 冒頭に記したように 出力カード
を Armadilloとあわせて購入使用し 特定のパターンに従って LED群を個々に点灯制御する応用で
その点灯パターン登録や確認動作などの 人間とのインターフェイスに Webサーバ機能も立ち上げ
CGI活用のページを作成し パソコンのブラウザにて 画面上の表示を見ながら マウスボタンで
対話操作していました  さて 機能としては動作するようになりまして パソコンを経由せずに
 直接Armdillo Linuxカードに付帯した 専用の操作装置の実現が 実際の使用を考えれば ぜひに
必要だな というのが発端で そこで 手掛けましたのが この専用の表示、制御操作装置です

そこで まず 20文字x4行という文字表示 と 幾つかのボタンの操作で どう対話しながら がいいのか
がテーマとなりますした  ロータリエンコーダを組み入れたのは 今回の作業では最後の方の挑戦でした
作業の初めの時期に 4つのボタンとLCD表示の部分だけの ともかく 対話に最小限必要なところを
動くようにして 最初にまとめた応用ソフトがが 次に紹介する メニューの表示 ボタンでの選択 そして
指定の新しいメニューページにジャンプすろ というシンプルな対話型のリモート装置での 確認でした



上の図について 説明します  一番上のリストは その右中央のループのプログラム実行の初めのところで
db_henkan プログラム実行で その左のWEB画面上のデータベース編集作成の確認画面のHTMLタグ記述を
変換し loopプログラムの実行で使い易い形で保持されている中間データです  また loop実行では
右側下の jp プログラムを使っています  それら関連しているので ひとつにまとめて 図にしました

このループの実行プログラムは データベースをリファーして 表示し そして 4つのボタンの監視を
しながら 押されたら どのボタンかによって 新しい表示をする というループを繰り返すだけです

リファーしているそのデータベース次第でどんな応用にも対応できる仕掛けなんです そのデータベースは
Webサーバ機能も立ち上げてあり LAN上のパソコンで PerlのCGIで作成された対話ゲームの感じで編集作成
します  下の図をご覧下さい これは その対話の最後で内容を確認する画面です  そのWebサーバ内の
記述そのものがデータベースとして 上で述べたように 変換ソフトでloopプログラム実行で使用されます

下の図で 一番左が各メニュー画面ページの登録名称 2番目の欄が20文字x4行LCDに表示させる内容を
置いてあります  すでに図でお分かりかと思いますが 4行目部分は4つのボタンで実行される行き先
あるいは 実行プログラム名が 簡潔な表現で表示されています  操作装置の意匠デザイン的なイメージ
ではLCD表示器の下方に4つのボタンが並べられ 直感的に ボタン操作が何をさせるかが判るように
配置するであろう と考えています  上部の3行は解説やコメントなどの表示となるのでしょう
その後の4つの欄には 1〜4のボタンが押されたときの実行プログラムです  jp もプログラムですね



トップダウンで仕掛けをしたところを述べてきました  上に示したデータベースでは まず mainの
メニュー表示の画面で始まります  ボタン左から ページ1、2、3、4が割り振られていますので
そのようなジャンプが実行されます  同様なことがつぎも起こります  それだけのことですが
トップダウンの進め方では それでいいのです  応用ソフトが出来上がるたびに このデータベースを
編集してゆけば イメージどおりに出来上がってゆきます  これまでに まとめた応用ソフトについて
説明しましょう  上の データベースに記入されているのは p1ページに disp_t というのが見えますね
表示の方では D/T とか D/T2 になっていますね  これに対応するボタンを押すと 現在の日時表示
ということなんです  飛び先欄に2つ書かれているのは 先に書かれているプログラムの実行から抜けた後
そのあとの実行を指定しているのです  今のところは2つ先まで可としてあります  これも仕掛けなんです



これだけのソフトですが 毎秒更新のすばらしく正確な表示です  Armdilloは毎朝 ntpupdate をやってます
当たり前といえば そうなんですが  見えない目で切った貼ったの改造のための半田付けから始まった作業の
なか 感激ものでした  それから もう 半年以上 2台とも 相変わらず 正確に時を刻んでいます

先程のデータベースで p1 ページに もう一つ calc というのが見えますね  これは ロータリエンコーダ
つまみで 値ばかりではなく +,-,x,÷のセレクトなどの設定の算術計算ソフトです  設定中の項目のブリンク
は毎秒1回位で まぁまぁ  先述の re_check を随所で使った 結構ゴツイ出来です ↑クリックで見て下さい

さて こんな調子で これまでに仕上げてきたLED列の点灯応用のコントロールをやらせてみようかな
それらしい装置になりそうで 楽しみです
では さいごに リモート表示・制御操作装置の写真を掲げさせて頂いて おわりにします


上の写真をクリックしますと もう一枚 − さて それが ご自慢の成果なんです −

−−−−−−−−−

ここまで 延々と述べてきましたが お読みになられる方のことを考えず という感じはしています
お疲れになられたこととお察し申し上げます  ご容赦!!  何分 半年以上掛かってますので

その間の 出来事 ひとつ  −  9/1メモから

September 9文字ですね  昨夜 仕上げた積りの 自動改行のPIC LCD端末で
時刻表示の画面崩れが発覚 !!!
あさ 4時半から 悩みました  これまでの端末は自動改行させてなかったので 問題なかったのに‥
4行が5行になって最初の月日が書き換えられた ということでした
Linuxのdisp_tのスクリプトプログラムを修正して決着
−  3月から8月、Augustでも6文字で 9月、Septemberで行から溢れたという 出来事でした

−−−−−−−−−


ここまで 纏め上げるには PICマイコンでは 割り込み機能も活用したアセンブラでのプログラム作成、
コンパイルしてライタで書き込み、PCB基板上ソケットへ挿入し動作の確認 という手順の繰り返し  そして
Armadillo-Linux側での 2番目のRS232ポート活用に必要な通信プログラム、これには Cでの開発が また
ボタンやつまみの操作の処理にも 速度の点で Cでの開発が必要でした  応用デモとして ボタン操作で
LCD表示画面が別ページに飛ぶとか 毎秒更新の日時表示、ロータリエンコーダつまみでの数値入力の算術計算
などの処理には シェルスクリプトで記述しながら 全体動作の確認を進めました  あっちやったり 戻ったり
切った、貼った の根気の要る作業でした − 夜中に はっと気が付いて徹夜もありました  年甲斐も無く‥

これからも まだまだ いろいろ壁に遭遇するでしょうが まずは めでたしめでたし です…    では

  

  作成:2005-11-7 最終更新日:2005-11-17