esp32实现万能红外遥控器 基于开源红外码库IREXT

前言

注意,该码库仅供学习和研究,请勿用于商业用途,官网已经关闭

想快速上手万能遥控器的同学可直接看第三节,前面是对irext的详细讲解,关于esp32如何发射/接收红外遥控信号,参考我另一篇文章:https://blog.csdn.net/weixin_44821644/article/details/108592858

一,IRext简介

支持红外遥控的设备,一般都会有自己的一套红外编码协议,而这个协议一般的厂家是不开源的。例如格力空调就有大约40套的编码协议。开发者如果要开发一个红外遥控器,就需要知道这些协议才能发射特定的信号。

网上的码库基本都需要公司进行合作,这对个人开发者不友好,irext就是一个开源的红外码库,他提供了多种电器,不同品牌的红外协议,把这些协议打包成二进制文件,并提供解码库,使开发者能解码打包的二进制代码,根据解码出的数据进行红外发射。

详细的irext情况,请看官网的介绍:http://irext.net/index.html#intro

二,IRext的使用

2.1 使用思路

本文以esp32为例介绍irext的简单使用。首先需要获得二进制文件,并使用irext提供的解码库将其解码,解码会得到一个特殊的数组,这个数组保存的数据就是红外发射所需的脉冲序列。

例如:解析格力空调的二进制码库得到的数组如下:

[8967,4499,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,598,598,1671,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,1671,598,598,598,598,598,1671,598,598,598,19984,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,1671,598,598,598,40150,8967,4499,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,598,598,1671,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,1671,598,1671,598,598,598,598,598,1671,598,598,598,19984,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,1671,598,1671,598,598,598,598,598]

第一个数据8969表示的是一个持续时间为8967us的电平,第二个数据表示持续时间为4499us的电平,熟悉主流红外协议的同学马上就知道,这两个数据组成了红外协议的起时码。
有了这个数组,我们就能在自己的设备上产生特定的脉冲序列。

2.2 获取二进制文件

IRext提供了多种方式获取二进制文件,具体如下:

2.2.1控制台下载

直接下载指定的二进制文件到电脑,或者点我下载码库二进制文件包
优点是简单暴力,但是需要再烧录到嵌入式设备中。
在这里插入图片描述

2.2.2 Web API下载

IRext支持Web API ,用户可以通过公有云发起http连接,获取电器分类,电器品牌以及具体的电器品牌下所有的红外编码二进制文件等。

具体的API可以查看其文档http://irext.net/doc/

2.3 解码

解码方式有在线解码与离线解码,在线解码使用的是Web API,具体参考文档,本文主要介绍离线解码。

离线解码需要使用解码仓库:https://github.com/irext/core,文档参考:http://irext.net/doc/

2.3.1 文件系统下的解码

设备有文件系统下,以下代码实现了将my_ir_code_file.bin文件解码,解码出的数组存放在user_data中,decode_len是数组的长度。category是电器类型代号,sub_category命令类编码的样本类型。(电器类型代号在文末)

ir_file_open(category, sub_category, "/path/my_ir_code_file.bin");
uint16_t decode_len=ir_decode(key_code, user_data, ac_status, 0);
ir_close();

这里重点介绍一下ac_status,通过对ac_status的成员赋值,可以产生对应数组。例如以下的代码,产生的是,制冷模式,打开,26℃,开启扫风的红外命令数组。

ac_status.ac_mode = AC_MODE_COOL;
	ac_status.ac_power = AC_POWER_OFF;
	ac_status.ac_temp = AC_TEMP_26;
	ac_status.ac_wind_dir = AC_SWING_ON;
	ac_status.ac_wind_speed = AC_WS_LOW;

2.3.2 加载到内存解码

使用ir_binary_open()代替ir_file_open(),其他的内容与文件系统下的操作一样。

ir_binary_open(category, sub_category, buffer, buffer_length);

三,基于esp32的irext

使用esp32进行红外发射的实现,我以前的博客讲过,ESP32 红外遥控 发射与接收的实现 IR_TX IR_RX 基于idf3.3,接下来就在这个博客的基础上,用irext解析出来的数组来构建item

3.1 整体思路

首先将irext_core解码仓库添加进项目,然后将二进制文件烧录进esp32的文件系统,最后在代码中解码出数组,使用数组构建item

3.1 将irext解码仓库添加到工程

