2. NEC フォーマットの信号データ合成¶
黒豆や IRKit, KURO-RS, クロッサム2+ などのプログラマブルな学習リモコン (スマートリモコン) の信号データを、リモコン同士ツノつき合わせて学習させるのではなく、PC 上で理想的な波形に合成するためのノウハウです。
- 赤外線リモコンの信号定義データの合成 [表紙]
- 家製協フォーマットの信号データ合成
- NEC フォーマットの信号データ合成 (このページ)
- ソニーフォーマットの信号データ合成
- 黒豆, IRKit, KURO-RS によるリモコン信号の解析
- 機器付属リモコンのコード
このページでは NEC フォーマットを取り上げます。
2.1. リモコン信号の詳細¶
「NEC フォーマット」と呼ばれているもの。
フォーマット¶
+---------------------------------------------------------------------
| リーダー部 | データ部 | トレーラー部 | リピートコード | ...
+---------------------------------------------------------------------
リーダー部¶
ON(16T)→OFF(8T)
Tは(9/16)msec。
データ部¶
4バイト (32 bit) の送信データ。
データ「0」は ON(1T)→OFF(1T)
データ「1」は ON(1T)→OFF(3T)
なお、データの内容は
- 最初の2バイトがカスタムコード (ベンダー/機器の識別)
- 3バイト目がデータコード (コマンド等)
- 4バイト目が3バイト目の補数 (チェック用)
である (LSB first)。コードの具体的な値 (東芝製 DVD/HDD レコーダーの例) は後述。
トレーラー部¶
ON(1T)→OFF(nnT)
nnは、リーダー+データ+トレーラーの合計が192T (108msec)になるように決める。
リピートコード¶
リモコンのボタンを押している間、出続けるコード。
ON(16T)→OFF(4T)→ON(1T)→OFF(171T)
キャリア周波数¶
赤外線 LED の発光時 (ON時) の点滅周波数。38kHz。
2.2. RM mini3 / eRemote mini 用信号定義データへの変換方法¶
この節は以下のページを参考にしました。
- https://qiita.com/kt-sz/items/1c36a7b22a58359a8e6f
- https://github.com/mjg59/python-broadlink/blob/master/protocol.md
データ形式¶
NEC フォーマットの Broadlink RM mini3 (通称「黒豆」), LinkJapan eRemote mini 用信号定義データは以下のようになる。
26 ; おまじない
00 ; 信号送出の繰り返し回数 (0=単発, 1=2回送出, ...)
48 00 ; この後に続くバイト数 (little endian)。72バイト=0x0048バイト
00 01 27 90 ; リーダー。ON(16T)→OFF(8T)、T=(9/16)msec
ONが0x0127クロック続いた後、OFFが0x90クロック続く
クロック周波数は (269/8192)GHz
[16T=16*(9/16)msec*(269/8192)GHz=295.5≒0x127]
信号長が1バイトに収まらないときは、0x00に続いて2バイトのbig endianで表現する
12 12 ; データ「0」。ON(1T)→OFF(1T)
12 36 ; データ「1」。ON(1T)→OFF(3T)
: (32ビット分続く)
12 00 0d 05 ; トレーラー。ON(1T)→OFF(nnT)
; OFF部分は0x00 0x0d 0x05で固定
サンプルコード¶
送信データを NEC フォーマットにエンコードする perl のサンプルコードを示す。
#! /usr/bin/perl
# データはコマンド行引数に16進数の列で与える
@data = (map { hex($_) & 0xff } @ARGV)[0..3];
$data[3] = 0xff - $data[2] if (@ARGV < 4);
# データを0/1列に変換
$bytes = scalar (@data); $bits = $bytes * 8;
$data = unpack ("b$bits", pack ("C" x $bytes, @data));
# 出力の作成
$t = 9000.0 / 16 * 269 / 8192; # T=(9/16)msec
# パケットヘッダ
$code = "26\n00\n";
$code .= sprintf ("%02x %02x\n", ($bits * 2 + 8) % 256, ($bits * 2 + 8) / 256);
# 信号部
# --- リーダー部 ON(16T)->OFF(8T)
$code .= sprintf ("00 %02x %02x %02x\n", (16 * $t) / 256, (16 * $t) % 256, 8 * $t);
# --- データ部 0:ON(1T)->OFF(1T), 1:ON(1T)->OFF(3T)
$len = 192;
foreach $bit (split ("", $data)) {
if ($bit eq "0") {
$code .= sprintf ("%02x %02x\n", 1 * $t, 1 * $t);
} else {
$code .= sprintf ("%02x %02x\n", 1 * $t, 3 * $t);
}
}
# --- トレーラー部 ON(1T)->OFF(NNmsec)
$code .= sprintf ("%02x 00 0d 05\n", 1 * $t);
# ベタ書きにしたいとき
# $code =~ s/\s//sg;
# $code .= "\n";
# 画面に出力
print $code;
# 黒豆に直接コマンド発行 (python-broadlinkを利用)
# $code =~ s/\s//sg;
# $device = "0x2737 192.168.xx.xx yyyyyyyyyyyy"; # broadlink_discoverの返値
# system "broadlink_cli --device '$device' --send '$code'";
このようにして作成したデータを、python-broadlink, BlackBeanControl 等で黒豆に転送する。
2.3. クロッサム2+ 用信号定義データへの変換方法¶
データ形式¶
NEC フォーマットのクロッサム2+ 用信号定義データは以下のようになる。
00 ; おまじない。
06 ; 信号波形定義の数。
ひと組の波形定義で「ON→OFF→」の一周期分を定義する。
21 ; キャリア周波数を決める分周比
[2.5MHz/38kHz/2=32.9≒0x21]。
; --- ここから信号波形定義 ---
7e0500 7e0500 ; データ「0」の波形。ON(1T)→ON(1T)、すなわち
ONが0x00057eクロック継続したあとOFFが0x00057eクロック継続
[1T=(9/16)msec*2.5MHz=1406.25=0x57e]。
7e0500 7a1000 ; データ「1」の波形。ON(1T)→OFF(3T)。
e45700 f22b00 ; リーダーの波形。ON(16T)→OFF(8T)。
7e0500 038601 ; トレーラーの波形。ON(1T)→OFF(nnT)。
e45700 f91500 ; リピートコードの波形その1。ON(16T)→OFF(4T)。
7e0500 54ab03 ; リピートコードの波形その1。ON(1T)→OFF(171T)。
; --- ここから送信信号の定義 ---
2 ; リーダー (波形「2」)
10100010 ; データ1バイト目 (0=波形「0」/1=波形「1」)
00111101 ; データ2バイト目
01001000 ; データ3バイト目
10110111 ; データ4バイト目 (3バイト目の補数)
3 ; トレーラー (波形「3」)
45 ; リピートコード (波形「45」)
fe02 ; 直前の2波形を永久に繰り返す、という制御コード。
これにより、ボタンを押している間リピートコードの信号が出続ける。
サンプルコード¶
送信データを NEC フォーマットにエンコードする 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進数×3バイトで与える
@data = map { hex($_) & 0xff } @ARGV[0..2];
$data[3] = 0xff - $data[2]; # 4バイト目は3バイト目の補数
# データを0/1列に変換
@data = map { b8($_) } @data;
# データ中の「0」「1」の数をかぞえる
$_ = join("", @data);
$n0 = tr/0/0/;
$n1 = tr/1/1/;
# 出力の作成
$t = 9 / 16 * 2500; # T=(9/16)msec
$f = int (2500 / 38 / 2 + 0.5); # キャリア周波数=38kHz
$nn = 192 - 24 - $n0 * 2 - $n1 * 4 - 1; # トレーラー長の計算
$out = "00\n";
$out .= "06\n";
$out .= sprintf ("%02x\n", $f);
$out .= hh3( 1*$t)." ".hh3( 1*$t)."\n";
$out .= hh3( 1*$t)." ".hh3( 3*$t)."\n";
$out .= hh3( 16*$t)." ".hh3( 8*$t)."\n";
$out .= hh3( 1*$t)." ".hh3($nn*$t)."\n";
$out .= hh3( 16*$t)." ".hh3( 4*$t)."\n";
$out .= hh3( 1*$t)." ".hh3(171*$t)."\n";
$out .= "2\n";
foreach (@data) {
$out .= $_."\n";
}
$out .= "3\n";
$out .= "45\n";
$out .= "fe02\n";
# ベタ書きにしたいとき (クロッサム・エクスプローラ風)
#$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+ に転送する。
2.4. 例: 東芝製 DVD/HDD レコーダー [RD-XS30] のリモコンコード¶
カスタムコード¶
45 bc
各ボタンの機能コード¶
コード | ボタン | コード | ボタン |
---|---|---|---|
00 | 0 | 52 | 初期設定 |
01 | 1 | 53 | クリア |
02 | 2 | 55 | ワンタッチリプレイ |
03 | 3 | 56 | ダビング |
04 | 4 | 57 | 修正/削除 |
05 | 5 | 5a | 表示 |
06 | 6 | 5b | ワンタッチスキップ |
07 | 7 | 5c | 残量表示 |
08 | 8 | 5e | ズーム |
09 | 9 | 80 | スキップ >>| |
0d | +10 | 84 | スキップ |<< |
0e | サーチ/転送 | 88 | スロー >| |
0f | 入力切替 | 8c | スロー <| |
11 | オープン/クローズ | 98 | ピクチャーサーチ/頁 >> |
12 | 電源 | 9a | ピクチャーサーチ/頁 << |
13 | 再生 | 9d | フレーム/値編集 >|| |
15 | 録画 | 9e | フレーム/値編集 ||< |
16 | 停止 | a3 | 延長 |
17 | 一時停止 | a7 | 録画モード |
18 | DVD | b1 | 表示窓切替 |
19 | HDD | c0 | カーソル ↑ |
1a | タイムスリップ | c4 | カーソル → |
1e | チャンネル ↑ | c8 | カーソル ↓ |
1f | チャンネル ↓ | cc | カーソル ← |
40 | 録るナビ | d0 | トップメニュー |
41 | 編集ナビ | d1 | メニュー |
42 | 見るナビ | d2 | リターン |
44 | 決定 | d3 | 音声/音多 |
45 | クイックメニュー | d4 | アングル |
46 | V-リモート | d5 | 字幕 |
47 | ライブラリ | d7 | P in P |
4a | A | d9 | チャプター分割 |
4b | B | da | タイムバー |
G コード予約¶
8単位の NEC フォーマットのデータを連続的に送信 (リピートコードなし)。カスタムコード「45 b1」のヘッダのあとに、「45 b2」のデータ列が続く。詳細は以下の例を参照。
45 b1 08 f7 ; ヘッダ
45 b2 99 66 ; Gコードが「99502」の場合
45 b2 50 af ; ・8桁のGコードを左詰めで2桁ずつ
45 b2 2f d0 ; ・余分な桁には「f」を詰める
45 b2 ff 00 ;
45 b2 fc 03 ; 録画先。DVDのとき「fc」、HDDのとき「fe」
45 b2 00 ff ; いつも「00」
45 b2 00 ff ; 録画モード。SPのとき「00」、LPのとき「02」