PC用 赤外線リモコン受信ユニット IRKey/PS2

製作:2019年6月1日~8月16日
執筆:2019年8月17日
全景 PCに接続してキーボードとして動作する赤外線リモコンの受信ユニットです。 汎用のリモコン形式(NEC/AEHA/SONY)を学習させ、キーボードの任意のキーストロークを割り当てられます。 マルチメディアキーを割り当てれば、YouTubeなどのサイトや動画再生アプリケーションにも柔軟に対応できます。

開発経緯

PCで音楽や動画・YouTubeなどを再生していると、離れた場所から音量や選曲の操作をしたくなる事があります。 ワイヤレスのマウスやキーボードを使えばよいと思うかもしれませんが、マウスは画面を見なければ操作ができず、遠くからはポインタが小さすぎて意外と使いにくいのです。 キーボードはサイズが大きすぎるので、枕元などでは手軽に利用できません。 今回は手持ちの赤外線リモコンを使って、キーボードデバイスとして動作する受信ユニットを製作しました。

机に置いても邪魔にならないよう出来る限り小さく作り、可能な限り手持ちの在庫部品で金をかけずに作るため、PS/2インターフェースで接続する方式にしました。 会社の同僚に話をすると、「どうしてUSBやBluetoothにしないの?」と言われてしまいました。 USBに対応するならライターを買い直したり、MCUの使い方を勉強し直さないといけませんし、Bluetoothレシーバーも持っていないので仕方ないですよね。

ハードウエア

基板 開発経緯にも書いたとおり、手持ちの部品で小さく仕上げるために工夫したところを挙げていきます。

  • PS/2のDINコネクタを使わず、Micro-B USBコネクタにPS/2の信号を流している。形状変換のためにUSB-PS/2変換アダプタを使った。 このアダプタはストレートで結線してあるだけで信号変換はされていません。USBコンボマウスに付属していたおまけ品。
  • 外部のメモリICは使わない。PIC内部のメモリになんとかしてデータを保存する。
  • 表面実装のPICは何かあった時に交換が難しいので、手持ちのDIPパッケージを使う。
  • 設定とデバッグ用のインターフェースはUSARTを使う。常時使う必要がないので、ヘッダピンを立てておくだけにする。
  • 初めて使うPS/2のデバッグ用途のため、状態表示のLEDはできるだけ残しておく。
  • ビアを作るのが面倒なので片面基板を使う。抵抗はできるだけ表面実装の部品を使う。
  • パターンの作成にEagleを使った。ワイヤはほとんどの部分で16milを使い、細くなり過ぎないように気を付けた。

回路図
パターン図

ケース・マウント

キャップ 基板の上部は半透明のキャップを使い、下部にUSBコネクタが挿せるようにスリットを切り込んでおきます。 基板はこのキャップに合うサイズで作り、うまく嵌まるように正円にカットします。 ガラスエポキシの基板は固く厚いので、カットと研磨に1時間ほどかかりました。

台座 基板を安定して固定し適度な重量で横倒しにならないように、東急ハンズに売っているφ50×10mmのアルミ円柱にM2のタップ加工をした台座を作りました。 売られているものは単にアルミをカットしただけの物なので、バリが多く表面も研磨されていません。 ペーパーで1時間ほど磨いてヘアライン加工を施します。

ソフトウエア

ソースリスト Ver.0.46
今回はフローチャートなどをほとんど書かずに作ったので、ソースがとても汚いです。
機能をどんどん詰め込んでいったので3ワードしか残っていません。プログラムの類似部分はかなり共通化したのですが、これ以上は限界です。

積極的に割り込み機能を使う

受信ルーチンや時間計測はポーリングをできる限り使わず、割り込みやタイマーモジュールを使います。 割り込みに任せているのは、リモコンのパルス幅計測(CCP1IF)、リモコンのトレーラ判定(TMR1IF)、リモコンのリピート有効時間判定(TMR0IF)、 USART送受信(TXIF,RCIF)、PS/2のクロック信号監視(INT0IF)となっています。 比較的近似したタイミングで多くの割り込みが発生するので、どれか一つのモジュールで割り込みが発生した場合、処理後にそのままリターンせず他のモジュールもチェックするようにしています。

リモコンコード解析関係

