Connect ESP32 to WiFi with Rust

Rajesh Pachaikani
3 min readDec 9, 2022

--

Photo by Umberto on Unsplash

Hey everyone,
If you’ve tried to do embedded systems development using Rust, you might feel the documentation is somewhat scarce. I felt the same when I tried to connect esp32-c3 devkit to WiFi network. This is my attempt to simplify the process for newbies like me.

Step 1: Setup your Development environment

Follow the instructions in this git repo’s readme: https://github.com/esp-rs/esp-idf-template

This is tl;dr; of the above link

$ rustup toolchain install nightly --component rust-src
$ cargo install cargo-generate
$ cargo install ldproxy
$ cargo install espflash
$ cargo install cargo-espflash

Then use cargo-generate to create a new esp32 rust project using the following

$ cargo generate --git https://github.com/esp-rs/esp-idf-template cargo
Project Name : <your_project_name>
Renaming project called `your_project_name` to `your-project-name`...
Basedir: /home/<USER>/Development/Rust-Projects ...
Generating template ...
? MCU ›
esp32
esp32s2
esp32s3
❯ esp32c3
? Configure project to use Dev Containers (VS Code, GitHub Codespaces and Gitpod)? (beware: Dev Containers not available for esp-idf v4.3.2) ›
❯ false
true
? STD support ›
false
❯ true
ESP-IDF native build version (v4.3.2 = previous stable, v4.4 = stable, mainline = UNSTABLE) ›
❯ v4.4
v4.3.2
mainline

The symbol “❯” indicates the options I’ve selected, you may select depending on your requirement but the code I share is tested to work only on esp32c3. Also the STD support is required for the following code.

Step 2: Add dependencies to your Cargo.toml

Open your cargo generated rust project and open Cargo.toml

Under the [dependencies] section add the following lines to add dependencies and do not remove existing dependencies. The package version used here are the latest when I write this blog. It will change in the future and the code may also need some tweaks depending on the version used.

esp-idf-svc = "0.43.4"
esp-idf-hal = "0.39.3"
embedded-hal = "0.2.7"
embedded-svc = "0.23.1"

Step 3: The main function


use std::{
thread::sleep,
time::Duration,
};
use esp_idf_sys as _;
use esp_idf_hal::{
peripherals::Peripherals,
};
use esp_idf_svc::{
wifi::EspWifi,
nvs::EspDefaultNvsPartition,
eventloop::EspSystemEventLoop,
};
use embedded_svc::wifi::{ClientConfiguration, Wifi, Configuration};

fn main(){
esp_idf_sys::link_patches();//Needed for esp32-rs
println!("Entered Main function!");
let peripherals = Peripherals::take().unwrap();
let sys_loop = EspSystemEventLoop::take().unwrap();
let nvs = EspDefaultNvsPartition::take().unwrap();

let mut wifi_driver = EspWifi::new(
peripherals.modem,
sys_loop,
Some(nvs)
).unwrap();

wifi_driver.set_configuration(&Configuration::Client(ClientConfiguration{
ssid: "YOUR_WIFI_SSID".into(),
password: "YOUR_WIFI_PASSWORD".into(),
..Default::default()
})).unwrap();

wifi_driver.start().unwrap();
wifi_driver.connect().unwrap();
while !wifi_driver.is_connected().unwrap(){
let config = wifi_driver.get_configuration().unwrap();
println!("Waiting for station {:?}", config);
}
println!("Should be connected now");
loop{
println!("IP info: {:?}", wifi_driver.sta_netif().get_ip_info().unwrap());
sleep(Duration::new(10,0));
}

}

`EspWifi::new()` is the most important function that create the wifi connection struct. All wifi connection related functions are implemented for this struct. It accepts 3 arguments
1. Modem — An esp32 peripheral
2. Sysloop — An ESP32 event loop for WiFi event handling
3. nvs — An optional parameter for saving WiFi data

set_configuration() function is used to set the WiFi mode and credentials. start() and connect() functions are to be called sequentially to connect to the WiFi access point saved in the configuration. is_connected() function returns false when the esp32 is not connected and it will attempt to connect to the network in a loop. Once it is connected the station ip address is fetched using the get_ip_info() function. It must be called on the struct EspNetif which is returned by the function sta_netif()

Github Gist for the code above: https://gist.github.com/rajeshpachaikani/2ef7c11b4d7e8a6704dba0f323bcdd6d

If you have any doubts, feel free to ask in the comments. See you in the next one.

--

--