概要
Arduinoで赤外線受信IC VS1831 を使って、割り込みを使って赤外線リモコンを受信します。
対象のリモコンはNECフォーマットのみ
他の受信プログラムとちょっと違うのは、都度解析するのでは無く、全文受信したら解析するようにしています。
micros()の約70分のオーバーフローは未考慮
IRremoteライブラリは重たいので使わない方法で実現。
他のSONYフォーマットや家電製品協会フォーマットも作れそうですがやらない(^^;
レグザリモコン
電源ボタン
NEC:00000010111111010100100010110111:2FD48B7
音量+
NEC:00000010111111010101100010100111:2FD58A7
音量-
NEC:00000010111111010111100010000111:2FD7887
チャンネル+
NEC:00000010111111011101100000100111:2FDD827
チャンネル-
NEC:00000010111111011111100000000111:2FDF807
CH1
NEC:00000010111111011000000001111111:2FD807F
CH2
NEC:00000010111111010100000010111111:2FD40BF
CH3
NEC:00000010111111011100000000111111:2FDC03F
回路図
基板
引用
赤外線リモコン受信(Physical Computingに挑戦!)
http://physicom.digick.jp/
http://physicom.digick.jp/?p=3928
赤外線リモコンの通信フォーマット(elm-chanさん)
http://elm-chan.org/index_j.html
http://elm-chan.org/docs/ir_format.html
赤外線リモコンのフォーマット(電子工作の森さん)
http://www.asahi-net.or.jp/~gt3n-tnk/
http://www.asahi-net.or.jp/~gt3n-tnk/IR_TX1.html
// 赤外線リモコン 割り込み受信プログラム
// buffにIr割り込み時間を記録しておき、後に受信内容を解析
// NEC用リモコン専用
//http://elm-chan.org/docs/ir_format.html
//http://www.asahi-net.or.jp/~gt3n-tnk/IR_TX1.html
//
# define BUFF_SIZE 256
# define PIN_IRLED 2
# define PIN_RUNLED 4
# define PIN_IRIN 3
# define S_MAX(n,t) (((n- 500) <= t) && (t < (n+ 500)))
# define V_MAX(n,t) (((n- 100) <= t) && (t < (n+ 100)))
unsigned long prev;
unsigned long time;
int index = 0;
unsigned long buff[BUFF_SIZE];
//--------------------------------------------------------------------------------
// arduino初期化
//--------------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
pinMode(PIN_RUNLED, OUTPUT); // IR受信した時に光らせるLED
pinMode(PIN_IRIN, INPUT); // Ir受信ポート
attachInterrupt(1, blink, CHANGE); // Ir割り込みポート設定 ※PIN_IRIN 3 だけど、1を設定
prev = micros();
}
//--------------------------------------------------------------------------------
// arduinoメインループ
//--------------------------------------------------------------------------------
void loop() {
enum{
ST_LEADER1 = 0,
ST_LEADER2,
ST_DATA_M,
ST_DATA_L,
ST_REPEAT,
ST_OFF_RUN,
};
unsigned long temp = 0;
unsigned long dat = 0;
unsigned char Ir_state = ST_LEADER1;
time = micros();
if ((index > 0) && (time-prev > 20000)) { // この処理は見直したほうがいいかも。
Serial.println("");
Serial.println("****************");
Serial.println(index,HEX);
for (int i = 1; i < index; i++) { // buff に記録されている時間間隔を表示
Serial.print(buff[i]);
Serial.print(",");
}
Serial.println("");
for (int i = 1; i < index; i++) { // buff 解析
temp = buff[i];
switch(Ir_state){
case ST_LEADER1:
if(V_MAX(8992,temp)){ // 562us * 16T = 8.992ms
Serial.print("NEC");
Ir_state = ST_LEADER2;
}
break;
case ST_LEADER2:
if(V_MAX(4496,temp)){ // 562us * 8T = 4.496ms
Serial.print(":");
Ir_state = ST_DATA_M;
} if(V_MAX(2248,temp)){ // 562us * 4T = 2.248ms
Ir_state = ST_REPEAT;
}
break;
case ST_DATA_M:
if(temp < 616){ // 0.56ms * 1.1 = 0.616ms
Ir_state = ST_DATA_L;
}
break;
case ST_DATA_L:
if(temp < 616){ // 0.56ms * 1.1 = 0.616ms
Serial.print("0");
dat=dat<<1;
}
else if(temp < 2475){ // 2.25ms * 1.1 =2.475ms
Serial.print("1");
dat=dat<<1;
dat=dat|0x0001;
}
Ir_state = ST_DATA_M;
break;
case ST_REPEAT:
if(temp < 616){ // 0.56ms * 1.1 = 0.616ms
Serial.print("Repeat");
}
break;
default:
break;
}
}
Serial.print(":");
Serial.println(dat,HEX);
dat = 0;
index = 0;
prev = time;
}
delay(10);
}
//--------------------------------------------------------------------------------
// 赤外線受信割り込み処理
// 立ち上がり、立ち下がり両方で割り込みがかかります。
//--------------------------------------------------------------------------------
void blink() {
PORTD |= _BV(2); // PIN_IRLED 点灯
time = micros();
buff[index] = time - prev;
prev = time;
index++;
if (index >= BUFF_SIZE) {
index = 0;
}
PORTD &= ~_BV(2); // PIN_IRLED 消灯
}