<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vaishnav-sabari-girish</title>
    <description>The latest articles on DEV Community by Vaishnav-sabari-girish (@vaishnav_sabari_girish).</description>
    <link>https://dev.to/vaishnav_sabari_girish</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1287528%2F92447b67-d677-44dc-b578-18b0f4c3f9ef.png</url>
      <title>DEV Community: Vaishnav-sabari-girish</title>
      <link>https://dev.to/vaishnav_sabari_girish</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vaishnav_sabari_girish"/>
    <language>en</language>
    <item>
      <title>Embedded Rust on the ESP32 : Sensor Integration : DHT22 (Temperature and Humidity Sensor)</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Mon, 28 Jul 2025 13:57:55 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-sensor-integration-dht22-temperature-and-humidity-sensor-4ngl</link>
      <guid>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-sensor-integration-dht22-temperature-and-humidity-sensor-4ngl</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-interfacing-button-with-esp32-kd9"&gt;blog&lt;/a&gt;, we interfaced a button. &lt;/p&gt;

&lt;p&gt;We shall now get started with interfacing a few sensors. This blog will walk you through interfacing the DHT22 temperature and Humidity Sensor. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let us create our new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;esp-generate &lt;span class="nt"&gt;--chip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esp32 dht22_sensor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;src/bin/main.rs&lt;/code&gt; and type the below code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;DriveMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;embedded_dht_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dht22&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_cpu_clock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;od_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.with_drive_mode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;DriveMode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OpenDrain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with_pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;od_for_dht22&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;High&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;od_config&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.into_flex&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;od_for_dht22&lt;/span&gt;&lt;span class="nf"&gt;.peripheral_input&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;dht22&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;dht22&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Dht22&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;od_for_dht22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;dht22&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"DHT22 Sensor - Temperature: {} C , Humidity: {} %"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="py"&gt;.temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="py"&gt;.humidity&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"An error occurred while trying to read the sensor"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_____________________________________________________"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Output GIF
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzy95pgm9gq6kmiiggw9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzy95pgm9gq6kmiiggw9.gif" alt="Output GIF" width="470" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Into the code : Line-by-line explanation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Disables the Rust standard library for embedded programming.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replaces the default &lt;code&gt;main&lt;/code&gt; entry point with a custom embedded one.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prevents the use of &lt;code&gt;mem::forget&lt;/code&gt; as it can cause unsafe behavior in this context.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables backtrace support on panic (if supported by target). &lt;code&gt;as _&lt;/code&gt; suppresses warnings.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;DriveMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Imports required ESP HAL modules:

&lt;ul&gt;
&lt;li&gt;Clock configuration&lt;/li&gt;
&lt;li&gt;Delay handling&lt;/li&gt;
&lt;li&gt;GPIO configuration (including open-drain and pull options)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; macro
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables UART-based printing to a terminal.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;embedded_dht_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;dht22&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Imports DHT22 support from the &lt;code&gt;embedded_dht_rs&lt;/code&gt; crate.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Embeds metadata about the application (like name, version).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Entry point of the embedded program that never returns (&lt;code&gt;-&amp;gt; !&lt;/code&gt;).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_cpu_clock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configures system with maximum CPU clock speed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes the HAL and returns access to hardware peripherals.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;od_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.with_drive_mode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;DriveMode&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;OpenDrain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.with_pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Pull&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sets up GPIO pin as Open-Drain with no internal pull-up/down. This is essential for DHT22 communication.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;od_for_dht22&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;High&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;od_config&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;.into_flex&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes GPIO4 with the config above and converts it to a flexible IO pin (&lt;code&gt;Flex&lt;/code&gt;), which allows bidirectional control.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="n"&gt;od_for_dht22&lt;/span&gt;&lt;span class="nf"&gt;.peripheral_input&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables input mode for this flexible pin — DHT22 is bidirectional, so the pin needs to receive data too.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creates a delay instance for timing control.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;dht22&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;dht22&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Dht22&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;od_for_dht22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes the DHT22 driver with the GPIO and delay.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Begins infinite polling loop.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Waits 2 seconds between each sensor read (recommended minimum delay for DHT22).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prints a blank line for readability.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;dht22&lt;/span&gt;&lt;span class="nf"&gt;.read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Tries to read temperature and humidity from the sensor.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;            &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;"DHT22 Sensor - Temperature: {} C , Humidity: {} %"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="py"&gt;.temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;sensor_reading&lt;/span&gt;&lt;span class="py"&gt;.humidity&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If read is successful, prints temperature and humidity.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;            &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"An error occurred while trying to read the sensor"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If read fails, prints a basic error message (you can expand this with &lt;code&gt;{:?}&lt;/code&gt; for debugging).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_____________________________________________________"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prints a separator line to visually break up readings.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Closes loop and function.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Summary:
&lt;/h3&gt;

