avenlee2023 2024-05-28 14:19 采纳率: 3.8%
浏览 41

esp32 rmt发射红外信号控制小米电视开机

esp32 idf 开发,RMT发射红外数据,配置rmt_config_t的时候,需不需要开载波,另外一个是没有修改过主频,160Mhz,RMT时钟源是不是就是80M?对于数据配置的高低电平周期item->duration0应该是怎么计算的,假如我想要控制电视机开机,载波38K,数据信号是引导码低电平1ms高电平0.6ms,数据码低电平0.6ms高电平0.6ms,低电平0.6ms高电平1.5ms,结束码低电平0.6ms高电平1ms,应该要怎么进行配置?这些数据经过载波后发送,是不是高低电平相反了?

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-05-28 14:19
    关注

    引自免费微信小程序:皆我百晓生

    为了帮助您实现ESP32通过RMT(远程信道)接口发送红外信号以控制小米电视开机,这里我会提供详细的步骤和代码示例。首先确保您的ESP32开发板已经正确连接,并且安装了必要的开发环境。

    1. 配置RMT模块

    在配置RMT时,我们通常不需要开启载波,因为红外遥控器接收的是脉冲宽度编码的信号,而不是载波调制。因此,在设置rmt_config_t结构体时,可以将载波相关的参数设为0。关于时钟源,ESP32的外设时钟通常是系统时钟的一半,所以160MHz的系统时钟对应的RMT时钟源是80MHz。

    #include "driver/rmt.h"
    
    // RMT通道配置
    rmt_channel_config_t config = {
        .tx ALIGN_LEFT,     // 传输模式:左对齐
        .idle_level LOW,   // 闲置电平:低电平
        .pin_id RMT_CHANNEL_0_TXD, // TX引脚ID
        .clk_divider 8,      // 时钟分频,80MHz / 8 = 10MHz
    };
    
    1. 计算信号周期

    根据您提供的信号描述,我们可以计算出每个信号的周期。这里使用一个简单的函数来计算每个信号的周期(单位为微秒),并将其转换为RMT的计数单位(一个周期等于1个时钟周期,即1/10MHz)。

    int calculate_duration(int us) {
        return (us * 10) / 8; // 10MHz时钟,除以8得到实际周期数
    }
    
    1. 创建红外信号序列

    接下来,我们将创建一个包含所有信号的数组。每个信号由两个元素组成:信号类型(0表示低电平,1表示高电平)和持续时间。

    // 红外信号序列
    uint16_t signal_sequence[] = {
        {0, calculate_duration(1000)}, // 引导码低电平1ms
        {1, calculate_duration(600)},  // 引导码高电平0.6ms
        {0, calculate_duration(600)},  // 数据码低电平0.6ms
        {1, calculate_duration(600)},  // 数据码高电平0.6ms
        {0, calculate_duration(600)},  // 数据码低电平0.6ms
        {1, calculate_duration(1500)}, // 数据码高电平1.5ms
        {0, calculate_duration(600)},  // 结束码低电平0.6ms
        {1, calculate_duration(1000)}  // 结束码高电平1ms
    };
    
    const int signal_count = sizeof(signal_sequence) / sizeof(signal_sequence[0]);
    
    1. 发送红外信号

    现在我们可以使用RMT API来发送这个信号序列。记得先初始化RMT通道,然后启动RMT发送。

    void setup_rmt() {
        rmt_init(&config);
        rmt_tx_config_t tx_cfg = {
            .data_num = signal_count,
            .times = 1, // 发送次数
        };
        rmt_set_pin(config.idle_level, config.pin_id);
        rmt_tx_start(RMT_CHANNEL_0, &tx_cfg, signal_sequence, NULL);
    }
    
    void loop() {
        setup_rmt();
        vTaskDelay(pdMS_TO_TICKS(100)); // 等待一段时间后再发送,防止连续发送导致干扰
    }
    

    这段代码将在loop()函数中每100毫秒发送一次红外信号。请注意,由于红外遥控器可能有接收延迟,建议您在实际应用中适当增加等待时间。

    这个例子没有涉及到具体的数据编码,因为您没有提供具体的遥控器指令。如果您有特定的指令二进制数据,您可以将其转换为上述格式的信号序列。通常,红外遥控器的数据部分会包含一个起始位、多个数据位、校验位和停止位。您可以按照这些规则来构建数据信号。

    最后,发送的信号不会受到载波的影响,因为RMT接口只关心脉冲的宽度,而不考虑是否有载波。只要脉冲宽度符合遥控器的要求,信号就能被正确解码。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月28日