DEV Community

Cover image for IoT with Rust on ESP: Connecting WiFi

IoT with Rust on ESP: Connecting WiFi

Omar Hiari on September 29, 2023

Introduction This post is the first in a new IoT series for using Rust on the ESP32. This new series will focus on several IoT hardware ...
Collapse
 
jarusauskas profile image
AJ

Thanks for your helpful articles! I'm experimenting with porting my ESP-IDF project to Rust. In C API, I use esp_event_handler_instance_register to perform an action on WiFi connect event and would like to achieve the same in Rust.

Can the connection checking loop (while !wifi.is_connected()) be replaced with an event callback in Rust? I would appreciate an example!

Collapse
 
apollolabsbin profile image
Omar Hiari • Edited

Absolutely!
I hadn't done WiFi interrupts with Rust, but from the documentation, I realized there aren't any abstractions within EspWifi enabling interrupts with callbacks in the traditional sense. Though from what I've seen there are two alternative options:

  1. Going the non-blocking async path. There exists an AsyncWifi abstraction within the esp-idf-svc that achieves non-blocking operations (link to documentation). There are some usage examples in the esp-idf-svc repo. Note that its all the examples with the _async suffix.
  2. Leverage the lower level raw Rust bindings in the esp-idf-sys (link). Warning: not fun! :D. The older version of the Ferrous/Espressif ESP Rust training has an example of button interrupts using low-level bindings here and the associated explanations here and here. Additionally, I wrote a blog post about using the bindings for creating a multithreaded application here. I can tell you that as simple as it may look, it was quite a pain to get it to work. If you are not familiar with how the ESP Rust abstractions work you can check this post out as well.

I apologize if it seems that I overwhelmed you with information. However, I figure until more stability is brought to the project, workarounds need to be found to apply things in a certain manner.

Collapse
 
jarusauskas profile image
AJ

Thanks! After going through esp-idf-svc sources I found some examples using sys_loop and was able to write the following function:

pub fn on_connect<F: Fn() + Send + 'static>(
    sys_loop: EspSystemEventLoop,
    cb: F,
) -> Result<EspSubscription<'static, System>, EspError> {
    sys_loop.subscribe::<WifiEvent, _>(move |event| {
        if let WifiEvent::ApStaConnected = event {
            cb()
        }
    })
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
apollolabsbin profile image
Omar Hiari • Edited

Ah interesting, I wasn't aware of those abstractions :D This sparks the potential start of a whole new series for event handling with svc abstractions. Though where did you find the examples? I tried looking again but couldn't locate anything. Could you probably share a link please?

Thread Thread
 
jarusauskas profile image
AJ • Edited

It was not in examples, that's why it took me quite some effort. Here is the link: github.com/esp-rs/esp-idf-svc/blob...

There is also this, but not as useful for my application.

Thread Thread
 
apollolabsbin profile image
Omar Hiari • Edited

Thanks for the insight! This also came in handy. Believe it or not, my exposure to the ESP-IDF came through Rust :D In std context, I often find myself referring back to the C documentation for insight. The Rust documentation still has a ways to go.

Thread Thread
 
jarusauskas profile image
AJ

Indeed. I found it quite useful to refer to my C code and also look at how the Rust wrappers use the C API.