&lt;p&gt;This ESP32 firmware reads data from a DHT22 sensor connected to GPIO4 and prints temperature and humidity to the serial console every 2 seconds. It uses open-drain GPIO configuration and the &lt;code&gt;embedded_dht_rs&lt;/code&gt; crate for protocol handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thank You&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en"&gt;Getting Started Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-interfacing-button-with-esp32-kd9"&gt;Interfacing a Button Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/Embedded-Rust" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>sensor</category>
      <category>embeddedsystems</category>
      <category>rust</category>
      <category>esp32</category>
    </item>
    <item>
      <title>Embedded Rust on the ESP32 : Interfacing Button with ESP32</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Wed, 16 Jul 2025 17:29:42 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-interfacing-button-with-esp32-kd9</link>
      <guid>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-interfacing-button-with-esp32-kd9</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1"&gt;blog&lt;/a&gt;, we blinked an LED. &lt;/p&gt;

&lt;p&gt;Now, we shall interface a button (inbuilt Flash Button), which is connected to GPOI0 to read button presses. &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let us create our new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;esp-generate &lt;span class="nt"&gt;--chip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esp32 button_press
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;src/bin/main.rs&lt;/code&gt; file and type the below code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;InputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="nf"&gt;.is_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Button Pressed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Into the Code : Line-by-line explanation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Removes the standard library to suit bare-metal embedded systems.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Disables Rust's default entry point, enabling use of a custom embedded &lt;code&gt;main&lt;/code&gt; function.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Prevents using &lt;code&gt;mem::forget&lt;/code&gt;, which can cause resource leaks with peripherals like GPIOs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Provides support for backtraces during panics, aiding debugging.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Brings in delay functionality, GPIO level enums, input/output pin types, and the custom entry macro.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables logging via &lt;code&gt;println!&lt;/code&gt;, useful for debugging over serial.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Embeds metadata (app version, timestamp, etc.) into the firmware.&lt;/li&gt;
&lt;/ul&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Entry point of the application. Uses &lt;code&gt;-&amp;gt; !&lt;/code&gt; since it loops forever.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes peripherals using default configuration.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configures GPIO2 as an output pin, initially set to Low (LED off).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;InputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configures GPIO0 as an input pin (for reading a button's state).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes a delay instance for blocking waits.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Begins an infinite loop to continuously check the button and control the LED.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="nf"&gt;.is_low&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Checks if the button is pressed (logic Low, assuming pull-up setup).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;            &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Turns the LED on.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Button Pressed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Logs button press to serial console.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;            &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Adds a small delay for button debounce.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the button is not pressed, turns the LED off.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Outputs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Terminal Output
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ku6oie1e0x03vp2cytu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ku6oie1e0x03vp2cytu.gif" alt="terminal op" width="470" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware Output
&lt;/h3&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/EDrQQc08X9g"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en"&gt;Getting Started Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1"&gt;Blinking an LED Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/Embedded-Rust" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>rust</category>
      <category>embeddedsystems</category>
      <category>esp32</category>
      <category>hal</category>
    </item>
    <item>
      <title>Embedded Rust on the ESP32 : Blinking an LED</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Mon, 14 Jul 2025 17:25:21 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1</link>
      <guid>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm"&gt;blog&lt;/a&gt;, we coded our first Embedded Rust application which prints &lt;code&gt;Hello World&lt;/code&gt;, now we will start a new application that is LED Blinking. &lt;br&gt;
LED blinking in hardware is what &lt;code&gt;Hello World&lt;/code&gt; is to software i.e it is the starting point of anyone who plans on starting microcontroller programming. &lt;/p&gt;

&lt;p&gt;LED blinking gives you a basic idea of how to select which pin to toggle, make it an input or an output and how to set the pin as HIGH or LOW. &lt;/p&gt;

&lt;p&gt;In this blog, we will be learning how to blink an LED in 2 ways :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;[Setting HIGH and LOW separately]&lt;/li&gt;
&lt;li&gt;[Toggling the LED]&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let us create a new project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;esp-generate &lt;span class="nt"&gt;--chip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esp32 blinky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refer the previous &lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm#creating-the-project"&gt;blog&lt;/a&gt; , for the steps. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;br&gt;
The above link takes you directly to the section in the previous blog where steps are outlined&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These steps are common for all projects. &lt;br&gt;
&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;After the project has been created, let us get into the programming aspect. &lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;src/bin/main.rs&lt;/code&gt; file in the project. &lt;/p&gt;
&lt;h3&gt;
  
  
  Code 1 - Mentioning the Level of the Pin separately.
&lt;/h3&gt;

&lt;p&gt;In this code, the Logic Level of the LED pin is mentioned explicitly as HIGH or LOW. &lt;/p&gt;

&lt;p&gt;Here's the full code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED HIGH"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED LOW"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h4&gt;
  
  
  Into the code : A line-by-line explanation
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;This disables Rust's standard library, which is required in embedded environments where there is no OS.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Tells the Rust compiler that this binary has no standard entry point (&lt;code&gt;main&lt;/code&gt; from &lt;code&gt;std&lt;/code&gt;) and instead uses a custom entry point, suitable for embedded.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;This directive disallows the use of &lt;code&gt;mem::forget&lt;/code&gt;, which can lead to memory/resource leaks when dealing with HAL (Hardware Abstraction Layer) resources like GPIOs or DMA.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;This macro provides backtraces on panic, helping with debugging crashes.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Brings in essential traits and modules from the &lt;code&gt;esp_hal&lt;/code&gt; crate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Delay&lt;/code&gt;: For implementing delay operations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gpio::{Level, Output, OutputConfig}&lt;/code&gt;: For configuring and using GPIO pins.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: Used to mark the entry point.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Provides the &lt;code&gt;println!&lt;/code&gt; macro, which sends debug messages to a serial console.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Macro that embeds application metadata like version, build date, etc., into the firmware binary.&lt;/li&gt;
&lt;/ul&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Defines the custom entry point of the application, marked with &lt;code&gt;#[main]&lt;/code&gt; for &lt;code&gt;esp_hal&lt;/code&gt;. The &lt;code&gt;-&amp;gt; !&lt;/code&gt; return type means this function never returns (infinite loop or system reset).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Initializes the HAL with default configuration and gets access to hardware peripherals like GPIO.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Prints "Hello World" over serial (for debugging).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Configures GPIO2 as a digital output with default settings and initial level &lt;code&gt;Low&lt;/code&gt;. &lt;code&gt;Output::new()&lt;/code&gt; takes the pin, initial logic level, and an optional output config.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Initializes the delay timer used for timing operations like &lt;code&gt;delay_millis()&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Infinite loop to blink the LED repeatedly.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_high&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Sets the GPIO2 pin to logic high (turns LED on).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED HIGH"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Logs the LED state to the serial console.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Waits for 1000 milliseconds (1 second).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.set_low&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Sets the GPIO2 pin to logic low (turns LED off).
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED LOW"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Logs the LED state to the serial console.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Waits for another second before repeating.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Code 2 - Toggling the pin without mentioning it's level.
&lt;/h3&gt;

&lt;p&gt;In this code, we directly toggle the pin instead of mentioning it's logic level. This reduces the lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED TOGGLED"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Into the code : Line-by-line explanation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Disables the standard Rust library, which isn't available in embedded systems.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Replaces the standard &lt;code&gt;main&lt;/code&gt; entry point with a custom one suitable for bare-metal applications.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![deny(&lt;/span&gt;
    &lt;span class="nd"&gt;clippy::mem_forget,&lt;/span&gt;
    &lt;span class="nd"&gt;reason&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mem::forget is generally not safe to do with esp_hal types, especially those &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;
    holding buffers for the duration of a data transfer."&lt;/span&gt;
&lt;span class="nd"&gt;)]&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Forbids use of &lt;code&gt;mem::forget&lt;/code&gt;, which can cause resource leaks in hardware abstractions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enables backtrace functionality for debugging panics in embedded context.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;gpio&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Imports delay functionality, GPIO control types, and the custom &lt;code&gt;main&lt;/code&gt; macro.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Allows the use of &lt;code&gt;println!&lt;/code&gt; for serial output, typically for debugging.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Embeds application metadata into the binary (e.g., version, date, etc.).&lt;/li&gt;
&lt;/ul&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Marks this as the custom entry point with an infinite loop (&lt;code&gt;-&amp;gt; !&lt;/code&gt;).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes hardware abstraction and retrieves access to peripherals (GPIO, timers, etc).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sends a "Hello World" message over serial for initial confirmation/debug.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;led&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;peripherals&lt;/span&gt;&lt;span class="py"&gt;.GPIO2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;OutputConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes GPIO2 as a push-pull output pin, starting in a Low state.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creates a delay instance for blocking delay operations.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Starts an infinite loop for repeated toggling of the LED.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;led&lt;/span&gt;&lt;span class="nf"&gt;.toggle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Toggles the LED pin state (High &amp;lt;-&amp;gt; Low) each cycle.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"LED TOGGLED"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Logs that the LED state was toggled.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Waits for 2000 milliseconds (2 seconds) before toggling again.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now let's run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to get the output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Outputs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Code 1 outputs
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Terminal Output
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxa1mm0c8gignb3yp38sd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxa1mm0c8gignb3yp38sd.gif" alt="terminal op"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Hardware output
&lt;/h4&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Nm6hJDAjop4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Code 2 outputs
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Terminal output
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovtniweo2b81z1t0t6ff.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovtniweo2b81z1t0t6ff.gif" alt="terminal op 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Hardware Output
&lt;/h4&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/NRWvRTvCVPM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Important Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en"&gt;Getting Started Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm"&gt;Hello World Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/Embedded-Rust" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Thank You&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>embeddedsystems</category>
      <category>rust</category>
      <category>esp32</category>
      <category>led</category>
    </item>
    <item>
      <title>Embedded Rust on the ESP-32 : Hello World</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Mon, 14 Jul 2025 08:56:06 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm</link>
      <guid>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm</guid>
      <description>&lt;p&gt;In my previous blog &lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en"&gt;link&lt;/a&gt;, I wrote about getting started with Embedded Rust on the ESP-32. &lt;br&gt;
In this blog we will now create our first Embedded Rust application. &lt;br&gt;
We will be creating the famous "Hello World" application. &lt;/p&gt;
&lt;h2&gt;
  
  
  Installing the necessary tools - Part 2
&lt;/h2&gt;

&lt;p&gt;Install &lt;code&gt;esp-generate&lt;/code&gt;. This generates the template for an Embedded Rust application for ESP32.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;esp-generate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Setting Up
&lt;/h2&gt;

&lt;p&gt;Assuming that you have installed all the required tools as told in the previous blog and above, we can start with using a template to create a project (This make things really easy). You can build from scratch too, but , &lt;strong&gt;only&lt;/strong&gt; if you have enough technical knowledge and debugging expertise. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the directory where you want to save you project (Say &lt;code&gt;Desktop&lt;/code&gt;) using the command &lt;code&gt;cd Desktop&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create the project using the &lt;code&gt;esp-generate&lt;/code&gt; function as follows :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;esp-generate &lt;span class="nt"&gt;--chip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esp32 &amp;lt;project_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;--chip&lt;/code&gt; parameter depends on the ESP32 module being used. I personally am using the ESP32-WROOM module so it's &lt;code&gt;esp32&lt;/code&gt; for me. Refer the documentation for more chips.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you do not forget to follow the steps here&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After creating the project, you will now get a directory of the below structure :&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
├── .cargo
│   └── config.toml
├── .gitignore
├── build.rs
├── Cargo.lock
├── Cargo.toml
├── rust-toolchain.toml
├── src
│   ├── bin
│   │   └── main.rs
│   └── lib.rs
└── tests
    └── hello_test.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before going further, let us see what these files are for &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build.rs&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sets the linker script arguments based on the template options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.cargo/config.toml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Cargo configuration. This defines a few options to correctly build the project. Contains the custom runner command for &lt;code&gt;espflash&lt;/code&gt; or &lt;code&gt;probe-rs&lt;/code&gt;. For example, &lt;code&gt;runner = "espflash flash --monitor"&lt;/code&gt; - this means you can just use &lt;code&gt;cargo run&lt;/code&gt; to flash and monitor your code&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The usual Cargo manifest declares some meta-data and dependencies of the project&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tells git which folders and files to ignore&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rust-toolchain.toml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Defines which Rust toolchain to use. The toolchain will be nightly or esp depending on your target&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/bin/main.rs&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main source file of the newly created project.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/lib.rs&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tells the Rust compiler that this code doesn't use libstd.&lt;/p&gt;




&lt;h2&gt;
  
  
  The &lt;code&gt;Hello World&lt;/code&gt; Embedded Rust Program
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating the project
&lt;/h3&gt;

&lt;p&gt;When you run the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;esp-generate &lt;span class="nt"&gt;--chip&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;esp32 hello_world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a TUI interface for more settings. &lt;br&gt;
To select a feature, press &lt;strong&gt;→&lt;/strong&gt;. As shown in the below GIF.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv1nrwwn5nojd3efsdfk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv1nrwwn5nojd3efsdfk.gif" alt="esp-generate" width="1041" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you choose the ones selected on the GIF only i.e only the &lt;strong&gt;Enable Unstable HAL features&lt;/strong&gt; and &lt;strong&gt;Use esp-backtrace as panic handler&lt;/strong&gt; which is inside &lt;strong&gt;Flashing, Logging and Debugging&lt;/strong&gt;. &lt;/p&gt;
&lt;h3&gt;
  
  
  Writing the code
&lt;/h3&gt;

&lt;p&gt;Now, in the &lt;code&gt;src/bin/main.rs&lt;/code&gt; file inside the project directory, write the below code :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_cpu_clock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code prints &lt;code&gt;Hello World&lt;/code&gt; after every 500 milliseconds or 1/2 a second. &lt;/p&gt;

&lt;p&gt;To run and flash this code , type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo run &lt;span class="nt"&gt;--release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will compile and flash the code to the ESP32. &lt;/p&gt;

&lt;p&gt;Here's the output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58z61ehezo3ddf85tgrd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F58z61ehezo3ddf85tgrd.gif" alt="Hello World" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Into the Code : A line-by-line explanation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Line-by-Line Explanation: ESP32 "Hello World" in Embedded Rust
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_std]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This disables the Rust standard library. In embedded systems, the standard library is often unavailable or unnecessary due to hardware constraints.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![no_main]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This tells the Rust compiler not to use the default entry point (&lt;code&gt;main&lt;/code&gt; from the std lib). Instead, we define our own entry point suitable for embedded devices.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;esp_backtrace&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This pulls in the &lt;code&gt;esp_backtrace&lt;/code&gt; crate to provide panic handlers and backtraces (when supported), which are essential for debugging embedded systems. The &lt;code&gt;as _&lt;/code&gt; suppresses the unused import warning.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Imports:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CpuClock&lt;/code&gt;: lets you configure the CPU clock speed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Delay&lt;/code&gt;: for inserting delays into your program.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt;: an attribute macro that marks the main function as the program's entry point.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;esp_println&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This brings in &lt;code&gt;println!&lt;/code&gt; macro functionality, which outputs to UART so we can see debug output from the ESP32.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;esp_bootloader_esp_idf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;esp_app_desc!&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This macro embeds metadata from the &lt;code&gt;esp-idf&lt;/code&gt; build into the binary (like project name, version, etc.). It’s optional but helpful for diagnostics and logging.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[main]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;#[main]&lt;/code&gt; macro from &lt;code&gt;esp_hal&lt;/code&gt; designates the following function as the program’s entry point.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Defines the entry point of the application. The &lt;code&gt;-&amp;gt; !&lt;/code&gt; return type indicates it never returns (infinite loop).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.with_cpu_clock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;CpuClock&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creates a default configuration and sets the CPU clock to the maximum supported frequency.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;_peripherals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;esp_hal&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Initializes the ESP32 HAL with the provided configuration and takes ownership of the device’s peripherals.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Instantiates a delay object used to insert blocking delays into the code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Infinite loop to run your logic continuously (typical in embedded firmware).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sends the string "Hello World" to the serial output using UART.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;        &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="nf"&gt;.delay_millis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Inserts a 500 ms delay between messages.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Closes the loop and main function.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Important Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en"&gt;Getting Started blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1"&gt;Blinking an LED&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/Embedded-Rust" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.espressif.com/projects/rust/book/introduction.html" rel="noopener noreferrer"&gt;Official Espressif Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Thank You&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>embeddedsystems</category>
      <category>rust</category>
      <category>esp32</category>
      <category>helloworld</category>
    </item>
    <item>
      <title>Embedded Rust on the ESP32 : Getting started - Setup</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Mon, 14 Jul 2025 07:10:19 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en</link>
      <guid>https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-getting-started-setup-28en</guid>
      <description>&lt;h2&gt;
  
  
  What are Embedded Systems ?
