IRKit, KURO-RS使ったリモコン信号の解析

はじめに

IRKitやKURO-RS、クロッサム2+などのプログラマブルな学習リモコンの信号データを、リモコン同士ツノつき合わせて学習させるのではなく、PC上で理想的な波形に合成するためのノウハウです。

信号データが合成できると、以下のようなメリットが期待できます。

  • なまっていない、きれいな信号が出せるようになるので、機器の反応が良くなる。
  • いつでも欲しいときにデータが合成できるので、学習したデータの保存に気を使わなくてもよくなる。
  • 機器付属のリモコンでは送れない、未知のコマンドを探求できる(笑)。

このページでは、IRKitやKURO-RSを利用して簡便に機器付属のリモコン信号を解析するサンプルコードを紹介します。

IRKitによるリモコンコードの解析

IRKitで「学習」したJSON形式のデータから、リモコン信号のフォーマット (家製協/NEC/ソニー) を判別し、デコードするためのperlスクリプトです。アドホックな作りですが、そこそこの精度で解析できています。

  • 入力は、1行にJSON一つの形式のテキストファイル。1行に複数のJSONがあれば最初だけ処理する。読めない行は黙って捨てる。
  • 出力は、各JSONを解析した結果が標準出力に書き出される。

サンプルコード

#! /usr/bin/perl

while (<>) {
    # 信号フォーマット/コードの解析
    next unless /"data":\[(.*?)\]/;
    @run = split (",", $1);
    $raw = join (" ", @run);
    @run = map { $_ /= 2; } @run;       # μsec単位に揃える

    $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})(.*)/);
        printf ("sony(%d): %x %02x\n", $len, unpack ("SS", pack ("b16b16", $id, $cmd)));

    } elsif ($run[0] <= 4800) {         # 家製協フォーマット (仕様上は2800~4000μsec)
        shift (@run); shift (@run);
        $t = 425;
        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);
        printf ("aeha(%d): ", $len);
        print join (" ", unpack ("H2"x ($len / 8), pack ("b$len", $code))), "\n";

    } 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);
        printf ("nec(%d): ", $len);
        print join (" ", unpack ("H2"x 4, pack ("b32", $code))), "\n";

    } else {                            # 未知フォーマット
      unknown:
        print "raw: ", $raw, "\n";
    }
}

KURO-RSによるリモコンコードの解析

KURO-RSで「学習」した1920ビットのバイナリデータを解析する場合は、IRKitのサンプルコードの入力ファイル読み込み部分、すなわち

.   next unless /"data":\[(.*?)\]/;
    @run = split (",", $1);
    $raw = join (" ", @run);
    @run = map { $_ /= 2; } @run;       # μsec単位に揃える

の部分を、以下のように書き換えれば、解析ロジック部分はそのまま利用できる。

.   $data = (1920ビットの学習データ);

    # -- ビット列→ランレングス列
    $data = unpack ("b1920", $data);
    @run = map (length, $data =~ /(0+|1+)/g);
    $raw = join (" ", @run);
    @run = map { $_ *= 100; } @run;     # μsec単位に揃える

改版履歴

Ver 1.0: 2004/1/22 - クロッサム2+向けに執筆
Ver 1.1: 2014/11/24 - IRKit、KURO-RS/PC-OP-RS1向けに加筆 (家製協のみ)、信号解析のページを追加

本稿の内容は、独自の調査・解析の結果にもとづくものであり、内容の正確性については保証いたしません。自己責任にてご利用ください。