06
2019
05

WIFI作品DIY教程12-《红外遥控》控制家电、自学、发射红外。

上篇WIFI作品DIY教程07-《wifi家居网关》家居控制中心zigbee/nrf24l01等完成了家居网关。


在家里一些使用红外遥控器的电器,我们可以代替他,用我们自己diy的模块远程控制他。





第一部分:红外发射、接收编码介绍

红外线又称红外光波,在电磁波谱中,光波的波长范围为0.01um~1000um。根据波长的不同可分为可见光和不可见光,波长为0.38um~0.76um的光波可为可见光,依次为红、橙、黄、绿、青、蓝、紫七种颜色。光波为0.01um~0.38um的光波为紫外光(线),波长为0.76um~1000um的光波为红外光(线)。红外光按波长范围分为近红外、中红外、远红外、极红外4类。红外线遥控是利用近红外光传送遥控指令的,波长为0.76um~1.5um。用近红外作为遥控光源,是因为目前红外发射器件(红外发光管)与红外接收器件(光敏二极管、三极管及光电池)的发光与受光峰值波长一般为0.8um~0.94um,在近红外光波段内,二者的光谱正好重合,能够很好地匹配,可以获得较高的传输效率及较高的可靠性。


红外遥控的发射电路是采用红外发光二极管来发出经过调制的红外光波;红外接收电路由红外接收二极管、三极管或硅光电池组成,它们将红外发射器发射雕红外光转换为相应的电信号,再送后置放大器。
发射机一般由指令键(或操作杆)、指令编码系统、调制电路、驱动电路、发射电路等几部分组成。当按下指令键或推动操作杆时,指令编码电路产生所需的指令编码信号,指令编码信号对载体进行调制,再由驱动电路进行功率放大后由发射电路向外发射经调制定指令编码信号。


        接收电路一般由接收电路、放大电路、调制电路、指令译码电路、驱动电路、执行电路等几部分组成。接收电路将发射器发出的已调制的编码指令信号接收下来,并进行放大后送解调电路,解调电路将已调制的指令编码信号解调出来,即还原为编码信号。指令译码器将编码指令信号进行译码,最后由驱动电路来驱动执行电路实现各种指令的操作控制。





第二部分:下载编译源代码
1、CH340驱动

在drivers目录里找到CH340驱动,然后按说明安装(之前安装了就不用再安装了)。


2、源代码


001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
/*
 *NRF24l01针脚连接线
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 * Configurable:
 * CE -> 8
 * CSN -> 7
*/
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
#include <EEPROM.h>
#include <IRremote.h>
 
int sid=20;//模块类型
int nid=1;//模块编号
 
//声名变量
//无线串口通信处理(zigbee/bluetooth等)
unsigned long serial1nowlast;
char serial1buff[129]={0};
char serial1Data;
int serial1i=0;
 
//NRF24l01
unsigned long nrf24l01nowlast;
char nrf24l01buff[33]={0};
char nrf24l01Data;
int nrf24l01i=0;
 
int pinIn0=A0;
int val0;
int pinOut0=A1;
 
 
IRsend irsend;
int isdump=0;//
 
int RECV_PIN = A5;
IRrecv irrecv(RECV_PIN);
decode_results results;
 
 
void setup()
{
    Serial.begin(115200);
 
    char client[10]={0};//client
    sprintf(client,"clie%d",sid);
    //初始化Mirf,用于NRF24l01收发
    Mirf_Init(0,client,sid);
 
    pinMode(pinIn0,INPUT);      
    pinMode(pinOut0,OUTPUT);   
    pinMode(pinIn0,INPUT_PULLUP); //将管脚设置为输入并且内部上拉模式
    digitalWrite(pinIn0, HIGH);
 
    irrecv.enableIRIn(); // Start the receiver
 
    Serial.println("zwifi_hongweixian");
}
 