&lt;/h2&gt;

&lt;p&gt;Embedded systems are tiny computers built into devices to perform specific tasks. Unlike general-purpose computers, they are designed for control, automation, and real-time operations. You'll find them in everything from smartwatches to washing machines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is ESP32 ?
&lt;/h2&gt;

&lt;p&gt;The ESP32 is a low-cost, low-power microcontroller with built-in Wi-Fi and Bluetooth, developed by Espressif Systems. It's widely used in IoT projects due to its rich set of peripherals, dual-core processor, and community support. Perfect for smart devices, sensors, and wireless applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Rust ?
&lt;/h2&gt;

&lt;p&gt;Rust is a systems programming language focused on safety, speed, and concurrency. It’s known for preventing common bugs at compile time without needing a garbage collector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features of Rust
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Memory Safety&lt;/strong&gt; : Eliminates NULL pointer and buffer overflows due to it's ownership and lifetimes  features. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-cost abstraction&lt;/strong&gt; : High-level code with low-level performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; : Fearless Multithreading without Race conditions. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern Tooling&lt;/strong&gt; : &lt;code&gt;cargo&lt;/code&gt; makes it easier for project management and installing Rust tools. &lt;code&gt;cargo&lt;/code&gt; is for Rust what &lt;code&gt;pip&lt;/code&gt; and &lt;code&gt;uv&lt;/code&gt; are for Python.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-platform support&lt;/strong&gt; : From Bare-metal Linux to WebAssembly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why use Rust for Embedded Systems ?
&lt;/h2&gt;

