红外万能遥控器-解码发射-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2496|回复: 1

红外万能遥控器--解码发射

[复制链接]
发表于 2021-8-19 16:43 | 显示全部楼层 |阅读模式
本帖最后由 z01228 于 2021-8-19 16:45 编辑

最近在写艾韵智能红外遥控器的代码,已经可以通过点灯科技的app远程控制家里的格力空调了。官方的服务器已经停服了所以就只能自己写了。

~5@T95HDBVJ8C_7ED~C$H07.png

这个模块就控制一个空调是不是有一些浪费 就想添加可以控制其他红外设备的功能,但是通过协议发射的方式已经不能满足我的要求了。目前的程序是通过解码raw红外信号再进行红外发射。

试验平台:

11_55JXO}({LMP7NW0.png

因为IRremoteESP8266库中有解码的函数 但是出来的结果不能直接使用。所以本来程序就真对这个问题进行算法 解析:基于IRrecvDumpV2示例。

代码:

  1. //红外解码raw
  2. //2021年8月19日02:35:43
  3. //程序效果
  4. /*模块新上电后进行一次红外编码学学习
  5. *后进行2s重复发射红外信号
  6. *红外接收--D5
  7. *红外发射--D6
  8. */

  9. //接收库
  10. #include <Arduino.h>
  11. #include <assert.h>
  12. #include <IRrecv.h>
  13. #include <IRremoteESP8266.h>
  14. #include <IRac.h>
  15. #include <IRtext.h>
  16. #include <IRutils.h>




  17. //接收定义
  18. const uint16_t kRecvPin = 14;//ESP8266--D5
  19. const uint32_t kBaudRate = 115200;
  20. const uint16_t kCaptureBufferSize = 1024;
  21. #if DECODE_AC
  22. const uint8_t kTimeout = 50;
  23. #else   // DECODE_AC
  24. const uint8_t kTimeout = 15;
  25. #endif  // DECODE_AC
  26. const uint16_t kMinUnknownSize = 12;
  27. const uint8_t kTolerancePercentage = kTolerance;  // kTolerance is normally 25%
  28. #define LEGACY_TIMING_INFO false
  29. IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
  30. decode_results results;  // Somewhere to store the results

  31. //发射库
  32. #include <IRsend.h>

  33. //发射定义
  34. const uint16_t kIrLed =12;  //ESP8266--D6
  35. IRsend irsend(kIrLed);


  36. String ysml_1 ="";//原始命令-1--提取频率
  37. String ysml_2 ="";//原始命令-1--提取长度 编码


  38. int pl_1=0;//频率
  39. int cd_2=0;//长度
  40. unsigned int  wssj1[200]; //无损数组1--raw解码成功的//过渡
  41. //unsigned int wssj2[200]; //无损数组1--raw解码成功的
  42. uint16_t  wssj2[200]; //无损数组1--raw解码成功的

  43. boolean zdfs_bzw = 0; //自动发射

  44. void setup() {
  45. #if defined(ESP8266)
  46.   Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY);
  47. #else  // ESP8266
  48.   Serial.begin(kBaudRate, SERIAL_8N1);
  49. #endif  // ESP8266
  50.   while (!Serial)  
  51.     delay(50);

  52.   assert(irutils::lowLevelSanityCheck() == 0);

  53.   Serial.printf("\n" D_STR_IRRECVDUMP_STARTUP "\n", kRecvPin);
  54. #if DECODE_HASH

  55.   irrecv.setUnknownThreshold(kMinUnknownSize);
  56. #endif  // DECODE_HASH
  57.   irrecv.setTolerance(kTolerancePercentage);  // Override the default tolerance.
  58.   irrecv.enableIRIn();  //接收初始化
  59.   irsend.begin();//发射初始化
  60. }


  61. void loop() {
  62.   
  63.   if (irrecv.decode(&results)) {
  64.     if(zdfs_bzw == 0){
  65.    
  66.     Serial.println("**///////原始数据///////**");   
  67.     Serial.println("//*协议-内容-频率*//");
  68.     // Serial.print(resultToHumanReadableBasic(&results));
  69.     ysml_1="";//清空字符串
  70.     ysml_1=resultToHumanReadableBasic(&results);
  71.     ysml_1.replace(" ", "");//删除ysml_2中的所有空格--这个使用的是替换   
  72.     Serial.println(ysml_1);
  73.    
  74.     Serial.println("//*字符串raw-(长度,内容)*//");
  75.     //Serial.println(resultToSourceCode(&results));
  76.     ysml_2="";//清空字符串
  77.     ysml_2=resultToSourceCode(&results);
  78.     ysml_2.replace(" ", "");//删除ysml_2中的所有空格--这个使用的是替换
  79.     Serial.println(ysml_2);   
  80.     Serial.println();    // 条目之间的空行
  81.     yield();             // 馈送 WDT(再次)

  82.     Serial.println("//*开始解析*//");
  83.     pltq();
  84.     cdtq();
  85.     zfcsz();
  86.    
  87.   zdfs_bzw =1;
  88.   }
  89.   }
  90.   
  91.   if(zdfs_bzw == 1){
  92.   delay(2000);
  93.     irsend.sendRaw(wssj2, cd_2, pl_1);  //发射解析出来的raw  (数组,长度,频率)
  94.   }
  95. }
复制代码

下面是解析部分




  1. //下面进行命令解析

  2. //频率提取--对ysml_1进行数据分析
  3. void pltq() {

  4.   int ja1, ja2; //存放收到的字符串中标志字母的下标
  5.   boolean pltq_bzw = 0; //频率提取标志位
  6.   String pl_zjl = ""; //存放解析出的频率数据--频率-中间量


  7.   for (int i = 0; i < ysml_1.length() ; i++)//for循环1
  8.   {
  9.     if (ysml_1[i] == '(') {
  10.       ja1 = i;
  11.       pltq_bzw = 1;
  12.     }
  13.     if (pltq_bzw == 1)
  14.     {
  15.       if (ysml_1[i] == 'B')
  16.       {
  17.         ja2 = i;
  18.         break; //退出for循环1
  19.       }
  20.     }
  21.   }


  22.   for (int k = ja1 + 1; k < ja2 ; k++)
  23.   {
  24.     pl_zjl += char(ysml_1[k]);
  25.   }

  26.   pl_1 = pl_zjl.toInt(); //将解析得到的字符串转换为int类型

  27.   Serial.println("int频率:");
  28.   Serial.println(pl_1);

  29. }


  30. //频率提取--对ysml_2进行数据分析
  31. void cdtq() {

  32.   int ja3, ja4, ja5, ja6; //存放收到的字符串中标志字母的下标
  33.   boolean cdtq_bzw = 0; //长度提取标志位
  34.   String cd_zjl = ""; //存放解析出的长度数据--长度-中间量
  35.   String nr_zjl = ""; //存放解析出的内容数据--内容-中间量

  36.   for (int i = 0; i < ysml_2.length() ; i++) //for循环2
  37.   {
  38.     if (ysml_2[i] == '[') {
  39.       ja3 = i;
  40.       cdtq_bzw = 1;
  41.     }
  42.     if (cdtq_bzw == 1)
  43.     {
  44.       if (ysml_2[i] == ']')
  45.       {
  46.         ja4 = i;
  47.         break; //退出for循环2
  48.       }
  49.     }
  50.   }


  51.   for (int k = ja3 + 1; k < ja4; k++)
  52.   {
  53.     cd_zjl += char(ysml_2[k]);
  54.   }

  55.   cd_2 = cd_zjl.toInt(); //将解析得到的字符串转换为int类型

  56.   Serial.println("int长度:");
  57.   Serial.println(cd_2);
  58. }

  59. //命令数组
  60. void zfcsz() {


  61.   int j = 0;
  62.   boolean pltq_bzw = 0; //频率提取标志位
  63.   delay(2);

  64.   Serial.println("//7*调试3**");
  65.   Serial.println(ysml_2);

  66.   for (int i = 0; i < ysml_2.length() ; i++) //for循环3
  67.   {
  68.     if (ysml_2[i] == '}')
  69.     {
  70.       break; //退出for循环3
  71.     }
  72.     if (ysml_2[i] == '{' || ysml_2[i] == ',')
  73.     {

  74.       if (pltq_bzw == 1)
  75.       {
  76.         j = j + 1;
  77.       }
  78.       pltq_bzw = 1;
  79.     }

  80.     else {
  81.       if (pltq_bzw == 1)
  82.       {
  83.         wssj1[j] = wssj1[j] * 10 + (ysml_2[i] - '0');
  84.         delay(1);
  85.       }

  86.     }
  87.   }


  88.   memset(wssj2, 0, sizeof(wssj2)); //清空最终数组

  89.   for (int i = 0; i < cd_2; i++)//把过渡数组赋予最终数组
  90.   {
  91.     wssj2[i] = wssj1[i];
  92.     delay(1);
  93.   }

  94.   //上面是分析下面是结果输出

  95.   //打印结果
  96.   Serial.println(" ");
  97.   Serial.println("中间数组(wssj1)编码//位置--内容:");
  98.   for (int i = 0; i < cd_2; i++)
  99.   {
  100.     Serial.print(i);
  101.     Serial.print("--");
  102.     Serial.print(wssj1[i]);
  103.     Serial.print(",");
  104.     delay(1);
  105.   }


  106.   Serial.println(" ");
  107.   Serial.println("使用的数组(wssj2)编码:位置--内容:");


  108.   for (int i = 0; i < cd_2; i++) {
  109.     Serial.print(i);
  110.     Serial.print("--");
  111.     Serial.print(wssj2[i]);
  112.     Serial.print(",");
  113.     delay(1);
  114.   }
  115.   Serial.println();
  116.   Serial.println("///*分析结束*/// ");
  117.    Serial.println();
  118. }
复制代码

串口输出结果:

QQ图片20210819163305.png

原始编码 以及解号结果


程序简介:

模块上电后进行一次红外编码学习,之后以2s一次的时间间隔发射学习的红外信号,需要重启之后才可以退出。


估计再有2天带万能解码的 空调遥控器 就可以与大家见面了。



发表于 2021-9-10 16:23 | 显示全部楼层
不错不错,学习了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 09:48 , Processed in 0.075851 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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