Created
March 8, 2022 18:01
-
-
Save bernii/dab01df90b0f3dc45fbd69749e8934b8 to your computer and use it in GitHub Desktop.
esp now tests with esp-rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::convert::TryInto; | |
use std::process; | |
use esp_idf_sys::{self as _, c_types}; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported | |
use std::net::Ipv4Addr; | |
use std::{sync::Arc, thread, time::*}; | |
use anyhow::bail; | |
use log::*; | |
use embedded_svc::ipv4; | |
use embedded_svc::wifi::*; | |
use esp_idf_svc::netif::*; | |
use esp_idf_svc::wifi::*; | |
use esp_idf_svc::sysloop::*; | |
use esp_idf_svc::nvs::*; | |
use anyhow::Result; | |
use esp_idf_sys::{self, esp, EspError}; | |
use std::ptr; | |
use std::ffi::CStr; | |
use embedded_svc::event_bus::{EventBus, Postbox}; | |
const SSID: &str = env!("WIFI_SSID"); | |
const PASS: &str = env!("WIFI_PASS"); | |
const BROADCAST: [u8; 6] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; | |
fn main() -> Result<()> { | |
// Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, | |
// or else some patches to the runtime implemented by esp-idf-sys might not link properly. | |
esp_idf_sys::link_patches(); | |
// Bind the log crate to the ESP Logging facilities | |
esp_idf_svc::log::EspLogger::initialize_default(); | |
// let sys_loop_stack = Arc::new(EspSysLoopStack::new()?); | |
// let (mut eventloop, _subscription) = init_eventloop().unwrap(); | |
// init stack | |
let netif_stack = Arc::new(EspNetifStack::new().unwrap()); | |
let sys_loop_stack = Arc::new(EspSysLoopStack::new().unwrap()); | |
let default_nvs = Arc::new(EspDefaultNvs::new().unwrap()); | |
info!("starting wifi....."); | |
// keep var so wifi is no getting deallocated | |
let wifi = setup_wifi( | |
netif_stack.clone(), | |
sys_loop_stack.clone(), | |
default_nvs.clone(), | |
)?; | |
info!("Initializing ESP NOW"); | |
let resp = esp!(unsafe { esp_idf_sys::esp_now_init() }); | |
info!("Initializing ESP NOW: resp {:?}", resp); | |
let mut peer_info = esp_idf_sys::esp_now_peer_info_t::default(); | |
peer_info.peer_addr = BROADCAST; | |
peer_info.channel = 2; | |
peer_info.encrypt = false; | |
let resp1 = unsafe { esp_idf_sys::esp_now_add_peer(&peer_info) }; | |
info!("Initializing ESP NOW, add peer resp: {:?}", resp1); | |
info!("Register callback"); | |
extern "C" fn mycallback(mac_addr: *const u8, data: *const u8, data_len: c_types::c_int) -> () { | |
info!("raw data {:?}, DATA {:?} L: {}", mac_addr, data, data_len); | |
let c_mac = unsafe{ std::slice::from_raw_parts(mac_addr, 6usize) }; | |
let c_str = unsafe { | |
std::str::from_utf8_unchecked(std::slice::from_raw_parts( | |
data, data_len as usize | |
)) | |
}; | |
info!("data mac: {:x?} data: {:?}", c_mac, c_str); | |
} | |
let resp_cb = unsafe { esp_idf_sys::esp_now_register_recv_cb(Some(mycallback)) }; | |
info!("cb resp: {:?}", resp_cb); | |
let mut i = 0; | |
loop { | |
info!("Loop i={}", i); // sleep | |
esp_now_send(i); | |
thread::sleep(Duration::from_millis(100)); | |
// std::thread::yield_now(); | |
i += 1; | |
if i > 100 { i = 0; } | |
} | |
} | |
fn esp_now_send(i: i32) { | |
let br = BROADCAST.clone(); | |
let mut data = format!("i={}", i); | |
let resp = esp!(unsafe { esp_idf_sys::esp_now_send( | |
br.as_ptr() as _, | |
data.as_ptr() as _, | |
data.len() as _, | |
)}); | |
info!("esp_now_send {:?}", resp); | |
} | |
use embedded_svc::ipv4::ClientSettings; | |
use embedded_svc::ipv4::Subnet; | |
use crate::ipv4::Mask; | |
fn setup_wifi( | |
netif_stack: Arc<EspNetifStack>, | |
sys_loop_stack: Arc<EspSysLoopStack>, | |
default_nvs: Arc<EspDefaultNvs>, | |
) -> Result<Box<EspWifi>> { | |
let mut wifi = Box::new(EspWifi::new(netif_stack, sys_loop_stack, default_nvs)?); | |
info!("Wifi created, about to scan"); | |
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 access point {} on channel {}", SSID, ours.channel); | |
Some(ours.channel) | |
} else { | |
info!("Configured AP {} not found, will go with unknown channel", SSID); | |
None | |
}; | |
wifi.set_configuration(&Configuration::Client( | |
ClientConfiguration { | |
ssid: SSID.into(), | |
password: PASS.into(), | |
channel, | |
..Default::default() | |
}, | |
))?; | |
info!("Wifi configuration set, about to get status"); | |
wifi.wait_status_with_timeout(Duration::from_secs(20), |status| !status.is_transitional()) | |
.map_err(|e| anyhow::anyhow!("Unexpected Wifi status: {:?}", e))?; | |
let status = wifi.get_status(); | |
if let Status( | |
ClientStatus::Started(ClientConnectionStatus::Connected(ClientIpStatus::Done(_ip_settings))), | |
ApStatus::Stopped, | |
) = status { | |
info!("Wifi connected"); | |
} else { | |
bail!("Unexpected Wifi status: {:?}", status); | |
} | |
Ok(wifi) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment