PCで解析したところ、基本的に次の処理で解析できた。
1.最小値で各値を割る(実際には最小値を0.9倍したものを使う)
2.リーダー部の最初の値を2番目の値で割って商が2ならNECかAEHA
3.リーダー部の最初の値が16ならNEC、8ならAEHA、4ならSONY
NECフォーマットなら
1.リーダー部の次から1, 1または1, 3を判定してそれぞれ0, 1とデータ部を組み立てる
2.1, 3以外の値が出たら終了
AEHAフォーマットなら
1.リーダー部の次から1, 1または1, 3を判定してそれぞれ0, 1とデータ部を組み立てる
2.1, 3以外の値が出たら終了
SONYフォーマットなら
1.リーダー部の次から1, 1または1, 2を判定してそれぞれ0, 1とデータ部を組み立てる
2.データ部が7ビット、アドレス部が5/8/13ビットなので、それに合わせてデコードする
#define BUFF_SIZE 256 #define NEC 1 #define AEHA 2 #define SONY 3 volatile int state = HIGH; unsigned long prev; unsigned long time; int index = 0; unsigned long buff[BUFF_SIZE]; unsigned char data[BUFF_SIZE/8]; unsigned char temp; int pos; char format = 0; int error = 0; void setup() { prev = micros(); Serial.begin(9600); pinMode(13, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(13, state); time=micros(); if ((index > 0) && (time-prev > 200000)) { error = 0; format = 0; pos = 0; analyzePass1(); analyzePass2(); Serial.println("****************"); if (format==NEC) { Serial.println("Format=NEC"); } else if (format==AEHA) { Serial.println("Format=AEHA"); } else if (format==SONY) { Serial.println("Format=SONY"); } else { Serial.println("Format=UNKNOWN"); Serial.print("Error="); Serial.println(error); } Serial.println(">>>>>>>>>>>>>>>>"); for (int i = 0; i < pos; i++) { Serial.println(data[i]); } if (error) { Serial.println("****************"); for (int i = 1; i < index; i++) { Serial.println(buff[i]); } } index = 0; prev=time; } delay(10); } void blink() { state = !state; time = micros(); buff[index]=time-prev; prev=time; index++; if (index >= BUFF_SIZE) { index=0; } } void analyzePass1() { unsigned long minval = 10000000; for (int i = 0; i < index; i++) { if ((buff[i] > 350) && (buff[i] < minval)) { minval = buff[i]; } } minval = (minval * 9) / 10; for (int i = 0; i < index; i++) { buff[i] = buff[i] / minval; } } void analyzePass2() { if (index < 20) { error = 1; return; } if (buff[2] == 0) { error = 2; return; } int leader; leader = buff[1] / buff[2]; if (leader == 2) { if ((buff[2] >= 8) && (buff[2] <= 11)) { // NEC format if (nec()) { format=NEC; } } else if ((buff[2] == 4) || (buff[2] == 5)) { // AEHA format if (aeha()) { format=AEHA; } } else { Serial.print("!!!buff[2]="); Serial.println(buff[2]); error = 3; return; } } else if ((buff[1] == 4) || (buff[1] == 5)) { // SONY format if (sony()) { format=SONY; } } else { error = 4; Serial.print("!!!leader="); Serial.println(leader); Serial.print("!!!buff[1]="); Serial.println(buff[1]); Serial.print("!!!buff[2]="); Serial.println(buff[2]); return; } } int nec() { int b = 0; temp = 0; for (int i = 3; i < index; i+=2) { if (buff[i]==1) { if (buff[i+1]==1) { // 0 } else if (buff[i+1]==3) { // 1 temp |= 1<=4) { return 1; } else { error = 5; Serial.print("!!!pos="); Serial.println(pos); Serial.print("!!!bit="); Serial.println(b); Serial.print("!!!buff[i+1]="); Serial.println(buff[i+1]); return 0; } } else if (pos>=4) { return 1; } else { error = 6; Serial.print("!!!pos="); Serial.println(pos); Serial.print("!!!bit="); Serial.println(b); Serial.print("!!!buff[i]="); Serial.println(buff[i]); return 0; } b++; if (b==8) { data[pos++]=temp; b=0; temp=0; if (pos >= BUFF_SIZE/8) { error = 7; return 0; } } } if (b > 0) { data[pos++]=temp; } return 1; } int aeha() { int b = 0; temp = 0; for (int i = 3; i < index; i+=2) { if (buff[i]==1) { if (buff[i+1]==1) { // 0 } else if (buff[i+1]==3) { // 1 temp |= 1<= 3) { return 1; } else { error = 5; Serial.print("!!!i="); Serial.println(i); Serial.print("!!!buff[i+1]="); Serial.println(buff[i+1]); return 0; } } else if (pos >= 3) { return 1; } else { error = 6; return 0; } b++; if (b==8) { data[pos++]=temp; b=0; temp=0; if (pos >= BUFF_SIZE/8) { error = 7; return 0; } } } if (b > 0) { data[pos++]=temp; } return 1; } int sony() { int b = 0; temp = 0; for (int i = 2; i < 16; i+=2) { if (buff[i]==1) { if (buff[i+1]==1) { // 0 } else if (buff[i+1]==2) { // 1 temp |= 1<= 3) { return 1; } else { error = 5; Serial.print("!!!i="); Serial.println(i); Serial.print("!!!buff[i+1]="); Serial.println(buff[i+1]); return 0; } } else { Serial.print("!!!i="); Serial.println(i); Serial.print("!!!buff[i]="); Serial.println(buff[i]); error = 6; return 0; } b++; } data[pos++]=temp; b=0; temp=0; for (int i = 16; i < index; i+=2) { if (buff[i]==1) { if (buff[i+1]==1) { // 0 } else if (buff[i+1]==2) { // 1 temp |= 1<= 1) { data[pos++]=temp; return 1; } else { error = 5; Serial.print("!!!i="); Serial.println(i); Serial.print("!!!buff[i+1]="); Serial.println(buff[i+1]); return 0; } } else { data[pos++]=temp; return 1; } b++; if (b==8) { data[pos++]=temp; b=0; temp=0; if (pos >= BUFF_SIZE/8) { error = 7; return 0; } } } return 1; }