📟 pmme-device: Switch back to povisioning test, add a button + LED for potential later use

This commit is contained in:
Joseph Ferano 2025-06-13 18:00:52 +07:00
parent 4e07dbb461
commit b9b9a0bdd0
3 changed files with 135 additions and 76 deletions

View File

@ -1,14 +1,36 @@
# Rust often needs a bit of an extra main task stack size compared to C (the default is 3K) # Rust often needs a bit of an extra main task stack size compared to C (the default is 3K)
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8000 CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
# CONFIG_PARTITION_TABLE_CUSTOM=y # CONFIG_PARTITION_TABLE_CUSTOM=y
# CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="./partitions.csv" # CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="./partitions.csv"
CONFIG_BT_ENABLED=y CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_BLE_ENABLED=y
CONFIG_BT_NIMBLE_HOST_ENABLED=y
CONFIG_WIFI_PROV_SCHEME_BLE=y CONFIG_WIFI_PROV_SCHEME_BLE=y
# CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 # CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
# CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y # CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y
# CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK=y
# Increase stack sizes
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=8192
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
# CONFIG_LOG_COLORS=y
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION=y
# CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=10
# CONFIG_ESP_PHY_REDUCE_TX_POWER=y
# Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default). # Use this to set FreeRTOS kernel tick frequency to 1000 Hz (100 Hz by default).
# This allows to use 1 ms granularity for thread sleeps (10 ms by default). # This allows to use 1 ms granularity for thread sleeps (10 ms by default).
#CONFIG_FREERTOS_HZ=1000 #CONFIG_FREERTOS_HZ=1000

View File