void loop()
{
 
  //检测无线串口数据处理 (zigbee/bluetooth等)
  
      unsigned long serial1now = millis();//获取现在的时间
      if(serial1now - serial1nowlast >= 5000)//如果数据间隔超过5秒而清空字符(为了防止数据错乱)
      {
        serial1nowlast = millis();
        memset(serial1buff, 0, 129);
        serial1i=0;
      }
 
      while( Serial.available() )//如果无线串口有数据
      {
        if(serial1i==0)
        {
          Serial.println("serial->");//打印出来方便调试
        }      
        serial1Data=(char)Serial.read();//读取串口数据
        //Serial.print(serial1Data);////这里不打印,否则检测到{ckxxxx}就认为是命令
        serial1buff[serial1i]=serial1Data;////保存到数组
        serial1i++;////数组长度+1
        if(serial1Data=='}' || serial1i>=129)//如果发现}而说明命令结束(并少于129个字符,太长会出错)
        {               
          serial1nowlast = millis(); //更新当前时间,不然5秒就超时了
 
          char body[129]={0};
          get_znck_body(serial1buff,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
          //serial.println(body);
 
          //如果命令格式真确则发送到无线串口
          if(strstr(body,"{ck") && strstr(body,"}") )
          {
            //Serial.println(body);
 
            if(strlen(body)>10)
            {
              send_infrared(body);
 
            }
 
          }
          serial1i=0;//字符长度为0
          Serial.println("-------------------");
 
          delay(100);
        }
      }
 
  }
 
  unsigned long nrf24l01now = millis();//获取现在的时间
  if(nrf24l01now - nrf24l01nowlast >= 5000)//如果数据间隔超过5秒而清空字符(为了防止数据错乱)
  {
     nrf24l01nowlast = millis();
     memset(nrf24l01buff, 0, 33);
     nrf24l01i=0;
   }
 
   byte data[Mirf.payload];
   if(Mirf.dataReady()){//!Mirf.isSending() &&
 
    Mirf.getData(data);
    Mirf.rxFifoEmpty();   //清理24L01援存
    //Serial.println((char)*data); 
 
    for (int i = 0; i < Mirf.payload; i++) //把收到的信息拼起来
    {         
      if(nrf24l01i==0)
      {
        Serial.println("nrf24l01->");//打印出来方便调试
      }
 
      nrf24l01Data=(char)data[i];
      if( nrf24l01Data=='{') nrf24l01i=0;
      nrf24l01buff[nrf24l01i]=nrf24l01Data;//保存到数组
      nrf24l01i++;////数组长度+1
      if(nrf24l01Data=='}' || nrf24l01i>=33)//如果发现}而说明命令结束(并少于33个字符,太长会出错)
      {               
            nrf24l01nowlast = millis(); //更新当前时间,不然5秒就超时了
 
            char body[33]={0};
            get_znck_body(nrf24l01buff,body);//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
            //Serial.println(body);
 
            //如果命令格式真确则发送到无线串口
            if(strstr(body,"{ck") && strstr(body,"}") )
            {
              //Serial.println(body);
 
              if(strlen(body)>10)
              {
                  send_infrared(body);
 
              }
 
            }
            memset(nrf24l01buff, 0, 33);
            nrf24l01i=0;//字符长度为0
            Serial.println("-------------------");
 
            delay(100);
      }
    }
   }   
 
 
  val0=digitalRead(pinIn0);//读取数字 
  if(val0==LOW || isdump==1)//检测按键是否按下
  {
     digitalWrite(pinOut0,HIGH);
     //delay(2000);
     if (irrecv.decode(&results)) {
        Serial.println(results.value, HEX);
        dump(&results);
        irrecv.resume(); // Receive the next value
      }
 
      //Serial.println("dumpcheck...");
      //delay(100);
  }
 
  digitalWrite(pinOut0,LOW);    
  delay(10);   
 
}
 
//初始化Mirf 0初始化1为接收2为发送
void Mirf_Init(int txrx,char *server,int channel){
    //初始化Mirf,用于NRF24l01收发       
    if(txrx==0)  {    
      Mirf.spi = &MirfHardwareSpi;
      Mirf.init();
      Mirf.setRADDR((byte *)server);//设置接收地址
    }
 
    if(txrx==1)  {    
      Mirf.setRADDR((byte *)server);//设置接收地址
    }
    if(txrx==2)  {
      Mirf.setTADDR((byte *)server);//设置发送地址
    }
 
    Mirf.payload = sizeof(char);//收发字节
    Mirf.channel = channel;
    Mirf.config();
}
 
