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;
}