使用Arduino接收红外遥控编码并打印到串口
IR_PIN 默认为2
/*本程序用来接收NEC红外编码* 程序原理:通过判断两次下降沿的周期宽度判断当前bit是逻辑1还是逻辑0* 逻辑1 560+1690=2250us 逻辑0 560+560=1120us* 接收到的数据是低位在前,保存的bit顺序为 0->7*** 当收到第1个下降沿时认为程序进入等待前导码阶段,即:9ms低+4.5ms高,* 所以可在下一个下降沿时判断脉宽是否在13.5ms左右,如果是则标记进入收码阶段,否则返回重新等待新的下降沿** 进入收码阶段后每次下降沿判断脉宽,得到逻辑1或0并写入buf,写满1个字节后转存至全局变量数组中** 接收IO连续高电平100ms以上时认为收码结束,标记结束* loop检测到收码结束时打印结果** BH3PXN* 2020.05.29*/#define IR_PIN 2#define STEP_FREE 0#define STEP_WAIT_PRECODE 1#define STEP_RECV_CODE 2#define STEP_RECV_OVER 3unsigned char recvStep = STEP_FREE;unsigned char irCode[100];unsigned char idx = 0;void setup() {// put your setup code here, to run once:pinMode(IR_PIN, INPUT_PULLUP); //开启上拉Serial.begin(9600);}void loop() {// put your main code here, to run repeatedly:IR_RECV();outputIRCODE();}void outputIRCODE() {if (recvStep != STEP_RECV_OVER) {return;}recvStep = STEP_FREE; //重置Serial.print(\"IR CODE \");Serial.print(\" : \");for (unsigned char i = 0; i < idx; i++) {Serial.print(irCode[i],HEX);Serial.print(\" \");}Serial.println();idx = 0;}void IR_RECV() {static unsigned char lastIR = 1;static unsigned char nowIR = 1;static unsigned long tus = 0;static unsigned long tms = 0;static unsigned long nowus = 0;static unsigned long t = 0;static unsigned char irbuf; // 一个字节的数据static unsigned char i = 0;//获取当前电平nowIR = digitalRead(IR_PIN);//高电平维持if (lastIR && nowIR) {//大于100ms时返回if (millis() - tms > 100) {t = 0;if (recvStep == STEP_RECV_CODE) {recvStep = STEP_RECV_OVER; //接收完成,交给主程序}return;}}//end lastIR && nowIR//上升沿 忽略if (!lastIR && nowIR == HIGH) {tms = millis();lastIR = HIGH;// return;}//下降沿if (lastIR && nowIR == LOW) {lastIR = LOW;nowus = micros();t = nowus - tus;tus = nowus;//第1个下降沿if (recvStep == STEP_FREE) {tus = nowus;recvStep = STEP_WAIT_PRECODE; //等待前导码return;}// end recvStepif (recvStep == STEP_WAIT_PRECODE ) {if (t >= 12000 && t <= 16000) {//Serial.print(\"ir recv begin\");//正确的引导码recvStep = STEP_RECV_CODE;return;} else {Serial.print(\"error pre code,t=\");Serial.print(t);Serial.println();recvStep = STEP_FREE;delay(1000);return;}}//标准NEC码:逻辑1 560+1690=2250us 逻辑0 560+560=1120us//接收到的数据是低位在前,//逻辑1if (t >= 1800 && t < 2800) {irbuf |= 0x01 << i;i++;}//end 1//逻辑0if (t >= 800 && t < 1800) {i++;}//end 0//接收够1个字节,写入编码缓存if (i == 8) {irCode[idx++] = irbuf;irbuf = 0x00;i = 0;}// end i==8}// end lastIR && IR == LOW}// end void IR_RECV()