@ -1,4 +1,5 @@
use anyhow::Result; use anyhow::{bail, Result};
use log::info;
use std::{ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread, thread,
@ -7,7 +8,8 @@ use std::{
use esp_idf_svc::{ use esp_idf_svc::{
eventloop::EspSystemEventLoop, eventloop::EspSystemEventLoop,
hal::{ hal::{
gpio, delay::FreeRtos,
gpio::{self, Level, PinDriver},
i2c::{I2cConfig, I2cDriver}, i2c::{I2cConfig, I2cDriver},
peripherals::Peripherals, peripherals::Peripherals,
prelude::FromValueType, prelude::FromValueType,
@ -16,6 +18,8 @@ use esp_idf_svc::{
}, },
log::EspLogger, log::EspLogger,
nvs::EspDefaultNvsPartition, nvs::EspDefaultNvsPartition,
sys::CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT,
wifi::{AuthMethod, BlockingWifi, ClientConfiguration, Configuration, EspWifi},
}; };
use pmme_device::{display::oled_task, sensors::sensors_task, wifi::wifi_task, Pms7003Data}; use pmme_device::{display::oled_task, sensors::sensors_task, wifi::wifi_task, Pms7003Data};
@ -28,7 +32,15 @@ fn main() -> Result<()> {
EspLogger::initialize_default(); EspLogger::initialize_default();
let nvs = EspDefaultNvsPartition::take()?; let nvs = EspDefaultNvsPartition::take()?;
FreeRtos::delay_ms(100);
let peripherals = Peripherals::take()?; let peripherals = Peripherals::take()?;
FreeRtos::delay_ms(100);
let mut button = PinDriver::input(peripherals.pins.gpio5)?;
let mut led = PinDriver::output(peripherals.pins.gpio19)?;
led.set_low()?;
let i2c = peripherals.i2c0; let i2c = peripherals.i2c0;
let sda = peripherals.pins.gpio21; let sda = peripherals.pins.gpio21;
let scl = peripherals.pins.gpio22; let scl = peripherals.pins.gpio22;
@ -50,6 +62,7 @@ fn main() -> Result<()> {
)?; )?;
let sysloop = EspSystemEventLoop::take()?; let sysloop = EspSystemEventLoop::take()?;
let sysloop_clone = sysloop.clone();
let modem = peripherals.modem; let modem = peripherals.modem;
let pm_data = Arc::new(Mutex::new(Pms7003Data::default())); let pm_data = Arc::new(Mutex::new(Pms7003Data::default()));
@ -57,6 +70,48 @@ fn main() -> Result<()> {
let sensors_arc = Arc::clone(&pm_data); let sensors_arc = Arc::clone(&pm_data);
// let wifi_arc = Arc::clone(&pm_data); // let wifi_arc = Arc::clone(&pm_data);
// let ssid = "Bad Math Bird";
// let pass = "shocktop";
// let mut auth_method = AuthMethod::WPA2Personal;
// if ssid.is_empty() {
// bail!("Missing WiFi name")
// }
// if pass.is_empty() {
// auth_method = AuthMethod::None;
// info!("Wifi password is empty");
// }
// let mut esp_wifi = EspWifi::new(modem, sysloop.clone(), Some(nvs))?;
// let mut wifi = BlockingWifi::wrap(&mut esp_wifi, sysloop)?;
// wifi.set_configuration(&Configuration::Client(ClientConfiguration::default()))?;
// info!("Starting wifi...");
// wifi.set_configuration(&Configuration::Client(ClientConfiguration {
// ssid: ssid
// .try_into()
// .expect("Could not parse the given SSID into WiFi config"),
// password: pass
// .try_into()
// .expect("Could not parse the given password into WiFi config"),
// channel: None,
// auth_method,
// ..Default::default()
// }))?;
// wifi.start()?;
// 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);
let handles = vec![ let handles = vec![
thread::spawn(move || { thread::spawn(move || {
if let Err(e) = oled_task(oled_arc, i2c) { if let Err(e) = oled_task(oled_arc, i2c) {
@ -68,10 +123,41 @@ fn main() -> Result<()> {
log::error!("PM Sensor Task Error: {:?}", e); log::error!("PM Sensor Task Error: {:?}", e);
} }
}), }),
std::thread::Builder::new()
// NOTE: According to CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT, this was set to 3072 and the wifi task
// was getting a stack overflow
.stack_size(12288)
.spawn(move || {
unsafe {
let free_stack =
esp_idf_svc::sys::uxTaskGetStackHighWaterMark(std::ptr::null_mut());
let stack_size = CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT;
log::info!(
"Pthread stack size configured: {} bytes, Current free stack: {} bytes",
stack_size,
free_stack * 4
);
}
if let Err(e) = wifi_task(modem, sysloop_clone, nvs) {
log::error!("PM Wifi Task Error: {:?}", e);
}
})?,
thread::spawn(move || { thread::spawn(move || {
// if let Err(e) = wifi_task(wifi_arc, &uart) { let mut is_pressed = false;
if let Err(e) = wifi_task(modem, sysloop, nvs) { let mut curr_state = Level::High;
log::error!("PM Sensor Task Error: {:?}", e); loop {
if curr_state == Level::High && button.is_low() {
led.set_high().unwrap();
curr_state = Level::Low;
is_pressed = true;
} else if curr_state == Level::Low && button.is_high() {
led.set_low().unwrap();
curr_state = Level::High;
is_pressed = true;
}
if is_pressed {
FreeRtos::delay_ms(100);
}
} }
}), }),
]; ];

View File

@ -1,4 +1,4 @@
use anyhow::Result; use anyhow::{bail, Result};
use log::info; use log::info;
use esp_idf_svc::{ use esp_idf_svc::{
@ -6,9 +6,12 @@ use esp_idf_svc::{
hal::peripheral, hal::peripheral,
nvs::EspDefaultNvsPartition, nvs::EspDefaultNvsPartition,
sys::{ sys::{
esp, esp_err_t, wifi_prov_event_handler_t, wifi_prov_mgr_config_t, wifi_prov_mgr_deinit, wifi_prov_mgr_init, wifi_prov_mgr_is_provisioned, wifi_prov_mgr_start_provisioning, wifi_prov_mgr_stop_provisioning, wifi_prov_mgr_wait, wifi_prov_scheme_ble, wifi_prov_security_WIFI_PROV_SECURITY_1, wifi_prov_security_t, EspError esp, esp_err_t, wifi_prov_event_handler_t, wifi_prov_mgr_config_t, wifi_prov_mgr_deinit,
wifi_prov_mgr_init, wifi_prov_mgr_is_provisioned, wifi_prov_mgr_start_provisioning,
wifi_prov_mgr_stop_provisioning, wifi_prov_mgr_wait, wifi_prov_scheme_ble,
wifi_prov_security_WIFI_PROV_SECURITY_1, wifi_prov_security_t, EspError,
}, },
wifi::{BlockingWifi, ClientConfiguration, Configuration, EspWifi}, wifi::{AuthMethod, BlockingWifi, ClientConfiguration, Configuration, EspWifi},
}; };
use std::ffi::c_void; use std::ffi::c_void;
use std::ffi::CString; use std::ffi::CString;
@ -93,24 +96,34 @@ pub fn wifi_task(
modem: impl peripheral::Peripheral<P = esp_idf_svc::hal::modem::Modem> + 'static, modem: impl peripheral::Peripheral<P = esp_idf_svc::hal::modem::Modem> + 'static,
sysloop: EspSystemEventLoop, sysloop: EspSystemEventLoop,
nvs: EspDefaultNvsPartition, nvs: EspDefaultNvsPartition,
// esp_wifi: EspWifi,
) -> Result<()> { ) -> Result<()> {
// info!("Got wifi");
// let ssid = "Bad Math Bird";
// let pass = "shocktop";
info!("Provisioning device!"); info!("Provisioning device!");
return Ok(()); let wifi = esp_idf_svc::wifi::EspWifi::new(modem, sysloop.clone(), Some(nvs))?;
let wifi = EspWifi::new(modem, sysloop.clone(), Some(nvs))?;
let mut wifi = BlockingWifi::wrap(wifi, sysloop)?; let mut wifi = BlockingWifi::wrap(wifi, sysloop)?;
info!("Make blocking wifi");
let prov = WifiProvisioning::new()?; let prov = WifiProvisioning::new()?;
info!("New Provision");
if !prov.is_provisioned()? { if !prov.is_provisioned()? {
info!("Not provisioned");
let wifi_configuration: Configuration = Configuration::Client(ClientConfiguration { let wifi_configuration: Configuration = Configuration::Client(ClientConfiguration {
..Default::default() ..Default::default()
}); });
info!("Got configuration");
wifi.set_configuration(&wifi_configuration)?; wifi.set_configuration(&wifi_configuration)?;
info!("Set configuration");
wifi.start()?; wifi.start()?;
info!("Started wifi");
prov.start_provisioning( prov.start_provisioning(
wifi_prov_security_WIFI_PROV_SECURITY_1, wifi_prov_security_WIFI_PROV_SECURITY_1,
"abcd1234", // Proof of Possession (POP) "88888888", // Proof of Possession (POP)
"PROV_ESP32", // Service Name "PROV_ESP32", // Service Name
None, // No Service Key None, // No Service Key
)?; )?;
info!("Start provisioning");
println!("Waiting for Wi-Fi provisioning..."); println!("Waiting for Wi-Fi provisioning...");
prov.wait(); prov.wait();
@ -118,75 +131,13 @@ pub fn wifi_task(
println!("Provisioning completed. Stopping..."); println!("Provisioning completed. Stopping...");
prov.stop(); prov.stop();
} else { } else {
info!("Provisioned!");
wifi.start()?; wifi.start()?;
wifi.connect()?; wifi.connect()?;
} }
wifi.wait_netif_up()?; wifi.wait_netif_up()?;
let ip_info = wifi.wifi().sta_netif().get_ip_info()?; let ip_info = wifi.wifi().sta_netif().get_ip_info()?;
println!("Wifi DHCP info: {:?}", ip_info); // println!("Wifi DHCP info: {:?}", ip_info);
// let mut auth_method = AuthMethod::WPA2Personal;
// if ssid.is_empty() {
// bail!("Missing WiFi name")
// }
// if pass.is_empty() {
// auth_method = AuthMethod::None;
// 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::Client(ClientConfiguration {
// ssid: ssid
// .try_into()
// .expect("Could not parse the given SSID into WiFi config"),
// password: pass
// .try_into()
// .expect("Could not parse the given password into WiFi config"),
// channel,
// auth_method,
// ..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))
Ok(()) Ok(())
} }