&lt;p&gt;Rust offers the performance of C/C++ with memory safety guarantees, making it ideal for low-level, resource-constrained environments. Its strong compile-time checks prevent many common embedded bugs early in development. With growing ecosystem support (like &lt;code&gt;esp-hal&lt;/code&gt;), Rust is becoming a powerful and ergonomic choice for writing safe, efficient firmware for microcontrollers like the ESP32.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting up the Environment
&lt;/h2&gt;

&lt;p&gt;This blog assumes that : &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You are using a Linux Distribution (Like Ubuntu, Fedora , Debian or Arch).&lt;/li&gt;
&lt;li&gt;You have installed Rust. If not install it by following the instruction &lt;a href="https://www.rust-lang.org/tools/install" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You are familiar with using the Terminal.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Hardware
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ESP32-WROOM&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fshopping%3Fq%3Dtbn%3AANd9GcQKpLXQS6qKVYMCCNCgU5PiWP3W_lyBHPhYD8huzKvK72S2tVD3X74lYByMd2_TizXN1ssWOSwxNOZa6EVXU1TfNlsZQ4Fu33SO3n1f8-yrOWbbIWp7givu" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fshopping%3Fq%3Dtbn%3AANd9GcQKpLXQS6qKVYMCCNCgU5PiWP3W_lyBHPhYD8huzKvK72S2tVD3X74lYByMd2_TizXN1ssWOSwxNOZa6EVXU1TfNlsZQ4Fu33SO3n1f8-yrOWbbIWp7givu" alt="esp32wroom" width="450" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For future blogs, the following sensors are required :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;HC-SR04 Ultrasonic Sensor&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanhlp7qx69l29o707bcr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fanhlp7qx69l29o707bcr.jpg" alt="us" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DHT22 Temperature and Humidity Sensor&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa05ckn2h30hm5e1w5ly7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa05ckn2h30hm5e1w5ly7.jpg" alt="dht22" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Touch Sensor&lt;/strong&gt; : &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65fxy3bdsddzubw61tgy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65fxy3bdsddzubw61tgy.jpg" alt="ts" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing the tool chain
&lt;/h3&gt;

