From 5c1259152428384f05b88a9378a59634b435c241 Mon Sep 17 00:00:00 2001 From: Priec Date: Sun, 18 Jan 2026 10:13:21 +0100 Subject: [PATCH] changes to more modern way --- mqtt_display/old_main.rs | 181 ++++++++++++++++++++++++++++++++ mqtt_display/src/bin/main.rs | 28 ++--- mqtt_display/src/mqtt/client.rs | 6 -- 3 files changed, 196 insertions(+), 19 deletions(-) create mode 100644 mqtt_display/old_main.rs diff --git a/mqtt_display/old_main.rs b/mqtt_display/old_main.rs new file mode 100644 index 0000000..7e4b2df --- /dev/null +++ b/mqtt_display/old_main.rs @@ -0,0 +1,181 @@ +// src/bin/main.rs + +#![no_std] +#![no_main] +#![deny( + clippy::mem_forget, + reason = "mem::forget is generally not safe to do with esp_hal types" +)] + +use embassy_executor::Spawner; +use embassy_futures::select::{select, Either}; +use embassy_net::{Runner, StackResources}; +use embassy_time::{Duration, Timer}; +use esp_alloc as _; +use esp_backtrace as _; +use esp_hal::{clock::CpuClock, rng::Rng, timer::timg::TimerGroup}; +use esp_wifi::{ + init, + wifi::{ClientConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, WifiState}, + EspWifiController, +}; +use log::info; +use rust_mqtt::packet::v5::publish_packet::QualityOfService; +use projekt_final::mqtt::client::{ + mqtt_events, mqtt_publish, mqtt_subscribe, mqtt_task, IncomingMsg, +}; +use defmt_rtt as _; + +extern crate alloc; + +esp_bootloader_esp_idf::esp_app_desc!(); + +macro_rules! mk_static { + ($t:ty,$val:expr) => {{ + static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); + #[deny(unused_attributes)] + let x = STATIC_CELL.uninit().write(($val)); + x + }}; +} + +const SSID: &str = env!("SSID"); +const PASSWORD: &str = env!("PASSWORD"); + +#[esp_hal_embassy::main] +async fn main(spawner: Spawner) -> ! { + esp_println::logger::init_logger_from_env(); + let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); + let peripherals = esp_hal::init(config); + + esp_alloc::heap_allocator!(size: 72 * 1024); + + let timg0 = TimerGroup::new(peripherals.TIMG0); + let mut rng = Rng::new(peripherals.RNG); + + let esp_wifi_ctrl = &*mk_static!( + EspWifiController<'static>, + init(timg0.timer0, rng.clone()).unwrap() + ); + + let (controller, interfaces) = + esp_wifi::wifi::new(&esp_wifi_ctrl, peripherals.WIFI).unwrap(); + + let wifi_interface = interfaces.sta; + + let timg1 = TimerGroup::new(peripherals.TIMG1); + esp_hal_embassy::init(timg1.timer0); + + let config = embassy_net::Config::dhcpv4(Default::default()); + + let seed = (rng.random() as u64) << 32 | rng.random() as u64; + + // Init network stack + let (stack, runner) = embassy_net::new( + wifi_interface, + config, + mk_static!(StackResources<3>, StackResources::<3>::new()), + seed, + ); + + spawner.spawn(connection(controller)).ok(); + spawner.spawn(net_task(runner)).ok(); + + // Wait for link up + loop { + if stack.is_link_up() { + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + info!("Waiting to get IP address..."); + loop { + if let Some(config) = stack.config_v4() { + info!("Got IP: {}", config.address); + break; + } + Timer::after(Duration::from_millis(500)).await; + } + + spawner.spawn(mqtt_task(stack)).expect("failed to spawn MQTT task"); + info!("MQTT task started"); + + mqtt_publish("esp32/topic", b"hello from ESP32 (init)", QualityOfService::QoS1, false).await; + info!("Sent initial MQTT message"); + + mqtt_subscribe("esp32/topic").await; + + // Get a receiver for incoming MQTT messages + let mqtt_rx = mqtt_events(); + + loop { + // Drive both: either process an MQTT message or publish periodically + match select(mqtt_rx.receive(), Timer::after(Duration::from_secs(5))).await + { + // Received inbound MQTT message (from broker) + Either::First(msg) => { + handle_incoming(msg); + } + // Time-based example publish + Either::Second(_) => { + // mqtt_publish( + // "esp32/topic", + // b"hello from main", + // QualityOfService::QoS1, + // false, + // ) + // .await; + } + } + } +} + +fn handle_incoming(msg: IncomingMsg) { + if let Ok(txt) = core::str::from_utf8(&msg.payload) { + info!("MAIN RX [{}]: {}", msg.topic.as_str(), txt); + info!("Received MQTT message -> topic: '{}', payload: '{}'", msg.topic.as_str(), txt); + } else { + info!("MAIN RX [{}]: {:?}", msg.topic.as_str(), msg.payload); + } +} + +#[embassy_executor::task] +async fn connection(mut controller: WifiController<'static>) { + info!("start connection task"); + info!("Device capabilities: {:?}", controller.capabilities()); + loop { + match esp_wifi::wifi::wifi_state() { + WifiState::StaConnected => { + controller.wait_for_event(WifiEvent::StaDisconnected).await; + Timer::after(Duration::from_millis(5000)).await + } + _ => {} + } + if !matches!(controller.is_started(), Ok(true)) { + let client_config = Configuration::Client(ClientConfiguration { + ssid: SSID.into(), + password: PASSWORD.into(), + ..Default::default() + }); + controller.set_configuration(&client_config).unwrap(); + info!("Starting wifi"); + controller.start_async().await.unwrap(); + info!("Wifi started!"); + } + info!("About to connect..."); + + match controller.connect_async().await { + Ok(_) => info!("Wifi connected!"), + Err(e) => { + info!("Failed to connect to wifi: {e:?}"); + Timer::after(Duration::from_millis(5000)).await + } + } + } +} + +#[embassy_executor::task] +async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { + runner.run().await +} diff --git a/mqtt_display/src/bin/main.rs b/mqtt_display/src/bin/main.rs index e7ea107..16e7557 100644 --- a/mqtt_display/src/bin/main.rs +++ b/mqtt_display/src/bin/main.rs @@ -32,7 +32,6 @@ use rust_mqtt::packet::v5::publish_packet::QualityOfService; use static_cell::StaticCell; use core::cell::RefCell; -// Our crate use projekt_final::{ bus, display, @@ -46,9 +45,11 @@ use alloc::format; static I2C_BUS: StaticCell> = StaticCell::new(); macro_rules! mk_static { - ($t:ty, $val:expr) => {{ - static STATIC_CELL: StaticCell<$t> = StaticCell::new(); - STATIC_CELL.init($val) + ($t:ty,$val:expr) => {{ + static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); + #[deny(unused_attributes)] + let x = STATIC_CELL.uninit().write(($val)); + x }}; } @@ -61,9 +62,9 @@ esp_bootloader_esp_idf::esp_app_desc!(); #[esp_hal_embassy::main] async fn main(spawner: Spawner) -> ! { esp_println::logger::init_logger_from_env(); - info!("═══════════════════════════════════════════════════════════"); + info!("==============================="); info!(" ESP32 IoT Firmware Starting"); - info!("═══════════════════════════════════════════════════════════"); + info!("==============================="); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); @@ -108,7 +109,6 @@ async fn main(spawner: Spawner) -> ! { spawner.spawn(connection_task(controller)).expect("spawn connection_task"); spawner.spawn(net_task(runner)).expect("spawn net_task"); - wait_for_network(stack).await; spawner.spawn(mqtt_task(stack)).expect("spawn mqtt_task"); @@ -116,8 +116,8 @@ async fn main(spawner: Spawner) -> ! { spawner.spawn(mpu::task::mpu_task(mpu_i2c)).expect("spawn mpu_task"); display::api::set_status("Booting...").await; - mqtt_subscribe("esp32/cmd").await; - mqtt_publish("esp32/status", b"online", QualityOfService::QoS1, false).await; + mqtt_subscribe("esp32/topic").await; + mqtt_publish("esp32/topic", b"online", QualityOfService::QoS1, false).await; display::api::set_status("Running").await; display::api::set_mqtt_status(true, 0).await; @@ -197,10 +197,12 @@ async fn connection_task(mut controller: WifiController<'static>) { info!("Wi-Fi starting..."); controller.start_async().await.unwrap(); } - if let Err(e) = controller.connect_async().await { - info!("Wi-Fi reconnect failed: {:?}", e); - } else { - info!("Wi-Fi connected."); + match controller.connect_async().await { + Ok(_) => info!("Wifi connected!"), + Err(e) => { + info!("Failed to connect to wifi: {e:#?}"); + Timer::after(Duration::from_millis(5000)).await + } } } } diff --git a/mqtt_display/src/mqtt/client.rs b/mqtt_display/src/mqtt/client.rs index 31541c7..4944761 100644 --- a/mqtt_display/src/mqtt/client.rs +++ b/mqtt_display/src/mqtt/client.rs @@ -150,12 +150,6 @@ async fn run_one_session( } // Operational loop - let default_topic = "esp32/topic"; - match client.subscribe_to_topic(default_topic).await { - Ok(_) => info!("Subscribed to '{}'", default_topic), - Err(e) => info!("Default subscribe failed: {:?}", e), - }; - loop { let net_or_ping = select(client.receive_message(), Timer::after(PING_PERIOD));