//NRF24l01发送函数
void Mirf_Send(int channel,char *server,char *str){
  Mirf_Init(2,server,channel);
  int bufi=0;
  for(bufi=0;bufi<strlen(str);bufi++){ 循环发送
    char words=str[bufi];//发送的字符
    Mirf.send((byte *)&words);//发送命令
    while(Mirf.isSending()){//等待发送完闭
    }
    delay(50);//延时,否则可能出现发送丢失现象
    //Serial.print(words);
  }
  //Serial.println("");
}
 
 
//获取只是{ckxxxxxx}的字符,因为这是我们的命令格式
void get_znck_body(char *p,char *s){
 
  char rechar[33]={0};
  int bufi=0;
 
  bool isend=false;
  int charnum=0;   
 
  for(bufi=0;bufi<strlen(p);bufi++){
    //Serial.print(p[bufi]);
 
    if(p[bufi]=='{'){
      isend=true;
    }
    if(p[bufi]=='}' && isend==true){
      isend=false;
      rechar[charnum]=p[bufi];
      break;
    }
    if(isend){
      if(charnum<33)
      {
        rechar[charnum]=p[bufi];//Serial.print(rechar[charnum]);
        charnum++;       
      }
    }
 
  }
  //Serial.println("");
  //memcpy(s,rechar,33);
  sprintf(s,"%s",rechar);
}
 
 
//
void send_infrared(char *body){
 
    int s=get_sid(body);
    int n=get_nid(body);
    char d[32]={0};
    get_data(body,d);
 
    if(  s==sid && n==nid )
    {
      if( strlen(d)==1 && d[0]=='0' )
      {
         isdump=1;
      }
      if( strlen(d)==1 && d[0]=='1' )
      {
         char sdata[20]={0};
         sendEEPROM(sdata);
      }
      ifstrlen(d)>5 )
      {
         sendEEPROM(d);
      }
    }
 
 
    if(  s==sid ){
      char server[10]={0};//server
      sprintf(server,"serv%d",1);
      //Serial.println(server);
 
      char updateData[33]={0};
      char front[10]={0};
      //memcpy(front,body,9);
      sprintf(front," {ck%03d%03d",s,n);
      sprintf(updateData,"%supdate}",front);
      Serial.println(updateData);
 
      Mirf_Send(1,server,updateData);
 
      char client[10]={0};//client
      sprintf(client,"clie%d",sid);
      Mirf_Init(1,client,sid);
 
      delay(2000);
    }
 
 
}
 
 
int get_sid(char *buff){
 
  if( strstr(buff,"{ck") && strstr(buff,"}") && strlen(buff)>10)
    {
      char charSid[4]={0};
      memcpy(charSid,buff+3,3);
      Serial.println(charSid);
      int intSid=atoi(charSid);
      Serial.println(intSid);
      return intSid;     
    }
    else
    {
      return 0;
    }
 
}
 
int get_nid(char *buff){
 
  if( strstr(buff,"{ck") && strstr(buff,"}") && strlen(buff)>10)
    {
      char charNid[4]={0};
      memcpy(charNid,buff+6,3);
      Serial.println(charNid);
      int intNid=atoi(charNid);
      Serial.println(intNid);
      return intNid;     
    }
    else
    {
      return 0;
    }
 
}
 
int get_data(char *buff,char *sdata){
 
  if( strstr(buff,"{ck") && strstr(buff,"}") && strlen(buff)>10)
    {
      for (int i = 0; i < strlen(buff); i++) {
        if( buff[9+i]=='}' ) break;
        sdata[i]=buff[9+i];       
      }
      //char charData[20]={0};
      //memcpy(charData,buff+9,1);
 
      //Serial.println(charData);
      //int intData=atoi(charData);
      //Serial.println(intData);
      return 1;//intData;     
    }
    else
    {
      return 0;
    }
 
}
 
