i-SOBOTをPCからコントロール
はじめに
タカラトミーから『i-SOBOT』というロボットが発売されています。17個のサーボモーターに高さ17cmというコンパクトな筐体、音声認識やリモコンなどいたれりつくせりの内容でした。これは面白そう、ということで、さっそく息子と折半で購入してみたものの、リモコンのコマンドは覚えにくく、プリセットコマンドは多数あるけれども新しいコマンド(モーションというらしい)は作れず、リモコンに連続動作を覚えさせても3つまでの制約はあるし、作った動作を保存しておくことも出来ず、半日で飽きてしまいました。
でも、これではもったいないので、手始めに、PCから制御してみることにしました。幸い、リモコンは普通の赤外線コードのようなので、秋月電子のH8マイコンボードAKI-H8/3664を使って、赤外線リモコンの読み込みと出力が出来るボードを作成しました。
まずはこのボードで赤外線コードを調査してみました。結果がこれ。
学習リモコンの回路を作る
とりあえず、キャプチャするために学習リモコン回路を作ります。と言っても、たいした回路ではありません。ありあわせのマイコンボードや赤外線リモコン受光部(200円也)と、いらなくなったTV用リモコンから外した赤外線LEDをつなぐくらいです。以下、回路図。だいぶ省略していますが、赤外線LEDと受光部のVcc-GND間には積層セラミックコンデンサなどをいくつかつけてノイズ対策します。
受光部の出力は外部割込み(IRQ0/P14)に接続し、立下りエッジで割り込みを掛けてエッジ間の時間を計測します。本来はエッジ間の時間計測と、一定時間毎のHi/Lo計測を併用すべきなのでしょうが、そこはアマチュアということで、うんと省略します。
送信部は、タイマVの外部出力(TMOV/P76)に接続します。赤外線受光部は通常38kHzのフィルタが入っているため、送信部の赤外線LEDは38kHzの周波数で点滅させてやる必要があるのですが、ソフトで点滅させるには、13.15uSの割り込みかソフトタイマを使う必要があります。これはちょっと厳しいので、タイマVで38kHzのPWMを作ります。(といってもDutyは33%固定なので、初期設定で固定値をレジスタにセットするだけですが。)このPWMの出力をリモコンのビット単位でON/OFFしてやることによって赤外線コードを送信します。
トランジスタの2SC2240は、そのへんに転がっていたジャンクです。Ic=200mA程度流せるものならなんでもOKです。2SC1815とかでも多分OK。そもそもDuty33%のPWMなので、点灯しっぱなしでも平均電流は50mA程度しか流れないはずです。

デバッグ用に作ったものなので、けっこういいかげんです。外観。左側についているのは、秋月電子のUSB-シリアル変換ケーブル(M-720)です。外側のモールドを無理やりひっぺがして、5Vを直接取り出してH8/3664ボードに供給しています。最近のノートPCはCOMポートがついていないので、どうしてもUSB-シリアル変換ケーブルにお世話になる必要があります。

うらめん。いいかげんな配線。

表側、赤外線受光部と赤外線LEDが載っているところ。手前の透明な部品が赤外線LED、その左にわかりにくいですが赤外線受光部があります。赤外線LEDの左にはテスト用の赤色LED、その左には赤外線LEDをドライブするトランジスタがあります。左の奥にあるタクトスイッチは、黄色がリセットスイッチ、黒がNMIを発生させるスイッチです。NMIは、何も波形整形せずに使用していますが、チャタリングは少ないようです。10回に1回くらい、チャタリングで二重にNMIがかかることがあります。

i-SOBOTのリモコン波形
i-SOBOTのリモコン波形をソフトオシロでキャプチャしてみました。DCカットされているので波形が上下にふらついていますが、本来は0-5Vの矩形波です。この波形を見ると、世の中にあるリモコン(大きくは、家電協会方式とNEC方式が主流らしい)とは異なっているようです。とりあえず、いろいろなコマンドを送信して、その結果を見ると、なんとなく解釈できます。

