diff --git a/.gitignore b/.gitignore index deb0257..3fe723d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ debug/ target/ # Editor configuration +.idea/ .vscode/ .zed/ .helix/ diff --git a/Cargo.lock b/Cargo.lock index acbf913..5dfa98d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1358,29 +1358,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" -[[package]] -name = "https" -version = "0.1.0" -dependencies = [ - "critical-section", - "defmt 1.1.0", - "embassy-executor", - "embassy-net", - "embassy-time", - "embedded-dht-rs", - "embedded-io 0.7.1", - "embedded-io-async 0.7.0", - "esp-alloc", - "esp-bootloader-esp-idf", - "esp-hal", - "esp-println", - "esp-radio", - "esp-rtos", - "reqwless", - "smoltcp", - "static_cell", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -1436,9 +1413,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.24" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00b5dbd620d61dfdcb6007c9c1f6054ebd75319f163d886a9055cec1155073d" +checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102" dependencies = [ "jiff-static", "log", @@ -1449,9 +1426,9 @@ dependencies = [ [[package]] name = "jiff-static" -version = "0.2.24" +version = "0.2.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e000de030ff8022ea1da3f466fbb0f3a809f5e51ed31f6dd931c35181ad8e6d7" +checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47" dependencies = [ "proc-macro2", "quote", @@ -1487,9 +1464,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "managed" @@ -1499,9 +1476,29 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "mqtt-master" +version = "0.1.1" +dependencies = [ + "defmt 1.1.0", + "embassy-executor", + "embassy-net", + "embassy-time", + "embedded-dht-rs", + "esp-alloc", + "esp-bootloader-esp-idf", + "esp-hal", + "esp-println", + "esp-radio", + "esp-rtos", + "reqwless", + "rlib", + "static_cell", +] [[package]] name = "nb" @@ -1789,6 +1786,14 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1376b15f3ff160e9b1e8ea564ce427f2f6fcf77528cc0a8bf405cb476f9cea7" +[[package]] +name = "rlib" +version = "0.1.0" +dependencies = [ + "esp-hal", + "esp-println", +] + [[package]] name = "rlsf" version = "0.2.2" @@ -2050,9 +2055,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -2194,18 +2199,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "bce33a6288fa3f072a8c2c7d0f2fdbb90e28298f0135c1f99b96c3db2efcc60b" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "8fd425244944f4ab65ccff928e7323354c5a018c75838362fdce749dfad2ee1e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 1fa4c11..c033aaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,8 @@ [package] edition = "2024" -name = "https" +name = "mqtt-master" rust-version = "1.88" -version = "0.1.0" -# https://esp32.implrust.com/wifi/web-server/wifi.html +version = "0.1.1" [[bin]] name = "mqtt-master" @@ -32,13 +31,15 @@ embassy-net = { version = "0.7.1", features = [ #addition: "dns", ] } -embedded-io = { version = "0.7.1", features = ["defmt"] } -embedded-io-async = { version = "0.7.0", features = ["defmt"] } + esp-alloc = { version = "0.9.0", features = ["defmt"] } esp-println = { version = "0.16.1", features = ["defmt-espflash", "esp32"] } + # for more networking protocol support see https://crates.io/crates/edge-net embassy-executor = { version = "0.9.1", features = ["defmt"] } + embassy-time = { version = "0.5.0", features = ["defmt"] } + esp-radio = { version = "0.17.0", features = [ "defmt", "esp-alloc", @@ -47,23 +48,7 @@ esp-radio = { version = "0.17.0", features = [ "unstable", "wifi", ] } -smoltcp = { version = "0.12.0", default-features = false, features = [ - "defmt", - "medium-ethernet", - "multicast", - "proto-dhcpv4", - "proto-dns", - "proto-ipv4", - "socket-dns", - "socket-icmp", - "socket-raw", - "socket-tcp", - "socket-udp", - # addition: - "dns-max-server-count-4", -] } -critical-section = "1.2.0" static_cell = "2.1.1" reqwless = { version = "0.13.0", default-features = false, features = [ @@ -72,6 +57,8 @@ reqwless = { version = "0.13.0", default-features = false, features = [ embedded-dht-rs = { version = "0.5.0", features = ["dht22"] } +rlib = { path = "../rlib" } + [profile.dev] # Rust debug is too slow. # For debug builds always builds with some optimization @@ -89,6 +76,6 @@ overflow-checks = false # cargo build # espflash flash target/xtensa-esp32-none-elf/debug/https --monitor -# cargo build -release -# cargo run -release +# cargo build --release +# cargo run --release # espflash flash target/xtensa-esp32-none-elf/release/https --monitor \ No newline at end of file diff --git a/src/bin/main.rs b/src/bin/main.rs index 860399f..f99a25f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -20,29 +20,30 @@ use esp_hal::{ delay::Delay, gpio::{DriveMode, Flex, OutputConfig, Pull}, rng::Rng, + rtc_cntl::{Rtc, sleep::TimerWakeupSource}, timer::timg::TimerGroup, + }; use esp_println::{self as _, println}; -use esp_radio::wifi::{ - ClientConfig, ModeConfig, WifiController, WifiDevice, WifiEvent, WifiStaState, -}; +use esp_radio::wifi::{ClientConfig, ModeConfig, WifiDevice, WifiController}; use reqwless::client::{HttpClient, TlsConfig}; use embedded_dht_rs::dht22::Dht22; #[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { - loop {} +fn panic(info: &core::panic::PanicInfo) -> ! { + println!("Panic occurred: {}", info); + + // Trigger a software reset + esp_hal::system::software_reset(); } extern crate alloc; // This creates a default app-descriptor required by the esp-idf bootloader. -// For more information see: esp_bootloader_esp_idf::esp_app_desc!(); -// If you are okay with using a nightly compiler, you can use the macro provided by the static_cell crate: https://docs.rs/static_cell/latest/static_cell/macro.make_static.html macro_rules! mk_static { ($t:ty,$val:expr) => {{ static STATIC_CELL: static_cell::StaticCell<$t> = static_cell::StaticCell::new(); @@ -58,10 +59,15 @@ macro_rules! mk_static { const SSID: &str = "COSMOTE-C90C60"; const PASSWORD: &str = "xPeRD7RytKyrXTE6"; +//const SSID: &str = "Pixel_7787"; +//const PASSWORD: &str = "dqtaq37q"; + const MQTT_URL: &str = "https://kouros-online.de/gin/mqtt/eo7sbjyWpmjSVFyELgbfrryqJ6ddNeq9"; const TOPIC: &str = "kefalovryso"; +const DEEP_SLEEP_TIME: u64 = 60 * 60; + #[esp_rtos::main] async fn main(spawner: Spawner) -> ! { // generator version: 1.0.0 @@ -86,14 +92,10 @@ async fn main(spawner: Spawner) -> ! { dht22_pin.set_high(); let mut dht22 = Dht22::new(dht22_pin, Delay::new()); - // let radio_init = esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller"); - let radio_init = &*mk_static!( - esp_radio::Controller<'static>, - esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller") - ); + let esp_radio_ctrl = &*mk_static!(esp_radio::Controller<'static>, esp_radio::init().unwrap()); - let (wifi_controller, interfaces) = - esp_radio::wifi::new(&radio_init, peripherals.WIFI, Default::default()) + let (mut wifi_controller, interfaces) = + esp_radio::wifi::new(&esp_radio_ctrl, peripherals.WIFI, Default::default()) .expect("Failed to initialize Wi-Fi controller"); let wifi_interface = interfaces.sta; @@ -113,13 +115,34 @@ async fn main(spawner: Spawner) -> ! { net_seed, ); - spawner.spawn(connection(wifi_controller)).ok(); spawner.spawn(net_task(runner)).ok(); - wait_for_connection(stack).await; - let delay = Delay::new(); + let mut rtc = Rtc::new(peripherals.LPWR); + let _ = spawner.spawn(health_check()); + + let client_config = ModeConfig::Client( + ClientConfig::default() + .with_ssid(SSID.into()) + .with_password(PASSWORD.into()), + ); + wifi_controller.set_config(&client_config).unwrap(); + wifi_controller.start_async().await.unwrap(); + println!("Wifi started!"); + + let _ = spawner.spawn(connection(wifi_controller)); + + wait_for_connection(stack).await; + match stack.config_v4() { + Some(config) => { + println!("Got IP: {}", config.address); + } + None => { + deep_sleep(&mut rtc, &delay, 30); + } + } + delay.delay_millis(100); loop { match dht22.read() { Ok(sensor_reading) => { @@ -138,64 +161,61 @@ async fn main(spawner: Spawner) -> ! { } Err(error) => { esp_println::dbg!("An error occurred while trying to read sensor: {:?}", error); + deep_sleep(&mut rtc, &delay, 5); } } - delay.delay_millis(30000); - } -} - -async fn wait_for_connection(stack: Stack<'_>) { - println!("Waiting for link to be up"); - loop { - if stack.is_link_up() { - break; - } - Timer::after(Duration::from_millis(500)).await; - } - - println!("Waiting to get IP address..."); - loop { - if let Some(config) = stack.config_v4() { - println!("Got IP: {}", config.address); - break; - } - Timer::after(Duration::from_millis(100)).await; + deep_sleep(&mut rtc, &delay, DEEP_SLEEP_TIME); } } #[embassy_executor::task] async fn connection(mut controller: WifiController<'static>) { println!("Start connection task"); - println!("Device capabilities: {:?}", controller.capabilities()); loop { - match esp_radio::wifi::sta_state() { - WifiStaState::Connected => { - // wait until we're no longer connected - controller.wait_for_event(WifiEvent::StaDisconnected).await; - Timer::after(Duration::from_millis(5000)).await - } - _ => {} - } - if !matches!(controller.is_started(), Ok(true)) { - let client_config = ModeConfig::Client( - ClientConfig::default() - .with_ssid(SSID.into()) - .with_password(PASSWORD.into()), - ); - controller.set_config(&client_config).unwrap(); - println!("Starting wifi"); - controller.start_async().await.unwrap(); - println!("Wifi started!"); - } - println!("About to connect..."); - match controller.connect_async().await { - Ok(_) => println!("Wifi connected!"), + Ok(info) => { + println!("Wifi connected to {:?}", info); + } Err(e) => { - println!("Failed to connect to wifi: {:?}", e); - Timer::after(Duration::from_millis(5000)).await + println!("Failed to connect to wifi: {e:?}"); } } + Timer::after(Duration::from_millis(2000)).await + } +} + +#[embassy_executor::task] +async fn health_check() { + loop { + let mut count = 0; + while count < 60 { + Timer::after(Duration::from_millis(1000)).await; + count = count + 1; + } + println!("Health not ok, reboot"); + panic!("Health"); + } +} + +async fn wait_for_connection(stack: Stack<'_>) { + let mut count = 0; + println!("Waiting for link to be up"); + while count < 10 { + if stack.is_link_up() { + break; + } + Timer::after(Duration::from_millis(1000)).await; + count = count + 1; + } + + println!("Waiting to get IP address..."); + count = 0; + while count < 30 { + if let Some(_) = stack.config_v4() { + break; + } + Timer::after(Duration::from_millis(1000)).await; + count = count + 1; } } @@ -209,7 +229,8 @@ async fn publish_mqtt(stack: Stack<'_>, tls_seed: u64, temperature: f32, humidit let mut tx_buffer = [0; 4096]; let dns = DnsSocket::new(stack); let tcp_state = TcpClientState::<1, 4096, 4096>::new(); - let tcp = TcpClient::new(stack, &tcp_state); + let mut tcp = TcpClient::new(stack, &tcp_state); + tcp.set_timeout(Some(Duration::from_millis(4000))); let tls = TlsConfig::new( tls_seed, @@ -234,11 +255,19 @@ async fn publish_mqtt(stack: Stack<'_>, tls_seed: u64, temperature: f32, humidit .request(reqwless::request::Method::GET, &url) .await .unwrap(); + info!("Send"); let response = http_req.send(&mut buffer).await.unwrap(); - info!("Got response"); let res = response.body().read_to_end().await.unwrap(); - let content = core::str::from_utf8(res).unwrap(); println!("{}", content); } + + +pub fn deep_sleep(rtc: &mut Rtc, delay: &Delay, time: u64) { + let timer = TimerWakeupSource::new(core::time::Duration::from_secs(time)); + println!("Going sleep for {:?} seconds", time); + delay.delay_millis(100); + rtc.sleep_deep(&[&timer]); + //rlib::deep_sleep(&mut rtc, &delay, DEEP_SLEEP_TIME); +}