请选择 进入手机版 | 继续访问电脑版

智能创客,中国最大的极客空间,智能平台,免费教学,视频教程,手把手教你创造儿时梦想!

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 15023|回复: 44

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

  [复制链接]

110

主题

396

帖子

2319

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2319
QQ
发表于 2015-1-23 15:43:21 | 显示全部楼层 |阅读模式
上篇WIFI作品DIY教程07-《wifi家居网关》家居控制中心zigbee/nrf24l01等完成了家居网关。


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




第一部分:红外发射、接收编码介绍
红外线又称红外光波,在电磁波谱中,光波的波长范围为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驱动
135305xx0d2whdhwzh2ffp.jpg
在drivers目录里找到CH340驱动,然后按说明安装(之前安装了就不用再安装了)。


2、源代码
[C] 纯文本查看 复制代码

/*
 *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);
      }
      if(  strlen(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;
    }

}
[/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i][/i]




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

打开arduino ide 的串口监视

310.jpg
输入{0200010}进入自学模式。

210.jpg
对着点遥控器。

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


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

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


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

331.jpg
这里发射就少了去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]这个数组【】内的数字根据你接受的数据大小来调整

[C] 纯文本查看 复制代码
/*
 * 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的工具了。
通过网购一个叫“逻辑分析仪”的设备分析出来空调的“关”编码。
142950x4pzqah3syaxurgu.jpg

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




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

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




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




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


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


145208henmzhurmdfepda5.jpg
放大,放大放大放大




215633rrrhq49t794779rt.jpg

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



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




150138t0kvjw0hr0kfvvhf.jpg
一拖到底




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

[C] 纯文本查看 复制代码
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


《WIFI作品DIY教程系列》
WIFI作品DIY教程01-《wifi开发板》介绍和联网等配置教程
WIFI作品DIY教程02-《openwrt摄像头》3D外壳和diy介绍
WIFI作品DIY教程03-《WIFI音响/MP3播放器/电台》
WIFI作品DIY教程04-《WIFI烟雾煤气报警器》
WIFI作品DIY教程05-《家居服务器》web server(php+mysql+uhttpd)
WIFI作品DIY教程06-《openwrt后台程序》控制mysql、串口通信等
WIFI作品DIY教程07-《wifi家居网关》家居控制中心zigbee/nrf24l01等
WIFI作品DIY教程08-《智能开关》电灯开关、插座(nrf24l01/zigbee)
WIFI作品DIY教程09-《人体红外检测》安防入侵报警功能
WIFI作品DIY教程10-《温湿传感器》DS18B20、DHT11应用。
WIFI作品DIY教程11-《烟雾火警》MQ-2烟雾/丙烷/天然气检测。
WIFI作品DIY教程12-《红外遥控》控制家电、自学、发射红外。


《Arduino开源智能家居DIY教程系列》
Arduino开源智能家居《花絮1》zigbee小底板DIY成功
Arduino开源智能家居《认识Zigbee》zigbee功能和自组网介绍
Arduino开源智能家居《zigbee开发板》手机/按键点亮LED
Arduino开源智能家居01《网关》升级版网关正式教程(zigbee)
Arduino开源智能家居02《温湿传感器》什么样温湿度才适居
Arduino开源智能家居03《开发板套件》学习zigbee家居-性价比高
Arduino开源智能家居04《插座开关》手机控制:网扇、空调...
Arduino开源智能家居05《红外线》手机红外线控制电器

《百元智能家居DIY教程系列》
《智能家居网关》DIY制作图文教程01-百元智能家居系列
《智能温湿度》DIY制作图文教程02-百元智能家居系列
《智能插座》DIY制作图文教程03-百元智能家居系列
《智能电灯开关》DIY制作图文教程04-百元智能家居系列
《手机红外线》DIY制作图文教程05-百元智能家居系列
关注@智能创客  微信:znck007(打造DIY创客平台)
135305tbbix1bdyd97948y.png
回复

使用道具 举报

0

主题

10

帖子

60

积分

注册会员

Rank: 2

积分
60
发表于 2015-3-9 15:10:46 | 显示全部楼层
代码有问题
回复 支持 反对

使用道具 举报

110

主题

396

帖子

2319

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2319
QQ
 楼主| 发表于 2015-3-9 17:09:15 | 显示全部楼层

qq610854837截图,日志等。
回复 支持 反对

使用道具 举报

0

主题

10

帖子

60

积分

注册会员

Rank: 2

积分
60
发表于 2015-3-10 12:40:00 | 显示全部楼层
znck007 发表于 2015-3-9 17:09
qq610854837截图,日志等。

我是说论坛贴的代码,库引用不全,代码复制到论坛的问题
回复 支持 反对

使用道具 举报

0

主题

29

帖子

92

积分

注册会员

Rank: 2

积分
92
发表于 2015-5-14 22:39:10 | 显示全部楼层
本帖最后由 创客帝国 于 2015-7-23 21:21 编辑

谢谢哦,辛苦辛苦!







回复 支持 反对

使用道具 举报

0

主题

9

帖子

38

积分

禁止发言

积分
38
发表于 2015-6-30 13:50:56 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

9

帖子

42

积分

禁止发言

积分
42
发表于 2015-7-2 04:52:13 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

1

帖子

11

积分

新手上路

Rank: 1

积分
11
发表于 2015-7-10 09:28:03 | 显示全部楼层

要顶
必须顶
不得不顶
用尽全力顶
再加上千斤顶
总之把它顶到顶
接着使出葵花宝顶
就算顶到史前也要顶
老子看了会用道德经顶
孔子亲自拜你为师天天顶
秦始皇站在阿房宫上使劲顶
汉高祖挥师杀向东罗马为你顶
吕布抛弃了貂禅而选择了帮你顶
张三丰见了后用太极拳九式全力顶
回复 支持 反对

使用道具 举报

0

主题

3

帖子

16

积分

新手上路

Rank: 1

积分
16
发表于 2015-8-17 17:20:41 | 显示全部楼层
FILE->EXAMPLES->Arduino_IRremote_ 后面那个master找不到怎么办
回复 支持 反对

使用道具 举报

110

主题

396

帖子

2319

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2319
QQ
 楼主| 发表于 2015-8-18 08:45:18 | 显示全部楼层
yleer3407 发表于 2015-8-17 17:20
FILE->EXAMPLES->Arduino_IRremote_ 后面那个master找不到怎么办

我们使用的库没有master
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|手机版|智能创客 ( 桂ICP备14000828号

GMT+8, 2019-1-19 13:50 , Processed in 0.093157 second(s), 12 queries , Apc On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表