&lt;p&gt;ESP32 doesn't have enough power to run a full OS based program, so we will be using the &lt;code&gt;no_std&lt;/code&gt; library for Embedded Programming. &lt;/p&gt;

&lt;p&gt;Install the following tool chains&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing &lt;code&gt;espup&lt;/code&gt; . This is a tool that simplifies installing and maintaining the components required to develop Rust applications for the &lt;code&gt;Xtensia&lt;/code&gt; and &lt;code&gt;RISC-V&lt;/code&gt; architectures. (Make sure that &lt;code&gt;cargo&lt;/code&gt; is in your PATH).
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;espup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Installing the necessary tool-chains
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;espup &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now a file named &lt;code&gt;export-esp.sh&lt;/code&gt; will be created in your &lt;code&gt;$HOME&lt;/code&gt; directory. Add it's contents to your &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.zshrc&lt;/code&gt; using the following command
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/export-esp.sh &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;export-esp.sh&lt;/code&gt; file consists of all the environment variables required to run the Rust Code. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You are now ready to write Embedded Rust Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Find the other blogs here&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp-32-hello-world-1bgm"&gt;Hello World&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-blinking-an-led-2jk1"&gt;LED Blinking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-interfacing-button-with-esp32-kd9"&gt;Button interfacing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Sensor Integration

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dev.to/vaishnav_sabari_girish/embedded-rust-on-the-esp32-sensor-integration-dht22-temperature-and-humidity-sensor-4ngl"&gt;DHT22 Temperature and Humidity Sensor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Ultrasonic Sensor]&lt;/li&gt;
&lt;li&gt;[Touch Sensor]&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Miscellaneous Links
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/Embedded-Rust" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.espressif.com/projects/rust/book/introduction.html" rel="noopener noreferrer"&gt;Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>embeddedsystems</category>
      <category>rust</category>
      <category>esp32</category>
      <category>hal</category>
    </item>
    <item>
      <title>Streamlining Arduino Development: Introducing Arduino-cli-interactive</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Sun, 06 Apr 2025 14:17:52 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/streamlining-arduino-development-introducing-arduino-cli-interactive-16o3</link>
      <guid>https://dev.to/vaishnav_sabari_girish/streamlining-arduino-development-introducing-arduino-cli-interactive-16o3</guid>
      <description>&lt;p&gt;Arduino has always been a cornerstone for me as a hobbyist and developer, offering an accessible way to dive into embedded systems. But as a Linux user, I’ve often found the traditional Arduino IDE more frustrating than inspiring— wrestling with permissions and setup hurdles was a constant battle. When the Arduino team released arduino-cli, I saw a glimmer of hope: a lightweight, command-line alternative that fit my terminal-centric workflow. Yet, its reliance on memorizing Fully Qualified Board Names (FQBNs) like arduino:avr:uno felt like a step backward for beginners and even slowed me down. That’s why I created Arduino-cli-interactive (ACI)—a Bash script that wraps arduino-cli in a Text User Interface (TUI), bringing the ease of the IDE into the terminal with menus and option selectors. It’s been a game-changer for me, and I hope it can be for you too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: My Linux Struggle
