2021年12月18日土曜日

FM77AVにUSBキーボードを接続する試み(その3)

 プログラムを手直しするとともに基板を製作してみました

今までは、以前別の用途に使用していたPIC24FJ64GB002の基板を流用していましたので、ATmega168の基板と2枚組になってしまって使いにくかったので、とりあえず手配線ですが基板を製作してみました。また、特に意味はありませんがATmega168をATmega88に交換してあります。それなりにコンパクトになりましたが、RJ-9コネクタのついたケーブルは非常にハンダ付けしにくいので、この部分にはRJ-9のメスコネクタが必要な感じです。





回路図を示します。電源はRJ-9コネクタを通してFM77AVから得ていますが5Vですので、ATmega88にはそのまま供給し、PIC24FJ64GB002には3.3Vに変換したものを供給しています。また、この中のプログラム書き込み用の端子は実装してありません。




プログラムですが、キーボードからの入力を処理するPIC側は前回報告したもののままですが、スキャンコードを変換してFM77AVに送るATmega88側は手直しをすることによって、PS/2キーボード変換器と同様な動作になりました。

そのプログラムを示します。


   
 

以上で、USBキーボードをFM77AVで使うという目標が一応達成できたわけですが、PS/2キーボード変換器の場合はATtiny85の1個だけで実現できたのと比べて、いかにもスマートではありませんので、何とかPICの1個で済ませるか、あるいは2個になるにしてももう少し安価でコンパクトなICで済ませられればと思います。

ということで、UART機能のあるコンパクトなAtmelがあればと考えて、Pickit4とSnapを購入する際にATtiny804も購入してみましたが、これが使えれば結構コンパクトになりそうです。一方、PICの方はUSBホスト機能を持つ安価でピン数の少ないものをまだ見つけていません...

蛇足ですが、最近の新しいAtmelのチップはPickit4やSnapでボードに装着したまま書き込みができるので便利です。(今回使用したATmega88や168も書き込めました。)


2021年12月11日土曜日

FM77AVにUSBキーボードを接続する試み(その2)


とりあえずFM77AVにUSBキーボードを接続できました

前回の報告はUSBキーボードのコードは読めたがFM77AVに送れないという段階まででした。

その後結局ATtiny85では無理だろうと判断して、USB機能を持っているAtmelのチップに変更することにしました。AtmelのチップにこだわるのはPS/2キーボード用に制作した変換プログラムを使用したかったからですが、手持ちのチップにはあまり適当なものがなく、20ピンのATmega88とATmega168ぐらいしかありませんでしたので、とりあえず、RAM容量の大きなATmega168を使うことにしました。

試作した回路を示します。右がPIC24FJ64GB002のキーボードインターフェース部、左がATmega168のコード変換部です。


左:ATmega168基板、右:PIC24FJ64GB002基板


全体の構成は図のようです。


プログラムの構成

[1]PIC24FJ64GB002側

ソフトは前回同様 MicrochipのMLA(Microchip Libraries for Applications  v2018-11-26版)中のusb frameworkを用いましたが、前回とは異なり、app_host_hid_keyboard.cの一部を書き換えることで、アスキーコードではなくUSB標準のキースキャンコードを得て、それをそのままUART(38400baud)でATmega168に送れるようにしました。

通常のキーは1バイトのキースキャンコードで、SHIFTキーやCTRLキーなどは2バイトのキースキャンコードとして送っています。

このために App_ProcessInputReport()関数の一部を下のように変更しました。

   

 

[2]ATmega168側

おおまかにはATtiny85でのPS/2キーボード用のプログラムのうちのキーボードのスキャンコードを得る箇所をUSBからの受信データに置き換えれば良いのですが、実際にはPS/2キーボードとUSBキーボードでは制御キーの扱いが異なっているので、その部分は書き換える必要がありました。

具体的には、SHIFTキーを押したときの処理はかなり書き換える必要がありました。

例えば、単純に’1’キーだけを押した場合に得られるコードは

0x1E,0x00 (押した時 0x1E、離した時 0x00)の2バイトなのですが、

SHIFTキーを押しながら’1’キーを押した場合に得られるコードは

0xE1,0x00,0xE1,0x1E,0xE1,0x00,0x00の7バイトになります。その内訳は、

SHIFTキーを押すと 0xE1,0x00

さらに’1’キーを押すと 0xE1,0x1E

続いて’1’キーを離すと 0xE1,0x00

SHIFTキーを離すと 0x00

となっています。

(注)上記の 0x00が余分なように思えますし、PICのプログラムを書き換えれば送られてこないようにできますが、これにはリリースコードの役割がありますので、なしにするとキーを離したことが検出できなくなります。

これを適切に処理しなければならないわけですが、その部分を下に示します。

   
 

これ以外の部分は、以前公開してありますPS/2キーボード用変換器とほとんど同じで、キーコードスキャン部をUARTからの入力に置き換えただけで、キーコード変換部は全く変更がありません。

以上により、試作した回路が間に合わせですし、プログラムもさらなる検討が必要な部分もありますが、とりあえず使えそうな段階まで達したと思います。

しかし、USBホストとしてPIC、そしてコード変換にAtmelと2つもマイコンを使うのはいかにもスマートではありません。何とかPICのみで済ませたいと思っていますが、それは次の課題ということにして、とりあえず一つの基板にまとめた回路を作るつもりです。


<余分な愚痴>

今回のプログラム作成ではPICとAtmelの2種を使いましたので、ライターとしてPICにはPICKIT3を、AtmelにはTL866ⅡPLUSを用いました。PICKIT3はPICを基板に装着したままで書き込めるので便利なのですが、残念ながらAtmelには対応していません。

