ESP-IDF v5.1 连接wifi后,红外信号发射控制空调失败

xuming
Posts: 1
Joined: Tue Sep 19, 2023 7:42 am

ESP-IDF v5.1 连接wifi后,红外信号发射控制空调失败

Postby xuming » Wed Sep 20, 2023 2:03 am

最近在练习在esp32-s2板子上连接wifi和发射红外信号控制格力空调的功能,这两个功能是分开来开发的。单独连接wifi,可以成功连接并且可以通过MQTT订阅和发布消息。单独发送红外信号控制空调,因为没有连接wifi,所以是hard code的,也是可以的,而且目前测试成功率是100%。但是将两个功能联合调试,发现wifi连接之后,红外信号控制空调的成功率不是100%了,时高时低,有时候一个信号要重复发几次才成功一次,有时候要几十次才能成功。
通过ir receiver接受红外信号,连接wifi后发现高低电平持续时间会出错,解析出来的二进制信号就不对。
在寻找解决办法的时候,看到说esp板子wifi运行是,ADC2的引脚是不可以使用的,但是试过ADC1,ADC2以及其他引脚发现问题依然存在。还有说电源问题,也接过电源适配器,排除了电源问题。所以不知道问题出在哪里了,寻求大家有什么建议?

wifi.rs

Code: Select all

use anyhow::{bail, Result};
use embedded_svc::wifi::{
    AccessPointConfiguration, AuthMethod, ClientConfiguration, Configuration,
};
use esp_idf_hal::peripheral;
use esp_idf_svc::{eventloop::EspSystemEventLoop, wifi::BlockingWifi, wifi::EspWifi};
use log::info;

pub const SSID: &str = env!("WIFI_SSID");
pub const PASSWORD: &str = env!("WIFI_PASS");

pub fn wifi(
    ssid: &str,
    pass: &str,
    modem: impl peripheral::Peripheral<P = esp_idf_hal::modem::Modem> + 'static,
    sysloop: EspSystemEventLoop,
) -> Result<Box<EspWifi<'static>>> {
    let mut auth_method = AuthMethod::WPA2Personal;
    if ssid.is_empty() {
        bail!("Missing WiFi name")
    }
    if pass.is_empty() {
        auth_method = AuthMethod::WPAWPA2Personal;
        info!("Wifi password is empty");
    }

    let mut esp_wifi = EspWifi::new(modem, sysloop.clone(), None)?;
    let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sysloop)?;
    wifi.set_configuration(&Configuration::Client(ClientConfiguration::default()))?;
    info!("Starting wifi...");
    wifi.start()?;
    info!("Scanning...");
    let ap_infos = wifi.scan()?;
    let ours = ap_infos.into_iter().find(|a| a.ssid == ssid);
    let channel = if let Some(ours) = ours {
        info!(
            "Found configured access point {} on channel {}",
            ssid, ours.channel
        );
        Some(ours.channel)
    } else {
        info!(
            "Configured access point {} not found during scanning, will go with unknown channel",
            ssid
        );
        None
    };

    wifi.set_configuration(&Configuration::Mixed(
        ClientConfiguration {
            ssid: ssid.into(),
            password: pass.into(),
            channel,
            auth_method,
            ..Default::default()
        },
        AccessPointConfiguration {
            ssid: "aptest".into(),
            channel: channel.unwrap_or(1),
            ..Default::default()
        },
    ))?;
    info!("Connecting wifi...");
    wifi.connect()?;
    info!("Waiting for DHCP lease...");
    wifi.wait_netif_up()?;
    let ip_info = wifi.wifi().sta_netif().get_ip_info()?;
    info!("Wifi DHCP info: {:?}", ip_info);

    Ok(Box::new(esp_wifi))
}
ir.rs

Code: Select all

impl<'d> IrPwm<'d> {
    pub fn new<C: LedcChannel, T: LedcTimer>(
        _timer: impl Peripheral<P = T> + 'd,
        _channel: impl Peripheral<P = C> + 'd,
        pin: impl Peripheral<P = impl OutputPin> + 'd,
    ) -> Result<Self, EspError> {
        let timer_driver =
            LedcTimerDriver::new(_timer, &TimerConfig::default().frequency(38.kHz().into()))?;
        let mut driver = LedcDriver::new(_channel, timer_driver, pin)?;
        let max_duty = driver.get_max_duty();
        driver.set_duty(max_duty / 3)?;
        driver.disable();

        Ok(Self { driver })
    }

    pub fn send(&mut self, data_code: u128) {
        let bytes = data_code.to_be_bytes();

        let temp: String = bytes.iter().map(|byte| format!("{:08b}", byte)).collect();
        let (data_code1, data_code2) = (&temp[0..35], &temp[35..67]);

        println!("{}, {}", data_code1, data_code2);
        self.driver.enable();
        Delay::delay_us(K_GREE_HDR_MARK.try_into().unwrap());
        // thread::sleep(Duration::from_micros(K_GREE_HDR_MARK));
        self.no_send_ir(K_GREE_HDR_SPACE);

        for i in data_code1.bytes() {
            if i == b'0' {
                self.send_ir_zero();
            } else {
                self.send_ir_one();
            }
        }

        self.send_ir_zero();
        self.no_send_ir(K_GREE_MSG_SPACE);
        for i in data_code2.bytes() {
            if i == b'0' {
                self.send_ir_zero();
            } else {
                self.send_ir_one();
            }
        }

        self.send_ir_zero();
    }

    fn no_send_ir(&mut self, t: u64) {
        self.driver.disable();
        Delay::delay_us(t.try_into().unwrap());
        // thread::sleep(Duration::from_micros(t));
    }

    fn send_ir(&mut self, e_t: u64, d_t: u64) {
        self.driver.enable();
        Delay::delay_us(e_t.try_into().unwrap());
        // thread::sleep(Duration::from_micros(e_t));
        self.driver.disable();
        Delay::delay_us(d_t.try_into().unwrap());
        // thread::sleep(Duration::from_micros(d_t));
    }

    // 发送二进制数据 1
    fn send_ir_one(&mut self) {
        self.send_ir(K_GREE_BIT_MARK, K_GREE_ONE_SPACE);
    }

    // 发送二进制数据 0
    fn send_ir_zero(&mut self) {
        self.send_ir(K_GREE_BIT_MARK, K_GREE_ZERO_SPACE);
    }
}

Who is online

Users browsing this forum: Bing [Bot] and 125 guests