&lt;/h2&gt;

&lt;p&gt;I love Linux for its flexibility, but setting up the Arduino IDE on it was a nightmare. Permissions issues turned a simple install into a troubleshooting marathon, and the GUI never quite meshed with my preference for the terminal. When I discovered arduino-cli, I was thrilled—it stripped away the bloat and let me script my workflow. But then I hit a snag: typing out exact FQBNs and commands every time was tedious. I’d forget a board identifier or mistype a port, and my momentum would grind to a halt. I knew I wasn’t alone—beginners especially would find this unforgiving. I wanted a solution that kept arduino-cli’s power but made it intuitive, so I set out to build one.&lt;br&gt;
Creating Arduino-cli-interactive (ACI)&lt;/p&gt;

&lt;p&gt;That’s how Arduino-cli-interactive, or ACI, was born. I built it as an open-source Bash script (check it out on GitHub), designing a TUI that feels like the Arduino IDE but lives in the terminal. With ACI, I don’t have to memorize board names or wrestle with long commands anymore. Instead, I launch it and get a clean menu: I pick my board from a list, select a port, and upload my sketch—all with a few keystrokes.&lt;/p&gt;

&lt;p&gt;I chose Bash for a reason. It’s everywhere on Linux, so ACI runs on any system without extra setup—no dependencies, no fuss. It’s lightweight, leveraging the terminal’s built-in tools, and lets me iterate quickly. Writing a TUI in Bash wasn’t just practical; it was a fun challenge that kept the project true to the hacker spirit I love about Arduino. The result? A tool that’s as simple as it is powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works for Me
&lt;/h2&gt;

