赤外線学習リモコンの信号定義データの合成/家製協フォーマット編¶
はじめに¶
IRKitやKURO-RS、クロッサム2+などのプログラマブルな学習リモコンの信号データを、リモコン同士ツノつき合わせて学習させるのではなく、PC上で理想的な波形に合成するためのノウハウです。
信号データが合成できると、以下のようなメリットが期待できます。
- なまっていない、きれいな信号が出せるようになるので、機器の反応が良くなる。
- いつでも欲しいときにデータが合成できるので、学習したデータの保存に気を使わなくてもよくなる。
- 機器付属のリモコンでは送れない、未知のコマンドを探求できる(笑)。
このページでは家製協フォーマットを取り上げます (動作確認はPanasonic製BS/110度CS/地デジチューナー [TU-MHD500] で行ないました)。
リモコン信号の詳細¶
「家製協 (家電製品協会/AEHA) フォーマット」と呼ばれているもの。
フォーマット¶
+-----------------------------------------------------
| リーダー部 | データ部 | トレーラー部 | ...
+-----------------------------------------------------
リーダー部¶
ON(8T)→OFF(4T)
Tは0.35〜0.5msと規定されている。典型的には中央値0.425msを使用する。
データ部¶
3バイト以上・任意バイト数の送信データ。各バイトはLSB first。
データ「0」は ON(1T)→OFF(1T)
データ「1」は ON(1T)→OFF(3T)
なお、データの内容は
- 1〜2バイト目がカスタムコード (ベンダー/機器の識別)
- 3バイト目以降がデータコード (コマンド等)
コードの具体的な値は後述。
トレーラー部¶
ON(1T)→OFF(nn)
nnは8ms以上と規定されている。Panasonic製デジタルチューナー付属のリモコンの場合は約75ms。
キャリア周波数¶
赤外線LEDの発光時 (ON時) の点滅周波数。
33〜40kHzが推奨されている。典型的には中央値に近い36.7kHzを使用する。
IRKit用信号定義データへの変換方法¶
データ形式¶
- 家製協フォーマットのIRKit用信号定義データは以下のようになる (キャリア周波数 38kHz、T=0.425ms、トレーラー長 75msの場合)。IRKitに関する詳細な技術情報は 公式サイト を参照のこと。
{ : JSON形式 "format":"raw", ; 定数 "freq":38, ; キャリア周波数。38と40しかないので38を選ぶ。 "data":[ ; ここから信号データ。 6800,3400, ; リーダー。ON(8T)→OFF(4T)。 ; [0.425ms*2MHz*8=6800, 0.425ms*2MHz*4=3400] 850,850, ; データ「0」のとき。ON(1T)→OFF(1T) 850,2550, ; データ「1」のとき。ON(1T)→OFF(3T) ; (送信データのビット数分続く) 850,2550, 850,65535, ; トレーラー。ON(1T)→OFF(75ms) 0,65535, ; [75ms*2MHz=150000=65535+65535+18930] 0,18930 ]} ; JSONおわり
サンプルコード¶
- 送信データを家製協フォーマットにエンコードするperlのサンプルコードを示す。
#! /usr/bin/perl # データはコマンド行引数に16進数の列で与える @data = map { hex($_) & 0xff } @ARGV; # データを0/1列に変換 $bytes = scalar (@data); $bits = $bytes * 8; $data = unpack ("b$bits", pack ("C" x $bytes, @data)); # 出力の作成 $f = 38; # キャリア周波数は38kHz (IRKitには38と40しかない) $t = 0.425 * 2000; # T=0.425ms $len = 135 * 2000; # 1送信単位を135msとする # JSON open $json = qq({\n); $json .= qq("format":"raw",\n); $json .= qq("freq":$f,\n); $json .= qq("data":[\n); # リーダー部 ON(8T)->OFF(4T) $json .= (8 * $t) . "," . (4 * $t) . ",\n"; $len -= 12 * $t; # データ部 0:ON(1T)->OFF(1T), 1:ON(1T)->OFF(3T) foreach $bit (split ("", $data)) { if ($bit eq "0") { $json .= (1 * $t) . "," . (1 * $t) . ",\n"; $len -= 2 * $t; } else { $json .= (1 * $t) . "," . (3 * $t) . ",\n"; $len -= 4 * $t; } } # トレーラー部 ON(1T)->OFF(Nms) Nはここまでの全体が1送信単位(135ms)になるように決める $json .= (1 * $t) . ","; $len -= 1 * $t; $len = 8 * 2000 if ($len < 8 * 2000); # 最小8ms while ($len > 0) { if ($len >= 65536) { $json .= "65535,\n0,"; $len -= 65535; } else { $json .= "$len\n"; last; } } # JSON close $json .= "]}\n"; # ベタ書きにしたいとき #$json =~ s/\n//sg; #$json .= "\n"; # 画面に出力 print $json; # IRKitに直接コマンド発行 #$json =~ s/\n//sg; #system qq(curl -s -i 'http://192.168.xx.xx/messages' -d '$json');
このようにして作成したデータを、http POSTプロトコルでIRKitに送信する。
KURO-RS(玄人志向)/PC-OP-RS1(Buffalo)用信号定義データへの変換方法¶
データ形式¶
- KURO-RSとPC-OP-RS1 (同一ハードウェア) の信号定義データは、10kHz (0.1msごと) でサンプリングしたLED ON/OFFのrawデータを192ms分 (1920ビット) のフレームにパックして与える。キャリア周波数は指定できない。
111111111111 : ON 1.2ms 0000 ; OFF 0.4ms 1111111111 : ON 1.0ms 000000 ; OFF 0.6ms : 0000000000 ; 全体が1920ビットになるようにパディング
サンプルコード¶
- 送信データを家製協フォーマットにエンコードするperlのサンプルコードを示す。
#! /usr/bin/perl # データはコマンド行引数に16進数の列で与える @data = map { hex($_) & 0xff } @ARGV; # データを0/1列に変換 $bytes = scalar (@data); $bits = $bytes * 8; $data = unpack ("b$bits", pack ("C" x $bytes, @data)); # リーダー部 ON(8T)->OFF(4T) T = 0.4ms $raw = "1" x 32 . "0" x 16; # データ部 0:ON(1T)->OFF(1T), 1:ON(1T)->OFF(3T) $b[0] = "1" x 4 . "0" x 4; $b[1] = "1" x 4 . "0" x 12; $data =~ s/./$b[$&]/ge; $raw .= $data; # トレーラー部 ON(1T)->OFF(Nms) Nはここまでの全体が1送信単位(192ms)になるように決める $raw .= "1" x 4; $raw = substr ($raw . "0" x 1920, 0, 1920); # 画面に出力 (1/0列のまま) print $raw, "\n"; # バイナリに変換 $raw = pack ("b1920", $raw)
このようにして作成したデータを、KURO-RS等が接続されたUSBシリアルポートにコマンドと共に送信する。
クロッサム2+用信号定義データへの変換方法¶
データ形式¶
- 家製協フォーマットのクロッサム2+用信号定義データは以下のようになる (キャリア周波数 36.7kHz、T=0.425ms、トレーラー長 75msの場合)。
00 ; おまじない。 04 ; 信号波形定義の数。 ひと組の波形定義で「ON→OFF→」の一周期分を定義する。 22 ; キャリア周波数を決める分周比 [2.5MHz/36.7kHz/2=34.1≒0x22]。 ; --- ここから信号波形定義 --- 260400 260400 ; データ「0」の波形。ON(1T)→OFF(1T)、すなわち ONが0x000426クロック継続したあとOFFが0x000426クロック継続 [1T=0.425ms*2.5MHz=1062.5≒0x426]。 260400 730c00 ; データ「1」の波形。ON(1T)→OFF(3T)。 342100 9a1000 ; リーダーの波形。ON(8T)→OFF(4T)。 260400 6cdc02 ; トレーラーの波形。ON(1T)→OFF(75ms)。 ; --- ここから送信信号の定義 --- 2 ; リーダー (波形「2」) 01101001 ; データ1バイト目 (0=波形「0」/1=波形「1」) 10010110 ; 2バイト目 01101001 ; 3バイト目 : 10010110 ; nバイト目 3 ; トレーラー (波形「3」) feXX ; 直前のXX波形を永久に繰り返す、という制御コード。 XXには直前の「2...3」の文字数を入れる。 これにより、ボタンを押している間リーダー〜トレーラーの信号が出続ける。
サンプルコード¶
- 送信データを家製協フォーマットにエンコードするperlのサンプルコードを示す。
#! /usr/bin/perl sub b8 { local($_) = shift; return join("", reverse(split("", sprintf("%08b", $_)))); } sub hh3 { local($_) = shift; return join("", (split("", sprintf("%06x", $_)))[4,5,2,3,0,1]); } # データはコマンド行引数に16進数の列で与える @data = map { hex($_) & 0xff } @ARGV; # 出力の作成 $f = 2500 / 36.7 / 2; # キャリア周波数は36.7kHz $t = 0.425 * 2500; # T=0.425ms $nn = 75 * 2500; # トレーラー長は75ms $out = "00\n"; $out .= "04\n"; $out .= sprintf("%02x\n", $f); $out .= hh3(1*$t)." ".hh3(1*$t)."\n"; $out .= hh3(1*$t)." ".hh3(3*$t)."\n"; $out .= hh3(8*$t)." ".hh3(4*$t)."\n"; $out .= hh3(1*$t)." ".hh3($nn)."\n"; $out .= "2\n"; foreach (@data) { $out .= b8($_)."\n"; } $out .= "3\n"; $out .= sprintf("fe%02x\n", @data * 8 + 2); # ベタ書きにしたいとき (クロッサム・エクスプローラ風) #$out =~ s/[^0-9a-f]//g; #$out .= "\n"; # バイトごとに分かち書きしたいとき (Sweet Memories風) #$out =~ s/[^0-9a-f]//g; #$out =~ s/(..)/$&,/g; #$out =~ s/.*/"$&"\n/; print $out;
このようにして作成したデータを、 Sweet Memories 等によりクロッサム2+に転送する。
Panasonic製デジタルチューナー [TU-MHD500] のリモコンコード¶
全体構成¶
カスタムコードを含め、6バイトで構成されている。
- 1〜4バイト目は「02 20 80 0f」で固定。
- 5バイト目は、リモコンのボタンごとに異なる機能コード (下記)。
- 6バイト目は、3〜5バイト目のパリティ。
各ボタンの機能コード¶
コード | ボタン | コード | ボタン | コード | ボタン |
---|---|---|---|---|---|
50 | 画面表示 | 74 | チャンネル+ | b0 | (CS) 1 |
52 | 戻る | 75 | チャンネル- | b1 | (CS) 2 |
53 | 決定 | 76 | 前選局 | b2 | (CS) 3 |
54 | メニュー | 77 | お好み選局 | b3 | (CS) 4 |
55 | 番組表 | 80 | 音声切替 | b4 | (CS) 5 |
56 | 文字クリア | 81 | 字幕 | b5 | (CS) 6 |
58 | 番組内容 | 85 | 番組ナビ | b6 | (CS) 7 |
5a | カーソル← | 87 | 便利機能 | b7 | (CS) 8 |
5b | カーソル→ | 89 | 文字切替 | b8 | (CS) 9 |
5d | カーソル↑ | 8a | Tnavi | b9 | (CS) 10/0 |
5e | カーソル↓ | 8b | ネット操作 | ba | (CS) 11/* |
5f | 元の画面 | 8d | 電源 | bb | (CS) 12/# |
60 | 1 | 90 | データ/d | c0 | (地上D) 1 |
61 | 2 | 91 | 青 | c1 | (地上D) 2 |
62 | 3 | 92 | 赤 | c2 | (地上D) 3 |
63 | 4 | 93 | 緑 | c3 | (地上D) 4 |
64 | 5 | 94 | 黄 | c4 | (地上D) 5 |
65 | 6 | 9e | 機器操作 | c5 | (地上D) 6 |
66 | 7 | a0 | (BS) 1 | c6 | (地上D) 7 |
67 | 8 | a1 | (BS) 2 | c7 | (地上D) 8 |
68 | 9 | a2 | (BS) 3 | c8 | (地上D) 9 |
69 | 10/0 | a3 | (BS) 4 | c9 | (地上D) 10/0 |
6a | 地上 | a4 | (BS) 5 | ca | (地上D) 11/* |
6b | BS | a5 | (BS) 6 | cb | (地上D) 12/# |
6c | CS 1/2 | a6 | (BS) 7 | ||
6f | 11/# | a7 | (BS) 8 | ||
70 | 12/* | a8 | (BS) 9 | ||
71 | チャンネル番号入力 | a9 | (BS) 10/0 | ||
72 | 放送切替 | aa | (BS) 11/* | ||
73 | サービス切替 | ab | (BS) 12/# |
参考¶
- 上記各perlスクリプトの入力部分、すなわち
# データはコマンド行引数に16進数の列で与える @data = map { hex($_) & 0xff } @ARGV;
- の部分を以下のように改変すれば、機能コードを与えるだけで特定ボタンのリモコン信号定義を自動生成できる。
# 機能コードはコマンド行引数に16進数1個で与える @data = ( 0x02, 0x20, 0x80, 0x0f, hex(shift) & 0xff ); $data[5] = $data[2] ^ $data[3] ^ $data[4]; # 6バイト目はパリティ
改版履歴¶
Ver 1.0: 2004/1/22 - クロッサム2+向けに執筆
Ver 1.1: 2014/11/24 - IRKit、KURO-RS/PC-OP-RS1向けに加筆 (家製協のみ)、信号解析のページを追加
本稿の内容は、独自の調査・解析の結果にもとづくものであり、内容の正確性については保証いたしません。自己責任にてご利用ください。