esp-hal/examples/src/bin/wifi_embassy_esp_now.rs
Kirill Mikhailov 8ca0f94715
Get rid of EspRadio prefix in esp-radio structs (#3869)
* get rid of `EspRadio` prefix in esp-radio structs

* changelog entry + migration guide entry

* reword entries

* fmt run

* Fix migration guide entry

* edit the changelog entry to still reflect `esp-wifi` changes
2025-07-28 11:40:56 +00:00

104 lines
3.5 KiB
Rust

//! Embassy ESP-NOW Example
//!
//! Broadcasts, receives and sends messages via esp-now in an async way
//!
//! Because of the huge task-arena size configured this won't work on ESP32-S2
//% FEATURES: embassy esp-radio esp-radio/esp-now esp-hal/unstable
//% CHIPS: esp32 esp32s2 esp32s3 esp32c2 esp32c3 esp32c6
#![no_std]
#![no_main]
use embassy_executor::Spawner;
use embassy_futures::select::{Either, select};
use embassy_time::{Duration, Ticker};
use esp_alloc as _;
use esp_backtrace as _;
use esp_hal::{clock::CpuClock, timer::timg::TimerGroup};
use esp_println::println;
use esp_radio::{
Controller,
esp_now::{BROADCAST_ADDRESS, PeerInfo},
};
esp_bootloader_esp_idf::esp_app_desc!();
// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/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();
#[deny(unused_attributes)]
let x = STATIC_CELL.uninit().write(($val));
x
}};
}
#[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);
esp_radio_preempt_baremetal::init(timg0.timer0);
let esp_wifi_ctrl = &*mk_static!(Controller<'static>, esp_radio::init().unwrap());
let wifi = peripherals.WIFI;
let (mut controller, interfaces) = esp_radio::wifi::new(&esp_wifi_ctrl, wifi).unwrap();
controller.set_mode(esp_radio::wifi::WifiMode::Sta).unwrap();
controller.start().unwrap();
let mut esp_now = interfaces.esp_now;
esp_now.set_channel(11).unwrap();
println!("esp-now version {}", esp_now.version().unwrap());
cfg_if::cfg_if! {
if #[cfg(feature = "esp32")] {
let timg1 = TimerGroup::new(peripherals.TIMG1);
esp_hal_embassy::init(timg1.timer0);
} else {
use esp_hal::timer::systimer::SystemTimer;
let systimer = SystemTimer::new(peripherals.SYSTIMER);
esp_hal_embassy::init(systimer.alarm0);
}
}
let mut ticker = Ticker::every(Duration::from_secs(5));
loop {
let res = select(ticker.next(), async {
let r = esp_now.receive_async().await;
println!("Received {:?}", r);
if r.info.dst_address == BROADCAST_ADDRESS {
if !esp_now.peer_exists(&r.info.src_address) {
esp_now
.add_peer(PeerInfo {
interface: esp_radio::esp_now::EspNowWifiInterface::Sta,
peer_address: r.info.src_address,
lmk: None,
channel: None,
encrypt: false,
})
.unwrap();
}
let status = esp_now.send_async(&r.info.src_address, b"Hello Peer").await;
println!("Send hello to peer status: {:?}", status);
}
})
.await;
match res {
Either::First(_) => {
println!("Send");
let status = esp_now.send_async(&BROADCAST_ADDRESS, b"0123456789").await;
println!("Send broadcast status: {:?}", status)
}
Either::Second(_) => (),
}
}
}