&lt;p&gt;ACI is my bridge to arduino-cli. When I run it, I see an interactive menu. If I need to pick a board, I scroll through a list—no more guessing FQBNs. Setting a port? ACI scans and shows me what’s connected. From there, I can compile my code, upload it, or tweak settings, all without leaving the terminal. For instance, instead of typing arduino-cli upload -p /dev/ttyUSB0 -b arduino:avr:uno sketch.ino, I just navigate the menu, hit my choices, and watch the Bash script do the rest. It’s fast, it’s clean, and it gets my code running in seconds.&lt;/p&gt;

&lt;p&gt;For example here's how selecting a board looks like : &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0fgt0j9s0wfp76akly8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0fgt0j9s0wfp76akly8.gif" alt="board_selection" width="480" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It’s a Big Deal to Me
&lt;/h2&gt;

&lt;p&gt;ACI has transformed how I work with Arduino. As someone who’s taught beginners, I see how it flattens the learning curve—newbies can focus on blinking LEDs instead of decoding commands. For me, it’s a time-saver; I iterate faster without breaking my flow. And since it’s Bash-based, it’s a perfect fit for Linux, dodging the IDE’s quirks while staying lean and mean. On GitHub, I wrote, “No need to remember board names or type long commands. Just pick options, navigate with buttons, and upload your code hassle-free.” That’s the freedom I wanted, and it’s what I’ve built.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Journey and What’s Next
&lt;/h2&gt;