// Dumps out the decode_results structure.
// Call this after IRrecv::decode()
// void * to work around compiler issue
//void dump(void *v) {
//  decode_results *results = (decode_results *)v
void dump(decode_results *results) {
 
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    return;
    Serial.print("Unknown encoding: ");  
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");
  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {       
    Serial.print("Decoded PANASONIC - Address: ");
    Serial.print(results->panasonicAddress,HEX);
    Serial.print(" Value: ");
  }
  else if (results->decode_type == JVC) {
     Serial.print("Decoded JVC: ");
  }
  else {
     return;
  }
  Serial.print(results->value, DEC);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");
 
 
  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    /*
    Serial.print(",");
    char tbuf[10]={0};
    sprintf(tbuf,"%02X",results->rawbuf[i]*USECPERTICK);
    //Serial.print(tbuf);
    strcat(rawbuf,tbuf);
    Serial.print(" ");
    */
  }
  Serial.println("");
 
  char rawbuf[255]={0};
  char decode_type[10]={0};
  sprintf(decode_type,"%d,",results->decode_type);
  strcat(rawbuf,decode_type);  
 
  char decode_value[16]={0};
  sprintf(decode_value,"%ld,",results->value);
  strcat(rawbuf,decode_value);
 
  char decode_bits[10]={0};
  sprintf(decode_bits,"%d,",results->bits);
  strcat(rawbuf,decode_bits);
 
  for (int i = 0; i < 256; i++) {
    EEPROM.write(i, 0);
  }
  for (int i = 0; i < strlen(rawbuf); i++) {
    EEPROM.write(i, rawbuf[i]);
  }
   Serial.println(rawbuf);
   Serial.print("EEPROM.write count=");
   Serial.print(strlen(rawbuf));
 
   Serial.println("");
 
   isdump=0;
}
 
 
void sendEEPROM(char* data){
  Serial.print("sendEEPROM=");
  Serial.println(data);
  char eepchar[32]={0};
  if( strlen(data)>5 ){
    memcpy(eepchar,data,strlen(data));
  }else{
    for (int i = 0; i < 256; i++) {
      long eep = EEPROM.read(i);
      if(eep==0){
       break;
      }
      eepchar[i]=eep;
      Serial.print(eep,DEC);
      Serial.print(" ");
    }
  }
  Serial.println("");
  Serial.println(eepchar);
 
  int ir_type=get_ir_type(eepchar);
  long ir_value=get_ir_value(eepchar);
  int ir_bits=get_ir_bits(eepchar);
  Serial.println(ir_type); Serial.println(ir_value); Serial.println(ir_bits);
 
  if( ir_type>0 && ir_value>0 && ir_bits>0 ){
     Serial.println("irsend.sendRaw");
     irsenddata(ir_type,ir_value,ir_bits);
  }         
   //irsend.sendRaw(rawbuf, strlen(rawbuf), 38 /* kHz */);
   //irsend.sendNEC(0x82e0040a, 32);
}
 
 
void irsenddata(int type, unsigned long value, int bits) {
 
    if (type == NEC) {
      irsend.sendNEC(value, bits);
      Serial.print("sendNEC=");
      Serial.print(value,DEC);
      Serial.print(" bits=");
      Serial.print(bits,DEC);
      Serial.println("");
    }
    else if (type == SONY) {
      irsend.sendSony(value, bits);
      Serial.print("sendSony=");
      Serial.print(value,DEC);
      Serial.print(" bits=");
      Serial.print(bits,DEC);
      Serial.println("");
    }
    else if (type == RC5) {
      irsend.sendRC5(value, bits);
      Serial.print("sendRC5=");
      Serial.print(value,DEC);
      Serial.print(" bits=");
      Serial.print(bits,DEC);
      Serial.println("");
    }
    else if (type == RC6) {
      irsend.sendRC6(value, bits);
      Serial.print("sendRC6=");
      Serial.print(value,DEC);
      Serial.print(" bits=");
      Serial.print(bits,DEC);
      Serial.println("");
    }
    else {
      Serial.print(type);
      Serial.println("Bad type!");
    }
    delay(200);
 
}
 
int get_ir_type(char *buff){
 
  if( strstr(buff,",") && strlen(buff)>5)
    {
      int n=0;
      int m=0;
      char chartype[4]={0};
      for(int i=0;i< strlen(buff);i++){       
        if((char)buff[i]==','){
          n++;
          if(n==1) break;
        }
        chartype[m]=buff[i];
        m++;
      }    
      //memcpy(chartype,buff+6,3);
      Serial.print("get_ir_type");
      Serial.print(" char=");
      Serial.print(chartype);
      int inttype=atoi(chartype);
      Serial.print(" int=");
      Serial.print(inttype);
      Serial.println("");
      return inttype;     
    }
    else
    {
      return 0;
    }
 
}
 