PICKIT4ならAtmelに対応しているそうですが最近は入手しにくくなっているようです。秋月電子は安いのですが入荷未定ですし、他店も高価なうえに納期が良く分かりません。ということでMicrochip.comの直販で購入することにしたのですが、即納のように書いてあったのに、注文後に何と納期が90日と言われてしまいました。がっかりしていたら、またメールが来て早くなりそうなので一安心しましたが、同時に購入しようとしたATtinyの2シリーズのチップなどは納期が来年の5月と言われて諦めました。

また、先日Y電機で注文したスキャナは納期が来年の3月だそうで、古いスキャナをもう処分してしまったので、結構不自由しています。

コロナの影響なのか半導体不足の影響なのか分かりませんが、一個人にも影響する事態になっていることを改めて思い知らされました。


【12月13日追記】

納期が遅れるというメールを受け取ったのでつい愚痴ってしまいましたが、実際には遅れることもなくPICKIT4とSNAPはアメリカから12日に、ATtiny804はタイから13日に到着しました。日本で購入するよりも安かったですし(送料は無料、VATのみ)、納期も遅くなかったので良かったです。Microchip.comの直販での購入は久しぶりでしたが個人相手でも丁寧な対応で好感が持てます。ということで、上記の愚痴は取り消します。(スキャナの方は相変わらず納期未定です...)

2021年12月4日土曜日

FM77AVにUSBキーボードを接続する試み(途中経過)

FM77AVにUSBキーボードを接続する試みの途中経過です

以前、「FM77AVにPS/2キーボードを接続する変換器の基板化(2019年7月31日)」と「FM77AV用PS/2キーボード変換器の不具合を修正(2020年1月21日)」で紹介したFM77AV用のキーボード変換器ですが、私は今でもFM77AVやFM77AV40SXで常用しています。

しかし、PS/2キーボードも入手しにくくなっておりますので、いつかはUSBキーボード用変換器を製作しようとは考えていたのですが、私にはUSBは敷居が高くて手が出しにくいのでそのままになっていました。

しかし最近、中華製のCH559の記事を読んでいて、このようなUSBホスト機能を持ったマイコンを使えば何とかなるのではないかと考えました。でも今更新しいマイコンの使い方を覚えるのも大変だなと思っていたのですが、ふと思いついて、以前マイコンとスマホの間のBluetooth通信に関してあれこれやっていた時のPIC24FJ64GB002があったなと思い出して、探してみたら3台も出てきました。


出てきたPIC24FJ64GB002基板


ハードはこれをそのまま用い、ソフトはMicrochipのMLA(Microchip Libraries for Applications  v2018-11-26版)中のusb frameworkを用いることで、USBキーボードからの入力を得てUARTに出力することができました。と言ってもMLAのサンプルはPIC24FJ64GB004用でしたので、すんなりとできたわけではなく、ビルドできるようになるまでが一苦労でした。(YTSのホームページ中のPIC24FJ64GB002(Bluetooth LE)の記事が大変参考になりました。感謝いたします。)



ATtiny85と接続


UARTの出力をTeraTermで表示させてみました。入力したキーがちゃんと表示されています。


キー入力を表示


しかし、このMLAのサンプルコードはUSBキーボードのキースキャンコードをそのまま出力するのではなく、内部でコードの処理をした結果のアスキーコードを出力するようになっているので、FM77AV用の変換器を作るためにはこの部分を取り除かなければなりません。

さらに、USBキーボードのキーコードは 'a'=0x04, 'b'=0x05,..., '1'=0x1e, '2'=0x1f,...

であり、キーボードが送るHID Reportは

Makeコード(8バイト):status,0x00,第一キーコード,第2キーコード,..,第6キーコード

Breakコード(8バイト):all 0x00

のはずだと思うのですが、サンプルコードの中にこのフォーマットのデータらしい箇所をまだ見つけることができていません。

また、このサンプルコードはハブ機能を持ったUSBキーボードには適合しないという記事がありましたが、確認してみますと確かに全く反応しませんでした。


全体の構成(予定)

全体の構成としては下図のようにPIC24FJ64GB002の1個だけでFM77AVのスキャンコードの出力ができれば理想なのですが、あれこれと試してみましたがどうも無理なようです。


構成図

その理由については今のところ分かっていません。

試しにメイン関数中に特定のスキャンコードを送るルーチンを書き込むとFM77AVに表示されますが、USBのスキャンコードを得る関数中にそのルーチンを書き込んだ場合は表示されないのです。FM77AVへの通信ルーチンといっても、単にPORTBの1ビットをオンオフしているだけなのですが...

USBでは1ms毎に通信しているので、その中にFM77AVへの通信ルーチンを入れ込むのはダメということのようなのですが、参考にした「YTSのホームページ」さんはUSBの関数中にUARTの送信ルーチンを入れて正常に動作させています。下の画像のパルス間隔が伸びている箇所がUART通信中の部分です。(もっとも、FM77AVへは4バイトのコードを正確に100us,125us,175usの間隔で送る必要があるので、これが原因かもしれませんが。)


PIC24のRB2出力


ATtiny85を使うことになりそう


ということで、PIC24FJ64GB002でUSBキーボードのスキャンコードを得て、それをATtiny85に転送してコード変換した後にFM77AVに送り込むという形を考えています。

しかしその転送手段ですが、ATtiny85にはUART機能がないため、試しにATtiny85をArduino化してSoftwareSerial機能を使ってみましたが、変数がRAMエリアの容量を超えてしまってビルドできませんでした。あとはUSI機能を使用するか、あるいは直接UART信号を読むルーチンを書くかということになりそうですが、まだどちらも実現できていません。

以上、途中経過でしたが、私が理解していないことが多々あるかと思いますので気づかれたことがありましたらアドバイスいただけると有難いです。