過去に製作したドリームライトTU-876CD用 赤外線リモコンモジュールでは独自の解析アルゴリズムを使っていました。 しかし、このアルゴリズムではソニーのリモコンコードを解析できないため、今回のプログラムではELMさんのサイトで公開されている赤外線リモコン制御モジュールを参考にさせていただきました。 キャプチャ(CCP)モジュールを使って信号パルスの間隔を測定し、3種類のリモコンコードの特性と比較・データの取り込みを行っています。

TU-876CD用のモジュールと同様に、リピートコードのタイムアウト特性を持たせるために、Timer0のオーバーフロー割り込みも追加で使っています。 これを応用することで、キーボードのコントロールパネルからキーリピートの待ち時間とリピート間隔を変更することができるようになっています。

PS/2通信関係

PS/2はPOSTで認識されていなければWindowsからも使えません。 いわゆるホットスワップができないデバイスなので、何とか認識させないとデバッグすらできずにとても困ります。 また、ポートの先にキーボードかマウスのどちらがつながっているのかIDを交換しているので、マウスで初期化したポートにキーボードをつないでも動作しません。

PS/2は半二重通信でI2Cのようにオープンドレインのバスなのですが、キーボードがクロックマスター側なのにもかかわらず、 PCからデータを送る時は無理やりクロックを止めて受信を要求してくる変態仕様です。 詳しい仕様はHOLTEKのキーボードコントローラHT82K629Aの資料などを利用すると良いのですが、エラーの復帰や再送の手順があいまいでよく解りませんので、 IBMの資料(物理層からデータリンク層あたり)とMicrosoftの資料(キースキャンコード関連)を参考にするのが一番良いと思います。一番下の参考文献にリンクを張っておきます。

キーデータの保存方法

キーデータ PIC16F88はプログラムの動作中にプログラムメモリを動的に書き換え・読み出すことができます。 これを利用してリモコンコードと送出キーストロークのデータをプログラムメモリに書き込みます。 プログラムメモリに書き込むメリットとして、1ワードあたり14bit記録することができる点があります。 通常データの8bitに加え、データサイズや終端マークなどの補助データとして6bit(0~63)のデータも保存できるのでとても便利です。

今回のプログラムではリモコンコード・キーコードと合わせてそれぞれのフィールドサイズを上位バイトに記録しています。 リモコンコードが長くなるとキーコードが短くなってしまいますが、リモコンコードは通常4~6バイト程度、キーコードは1つのキーあたり1バイトなので、長いキーストロークを記録させない限りオーバーする心配はありません。 データ長フィールドに10h以上の数値が入る事はデータ構造的にありえないため、不正な値が入っている場合は空きエリアとして検出する仕組みにしています。

右の例のキーコードを送出するには、受信したリモコンコードの長さとデータ内容が一致しているかを照合した後、12h・1Chのキー押さえデータを送出し、逆方向に1Ch・12hのキー離しデータを送出します。 こうすることで、同時押さえを可能にするとともに、離しのデータを明示的に書く必要がなくなります。

最終的にプログラムメモリの半分2kワードを、16ワード×64ボタン×2マップ構成の仕様としました。

設定画面

登録画面 リモコンコードの学習やキーストロークの編集はシリアルコンソールを使います。

setコマンドに続いて希望のリモコンのボタンを押さえると、対応しているリモコンであればリモコンコードの表示に続き、キーコードを16進数で入力できます。 リモコンコードを知っているのであればsetコマンドの後に手で入力する事もできます。後述のlsコマンドで表示させたものを少し加工すれば、流し込むことも可能です。

キーコードはPS/2のコードセット2に準じています。 キーの押さえはそのままコードを送信、キーの離しは頭にF0hを付けて送信、特殊キーはE0hに続いてコードを送るかE0h F0h コードのようにしてキー離しの意味にします。 E0hが付くかどうかはコードが90h以上かどうかで判断しています。90h以上ならば先行してE0hを送り、80hを引いた値を実際のスキャンコードとして送ります。 変態スキャンコードを持つPAUSEはうまい実装方法が見つからなかったので、旧コードで代用するようにしました。

リスト表示 lsコマンドを入力すると登録されているリモコンコードと、対応するキーコードの一覧を表示できます。 キーコード00はマップ切り替え、または、リピート送信OFFの意味です。

使ってみて分かった事

製作過程で苦労した点

PS/2に関する事

PS/2以外の事


参考文献

PS/2インターフェース関連

赤外線リモコン関連