long get_ir_value(char *buff){
 
  if( strstr(buff,",") && strlen(buff)>5)
    {
      int n=0;
      int m=0;
      char charvalue[16]={0};
      for(int i=0;i< strlen(buff);i++){       
        if(buff[i]==','){
          n++;
          if(n==1) { m=0; memset(charvalue,0,16); continue;};
          if(n==2) break;
        }
        charvalue[m]=buff[i];
        m++;
      }    
      //memcpy(charvalue,buff+6,3);
      Serial.print("get_ir_value");
      Serial.print(" char=");
      Serial.print(charvalue);
      long longvalue=atol(charvalue);
      Serial.print(" long=");
      Serial.print(longvalue);
      Serial.println("");
      return longvalue;     
    }
    else
    {
      return 0;
    }
 
}
 
 
int get_ir_bits(char *buff){
 
  if( strstr(buff,",") && strlen(buff)>5)
    {
      int n=0;
      int m=0;
      char charbits[16]={0};
      for(int i=0;i< strlen(buff);i++){       
        if((char)buff[i]==','){
          n++;
          if(n==1) { m=0; memset(charbits,0,16); continue;};
          if(n==2) { m=0; memset(charbits,0,16); continue;};
          if(n==3) break;
        }
        charbits[m]=buff[i];
        m++;
      }    
      //memcpy(charvalue,buff+6,3);
      Serial.print("get_ir_bits");
      Serial.print(" char=");
      Serial.print(charbits);
      int intbits=atoi(charbits);
      Serial.print(" int=");
      Serial.print(intbits);
      Serial.println("");
      return intbits;     
    }
    else
    {
      return 0;
    }
 
}





第三部分:测试学习,发射,无线通信等

打开arduino ide 的串口监视


输入{0200010}进入自学模式。


对着点遥控器。


红外自动解码,写入flash里。



输入{ck0200011}发射保存在flash里的红外编码。


取出组成字符,再解成红外编码,再发射。



直接发射已知的红外编码{ck02000111,16754775,32,}。


这里发射就少了去flash取编码了,直接发射字符转成的红外编码。



第四部分:关于工业家电红外解码的的方法。

A、修改arduino_iremote_master库文件
你要找到如下三个文件 IRremote.ccp IRremote.h IRremoteInt.h ,在 arduino安装目录下的librariesarduino_iremote_master1、修改IRremote.h
#define RAWBUF 270 // Length of raw duration buffer
这个默认值是100,因为我们接收的数据会超过100,所以在这里改成270,当然你也可以根据需要继续扩大


2、修改IRremoteInt.h
1)#define _GAP 50000 // Minimum map between transmissions
默认的数据是5000,因为遥控器会连续发两段代码,所以5000这个参数不适用,需要改到50000,否则你只能
接受到前一段代码仍然无法控制你家的空调


2)// information for the interrupt handler
typedef struct {
  uint8_t recvpin;           // pin for IR data from detector
  uint8_t rcvstate;          // state machine
  uint8_t blinkflag;         // TRUE to enable blinking of pin 13 on IR processing
  unsigned int timer;     // state timer, counts 50uS ticks.
  unsigned int rawbuf[RAWBUF]; // raw data
// uint8_t rawlen;         // counter of entries in rawbuf
int rawlen;
}
irparams_t;

这段代码我们要修改的 rawlen的定义,在默认库中这个数据被定义为uint8 也就是 一个字节的整数,最大只能到255
所以我们将此参数改成int


3、在arduino 中调出IRecvDump 的例程序,可以通过 FILE->EXAMPLES->Arduino_IRremote_master
1)编译和下载,打开com口监控 Tools->Serial Monitor
2)使用你家的空调遥控器对着接收头按一下开关键
3)这个时候串口会跳出你家空调开关的代码
“Raw (264): 13306 3500 -1700 450 -1250 500 -400 450。。。。”
请记住第一个 13306 不是代码头,你需要把这个放到你的数据的最后也就是说你的发送代码是
Raw (264):  3500 -1700 450 -1250 500 -400 450 。。。。。。。13306“


把你接受的数据 放入程序,也就是unsigned int rawCodes_ac_close[264]这个数组【】内的数字根据你接受的数据大小来调整


