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

z01228 发表于 2021-8-19 16:43

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

本帖最后由 z01228 于 2021-8-19 16:45 编辑

最近在写艾韵智能红外遥控器的代码,已经可以通过点灯科技的app远程控制家里的格力空调了。官方的服务器已经停服了所以就只能自己写了。这个模块就控制一个空调是不是有一些浪费 就想添加可以控制其他红外设备的功能,但是通过协议发射的方式已经不能满足我的要求了。目前的程序是通过解码raw红外信号再进行红外发射。试验平台: 因为IRremoteESP8266库中有解码的函数 但是出来的结果不能直接使用。所以本来程序就真对这个问题进行算法 解析:基于IRrecvDumpV2示例。代码://红外解码raw
//2021年8月19日02:35:43
//程序效果
/*模块新上电后进行一次红外编码学学习
*后进行2s重复发射红外信号
*红外接收--D5
*红外发射--D6
*/

//接收库
#include <Arduino.h>
#include <assert.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>




//接收定义
const uint16_t kRecvPin = 14;//ESP8266--D5
const uint32_t kBaudRate = 115200;
const uint16_t kCaptureBufferSize = 1024;
#if DECODE_AC
const uint8_t kTimeout = 50;
#else   // DECODE_AC
const uint8_t kTimeout = 15;
#endif// DECODE_AC
const uint16_t kMinUnknownSize = 12;
const uint8_t kTolerancePercentage = kTolerance;// kTolerance is normally 25%
#define LEGACY_TIMING_INFO false
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;// Somewhere to store the results

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

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


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


int pl_1=0;//频率
int cd_2=0;//长度
unsigned intwssj1; //无损数组1--raw解码成功的//过渡
//unsigned int wssj2; //无损数组1--raw解码成功的
uint16_twssj2; //无损数组1--raw解码成功的

boolean zdfs_bzw = 0; //自动发射

void setup() {
#if defined(ESP8266)
Serial.begin(kBaudRate, SERIAL_8N1, SERIAL_TX_ONLY);
#else// ESP8266
Serial.begin(kBaudRate, SERIAL_8N1);
#endif// ESP8266
while (!Serial)
    delay(50);

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

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

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


void loop() {

if (irrecv.decode(&results)) {
    if(zdfs_bzw == 0){
   
    Serial.println("**///////原始数据///////**");   
    Serial.println("//*协议-内容-频率*//");
    // Serial.print(resultToHumanReadableBasic(&results));
    ysml_1="";//清空字符串
    ysml_1=resultToHumanReadableBasic(&results);
    ysml_1.replace(" ", "");//删除ysml_2中的所有空格--这个使用的是替换   
    Serial.println(ysml_1);
   
    Serial.println("//*字符串raw-(长度,内容)*//");
    //Serial.println(resultToSourceCode(&results));
    ysml_2="";//清空字符串
    ysml_2=resultToSourceCode(&results);
    ysml_2.replace(" ", "");//删除ysml_2中的所有空格--这个使用的是替换
    Serial.println(ysml_2);   
    Serial.println();    // 条目之间的空行
    yield();             // 馈送 WDT(再次)

    Serial.println("//*开始解析*//");
    pltq();
    cdtq();
    zfcsz();
   
zdfs_bzw =1;
}
}

if(zdfs_bzw == 1){
delay(2000);
    irsend.sendRaw(wssj2, cd_2, pl_1);//发射解析出来的raw(数组,长度,频率)
}
}
下面是解析部分


//下面进行命令解析

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

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


for (int i = 0; i < ysml_1.length() ; i++)//for循环1
{
    if (ysml_1 == '(') {
      ja1 = i;
      pltq_bzw = 1;
    }
    if (pltq_bzw == 1)
    {
      if (ysml_1 == 'B')
      {
      ja2 = i;
      break; //退出for循环1
      }
    }
}


for (int k = ja1 + 1; k < ja2 ; k++)
{
    pl_zjl += char(ysml_1);
}

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

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

}


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

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

for (int i = 0; i < ysml_2.length() ; i++) //for循环2
{
    if (ysml_2 == '[') {
      ja3 = i;
      cdtq_bzw = 1;
    }
    if (cdtq_bzw == 1)
    {
      if (ysml_2 == ']')
      {
      ja4 = i;
      break; //退出for循环2
      }
    }
}


for (int k = ja3 + 1; k < ja4; k++)
{
    cd_zjl += char(ysml_2);
}

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

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

//命令数组
void zfcsz() {


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

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

for (int i = 0; i < ysml_2.length() ; i++) //for循环3
{
    if (ysml_2 == '}')
    {
      break; //退出for循环3
    }
    if (ysml_2 == '{' || ysml_2 == ',')
    {

      if (pltq_bzw == 1)
      {
      j = j + 1;
      }
      pltq_bzw = 1;
    }

    else {
      if (pltq_bzw == 1)
      {
      wssj1 = wssj1 * 10 + (ysml_2 - '0');
      delay(1);
      }

    }
}


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

for (int i = 0; i < cd_2; i++)//把过渡数组赋予最终数组
{
    wssj2 = wssj1;
    delay(1);
}

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

//打印结果
Serial.println(" ");
Serial.println("中间数组(wssj1)编码//位置--内容:");
for (int i = 0; i < cd_2; i++)
{
    Serial.print(i);
    Serial.print("--");
    Serial.print(wssj1);
    Serial.print(",");
    delay(1);
}


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


for (int i = 0; i < cd_2; i++) {
    Serial.print(i);
    Serial.print("--");
    Serial.print(wssj2);
    Serial.print(",");
    delay(1);
}
Serial.println();
Serial.println("///*分析结束*/// ");
   Serial.println();
}
串口输出结果:原始编码 以及解号结果
程序简介:模块上电后进行一次红外编码学习,之后以2s一次的时间间隔发射学习的红外信号,需要重启之后才可以退出。
估计再有2天带万能解码的 空调遥控器 就可以与大家见面了。

myself1820 发表于 2021-9-10 16:23

不错不错,学习了
页: [1]
查看完整版本: 红外万能遥控器--解码发射