### Start WiFi Protected Setup (WPS) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md Initiates a WPS connection process. Requires a `WpsConfig` parameter to configure the WPS session. ```rust fn start_wps(&mut self, config: &WpsConfig) -> Result<(), EspError> ``` -------------------------------- ### Start HTTP Server Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md Shows how to create a basic HTTP server that responds to GET requests on the root path with a simple HTML message. ```rust use esp_idf_svc::http::server::{Configuration, EspHttpServer, Method}; let mut server = EspHttpServer::new(&Configuration::default())?; server.fn_handler("/", Method::Get, |request| { request .into_ok_response()? .write_all(b"Hello!") })?; ``` -------------------------------- ### Web Server with mDNS Setup Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md Example of setting up mDNS for a web server. This involves initializing mDNS, setting a hostname and instance name, creating an HTTP service, and configuring the HTTP server. The service is then accessible via its .local domain. ```rust use esp_idf_svc::mdns::EspMdns; use esp_idf_svc::http::server::{EspHttpServer, Configuration, Method}; // Setup mDNS let mut mdns = EspMdns::new()?; mdns.set_hostname("esp32webserver")?; mdns.set_instance_name("My ESP32 Web Server")?; // Create HTTP service let mut service = mdns.create_service("http", "tcp", 80)?; service.set_properties(&[ ("path", "/"), ("version", "1.0"), ])?; // Setup HTTP server let mut server = EspHttpServer::new(&Configuration::default())?; server.fn_handler("/", Method::Get, |request| { request .into_ok_response()? .write_all(b"Hello from mDNS!") })?; // Now accessible at: http://esp32webserver.local ``` -------------------------------- ### Internal Ethernet Initialization Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md Example of initializing and starting the internal Ethernet driver on an ESP32. Ensure the `peripheral` variable is correctly defined in your scope. ```rust use esp_idf_svc::eth::{EthDriver, EthConfiguration, EthInterface, EthRmiiClkConfig, EthClockMode}; use esp_idf_svc::eventloop::EspSystemEventLoop; let sysloop = EspSystemEventLoop::take()?; let config = EthConfiguration { interface: EthInterface::Rmii(EthRmiiClkConfig { clock_mode: EthClockMode::GPIO0Out, clock_gpio: None, }), ..Default::default() }; let mut eth_driver = EthDriver::new( peripheral, &config, sysloop, )?; eth_driver.start()?; ``` -------------------------------- ### Basic HTTP Server with GET and POST Handlers Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md This snippet demonstrates how to set up an HTTP server with basic GET and POST handlers. It includes examples for serving HTML content and processing POST request payloads. Ensure the `esp-idf-svc` crate is included in your project dependencies. ```rust use esp_idf_svc::http::server::{Configuration, EspHttpServer, Method}; fn main() -> anyhow::Result<()> { let mut server = EspHttpServer::new(&Configuration { http_port: 8080, max_uri_handlers: 4, ..Default::default() })?; // GET handler server.fn_handler("/", Method::Get, |request| { request .into_ok_response()? .write_all(b"Hello from ESP32!") })?; // POST handler server.fn_handler("/submit", Method::Post, |mut request| { let mut buffer = [0; 512]; let len = request.read(&mut buffer)?; let payload = &buffer[..len]; let response = request.into_ok_response()?; response.write_all(b"Received ")?; response.write_all(payload)?; Ok(()) })?; // API handler with custom status server.fn_handler("/api/status", Method::Get, |request| { let mut response = request.into_response(200)?; response.set_header("Content-Type", "application/json")?; response.write_all(b"{\"status\":\"ok\"}") })?; // Keep server running std::thread::sleep(std::time::Duration::from_secs(u64::MAX)); Ok(()) } ``` -------------------------------- ### Typical partitions.csv Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md An example of a typical `partitions.csv` file format used for defining device partitions. ```text Name Type SubType Offset Size Flags nvs data nvs 0x9000 0x6000 phy_init data phy 0xf000 0x1000 factory app factory 0x10000 0x140000 ota_data data ota 0x150000 0x2000 ota_0 app ota_0 0x152000 0x140000 ota_1 app ota_1 0x292000 0x140000 spiffs data spiffs 0x3d2000 0x2e000 ``` -------------------------------- ### HTTP Server Handler Examples Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md Demonstrates registering both a static HTML handler for GET requests and a data processing handler for POST requests. ```rust let mut server = EspHttpServer::new(&Configuration::default())?; server.fn_handler("/index.html", Method::Get, |request| { request .into_ok_response()? .write_all(b"Hello world!") })?; server.fn_handler("/api/data", Method::Post, |mut request| { let mut buf = [0; 256]; let size = request.read(&mut buf)?; let body = std::str::from_utf8(&buf[..size])?; // Process body... request.into_ok_response()?.write_all(b"OK") })?; ``` -------------------------------- ### Build and Flash Example with cargo-espflash Source: https://github.com/esp-rs/esp-idf-svc/blob/master/README.md This command demonstrates how to build and flash a Wi-Fi example to an ESP32-C3 using cargo-espflash. Adjust the MCU and target for your specific ESP32 device. ```sh $ MCU=esp32c3 cargo espflash flash --target riscv32imc-esp-espidf --example wifi --monitor ``` -------------------------------- ### EspHttpServer::new Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-server.md Creates and starts a new HTTP server with the given configuration. The server automatically starts on creation and stops on drop. ```APIDOC ## EspHttpServer::new ### Description Creates and starts a new HTTP server with the given configuration. The server automatically starts on creation and stops on drop. ### Signature ```rust pub fn new(config: &Configuration) -> Result ``` ### Parameters #### Path Parameters - **config** (`&Configuration`) - Required - Server configuration ``` -------------------------------- ### Async One-Shot Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Example demonstrating how to use an asynchronous one-shot timer with EspAsyncTimer. ```APIDOC ### Async One-Shot ```rust use esp_idf_svc::timer::EspAsyncTimer; use std::time::Duration; async fn wait_example() -> Result<(), EspError> { let mut timer = EspAsyncTimer::new()?; println!("Waiting..."); timer.after(Duration::from_secs(1)).await?; println!("Done!"); Ok(()) } ``` ``` -------------------------------- ### Synchronous One-Shot Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Example demonstrating how to create and use a synchronous one-shot timer using EspTimerService. ```APIDOC ### Synchronous One-Shot ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; let timer_service = EspTimerService::new()?; let fired = Arc::new(AtomicBool::new(false)); let fired_clone = fired.clone(); let timer = timer_service.create(move || { fired_clone.store(true, Ordering::Release); })?; timer.after(Duration::from_millis(500))?; std::thread::sleep(Duration::from_secs(1)); assert!(fired.load(Ordering::Acquire)); ``` ``` -------------------------------- ### WifiDriver::start Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md Starts the WiFi driver, initiating its operation. ```APIDOC ## WifiDriver::start ### Description Starts the WiFi driver, initiating its operation. This is equivalent to `esp_wifi_start()`. ### Method `start` ### Returns `Result<(), EspError>` - Success or error. ``` -------------------------------- ### Example: Handling WiFi Connection Events Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/eventloop.md Demonstrates how to subscribe to WiFi events and handle connection and disconnection notifications. The subscription is automatically managed and cleaned up. ```rust use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::wifi::WifiEvent; let sysloop = EspSystemEventLoop::take()?; let subscription = sysloop.subscribe::(|event: WifiEvent| { match event { WifiEvent::StaConnected(_) => println!("Connected!"), WifiEvent::StaDisconnected(_) => println!("Disconnected"), _ => {} } })?; // Subscription automatically unsubscribes when dropped drop(subscription); ``` -------------------------------- ### Rust MQTT Client Configuration Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/configuration.md Configure MQTT client settings such as client ID, keep-alive interval, reconnect timeout, username, password, and LWT message. This example uses default values for other settings. ```rust use esp_idf_svc::mqtt::client::{MqttClientConfiguration, LwtConfiguration, QoS}; use std::time::Duration; let config = MqttClientConfiguration { client_id: Some("esp32-device-01"), keep_alive_interval: Some(Duration::from_secs(60)), reconnect_timeout: Some(Duration::from_secs(10)), username: Some("mqtt_user"), password: Some("mqtt_pass"), lwt: Some(LwtConfiguration { topic: "devices/esp32/status", payload: b"offline", qos: QoS::AtMostOnce, retain: true, }), ..Default::default() }; ``` -------------------------------- ### Full MQTT Client Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md Demonstrates connecting to an MQTT broker, configuring client options, subscribing to a topic, publishing a message, and handling incoming events in a separate thread. ```rust use esp_idf_svc::mqtt::client::* use std::time::Duration; let mqtt_config = MqttClientConfiguration { client_id: Some("esp32-client"), keep_alive_interval: Some(Duration::from_secs(30)), reconnect_timeout: Some(Duration::from_secs(10)), username: Some("user"), password: Some("pass"), ..Default::default() }; let (mut client, mut connection) = EspMqttClient::new( "mqtt://broker.mosquitto.org", &mqtt_config, |msg| { match msg.payload() { EventPayload::Connected(_) => println!("Connected"), EventPayload::Received(data) => { println!("Topic: {}, Data: {:?}", data.topic(), data.data()); } EventPayload::Disconnected(_) => println!("Disconnected"), _ => {} } Ok(()) } )?; // Subscribe to topic client.subscribe("home/temperature", QoS::AtLeastOnce)?; // Publish message client.publish( "home/status", QoS::AtMostOnce, true, b"online" )?; // Handle events std::thread::spawn(move || { while let Ok(msg) = connection.recv() { match msg { Some(event) => println!("Event: {:?}", event), None => break, } } }); ``` -------------------------------- ### EthDriver Start Method Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md Starts the Ethernet interface. Returns a Result indicating success or an error. ```rust pub fn start(&mut self) -> Result<(), EspError> ``` -------------------------------- ### Async Periodic Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Example demonstrating how to use an asynchronous periodic timer with EspAsyncTimer. ```APIDOC ### Async Periodic ```rust use esp_idf_svc::timer::EspAsyncTimer; use std::time::Duration; async fn periodic_example() -> Result<(), EspError> { let mut timer = EspAsyncTimer::new()?; timer.every(Duration::from_millis(100))?; for i in 0..10 { timer.tick().await?; println!("Tick {}", i); } Ok(()) } ``` ``` -------------------------------- ### Example: Using a Custom NVS Partition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Shows how to initialize a custom NVS partition by specifying its name and then use it to store key-value pairs within a specific namespace. ```rust use esp_idf_svc::nvs::{EspNvsPartition, NvsCustom}; let nvs = EspNvsPartition::::take("custom_partition")?; let mut storage = nvs.data::("settings")?; storage.put("wifi_ssid", "MyNetwork")?; storage.put("wifi_password", "SecurePass")?; ``` -------------------------------- ### Synchronous Periodic Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Example demonstrating how to create and use a synchronous periodic timer using EspTimerService. ```APIDOC ### Synchronous Periodic ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; let timer_service = EspTimerService::new()?; let count = Arc::new(AtomicU32::new(0)); let count_clone = count.clone(); let timer = timer_service.create(move || { count_clone.fetch_add(1, Ordering::AcqRel); })?; timer.every(Duration::from_millis(10))?; std::thread::sleep(Duration::from_millis(100)); timer.cancel()?; let final_count = count.load(Ordering::Acquire); assert!(final_count >= 9); // ~10 ticks in 100ms ``` ``` -------------------------------- ### Example: Using the Default NVS Partition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Demonstrates how to initialize the default NVS partition, create a namespace handle, store, retrieve, and delete values using the StorageBase trait. ```rust use esp_idf_svc::nvs::{EspDefaultNvsPartition, NvsDefault}; use embedded_svc::storage::StorageBase; // Initialize default NVS let nvs = EspDefaultNvsPartition::take_default()?; // Create a namespace handle let mut storage = nvs.data::("myapp")?; // Store a value storage.put("counter", 42)?; // Retrieve it let value: u32 = storage.get("counter")?.unwrap_or(0); assert_eq!(value, 42); // Check existence if storage.contains("counter")? { println!("Counter exists"); } // Delete storage.remove("counter")?; ``` -------------------------------- ### Example: Using an Encrypted NVS Partition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Demonstrates initializing an encrypted NVS partition, optionally providing a key storage partition. This is suitable for sensitive data. ```rust use esp_idf_svc::nvs::{EspNvsPartition, NvsEncrypted}; // Creates keys if they don't exist let nvs = EspNvsPartition::::take_with_key( "nvs_encrypted", Some("nvs_keys") )?; let mut storage = nvs.data::("sensitive")?; storage.put("api_key", "secret123")?; ``` -------------------------------- ### Initialize and Use WifiDriver Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md Demonstrates how to create, start, scan, and connect to Wi-Fi networks using the WifiDriver. Requires system loop and NVS partition for driver initialization. ```rust use esp_idf_svc::wifi::{WifiDriver, WifiDeviceId}; use esp_idf_svc::eventloop::EspSystemEventLoop; use esp_idf_svc::nvs::EspDefaultNvsPartition; // Create driver with NVS support let wifi_driver = WifiDriver::new( modem, sysloop, Some(nvs_partition) )?; // Start the driver let mut driver = wifi_driver; driver.start()?; // Scan for networks use esp_idf_svc::wifi::config::ScanConfig; driver.start_scan(&ScanConfig::default(), true)?; let (results, count) = driver.get_scan_result_n::<20>()?; // Connect to a network use embedded_svc::wifi::ClientConfiguration; let client_config = ClientConfiguration { /* ... */ }; driver.set_configuration(&embedded_svc::wifi::Configuration::Client(client_config))?; driver.connect()?; ``` -------------------------------- ### Encrypted Partition Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Shows how to set up and use an encrypted NVS partition, including the option to provide a key for encryption and decryption of sensitive data. ```APIDOC ## Encrypted Partition Usage ### Description Illustrates how to set up and utilize an encrypted NVS partition. This includes the option to provide a key for encrypting and decrypting sensitive data. ### Usage 1. Initialize an encrypted NVS partition using `EspNvsPartition::::take_with_key("nvs_encrypted", Some("nvs_keys"))?`. 2. Obtain a namespace handle using `nvs.data::("sensitive")?`. 3. Store sensitive data using `storage.put(key, value)?`. ``` -------------------------------- ### EspHttpClient Method (get) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md Initiates a GET request to a specified URL. Returns a connection object for further manipulation or an error. ```rust pub fn get(&mut self, url: &str) -> Result ``` -------------------------------- ### Default Partition Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Demonstrates how to initialize and use the default NVS partition for storing and retrieving data, including creating namespace handles and managing key-value pairs. ```APIDOC ## Default Partition Usage ### Description Initializes and utilizes the default NVS partition for storing and retrieving data. This includes creating namespace handles and managing key-value pairs. ### Usage 1. Initialize the default NVS partition using `EspDefaultNvsPartition::take_default()?`. 2. Obtain a namespace handle using `nvs.data::("myapp")?`. 3. Store data using `storage.put(key, value)?`. 4. Retrieve data using `storage.get(key)?.unwrap_or(default_value)`. 5. Check for key existence using `storage.contains(key)?`. 6. Remove a key-value pair using `storage.remove(key)?`. ``` -------------------------------- ### Custom Partition Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Illustrates how to use a custom NVS partition by specifying its name during initialization, enabling storage and retrieval of data within that specific partition. ```APIDOC ## Custom Partition Usage ### Description Demonstrates the usage of a custom NVS partition by specifying its name during initialization. This allows for data storage and retrieval within a designated partition. ### Usage 1. Initialize a custom NVS partition using `EspNvsPartition::::take("custom_partition")?`. 2. Obtain a namespace handle using `nvs.data::("settings")?`. 3. Store data using `storage.put(key, value)?`. ``` -------------------------------- ### Partition Instance Methods Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md Methods to get information about a specific partition instance. ```APIDOC ## Partition Instance Methods ### get_label() #### Description Gets the human-readable label/name of the partition. #### Signature ```rust pub fn get_label(&self) -> Result ``` #### Returns `Result` - Partition name or error. #### Example ```rust let partition = Partition::find(...)?; println!("Partition: {}", partition.get_label()?); ``` ### get_offset() #### Description Gets the flash memory offset where this partition starts. #### Signature ```rust pub fn get_offset(&self) -> Result ``` #### Returns `Result` - Offset in bytes or error. ### get_size() #### Description Gets the size of this partition in bytes. #### Signature ```rust pub fn get_size(&self) -> Result ``` #### Returns `Result` - Size in bytes or error. ### get_kind() #### Description Gets the partition type. #### Signature ```rust pub fn get_kind(&self) -> Result ``` #### Returns `Result` - Partition type or error. ### get_subtype() #### Description Gets the partition subtype as raw value. #### Signature ```rust pub fn get_subtype(&self) -> Result ``` #### Returns `Result` - Subtype code or error. ### read_raw() #### Description Reads raw bytes from the partition. #### Signature ```rust pub fn read_raw(&self, offset: u32, buf: &mut [u8]) -> Result ``` #### Parameters - **offset** (`u32`) - Required - Offset within partition - **buf** (`&mut [u8]`) - Required - Buffer to read into #### Returns `Result` - Bytes read or error. ### write_raw() #### Description Writes raw bytes to the partition (typically for OTA or user data). #### Signature ```rust pub fn write_raw(&mut self, offset: u32, data: &[u8]) -> Result ``` #### Parameters - **offset** (`u32`) - Required - Offset within partition - **data** (`&[u8]`) - Required - Data to write #### Returns `Result` - Bytes written or error. ``` -------------------------------- ### EthDriver::start Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md Starts the Ethernet interface, enabling network connectivity. ```APIDOC ## EthDriver::start ### Description Starts the Ethernet interface, enabling network connectivity. ### Method `pub fn start(&mut self) -> Result<(), EspError>` ### Parameters This method takes no parameters. ### Response #### Success Response - `Result<(), EspError>`: Returns Ok(()) on success, or an EspError if the interface fails to start. ``` -------------------------------- ### Simple GET Request Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md Performs a basic GET request to a specified URL and prints the response status and body. Requires the `EspHttpClient` to be initialized with default settings. ```rust use esp_idf_svc::http::client::EspHttpClient; let mut client = EspHttpClient::new_default()?; let mut response = client.get("http://api.example.com/data")?.submit()?; let mut buffer = [0u8; 1024]; let bytes_read = response.read(&mut buffer)?; let response_text = std::str::from_utf8(&buffer[..bytes_read])?; println!("Status: {}", response.status_code()); println!("Response: {}", response_text); ``` -------------------------------- ### Synchronous Periodic Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Shows how to set up and use a synchronous periodic timer. The timer is configured to fire repeatedly, and its execution count is checked after cancellation. ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; let timer_service = EspTimerService::new()?; let count = Arc::new(AtomicU32::new(0)); let count_clone = count.clone(); let timer = timer_service.create(move || { count_clone.fetch_add(1, Ordering::AcqRel); })?; timer.every(Duration::from_millis(10))?; std::thread::sleep(Duration::from_millis(100)); timer.cancel()?; let final_count = count.load(Ordering::Acquire); assert!(final_count >= 9); // ~10 ticks in 100ms ``` -------------------------------- ### Rust API Reference Structure Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/INDEX.md Illustrates the standard format for documenting Rust modules, including overview, types, methods, parameters, return values, and source file location. This structure ensures consistency and clarity in API documentation. ```rust # Module Name ## Overview [Description of module purpose] ## Main Types ### TypeName [Type definition in code block] #### Constructors/Methods **method_name()** ```rust signature ``` | Parameter | Type | Required | Default | Description | [parameter table] Returns `type` — description. **Example:** ```rust usage code ``` ## Notes [Important information] ## Source File `src/module.rs` ``` -------------------------------- ### OTA Partition Table Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Defines the required partition table structure for OTA updates, specifying partitions for OTA data and application images. ```plaintext # Name Type SubType Offset Size otadata data ota 0xd000 8K app0 app ota_0 0x10000 1600K app1 app ota_1 0x190000 1600K ``` -------------------------------- ### EspTimer::every Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Schedules a periodic timer that calls a callback repeatedly at specified intervals. Use this for recurring tasks. ```rust // Call closure every 100 milliseconds timer.every(Duration::from_millis(100))?; ``` -------------------------------- ### Discover HTTP Services (Python) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md This Python snippet uses the `zeroconf` library to discover HTTP services on the network. Ensure `zeroconf` is installed. ```python from zeroconf import ServiceBrowser, Zeroconf def on_service_found(zeroconf, service_type, name, state_change): print(f"Service found: {name}") zeroconf = Zeroconf() ServiceBrowser(zeroconf, "_http._tcp.local.", on_service_found) ``` -------------------------------- ### Synchronous One-Shot Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Demonstrates creating and using a synchronous one-shot timer. The timer fires after a specified duration, and its execution is verified. ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; let timer_service = EspTimerService::new()?; let fired = Arc::new(AtomicBool::new(false)); let fired_clone = fired.clone(); let timer = timer_service.create(move || { fired_clone.store(true, Ordering::Release); })?; timer.after(Duration::from_millis(500))?; std::thread::sleep(Duration::from_secs(1)); assert!(fired.load(Ordering::Acquire)); ``` -------------------------------- ### Example: Storing and Retrieving Different Data Types Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Illustrates how to store various data types (integer, float, string, byte array) in an NVS partition and then retrieve them, handling potential missing values. ```rust use esp_idf_svc::nvs::EspDefaultNvsPartition; let nvs = EspDefaultNvsPartition::take_default()?; let mut storage = nvs.data("app")?; // Store different types storage.put("boot_count", 1u32)?; storage.put("temperature", 23.5f32)?; storage.put("device_id", "ESP32-001")?; storage.put("mac_addr", &[0x00, 0x1A, 0x2B, 0x3C, 0x4D, 0x5E])?; // Retrieve them let count: u32 = storage.get("boot_count")?.unwrap_or(0); let temp: f32 = storage.get("temperature")?.unwrap_or(0.0); let id: String = storage.get("device_id")?.unwrap_or_default(); ``` -------------------------------- ### EspTimerService::create Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Creates a timer using the EspTimerService, which provides automatic lifecycle management. This is useful for creating timers within a managed service context, ensuring proper cleanup. The callback is executed on each timer event. ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; let timer_service = EspTimerService::new()?; let counter = std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)); let counter_clone = counter.clone(); let timer = timer_service.create(move || { counter_clone.fetch_add(1, std::sync::atomic::Ordering::Relaxed); })?; // Fire callback every 50ms timer.every(Duration::from_millis(50))?; // Let it run for a bit std::thread::sleep(Duration::from_secs(1)); // Stop timer.cancel()?; println!("Count: {}", counter.load(std::sync::atomic::Ordering::Relaxed)); ``` -------------------------------- ### EspHttpServer Methods and Configuration Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/DELIVERABLES.txt Enables the creation and management of an HTTP server. Supports handler registration for various request types (function and WebSocket), detailed configuration, and HTTPS setup. ```APIDOC ## EspHttpServer ### Description Enables the creation and management of an HTTP server. Supports handler registration for various request types (function and WebSocket), detailed configuration, and HTTPS setup. ### Constructors - `EspHttpServer::new()` ### Methods - `fn_handler(path, handler)`: Register a function-based handler. - `ws_handler(path, handler)`: Register a WebSocket handler. ### Configuration - `Configuration` struct with 16 fields. - `KeepAlive` configuration. ### Types - `Request` struct - `Response` struct - `Method` enum (9 HTTP verbs) ### Examples 4 usage examples are provided, including GET, POST, API, and WebSocket handling. ``` -------------------------------- ### Initiate WiFi Network Scan Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md Starts a WiFi network scan. Provide a `ScanConfig` for scan parameters and a boolean to indicate if the operation should block until completion. ```rust fn start_scan( &mut self, scan_config: &config::ScanConfig, blocking: bool, ) -> Result<(), EspError> ``` -------------------------------- ### Example ESP-IDF SDK Configuration Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/configuration.md Common ESP-IDF settings that can be configured in `sdkconfig.defaults` or via `menuconfig`. These include HTTP server limits, WiFi buffer sizes, NVS encryption, Bluetooth enablement, task name lengths, and SPIRAM configuration. ```ini # HTTP Server CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 # WiFi CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 # NVS CONFIG_NVS_ENCRYPTION_ENABLED=y # Bluetooth CONFIG_BT_ENABLED=y CONFIG_BLUEDROID_ENABLED=y # Threading CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 # Memory CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_QUAD=y ``` -------------------------------- ### MQTT Broker Discovery with mDNS Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md Example of advertising an MQTT broker using mDNS. This includes setting a hostname and creating services for both standard MQTT (port 1883) and MQTT over TLS (port 8883), along with their respective properties. Clients can discover these services using the specified service and protocol. ```rust use esp_idf_svc::mdns::EspMdns; let mut mdns = EspMdns::new()?; mdns.set_hostname("iot-hub")?; // Advertise MQTT broker let mut mqtt_service = mdns.create_service("mqtt", "tcp", 1883)?; mqtt_service.set_properties(&[ ("version", "3.1.1"), ("auth", "optional"), ("tls", "false"), ])?; // Advertise MQTT over TLS let mut mqtt_tls = mdns.create_service("mqtt", "tcp", 8883)?; mqtt_tls.set_property("tls", "true")?; // Clients can discover with: _mqtt._tcp.local ``` -------------------------------- ### Initialize WiFi and Connect Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md Demonstrates how to initialize the WiFi driver, set client configuration with SSID, authentication method, and password, and then connect to a WiFi network. ```rust use esp_idf_svc::wifi::{WifiDriver, WifiDeviceId, ClientConfiguration, AuthMethod}; use embedded_svc::wifi::Configuration; let wifi = WifiDriver::new(modem, sysloop, nvs)?; let mut driver = wifi; driver.start()?; let client_config = ClientConfiguration { ssid: "MyNetwork".try_into()?, auth_method: AuthMethod::WPA2Personal, password: "Password123".try_into()?, ..Default::default() }; driver.set_configuration(&Configuration::Client(client_config))?; driver.connect()?; ``` -------------------------------- ### Get OTA Partition Offset Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Returns the starting flash memory offset for a given OTA partition. Useful for low-level memory operations. ```rust pub fn get_offset(&self) -> Result ``` -------------------------------- ### RawStorage Methods for NVS Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Provides low-level key-value access methods for NVS partitions, including getting, setting, removing, and checking for the existence of raw data. ```rust pub fn get_raw(&self, name_space: &str, key: &str) -> Result, Self::Error>; pub fn set_raw(&mut self, name_space: &str, key: &str, data: &[u8]) -> Result<(), Self::Error>; pub fn remove(&mut self, name_space: &str, key: &str) -> Result<(), Self::Error>; pub fn contains(&self, name_space: &str, key: &str) -> Result; ``` -------------------------------- ### Validate Current OTA Partition and Rollback Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Checks the validity of the currently running firmware partition and provides an example of how to initiate a rollback to a previous partition if the current one is corrupt. Uses `EspOtaPartition`. ```rust use esp_idf_svc::ota::EspOtaPartition; // Get currently running partition let running = EspOtaPartition::get_running_partition()?; println!("Running partition: {:?}", running.get_label()?); // Check if it's valid if running.is_valid()? { println!("Current firmware is valid"); } else { println!("Current firmware is corrupt!"); // Could rollback to previous partition here if let Ok(Some(update_part)) = EspOtaPartition::get_update_partition() { EspOtaPartition::set_boot_partition(&update_part)?; esp_idf_svc::hal::reset::restart(); } } ``` -------------------------------- ### Iterate and Read ESP-IDF Partition Labels and Sizes Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md Use `Partition::iterate` to get a list of all partitions of a given type and then use instance methods like `get_label` and `get_size` to retrieve their details. This is helpful for discovering and inspecting available partitions. ```rust use esp_idf_svc::partition::{Partition, PartitionType}; let partitions = Partition::iterate(PartitionType::Data, None)?; for partition in partitions { println!("Name: {}", partition.get_label()?); println!("Size: {} bytes", partition.get_size()?); } ``` -------------------------------- ### Dynamic mDNS Property Updates Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md Demonstrates dynamic updates of mDNS service properties. This example shows how to initially set properties like 'type' and 'location', and then later update them with 'status' and 'readings', or remove properties using `remove_property`. ```rust use esp_idf_svc::mdns::EspMdns; let mut mdns = EspMdns::new()?; mdns.set_hostname("sensor")?; let mut service = mdns.create_service("http", "tcp", 8080)?; service.set_property("type", "temperature_sensor")?; service.set_property("location", "living_room")?; // Later, update properties service.set_property("status", "online")?; service.set_property("readings", "42")?; // Or remove old properties service.remove_property("status")?; ``` -------------------------------- ### List All Partitions Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md Iterates through and prints details for all application and data partitions on the device. Requires `esp_idf_svc::partition`. ```rust use esp_idf_svc::partition::{Partition, PartitionType}; fn list_partitions() -> Result<(), EspError> { println!("=== Application Partitions ==="); let apps = Partition::iterate(PartitionType::App, None)?; for partition in apps { let label = partition.get_label()?; let size = partition.get_size()?; let offset = partition.get_offset()?; println!(" {} @ 0x{:x} ({} bytes)", label, offset, size); } println!("\n=== Data Partitions ==="); let data = Partition::iterate(PartitionType::Data, None)?; for partition in data { let label = partition.get_label()?; let size = partition.get_size()?; let offset = partition.get_offset()?; println!(" {} @ 0x{:x} ({} bytes)", label, offset, size); } Ok(()) } ``` -------------------------------- ### EthDriver Get Capabilities Method Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ethernet.md Retrieves the driver's capabilities. Returns a Result containing the capabilities or an error. ```rust pub fn get_capabilities(&self) -> Result ``` -------------------------------- ### List Available OTA Partitions Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Iterates through all available OTA partitions of type 'App' and prints their labels, sizes, and indicates which one is currently running. Requires `Partition` and `PartitionType`. ```rust use esp_idf_svc::partition::{Partition, PartitionType}; let running = EspOtaPartition::get_running_partition()?; let running_label = running.get_label()?; println!("OTA Partitions:"); for partition in Partition::iterate(PartitionType::App, None)? { let label = partition.get_label()?; let is_running = label == running_label; let size = partition.get_size()?; println!( " {} - {} bytes{}", label, size, if is_running { " [RUNNING]" } else { "" } ); } ``` -------------------------------- ### Get OTA Partition Label Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Retrieves the string label (name) of an OTA partition. This is often used for identification purposes. ```rust pub fn get_label(&self) -> Result ``` -------------------------------- ### Check OTA Partition Validity Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Verifies if the partition currently being written to is valid for an OTA update. Call this before starting to write data. ```rust pub fn is_valid(&self) -> Result ``` -------------------------------- ### new() Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md Creates a new MQTT client instance. It requires the broker URL, client configuration, and a handler function for MQTT events. ```APIDOC ## new() ### Description Creates a new MQTT client. ### Signature ```rust pub fn new FnMut(Event<'a>) -> Result<()> + Send + 'static>( url: &str, client_config: &MqttClientConfiguration, handler: F, ) -> Result<(Self, Connection), EspError> ``` ### Parameters #### Path Parameters - **url** (`&str`) - Required - Broker URL (mqtt://, mqtts://, ws://, wss://) - **client_config** (`&MqttClientConfiguration`) - Required - Client configuration - **handler** (`F`) - Required - Closure handling MQTT events ### Returns - `Result<(EspMqttClient, Connection), EspError>` - Client and connection handle or error. ``` -------------------------------- ### Async One-Shot Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Demonstrates the usage of EspAsyncTimer for an asynchronous one-shot delay. The function waits for a specified duration before proceeding. ```rust use esp_idf_svc::timer::EspAsyncTimer; use std::time::Duration; async fn wait_example() -> Result<(), EspError> { let mut timer = EspAsyncTimer::new()?; println!("Waiting..."); timer.after(Duration::from_secs(1)).await?; println!("Done!"); Ok(()) } ``` -------------------------------- ### String Definition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/types.md UTF-8 encoded string requiring `alloc`. Supports methods for creation, appending, getting string slices, and length. ```rust pub struct String { /* ... */ } ``` -------------------------------- ### Connect to MQTT Broker Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md Illustrates connecting to an MQTT broker, setting a client ID, subscribing to a topic, and publishing a message. ```rust use esp_idf_svc::mqtt::client::{EspMqttClient, MqttClientConfiguration, QoS}; let config = MqttClientConfiguration { client_id: Some("esp32"), ..Default::default() }; let (mut client, _conn) = EspMqttClient::new( "mqtt://broker.example.com", &config, |_msg| Ok(()), )?; client.subscribe("home/temp", QoS::AtMostOnce)?; client.publish("home/status", QoS::AtMostOnce, false, b"online")?; ``` -------------------------------- ### Async Periodic Timer Example Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/timer.md Illustrates how to use EspAsyncTimer for periodic asynchronous operations. The timer triggers repeatedly, and the number of ticks is printed. ```rust use esp_idf_svc::timer::EspAsyncTimer; use std::time::Duration; async fn periodic_example() -> Result<(), EspError> { let mut timer = EspAsyncTimer::new()?; timer.every(Duration::from_millis(100))?; for i in 0..10 { timer.tick().await?; println!("Tick {}", i); } Ok(()) } ``` -------------------------------- ### EspMdns::new Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md Creates and initializes the mDNS responder. This is the entry point for using the mDNS service. ```APIDOC ## EspMdns::new ### Description Creates and initializes the mDNS responder. ### Method Rust function call ### Parameters None ### Response #### Success Response - **EspMdns** (EspMdns) - An initialized mDNS instance. - **EspError** (EspError) - An error if initialization fails. ### Example ```rust let mdns = EspMdns::new()?; ``` ``` -------------------------------- ### Get ESP-IDF Partition Label Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md Retrieve the human-readable name of a partition using its `get_label` method. This is often used after finding a partition to identify it. ```rust let partition = Partition::find(...)?; println!("Partition: {}", partition.get_label()?); ``` -------------------------------- ### List All Services (Linux/macOS) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mdns.md Use `avahi-browse -a` to list all discoverable mDNS services on the network. ```bash avahi-browse -a ``` -------------------------------- ### Perform Basic OTA Update from HTTP Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Initiates an OTA update by downloading firmware from a given URL via HTTP and writing it to the OTA partition. Requires `OtaUpdate` and `EspHttpClient`. ```rust use esp_idf_svc::ota::OtaUpdate; use esp_idf_svc::http::client::*; fn perform_ota_update(url: &str) -> Result<(), EspError> { // Start OTA session let mut ota = OtaUpdate::new()?; // Download firmware via HTTP let mut client = EspHttpClient::new_default()?; let mut response = client.get(url)?.submit()?; // Write downloaded data to OTA partition let mut buffer = [0u8; 4096]; loop { let len = response.read(&mut buffer)?; if len == 0 { break; } ota.write(&buffer[..len])?; } // Finalize and reboot ota.complete()?; esp_idf_svc::hal::reset::restart(); Ok(()) } ``` -------------------------------- ### Get Currently Running OTA Partition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Retrieves information about the OTA partition that is currently executing firmware. This is useful for debugging or status checks. ```rust pub fn get_running_partition() -> Result ``` -------------------------------- ### Create MQTT Client Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/mqtt.md Constructs a new MQTT client instance. Requires a broker URL, client configuration, and an event handler closure. The handler will be called for all MQTT events. ```rust pub fn new FnMut(Event<'a>) -> Result<()> + Send + 'static>( url: &str, client_config: &MqttClientConfiguration, handler: F, ) -> Result<(Self, Connection), EspError> ``` -------------------------------- ### Use Hardware Timer Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/README.md Shows how to create and configure a hardware timer that triggers a closure at a specified interval, in this case, every second. ```rust use esp_idf_svc::timer::EspTimerService; use std::time::Duration; let timer_service = EspTimerService::new()?; let timer = timer_service.create(|| println!("Tick!"))?; timer.every(Duration::from_secs(1))?; ``` -------------------------------- ### EspHttpClient Constructor (new) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md Creates a new HTTP client instance with custom configuration. Requires a Configuration struct as input. ```rust pub fn new(config: &Configuration) -> Result ``` -------------------------------- ### EspHttpClient Constructor (new_default) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md Creates a new HTTP client instance using default configuration settings. This is a convenient way to initialize the client without specifying individual configuration parameters. ```rust pub fn new_default() -> Result ``` -------------------------------- ### EspHttpRequest Method (status_code) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/http-client.md Gets the HTTP response status code. This is a simple integer representing the status (e.g., 200 for OK, 404 for Not Found). ```rust pub fn status_code(&self) -> u16 ``` -------------------------------- ### RawStorage Methods Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/nvs.md Provides low-level key-value access operations for NVS partitions, including getting, setting, removing, and checking for the existence of raw data. ```APIDOC ## RawStorage Methods ### Description Provides low-level key-value access operations for NVS partitions, including getting, setting, removing, and checking for the existence of raw data. ### Methods - `get_raw(name_space: &str, key: &str) -> Result, Self::Error>`: Retrieves raw data associated with a key in a given namespace. - `set_raw(name_space: &str, key: &str, data: &[u8]) -> Result<(), Self::Error>`: Sets raw data for a given key in a namespace. - `remove(name_space: &str, key: &str) -> Result<(), Self::Error>`: Removes a key-value pair from the NVS. - `contains(name_space: &str, key: &str) -> Result`: Checks if a key exists within a given namespace. ``` -------------------------------- ### WifiDriver::new (with NVS) Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/wifi.md Initializes the WiFi driver with an optional NVS partition for persistent configuration. ```APIDOC ## WifiDriver::new (with NVS) ### Description Initializes the WiFi driver with an optional NVS partition for persistent configuration. ### Method `new` ### Parameters #### Path Parameters - **_modem** (`M: WifiModemPeripheral`) - Required - WiFi modem peripheral - **sysloop** (`EspSystemEventLoop`) - Required - System event loop for WiFi events - **nvs** (`Option`) - Optional - Optional NVS partition for persistent config ### Returns `Result` - Initialized WiFi driver or error. ``` -------------------------------- ### Get ESP-IDF Partition Subtype Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/partition.md Fetch the raw subtype code for a partition using `get_subtype`. This provides a more granular classification than the partition type alone. ```rust pub fn get_subtype(&self) -> Result ``` -------------------------------- ### Get OTA Partition Size Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Returns the total size in bytes of an OTA partition. Essential for calculating buffer sizes or verifying data integrity. ```rust pub fn get_size(&self) -> Result ``` -------------------------------- ### Get Next Update OTA Partition Source: https://github.com/esp-rs/esp-idf-svc/blob/master/_autodocs/api-reference/ota.md Identifies the OTA partition designated for the next firmware update. Returns `None` if no update partition is configured. ```rust pub fn get_update_partition() -> Result, EspError> ```