01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * [url=http://arcfn.com]http://arcfn.com[/url]
 * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 */
  
#include
int RECV_PIN = 11;//定义红外接收器的引脚为11
//unsigned int rawCodes_ac_close[264]={3288,1591,432,1186,432,372,444,383,433,375,443,1184,434,382,434,383,433,384,433,383,433,1187,432,382,433,1186,432,1185,432,382,434,1186,431,1187,432,1186,432,1186,432,1186,432,383,433,1185,432,383,434,383,433,1186,432,383,433,383,433,383,433,384,433,1186,432,1186,432,1186,432,1186,432,383,433,383,433,383,433,384,433,384,433,384,433,383,433,383,433,383,433,383,433,383,433,384,433,384,432,384,432,383,433,383,432,384,432,385,432,385,432,384,432,384,432,385,432,384,432,384,432,384,432,1187,431,384,433,384,432,1187,431,1186,431,1186,431,384,433,27841,3287,1590,432,1186,431,384,434,383,433,383,433,1185,434,375,441,383,433,383,434,383,432,1186,433,382,433,1187,431,1186,432,383,433,1187,431,1186,432,1186,431,1186,432,1186,432,382,432,1187,431,383,433,384,433,1187,432,383,434,383,433,384,433,384,433,384,433,384,433,384,433,384,433,1186,432,1186,431,1187,431,1186,432,383,433,384,433,382,433,1186,430,1188,431,384,433,383,433,384,432,384,432,385,432,384,433,384,432,384,432,384,432,384,432,384,432,385,431,384,432,384,432,385,432,384,432,1188,431,383,433,384,432,1187,431,384,432,384,433,384,432,27841};
  
//unsigned int rawCodes_ac_close[264]={3448,1668,453,1244,453,390,466,402,454,393,464,1242,455,400,455,401,454,402,454,402,454,1244,453,401,454,1244,453,1243,453,401,455,1243,452,1244,453,1243,453,1243,453,1243,453,402,454,1243,453,402,455,401,454,1244,453,401,454,402,454,401,454,402,454,1244,453,1244,453,1244,453,1243,453,401,454,402,454,402,454,403,454,402,454,402,454,402,454,402,454,402,454,402,454,402,454,402,454,403,453,402,453,402,454,402,453,403,453,403,452,403,453,403,453,402,453,403,453,403,453,403,453,403,453,1245,452,402,454,402,452,1245,452,1244,452,1244,452,402,454,29191,3446,1668,453,1244,452,402,455,402,454,402,454,1242,455,394,462,401,454,402,455,402,453,1244,454,401,454,1244,452,1244,453,401,454,1244,452,1243,453,1243,452,1244,453,1243,453,401,453,1245,452,402,454,402,454,1244,452,401,455,402,454,402,454,402,454,402,454,402,454,402,454,403,454,1244,453,1244,452,1245,452,1244,453,402,454,402,454,401,454,1244,451,1245,452,402,454,402,454,403,453,403,453,403,453,403,454,403,453,403,453,402,453,403,453,403,453,403,452,403,453,403,453,403,453,403,453,1245,452,402,454,402,453,1245,452,403,453,402,454,402,453,29191};
  
unsigned int rawCodes_ac_close[264]={3500,1700,450,1250,500,400,450,400,450,450,450,1250,450,400,500,350,500,400,450,400,500,1250,450,400,500,1250,450,1250,450,400,500,1250,450,1300,450,1250,450,1300,450,1250,450,400,500,1250,450,400,450,400,500,1250,450,400,500,400,450,400,450,450,450,1250,450,1300,450,1250,450,1250,500,400,450,400,450,400,500,400,450,400,500,400,450,400,450,450,450,400,450,400,500,400,450,400,450,400,500,400,450,400,450,450,450,400,450,400,500,400,450,400,450,450,450,400,450,400,500,400,450,400,450,1300,450,400,450,400,500,1250,450,1250,450,1300,450,400,450,29650,3500,1700,450,1300,450,400,450,400,500,400,450,1250,500,400,450,400,450,400,500,400,450,1250,500,400,450,1250,450,1300,450,400,450,1250,500,1250,450,1250,500,1250,450,1250,500,400,450,1250,450,400,500,400,450,1250,500,400,450,400,450,450,450,400,450,400,500,400,450,400,450,400,500,1250,450,1250,500,1250,450,1250,500,400,450,400,450,400,500,1250,450,1250,500,400,450,400,450,450,450,400,450,400,500,350,500,400,450,450,450,400,450,400,450,450,450,400,450,400,500,400,450,400,450,450,450,1250,450,400,500,400,450,1250,450,400,500,400,450,400,500,13306};
//上面改成你接受到的数据,请注意把接受到的第一个数据放到最后
  
IRrecv irrecv(RECV_PIN);
  
decode_results results;
  
IRsend  irsend;
  
//test
  
void setup()
{
  Serial.begin(9600);
 irrecv.enableIRIn(); // 初始化红外接收器
}
  
  
void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");
  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {       
    Serial.print("Decoded PANASONIC - Address: ");
    Serial.print(results->panasonicAddress,HEX);
    Serial.print(" Value: ");
  }
  else if (results->decode_type == JVC) {
     Serial.print("Decoded JVC: ");
  }
  Serial.print(results->value, HEX);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");
  
  for (int i = 0; i < count; i++) {
    if ((i % 2) == 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println("");
}
  
  
void loop() {
  irsend.sendRaw(rawCodes_ac_close,264, 40);
  delay(5);
  // irsend.sendRaw(rawCodes_ac_close,264, 40);
  
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    dump(&results);
 //    irsend.mark(560);
  //    irsend.space(560);
  //    irsend.mark(2000);
   //   irsend.space(560);
   //rsend.sendRaw(rawCodes_ac_close,6, 32);
    irrecv.resume(); // Receive the next value
  }
   delay(5000);
}






B、使用逻辑分析仪,很多遥控器解不出来,那么就要利用更牛B的工具了。
通过网购一个叫“逻辑分析仪”的设备分析出来空调的“关”编码。


设备是上面的这个样子,也有其他样子,使用起来基本是一样的。
USB接口的,安装驱动、安装配套软件什么的不上图了,没什么悬念。





两根线,分析仪上标了“公共地线”的接arduino的GND,“数字通道1”接红外接收头的数字引脚。
注:红外接收头有3个引脚,vcc(3.3v),gnd(地),输出(我接到arduino的引脚2)
上图中,一个接到数字接收头的GND,一个接到输出了。

然后,然后才加电。逻辑分析仪特别指出要断电接线的。所以要小心,不要把¥35烧了。





运行软件,界面如下:
标1处是采样的时间长短(越大越占内存),
2是采样频率,
3是上升沿触发,
4是高电平触发,
5是下降沿触发,
6是低电平触发(分析红外就把它按下,红外是低电平触发)





因为抓红外原始数据就一个通道,我只要把数字通道1的“低电平触发”按下就可以开始捕获数据了。



在显示sampling(采样)的时候,对着红外接收头,按下红外遥控器的关,别按错键了。开和关在一个按键上,但是编码不一样。
记得用鼠标滚轮把图例缩小到最小,你能看到一团数据在哪里,看不到的话,多试几次。
嗯,如果你有心,会发现,这个数据团会根据你按键的时间点而往前或者往后移动。



放大,放大放大放大






这里我们选择下面的模式,经验告诉我,这样的"TimeStamps"导出格式后期处理最简单。




这种导出的数值,就是每个点的具体时间。
填上函数=INT((a3-a2)*1000*1000),这个函数的意思是:帮我算下两个之间的差值,再转换成毫秒,再转换成微秒,再取整。





一拖到底




这么多数字,取哪些呢?
看看原始格式,2个大数字在前,后面跟着一堆小数字,很容易就把头找到了。
转换成arduino的代码


1
unsigned int rawCodes_ac_close[200] ={4193,4096,595,1451,589,432,588,1453,589,1454,587,432,587,434,563,1475,591,433,564,458,586,1453,587,434,587,433,563,1476,590,1454,587,434,565,1475,566,456,563,1476,590,1453,587,1452,564,1477,566,457,585,1453,567,1477,587,1452,564,460,584,434,564,457,562,460,562,1475,587,434,588,433,562,1476,589,1455,563,1476,588,433,586,436,562,459,586,433,563,458,609,410,563,458,586,433,587,1454,587,1453,563,1477,564,1477,565,1476,581,4858,4237,4074,593,1453,562,460,563,1477,563,1477,565,458,587,434,584,1454,590,433,562,458,587,1453,588,436,584,436,562,1476,588,1453,590,434,562,1480,586,435,586,1453,565,1476,589,1453,589,1451,565,461,583,1453,589,1453,588,1454,564,457,587,434,587,433,587,435,561,1479,586,435,562,458,588,1452,590,1452,565,1476,564,458,587,436,584,433,562,458,588,432,562,461,585,434,584,435,589,1451,588,1453,588,1453,590,1453,590,1451,590};




irsend.sendRaw(rawCodes_ac_close,200, 38);
在代码里发射吧。


更多玩法,自己琢磨。
如果收集市面上所有的遥控器编码,那么就是一个万能遥控器,这可能需要一个公司才能做了,大家加油吧。
参考:http://www.geek-workshop.com/thread-5095-1-1.html


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。