&lt;p&gt;Building ACI wasn’t always smooth sailing. Crafting a TUI in Bash meant getting creative with loops and prompts to make it feel responsive. My goal was to keep it intuitive while tapping into arduino-cli’s full potential, and I’m proud of where it’s landed. Seeing it recognized in communities like &lt;a href="//terminaltrove.com"&gt;Terminaltrove&lt;/a&gt; has been a thrill—it’s proof this little script solves a real need.&lt;/p&gt;

&lt;p&gt;I’m not done yet, though. I’m thinking about porting it for windows too (using either Rust or Python). I’d love your ideas too—ACI is open-source, and I’m excited to see where the community takes it. If you’re a Bash tinkerer like me, dive in and contribute!&lt;/p&gt;

&lt;p&gt;Whether you’re a Linux die hard like me, a beginner just starting out, or a pro chasing efficiency, I invite you to try it. Head to &lt;a href="https://github.com/Vaishnav-Sabari-Girish/arduino-cli-interactive" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, give it a spin, and let me know what you think. In the maker space, every tweak matters—and I can’t wait to hear how ACI fits into your story.&lt;/p&gt;

&lt;h1&gt;
  
  
  Important Links
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://vaishnav-sabari-girish.github.io/" rel="noopener noreferrer"&gt;My Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Vaishnav-Sabari-Girish/arduino-cli-interactive" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vaishnav-sabari-girish.github.io/arduino-cli-interactive/" rel="noopener noreferrer"&gt;Documentation (Github Pages)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vaishnav-sabari-girish.codeberg.page/pages/intro.html" rel="noopener noreferrer"&gt;Documentation mirror link (Codeberg Pages)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://terminaltrove.com/arduino-cli-interactive/" rel="noopener noreferrer"&gt;Terminal Trove&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>bash</category>
      <category>ubuntu</category>
      <category>arduino</category>
      <category>arduinocli</category>
    </item>
    <item>
      <title>Keyoxide Proof</title>
      <dc:creator>Vaishnav-sabari-girish</dc:creator>
      <pubDate>Mon, 03 Feb 2025 06:08:25 +0000</pubDate>
      <link>https://dev.to/vaishnav_sabari_girish/keyoxide-proof-52ln</link>
      <guid>https://dev.to/vaishnav_sabari_girish/keyoxide-proof-52ln</guid>
      <description>&lt;p&gt;aspe:keyoxide.org:UGMJ6VGDFJEOVHF27DC7JD6WMQ&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>mastodon</category>
      <category>devto</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