github上下载该仓库 https://github.com/irext/core,如果速度太慢,解决办法:提升github下载速度最新解决方案

然后添加到项目文件夹下,记得修改CMakeLists.txt的内容。

在main.c中添加,ir_decode.h是irext解码的接口。是我们需要使用的唯一头文件。

#include "ir_decode.h"

3.2 将二进制文件烧录进spiffs文件系统

如何烧录spiffs文件系统请参考:三分钟上马 ESP32 spiffs文件系统
例如将xxx.bin放入根目录下的xxx文件夹,然后烧录进esp32,使用时路径名称:

char *filepath = "/spiffs/xxx/xxx.bin";

3.3 文件系统解码

以下是一个示例的流程,具体逻辑看注释。

uint16_t decoded[1024] = {
    
     0 };     //二进制文件解码的数据

t_remote_ac_status ac_status;   //编码红外的状态(用于开关温度调节)
void demo()
{
    
    
	char *filepath = "/spiffs/xxx/xxx.bin";
    ac_status.ac_mode = AC_MODE_COOL;
	ac_status.ac_power = AC_POWER_OFF;
	ac_status.ac_temp = AC_TEMP_26;
	ac_status.ac_wind_dir = AC_SWING_ON;
	ac_status.ac_wind_speed = AC_WS_LOW;
	
	ir_file_open(1,0,filepath);		//打开文件。空调代号1
	uint16_t decode_len = ir_decode(KEY_AC_POWER, decoded, &ac_status, 0);	//获得编码数组
	ir_close();	//关闭文件
	//格力的代码会发送两帧一模一样的数据,这里我只取第一帧
	if(decode_len > 200)
	{
    
    
		decode_len = (decode_len + 1) / 2;
	}
	item_num = (decode_len / 2);	//item数量是数组长度的一半
	size = (sizeof(rmt_item32_t) * item_num);
	item = (rmt_item32_t *)malloc(size);

	irext_build(item, item_num);	//根据数组构建item

	rmt_write_items(tx_channel, item, item_num, true); //将item集合写入通道对应的RAM并进入阻塞

	rmt_wait_tx_done(tx_channel, portMAX_DELAY); //等待发送完成 进入阻塞

	free(item);
}

主要的是irext_build()函数,nec_fill_item_level()在之前的文章也提过了。

/*
 * irext_build
 * brief:通过irext构建item 使用全局变量
 */
static void irext_build(rmt_item32_t* item,size_t item_num)
{
    
    
	int i = 0;

    nec_fill_item_level(item, decoded[0], decoded[1]);
    for (i = 1; i < item_num;i++)
	{
    
    
        item++;
		nec_fill_item_level(item, decoded[2*i], decoded[2*i + 1]);
		
	}
}

nec_fill_item_level()接收的参数是单位是us,所以我直接将数组里的数据放进去就行

/*
 * @brief 填充item的电平和电平时间 需要将时间转换成计数器的计数值 /10*RMT_TICK_10_US
 */
static inline void nec_fill_item_level(rmt_item32_t* item, int high_us, int low_us)
{
    
    
    item->level0 = 1;
    item->duration0 = (high_us) / 10 * RMT_TICK_10_US;
    item->level1 = 0;
    item->duration1 = (low_us) / 10 * RMT_TICK_10_US;
}

四,小结

本文的例子只展示了如何在esp32上使用irext,其他设备也是可以的,irext支持的平台很多。
irext可能是唯一一个开源的红外码库,使用也方便,对开发者还是非常友好的,但是网上的相关资料有点少,希望你点个赞,让更多使用红外的开发者能发现这个宝库。
在这里插入图片描述

电器类型代号

        {
    
    
            "id": 1,
            "name": "空调",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 2,
            "name": "电视机",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 3,
            "name": "机顶盒",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 4,
            "name": "网络盒子",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 5,
            "name": "IPTV",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 6,
            "name": "DVD",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 7,
            "name": "风扇",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 8,
            "name": "投影仪",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 9,
            "name": "音响",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 10,
            "name": "灯",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 11,
            "name": "机顶盒",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 12,
            "name": "扫地机器人",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 13,
            "name": "空气净化器",
            "status": 1,
            "updateTime": "2016-11-27 11:00:00"
        },
        {
    
    
            "id": 14,
            "name": "Dyson",
            "status": 1,
            "updateTime": "2017-01-20"
        }

猜你喜欢

转载自blog.csdn.net/weixin_44821644/article/details/109292942