i-SOBOTのリモコンコード(解析中)
分かる範囲で調べたのが以下の構成です。まだまだ要調査ですが、とりあえず、PCから制御するには、このフォーマットに従ってコードを送ってやると、リモコンと同じ動作は可能です。

2008.04.29現在、ここまで。
とりあえず、リモコンコードを受信したらPCに表示し、PCからコードを指定されたらそれをリモコンコードで送信するプログラムを掲載。あと、解析結果を以下に掲載。読み方は以下のとおり。
『左』『右』はそれぞれジョイスティックの操作。
①~⑧は、ジョイスティックの操作方向。
①:上、②:左上、③:左、④:左下、⑤:下、⑥:右下、⑦:右、⑧:右上。
区分の『連続』は操作中連続で同じコードが送信される。その場合、最後に連続コマンドの終了コードが送られる。
キー操作の『R』は、Rキーを押しながらの操作を表す。
Aコード、Bコードは、最初の4桁がコードのビット数(トレーラーを含む)で、次からの3バイトまたは4バイトが実際の送信コードとなる。MSBから出力される。最後のバイトが8ビットに満たない場合は、MSBから必要ビット数が有効になる。
リモコンのキー操作 |
動作 |
Aコード |
Bコード |
区分 |
左① |
前進 |
0015 6D B8 18 |
0015 4D B8 18 |
連続 |
左② |
左旋回 |
0015 7D C8 18 |
0015 5D C8 18 |
連続 |
左③ |
左 |
0015 4D D8 18 |
0015 6D D8 18 |
連続 |
左④ |
左後方旋回 |
0015 65 E8 18 |
0015 45 E8 18 |
連続 |
左⑤ |
後退 |
0015 75 C0 18 |
0015 55 C0 18 |
連続 |
左⑥ |
右後方旋回 |
0015 6D F0 18 |
0015 4D F0 18 |
連続 |
左⑦ |
右 |
0015 55 E0 18 |
0015 75 E0 18 |
連続 |
左⑧ |
右旋回 |
0015 45 D0 18 |
0015 65 D0 18 |
連続 |
右① |
前かがみ |
0015 66 B8 30 |
0015 6E B8 30 |
連続 |
右⑤ |
後に反る |
0015 7E B8 08 |
0015 46 B8 08 |
連続 |
右③ |
顔を左に向ける |
0015 6E B8 38 |
0015 76 B8 38 |
連続 |
右⑦ |
顔を右に向ける |
0015 5E B8 60 |
0015 66 B8 60 |
連続 |
R |
ホームポジション |
001D 34 24 04 00 |
001D 14 24 04 00 |
連続 |
R左① |
左腕を上げる |
001D 2C 27 84 00 |
001D 34 27 84 00 |
連続 |
R左③ |
左腕を左に広げる |
001D 30 A4 04 00 |
001D 10 A4 04 00 |
連続 |
R左⑤ |
左腕を下げる |
001D 34 20 84 00 |
001D 14 20 84 00 |
連続 |
R左⑦ |
左腕を右に曲げる |
001D 2F A4 04 00 |
001D 37 A4 04 00 |
連続 |
R右① |
右腕を上げる |
001D 34 3C 24 00 |
001D 34 3C 24 C0 |
連続 |
R右③ |
右腕を左に曲げる |
001D 34 24 00 80 |
001D 14 24 00 80 |
連続 |
R右⑤ |
右腕を下げる |
001D 34 04 24 00 |
001D 14 04 24 00 |
連続 |
R右⑦ |
右腕を右に広げる |
001D 2C 24 07 80 |
001D 34 24 07 80 |
連続 |
|
連続コマンドの終了 |
0015 6E B8 00 |
0015 4E B8 00 |
|
|
|
|
|
|
1P |
左パンチ |
0015 70 98 00 |
0015 50 98 00 |
単発 |
2P |
右パンチ |
0015 78 A0 00 |
0015 58 A0 00 |
単発 |
3P |
左裏拳 |
0015 40 A8 00 |
0015 60 A8 00 |
単発 |
4P |
右裏拳 |
0015 48 B0 00 |
0015 68 B0 00 |
単発 |
12P |
左右ワンツーツーパンチ |
0015 50 B8 00 |
0015 70 B8 00 |
単発 |
21P |
右左ワンツーツーパンチ |
0015 60 C0 00 |
0015 48 C0 00 |
単発 |
11P |
左チョップ |
0015 68 C8 00 |
0015 50 C8 00 |
単発 |
22P |
右チョップ |
0015 70 D0 00 |
0015 58 D0 00 |
単発 |
33P |
両手振り下ろしチョップ |
0015 78 D8 00 |
0015 60 D8 00 |
単発 |
44P |
両手アッパーチョップ |
0015 40 E0 00 |
0015 68 E0 00 |
単発 |
1234P |
パンチ系組み合わせ |
0015 48 E8 00 |
0015 70 E8 00 |
単発 |
14P |
左裏拳斜振り下ろし |
0015 50 F0 00 |
0015 78 F0 00 |
単発 |
23P |
右裏拳斜振り下ろし |
0015 58 F8 00 |
0015 40 F8 00 |
単発 |
43P |
往復ビンタ |
0015 69 00 00 |
0015 51 00 00 |
単発 |
34P |
両手裏拳 |
0015 71 08 00 |
0015 59 08 00 |
単発 |
|
|
|
|
|
1K |
左側面キック |
0015 79 10 00 |
0015 61 10 00 |
単発 |
2K |
右側面キック |
0015 41 18 00 |
0015 69 18 00 |
単発 |
3K |
左正面キック |
0015 49 20 00 |
0015 71 20 00 |
単発 |
4K |
右正面キック |
0015 51 28 00 |
0015 79 28 00 |
単発 |
11K |
左カンフーキック |
0015 59 30 00 |
0015 41 30 00 |
単発 |
22K |
右カンフーキック |
0015 61 38 00 |
0015 49 38 00 |
単発 |
33K |
左後まわし蹴り |
0015 71 40 00 |
0015 59 40 00 |
単発 |
44K |
右後まわし蹴り |
0015 79 48 00 |
0015 61 48 00 |
単発 |
31K |
左サッカーキック |
0015 41 50 00 |
0015 69 50 00 |
単発 |
42K |
右サッカーキック |
0015 49 58 00 |
0015 71 58 00 |
単発 |
12K |
左右連続キック |
0015 51 60 00 |
0015 79 60 00 |
単発 |
21K |
右左連続キック |
0015 59 68 00 |
0015 41 68 00 |
単発 |
1234K |
組み合わせキック |
0015 61 70 00 |
0015 49 70 00 |
単発 |
13K |
左ハイキック&振り下ろし |
0015 69 78 00 |
0015 51 78 00 |
単発 |
24K |
右ハイキック&振り下ろし |
0015 79 80 00 |
0015 61 80 00 |
単発 |
34K |
叉開き |
0015 41 88 00 |
0015 69 88 00 |
単発 |
|
|
|
|
|
1G |
左手頭上ガード |
0015 49 90 00 |
0015 71 90 00 |
単発 |
2G |
右手頭上ガード |
0015 51 98 00 |
0015 79 98 00 |
単発 |
3G |
左手顔前、右手胸ガード |
0015 59 A0 00 |
0015 41 A0 00 |
単発 |
4G |
右手顔前、左手胸ガード |
0015 61 A8 00 |
0015 49 A8 00 |
単発 |
11G |
左よけ |
0015 69 B0 00 |
0015 51 B0 00 |
単発 |
22G |
右よけ |
0015 71 B8 00 |
0015 59 B8 00 |
単発 |
33G |
前かがみ |
0015 49 C0 00 |
0015 69 C0 00 |
単発 |
44G |
スウェーバック |
0015 51 C8 00 |
0015 71 C8 00 |
単発 |
12G |
両手頭上ガード |
0015 59 D0 00 |
0015 79 D0 00 |
単発 |
34G |
開脚すわり(しりもち) |
0015 61 D8 00 |
0015 41 D8 00 |
単発 |
1234G |
ガード組み合わせ |
0015 69 E0 00 |
0015 49 E0 00 |
単発 |
|
|
|
|
|
1A |
肯定1 |
0015 41 F8 00 |
0015 61 F8 00 |
単発 |
2A |
肯定2 |
0015 52 00 00 |
0015 72 00 00 |
単発 |
3A |
否定1 |
0015 5A 08 00 |
0015 7A 08 00 |
単発 |
4A |
否定2 |
0015 62 10 00 |
0015 42 10 00 |
単発 |
11A |
会う1 |
0015 6A 18 00 |
0015 4A 18 00 |
単発 |
12A |
会う2 |
0015 72 20 00 |
0015 52 20 00 |
単発 |
13A |
会う3 |
0015 7A 28 00 |
0015 5A 28 00 |
単発 |
14A |
会う4 |
0015 42 30 00 |
0015 62 30 00 |
単発 |
21A |
会う5 |
0015 4A 38 00 |
0015 6A 38 00 |
単発 |
22A |
会う6 |
0015 5A 40 00 |
0015 7A 40 00 |
単発 |
23A |
会う7 |
0015 62 48 00 |
0015 42 48 00 |
単発 |
31A |
別れる1 |
0015 6A 50 00 |
0015 4A 50 00 |
単発 |
32A |
別れる2 |
0015 72 58 00 |
0015 52 58 00 |
単発 |
33A |
別れる3 |
0015 7A 60 00 |
0015 5A 60 00 |
単発 |
34A |
別れる4 |
0015 42 68 00 |
0015 62 68 00 |
単発 |
41A |
感謝1 |
0015 4A 70 00 |
0015 6A 70 00 |
単発 |
42A |
感謝2 |
0015 52 78 00 |
0015 72 78 00 |
単発 |
43A |
感謝3 |
0015 62 80 00 |
0015 42 80 00 |
単発 |
111A |
ラブ1 |
0015 6A 88 00 |
0015 4A 88 00 |
単発 |
222A |
ラブ2 |
0015 72 90 00 |
0015 52 90 00 |
単発 |
333A |
ラブ3 |
0015 7A 98 00 |
0015 5A 98 00 |
単発 |
11B |
お祝い1 |
0015 42 A0 00 |
0015 62 A0 00 |
単発 |
12B |
お祝い2 |
0015 4A A8 00 |
0015 6A A8 00 |
単発 |
13B |
よろこび1 |
0015 52 B0 00 |
0015 72 B0 00 |
単発 |
14B |
よろこび2 |
0015 5A B8 00 |
0015 7A B8 00 |
単発 |
21B |
よろこび3 |
0015 6A C0 00 |
0015 52 C0 00 |
単発 |
22B |
よろこび4 |
0015 72 C8 00 |
0015 5A C8 00 |
単発 |
23B |
怒る1 |
0015 7A D0 00 |
0015 62 D0 00 |
単発 |
24B |
怒る2 |
0015 42 D8 00 |
0015 6A D8 00 |
単発 |
31B |
泣く |
0015 4A E0 00 |
0015 72 E0 00 |
単発 |
32B |
悲しい1 |
0015 52 E8 00 |
0015 7A E8 00 |
単発 |
33B |
悲しい2 |
0015 5A F0 00 |
0015 42 F0 00 |
単発 |
34B |
悲しい3 |
0015 62 F8 00 |
0015 4A F8 00 |
単発 |
41B |
悲しい4 |
0015 73 00 00 |
0015 5B 00 00 |
単発 |
42B |
傷つく |
0015 7B 08 00 |
0015 63 08 00 |
単発 |
43B |
あやまる1 |
0015 43 10 00 |
0015 6B 10 00 |
単発 |
44B |
あやまる2 |
0015 4B 18 00 |
0015 73 18 00 |
単発 |
112B |
ポーズ1 |
0015 53 20 00 |
0015 7B 20 00 |
単発 |
112A |
ポーズ2 |
0015 5B 28 00 |
0015 43 28 00 |
単発 |
113A |
ポーズ3 |
0015 63 30 00 |
0015 4B 30 00 |
単発 |
114A |
ポーズ4 |
0015 6B 38 00 |
0015 53 38 00 |
単発 |
121A |
ポーズ5 |
0015 7B 40 00 |
0015 63 40 00 |
単発 |
122A |
ポーズ6 |
0015 43 48 00 |
0015 6B 48 00 |
単発 |
123A |
ポーズ7 |
0015 4B 50 00 |
0015 73 50 00 |
単発 |
124A |
おもしろアクション1 |
0015 53 58 00 |
0015 7B 58 00 |
単発 |
131A |
おもしろアクション2 |
0015 5B 60 00 |
0015 43 60 00 |
単発 |
132A |
おもしろアクション3 |
0015 63 68 00 |
0015 4B 68 00 |
単発 |
113B |
挫折 |
0015 6B 70 00 |
0015 53 70 00 |
単発 |
114B |
楽しい1 |
0015 73 78 00 |
0015 5B 78 00 |
単発 |
121B |
楽しい2 |
0015 43 80 00 |
0015 6B 80 00 |
単発 |
122B |
楽しい3 |
0015 4B 88 00 |
0015 73 88 00 |
単発 |
123B |
楽しい4 |
0015 53 90 00 |
0015 7B 90 00 |
単発 |
124B |
おどろき |
0015 5B 98 00 |
0015 43 98 00 |
単発 |
131B |
ほめる1 |
0015 63 A0 00 |
0015 4B A0 00 |
単発 |
132B |
ほめる2 |
0015 6B A8 00 |
0015 53 A8 00 |
単発 |
133B |
笑い1 |
0015 73 B0 00 |
0015 5B B0 00 |
単発 |
134B |
笑い2 |
0015 7B B8 00 |
0015 63 B8 00 |
単発 |
141B |
笑い3 |
0015 53 C0 00 |
0015 73 C0 00 |
単発 |
142B |
あぐら |
0015 5B C8 00 |
0015 7B C8 00 |
単発 |
143B |
脚を投げ出してすわる |
0015 63 D0 00 |
0015 43 D0 00 |
単発 |
144B |
ウェーブ1 |
0015 6B D8 00 |
0015 4B D8 00 |
単発 |
211B |
ウェーブ2 |
0015 73 E0 00 |
0015 53 E0 00 |
単発 |
212B |
横に寝る→尻をかく |
0015 7B E8 00 |
0015 5B E8 00 |
単発 |
213B |
落し物を拾う |
0015 43 F0 00 |
0015 63 F0 00 |
単発 |
214B |
ボディーランゲージ |
0015 4B F8 00 |
0015 6B F8 00 |
単発 |
221B |
のんびりする |
0015 5C 00 00 |
0015 7C 00 00 |
単発 |
222B |
伸び上がる |
0015 64 08 00 |
0015 44 08 00 |
単発 |
223B |
サッカーキック |
0015 6C 10 00 |
0015 4C 10 00 |
単発 |
224B |
まかせとけ |
0015 74 18 00 |
0015 54 18 00 |
単発 |
231B |
ブリッジ |
0015 7C 20 00 |
0015 5C 20 00 |
単発 |
232B |
腕立て伏せ |
0015 44 28 00 |
0015 64 28 00 |
単発 |
233B |
開脚腕立て伏せ |
0015 4C 30 00 |
0015 6C 30 00 |
単発 |
234B |
後ろ腕立て伏せ |
0015 54 38 00 |
0015 74 38 00 |
単発 |
241B |
逆立ち |
0015 64 40 00 |
0015 44 40 00 |
単発 |
242B |
物運び |
0015 6C 48 00 |
0015 4C 48 00 |
単発 |
411A |
決めポーズ1 |
0015 5E 38 00 |
0015 7E 38 00 |
単発 |
412A |
決めポーズ2 |
0015 6E 40 00 |
0015 4E 40 00 |
単発 |
413A |
決めポーズ3 |
0015 76 48 00 |
0015 56 48 00 |
単発 |
444A |
休む |
0015 46 58 00 |
0015 66 58 00 |
単発 |
444B |
ゼロポジション |
0015 7E 50 00 |
0015 5E 50 00 |
単発 |
A |
うつ伏せから起き上り |
0015 71 E8 00 |
0015 51 E8 00 |
単発 |
B |
仰向けから起き上り |
0015 79 F0 00 |
0015 59 F0 00 |
単発 |
i-SOBOTリモコンコード解析&送信プログラム(テスト版)
i-SOBOTのリモコンコードを解析するプログラムrmtest05.zip(AKI-H8/3664用)と、PCからi-SOBOTのリモコンコードを送出するテストプログラムtest.zip(PC用)を暫定版ですが公開します。
ライセンスはBSDです。ご自由にご利用ください。(とは言っても、ここで使った回路と同じものを作らないと意味ありませんが)
このrmtest05.absは、このホームページで公開している、AKI-H8/3664用デバッガ・ADBG3664の環境を前提に作られています。実行開始番地は0x1000、スタックポインタの初期値は0xff7cです。もし、これらと異なる環境で使用する場合は、subファイルで指定している配置と、ベクタ&スタートアップルーチンのromv3664.srcを修正してお使いください。
このプログラムは、タイマーA、W、V、IRQ0、SCI3を使用します。割り込みはタイマーA、タイマーW、IRQ0の3つを使用します。かなり効率の悪い使い方をしていますが、実験しながら作ったのでつぎはぎになってしまっています。H8を使うのは今回が初めてなもので・・・。そのうち整理してもう少し改造しやすいように修正する予定です。
動かし方:
ADBG3664+adebug.exe が動いている環境で、
>LO RMTEST05.ABS
>R PC 0x1000
>R SP 0xFF7C
>G
とコマンドラインから入力してください。この状態では、i-SOBOTのリモコンのキーが押されると、そのリモコンコードを解析して、ホストPCに送信してきます。
この状態で、一旦デバッガを終了(CTRL-Cでブレークするか、ESCキーを押して抜ける)し、上記のtest.exe
をコマンドラインから起動します。テスト用の送信コードファイル(testcode.txt)を渡してやると、そのコードを送信しはじめます。
送信コードファイルは、通常のテキストファイルで、送信ビット数、送信データがスペースで区切られて書かれています。カンマの後に、コード送信後の待ち時間(単位:mS)があり、セミコロン以下がコメントです。
あと、test.exe は -cN (N = 1 .. 9)で送信するCOMポートを指定します。実行例は以下の通り。

電源投入直後から動作させるには、ユーザープログラム優先実行フラグを書き込みます。
デバッガのコマンドラインから
>USR
と打ち込むと、ユーザープログラム優先実行フラグが立ち、次回の起動時はデバッガは起動せず、ユーザープログラムが直接実行されます。
ダウンロード
秋月電子 AKI-H8/3664側 rmtest05.zip
PC側 test.zip
おまけ:printf()のサブセット関数同梱
rmtest05.zip の中に、aprintf.c というCのソースファイルが入っています。この中の関数
aprintf()は自作の printf() のサブセット関数になっています。浮動小数点と精度指定はサポートしていませんが、それ以外はだいたいサポートしています。staticを使わないので、マルチタスク/マルチスレッド環境でも使用可能です。%sの右詰/左詰出力はバッファをより多く使用しますので、長い文字列を扱いたい場合は、ソースの中のCONVBUFFLENを大きくしてください(デフォルト16文字)。
もともと32bitの組み込み用RISC(もう無くなってしまったが・・・)の環境に合わせて作ったので、H8のノーマルモード(ポインタが16ビット)には合わない部分があり、修正しきれていないかも知れません。気づいた点は教えていただけるとうれしい。
top