4. 黒豆, IRKit, KURO-RS によるリモコン信号の解析¶
黒豆や IRKit, KURO-RS, クロッサム2+ などのプログラマブルな学習リモコン (スマートリモコン) の信号データを、リモコン同士ツノつき合わせて学習させるのではなく、PC 上で理想的な波形に合成するためのノウハウです。
- 赤外線リモコンの信号定義データの合成 [表紙]
- 家製協フォーマットの信号データ合成
- NEC フォーマットの信号データ合成
- ソニーフォーマットの信号データ合成
- 黒豆, IRKit, KURO-RS によるリモコン信号の解析 (このページ)
- 機器付属リモコンのコード
このページでは、IRKit や KURO-RS を利用して簡便に機器付属のリモコン信号を解析するサンプルコードを紹介します。
4.1. 黒豆によるリモコンコードの解析¶
黒豆で「学習」した16進数列形式のデータから、リモコン信号のフォーマット (家製協/NEC/ソニー) を判別し、デコードするための perl スクリプトです。アドホックな作りですが、そこそこの精度で解析できています。
- 入力は、1行に16進数列データ一つの形式のテキストファイル。読めない行は黙って捨てる。
- 出力は、各データを解析した結果が標準出力に書き出される。
サンプルコード¶
#! /usr/bin/perl
while (<>) {
# 信号フォーマット/コードの解析
chop;
next if (length ($_) < 16);
next if (/[^0-9a-fA-F]/);
@run = ($_ =~ /(..)/g);
@run = @run[4..$#run]; # ヘッダ4バイト捨てる
@run = map { hex ($_); } @run;
@run1 = ();
while (@run > 0) { # マルチバイトの処理
if ($run[0] == 0) {
push (@run1, $run[1] * 256 + $run[2]);
shift (@run); shift (@run); shift (@run);
} else {
push (@run1, shift (@run));
}
}
@run = map { $_ * 1000.0 * 269 / 8192; } @run1; # μsec単位に揃える
print &analyze (@run), "\n";
}
sub analyze {
my (@run) = @_;
my ($code) = "";
# -- ヘッダ部の「1」の長さでフォーマット判別
if ($run[0] <= 2600) { # ソニーフォーマット (仕様上は2400μsec)
shift (@run); shift (@run);
$t = 600;
while (@run) {
$d1 = int (shift (@run) / $t + 0.25);
$d0 = int (shift (@run) / $t + 0.25);
$code .= ($d1 == 1) ? "0" : "1";
last if ($d0 > 1);
}
$len = length ($code);
goto unknown if ($len != 12 && $len != 15 && $len != 20);
($cmd, $id) = ($code =~ /(.{7})(.*)/);
$result = sprintf ("sony(%d): %x %02x", $len, unpack ("SS", pack ("b16b16", $id, $cmd)));
} elsif ($run[0] <= 4800) { # 家製協フォーマット (仕様上は2800~4000μsec)
shift (@run); shift (@run);
$t = 425.0;
while (@run) {
$d1 = int (shift (@run) / $t + 0.25);
$d0 = int (shift (@run) / $t + 0.25);
last if ($d0 >= 10);
$code .= ($d0 == 1) ? "0" : "1";
}
$len = length ($code);
goto unknown if ($len % 8 != 0);
$result = sprintf ("aeha(%d): ", $len / 8);
$result .= join (" ", unpack ("H2"x ($len / 8), pack ("b$len", $code)));
} elsif ($run[0] <= 15000) { # NECフォーマット (仕様上は9000μsec)
shift (@run); shift (@run);
$t = 9000 / 16;
while (@run) {
$d1 = int (shift (@run) / $t + 0.25);
$d0 = int (shift (@run) / $t + 0.25);
last if ($d0 > 5);
$code .= ($d0 == 1) ? "0" : "1";
}
$len = length ($code);
goto unknown if ($len != 32);
$result = sprintf ("nec(%d): ", $len);
$result .= join (" ", unpack ("H2"x 4, pack ("b32", $code)));
} else { # 未知フォーマット
unknown:
$result = "unknown";
}
return $result;
}
4.2. IRKit によるリモコンコードの解析¶
IRKit で「学習」した JSON 形式のデータを解析する場合は、黒豆のサンプルコードの入力ファイル読み込み部分を以下のように書き換えれば、解析ロジック部分はそのまま利用できる。
#! /usr/bin/perl
while (<>) {
# 信号フォーマット/コードの解析
next unless /"data":\[(.*?)\]/;
@run = split (",", $1);
$raw = join (" ", @run);
@run = map { $_ /= 2; } @run; # μsec単位に揃える
print &analyze (@run), "\n";
}
4.3. KURO-RS によるリモコンコードの解析¶
KURO-RS で「学習」した1920ビットのバイナリデータを解析する場合は、黒豆のサンプルコードの入力ファイル読み込み部分を以下のように書き換えれば、解析ロジック部分はそのまま利用できる。
#! /usr/bin/perl
while (<>) {
# 信号フォーマット/コードの解析
chop;
$data = pack ("H*", $_);
$data = unpack ("b1920", $data);
@run = map (length, $data =~ /(0+|1+)/g);
@run = map { $_ *= 100; } @run; # μsec単位に揃える
print &analyze (@run), "\n";
}