Created
March 26, 2024 14:36
-
-
Save weiying-chen/0b9a69edc93c64f942259bfe2986b25a to your computer and use it in GitHub Desktop.
This file contains 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
//! Example of using blocking wifi. | |
//! | |
//! Add your own ssid and password | |
use embedded_svc::{ | |
http::client::Client as HttpClient, | |
io::Write, | |
wifi::{AuthMethod, ClientConfiguration, Configuration}, | |
}; | |
use esp_idf_hal::prelude::Peripherals; | |
use esp_idf_hal::sys::esp_wifi_set_max_tx_power; | |
use esp_idf_svc::http::client::{Configuration as HttpConfiguration, EspHttpConnection}; | |
use esp_idf_svc::log::EspLogger; | |
use esp_idf_svc::wifi::{BlockingWifi, EspWifi}; | |
use esp_idf_svc::{eventloop::EspSystemEventLoop, nvs::EspDefaultNvsPartition}; | |
use esp_idf_svc::{hal::delay::FreeRtos, handle::RawHandle}; | |
use esp_idf_sys::esp_http_client_close; | |
// use esp_idf_sys::{self as _}; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported | |
use log::info; | |
use crate::scale::Scale; | |
mod critical_section; | |
mod scale; | |
const SSID: &str = env!("WIFI_SSID"); | |
const PASSWORD: &str = env!("WIFI_PASS"); | |
const LOAD_SENSOR_SCALING: f32 = 0.0027; | |
fn main() -> anyhow::Result<()> { | |
esp_idf_svc::sys::link_patches(); | |
EspLogger::initialize_default(); | |
let peripherals = Peripherals::take().unwrap(); | |
let sys_loop = EspSystemEventLoop::take()?; | |
let nvs = EspDefaultNvsPartition::take()?; | |
let mut wifi = BlockingWifi::wrap( | |
EspWifi::new(peripherals.modem, sys_loop.clone(), Some(nvs))?, | |
sys_loop, | |
)?; | |
connect_wifi(&mut wifi)?; | |
let config = &HttpConfiguration { | |
buffer_size: Some(1024), | |
buffer_size_tx: Some(1024), | |
crt_bundle_attach: Some(esp_idf_svc::sys::esp_crt_bundle_attach), | |
..Default::default() | |
}; | |
let mut client = HttpClient::wrap(EspHttpConnection::new(&config)?); | |
// GET | |
get_request(&mut client)?; | |
// let payload = br#"{"content": "This is a message from ESP32"}"#; | |
// POST | |
// let payload = br#"{"content": "This is a message from ESP32"}"#; | |
// post_request(&mut client, payload)?; | |
let dt = peripherals.pins.gpio2; | |
let sck = peripherals.pins.gpio3; | |
let mut scale = Scale::new(sck, dt, LOAD_SENSOR_SCALING).unwrap(); | |
scale.wait_stable(); | |
scale.tare(32); | |
let mut iterations = 0; | |
loop { | |
if scale.is_ready() { | |
log::info!("Iteration {}", iterations); | |
let rounded_reading = scale.read_rounded().unwrap(); | |
let message = format!("This is a message from ESP32: {} g", rounded_reading); | |
let payload = serde_json::json!({ | |
"content": message | |
}); | |
// Convert the JSON object to a String | |
let payload_str = serde_json::to_string(&payload).unwrap(); | |
// `payload_str` is a `String` and needs to be converted to a byte slice (`&[u8]`) for the `post_request` | |
let payload_bytes = payload_str.as_bytes(); | |
// Now `payload_bytes` is ready to be sent with `post_request` | |
// post_request(&mut client, payload_bytes)?; | |
post_request_with_retry(&mut client, payload_bytes, &config)?; | |
} | |
// FreeRtos::delay_ms(1000u32); | |
FreeRtos::delay_ms(10000u32); | |
// Increment the iteration counter | |
iterations += 1; | |
// If approximately 5 seconds have passed, break the loop | |
// This is based on the assumption that each loop iteration takes roughly 2 seconds | |
if iterations >= 10 { | |
break; | |
} | |
} | |
// let ip_info = wifi.wifi().sta_netif().get_ip_info()?; | |
// info!("Wifi DHCP info: {:?}", ip_info); | |
info!("Shutting down in 5s..."); | |
std::thread::sleep(core::time::Duration::from_secs(5)); | |
Ok(()) | |
} | |
fn get_request(client: &mut HttpClient<EspHttpConnection>) -> anyhow::Result<()> { | |
let url = "https://httpbin.org/get"; | |
let request = client.get(url)?; | |
info!("-> GET {}", url); | |
let response = request.submit()?; | |
info!("<- {}", response.status()); | |
if let Some(content_length) = response.header("Content-Length") { | |
info!("Content-Length: {}", content_length); | |
} | |
if let Some(date) = response.header("Date") { | |
info!("Date: {}", date); | |
} | |
std::thread::sleep(core::time::Duration::from_secs(5)); | |
Ok(()) | |
} | |
fn post_request(client: &mut HttpClient<EspHttpConnection>, payload: &[u8]) -> anyhow::Result<()> { | |
let supabase_url = SUPABASE_URL | |
let supabase_key = SUPABASE_KEY | |
let content_length_header = format!("{}", payload.len()); | |
let headers = [ | |
("apikey", supabase_key), | |
("Authorization", &format!("Bearer {}", supabase_key)), | |
("Content-Type", "application/json"), | |
// ("Prefer", "return=representation"), | |
("Content-Length", &content_length_header), | |
]; | |
let mut request = client.post(supabase_url, &headers)?; | |
request.write_all(payload)?; | |
request.flush()?; | |
// let response = request.submit()?; | |
// let status = response.status(); | |
info!("-> POST {}", supabase_url); | |
match request.submit() { | |
Ok(response) => { | |
let status = response.status(); | |
info!("<- HTTP Status: {}", status); | |
// If possible, log body or additional response info | |
} | |
Err(e) => { | |
info!("Error sending POST request: {:?}", e); | |
// Depending on the error, you might decide to retry here | |
unsafe { | |
esp_http_client_close(client.raw_connection().unwrap().handle()); | |
} | |
} | |
} | |
// info!("<- {}", status); | |
// let mut buf = [0u8; 1024]; | |
// let bytes_read = io::try_read_full(&mut response, &mut buf).map_err(|e| e.0)?; | |
// info!("Read {} bytes", bytes_read); | |
// match std::str::from_utf8(&buf[0..bytes_read]) { | |
// Ok(body_string) => info!( | |
// "Response body (truncated to {} bytes): {:?}", | |
// buf.len(), | |
// body_string | |
// ), | |
// Err(e) => error!("Error decoding response body: {}", e), | |
// }; | |
// Drain any remaining bytes in the response to complete reading | |
// while response.read(&mut buf)? > 0 {} | |
Ok(()) | |
} | |
fn post_request_with_retry( | |
client: &mut HttpClient<EspHttpConnection>, | |
payload: &[u8], | |
config: &HttpConfiguration, | |
) -> anyhow::Result<()> { | |
let mut retries = 0; | |
let max_retries = 3; // Maximum number of retries | |
let supabase_url = SUPABASE_URL | |
let supabase_key = SUPABASE_KEY | |
let content_length_header = format!("{}", payload.len()); | |
let headers = [ | |
("apikey", supabase_key), | |
("Authorization", &format!("Bearer {}", supabase_key)), | |
("Content-Type", "application/json"), | |
// ("Prefer", "return=representation"), | |
("Content-Length", &content_length_header), | |
]; | |
// let response = request.submit()?; | |
// let status = response.status(); | |
loop { | |
let mut request = client.post(supabase_url, &headers)?; | |
if let Ok(payload_str) = std::str::from_utf8(payload) { | |
info!("Payload: {}", payload_str); | |
} else { | |
info!("Payload is not valid UTF-8"); | |
} | |
request.write_all(payload)?; | |
request.flush()?; | |
info!("Posting to {}", supabase_url); | |
match request.submit() { | |
Ok(_) => { | |
info!("Request succeeded"); | |
break; | |
} | |
Err(e) => { | |
info!("Error sending POST request: {:?}", e); | |
if retries >= max_retries { | |
info!("Max retries exceeded"); | |
return Err(e.into()); | |
} | |
*client = HttpClient::wrap(EspHttpConnection::new(&config)?); | |
retries += 1; | |
info!("Retrying... Attempt {}", retries + 1); | |
FreeRtos::delay_ms(5000u32); | |
} | |
} | |
} | |
Ok(()) | |
} | |
fn connect_wifi(wifi: &mut BlockingWifi<EspWifi<'static>>) -> anyhow::Result<()> { | |
let wifi_configuration: Configuration = Configuration::Client(ClientConfiguration { | |
ssid: SSID.try_into().unwrap(), | |
bssid: None, | |
auth_method: AuthMethod::WPA2Personal, | |
password: PASSWORD.try_into().unwrap(), | |
channel: None, | |
}); | |
wifi.set_configuration(&wifi_configuration)?; | |
wifi.start()?; | |
info!("Wifi started"); | |
unsafe { esp_wifi_set_max_tx_power(34) }; | |
wifi.connect()?; | |
info!("Wifi connected"); | |
wifi.wait_netif_up()?; | |
info!("Wifi netif up"); | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment