<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Electronics on Gabriel Cachadiña</title><link>https://gabrielcachadina.com/tags/electronics/</link><description>Recent content in Electronics on Gabriel Cachadiña</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><managingEditor>gabrielcachadina@protonmail.com (Gabriel Cachadiña)</managingEditor><webMaster>gabrielcachadina@protonmail.com (Gabriel Cachadiña)</webMaster><copyright>John Doe (CC BY 4.0)</copyright><lastBuildDate>Sun, 22 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://gabrielcachadina.com/tags/electronics/index.xml" rel="self" type="application/rss+xml"/><item><title>Using the BM612 PIR Sensor</title><link>https://gabrielcachadina.com/blog/bm612/</link><pubDate>Sun, 22 Mar 2026 00:00:00 +0000</pubDate><author>gabrielcachadina@protonmail.com (Gabriel Cachadiña)</author><guid>https://gabrielcachadina.com/blog/bm612/</guid><description>&lt;p&gt;I am currently working on a project with the BM612 sensor, which is an infrared detection sensor commonly used for human presence detection. Since I could not find a concise guide on its functionalities, I decided to create one myself. This information is based on its &lt;a href="https://akizukidenshi.com/goodsaffix/BM612.pdf"&gt;datasheet&lt;/a&gt; and the &lt;a href="https://www.codrey.com/electronics/mh-sr602-pir-motion-sensor-guide/"&gt;SR602 module&lt;/a&gt;, which integrates the BM612 onto a small PCB.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://gabrielcachadina.com/BM612.png" alt="BM612"&gt;&lt;/p&gt;
&lt;h1 id="pins"&gt;PINS&lt;/h1&gt;
&lt;p&gt;The BM612 has 6 pins. Below is a brief description of their functions.&lt;/p&gt;</description><content:encoded><![CDATA[<p>I am currently working on a project with the BM612 sensor, which is an infrared detection sensor commonly used for human presence detection. Since I could not find a concise guide on its functionalities, I decided to create one myself. This information is based on its <a href="https://akizukidenshi.com/goodsaffix/BM612.pdf">datasheet</a> and the <a href="https://www.codrey.com/electronics/mh-sr602-pir-motion-sensor-guide/">SR602 module</a>, which integrates the BM612 onto a small PCB.</p>
<p><img src="/BM612.png" alt="BM612"></p>
<h1 id="pins">PINS</h1>
<p>The BM612 has 6 pins. Below is a brief description of their functions.</p>
<p><img src="/BM612-Schematic.png" alt="BM612-Schematic"></p>
<h2 id="power-supply">Power Supply</h2>
<p>The device should be powered with a voltage between $2.2V$ and $3.7V$, drawing a current no higher than $11\mu A$. Power is supplied between the &ldquo;VDD&rdquo; and &ldquo;GND&rdquo; pins.</p>
<h2 id="outputs">Outputs</h2>
<h3 id="detection">Detection</h3>
<p>The system has a &ldquo;REL&rdquo; pin, which goes high whenever the sensor&rsquo;s sensitivity threshold is exceeded. When this occurs, the &ldquo;REL&rdquo; pin will stay high for the duration configured in the device, as long as no further detection occurs.</p>
<h3 id="output-enable">Output Enable</h3>
<p>The &ldquo;OEN&rdquo; pin is undocumented, but context suggests it is an &ldquo;Output Enable.&rdquo; If you want to disable the &ldquo;REL&rdquo; signal, you can connect &ldquo;OEN&rdquo; to ground. To allow normal operation, connect it to $V_{DD}$.</p>
<p>According to the datasheet, a voltage above $1.2V$ is considered a guaranteed high, and below $0.8V$ is considered a guaranteed low.</p>
<h2 id="inputs">Inputs</h2>
<h3 id="sensitivity">Sensitivity</h3>
<p>The detection sensitivity is controlled via the &ldquo;SENS&rdquo; pin. This determines the detection ratio, comparing active vs. inactive infrared cells.</p>
<p>To set the sensitivity, a voltage is applied to the &ldquo;SENS&rdquo; pin: maximum sensitivity occurs at $0V$, and minimum sensitivity at $V_{DD}/2$ or higher. In other words, connect &ldquo;SENS&rdquo; to ground to detect almost any presence, or use a voltage above $V_{DD}/2$ for stricter detection.</p>
<h3 id="detection-time">Detection Time</h3>
<p>The detection time sets how long the &ldquo;REL&rdquo; pin remains active—effectively acting as a memory of a detection.</p>
<p>You can configure the detection time using the &ldquo;ON_TIME&rdquo; pin in two ways:</p>
<h4 id="analog">Analog</h4>
<p>The &ldquo;ON_TIME&rdquo; pin generates an oscillation that determines how long &ldquo;REL&rdquo; stays active. The delay is calculated using the formula:</p>
<p>$$T_d = \frac{230400}{f}$$</p>
<p>A resistor and capacitor are used to set this timing: the larger the RC pair, the longer &ldquo;REL&rdquo; stays high. The datasheet provides tables showing the active durations.</p>
<h4 id="digital">Digital</h4>
<p>Alternatively, the duration of &ldquo;REL&rdquo; can be set by applying a constant voltage to &ldquo;ON_TIME&rdquo;: ground for minimum time, up to $V_{DD}/2$ for the maximum time (3600s). The datasheet’s section 4.2 provides tables for the corresponding resistor configurations.</p>
<h1 id="example-circuit">Example Circuit</h1>
<p>The diagram shows an example circuit with the following conditions:</p>
<ul>
<li>Power supply: $3.3V$</li>
<li>Sensitivity: connected to ground for maximum sensitivity</li>
<li>Pulse duration: maximum (3600s), with voltage near $V_{DD}/2$</li>
<li>Sensor always active: &ldquo;OEN&rdquo; at $3.3V$</li>
<li>Sensor output: read by a microcontroller</li>
</ul>
<p><img src="/BM612-Example.png" alt="BM612-Example"></p>
]]></content:encoded></item><item><title>Web Interface for Storing Non-Volatile Variables on an ESP32</title><link>https://gabrielcachadina.com/blog/webinterfaceinesp32/</link><pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate><author>gabrielcachadina@protonmail.com (Gabriel Cachadiña)</author><guid>https://gabrielcachadina.com/blog/webinterfaceinesp32/</guid><description>&lt;p&gt;I am currently working on a project using the &lt;a href="https://documentation.espressif.com/esp32-c3_datasheet_en.html"&gt;ESP32-C3&lt;/a&gt; chip that needs to connect to a Wi-Fi access point using its integrated antenna and send a set of data through the &lt;a href="https://mqtt.org/"&gt;MQTT&lt;/a&gt; protocol. To achieve this, I initially stored the access point username and password in several global variables used by the &lt;a href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/network/esp_wifi.html"&gt;&lt;code&gt;esp_wifi.h&lt;/code&gt;&lt;/a&gt; library. This is a valid solution if we do not expect this information to ever change.&lt;/p&gt;
&lt;p&gt;However, for my project I need a solution that:&lt;/p&gt;</description><content:encoded><![CDATA[<p>I am currently working on a project using the <a href="https://documentation.espressif.com/esp32-c3_datasheet_en.html">ESP32-C3</a> chip that needs to connect to a Wi-Fi access point using its integrated antenna and send a set of data through the <a href="https://mqtt.org/">MQTT</a> protocol. To achieve this, I initially stored the access point username and password in several global variables used by the <a href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/network/esp_wifi.html"><code>esp_wifi.h</code></a> library. This is a valid solution if we do not expect this information to ever change.</p>
<p>However, for my project I need a solution that:</p>
<ol>
<li>Allows these variables to be changed while the code is running.</li>
<li>Lets the user modify them without recompiling the firmware.</li>
<li>Stores them in non-volatile memory so that, in case of a power loss, the information remains in the controller.</li>
</ol>
<p>In this post I describe my solution to these problems, also reviewing alternatives that could be equally valid depending on the reader’s requirements.</p>
<h1 id="communication-interface">Communication Interface</h1>
<p>As mentioned earlier, in my case the Wi-Fi connection parameters must be configurable so the device can operate in any installation environment. The first step is to consider how the user will interact with our device. The main interfaces provided by the chip are:</p>
<ul>
<li>
<p><strong>Physical connection</strong>: If the user has direct access to the device, it could be configured through a serial terminal or a utility such as <a href="https://putty.org/index.html">PuTTY</a>.</p>
</li>
<li>
<p><strong>Remote connection</strong>: The ESP32-C3 provides several interfaces:</p>
<ul>
<li><strong>Bluetooth</strong>: By enabling the Bluetooth interface, information could be sent using applications such as <a href="https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&amp;hl=en-US">Serial Bluetooth Terminal</a>.</li>
<li><strong>Wi-Fi</strong>: This offers two possible approaches:
<ul>
<li>Connecting to an existing Wi-Fi network, which is exactly what we ultimately want but may fail if credentials are not yet configured.</li>
<li>Creating a <strong>Hotspot</strong>, that is, an access point that another device can connect to in order to interact with the ESP32.</li>
</ul>
</li>
<li><strong>Zigbee</strong>: This would require the user to have a Zigbee coordinator in order to communicate directly with the device.</li>
</ul>
</li>
</ul>
<p>After considering these alternatives, I decided to use a <strong>Hotspot</strong>, since—unlike the other solutions—it does not require any additional hardware or software (cables, programs, or external devices). It allows the variables to be modified using only a Wi-Fi capable device such as a smartphone.</p>
<h2 id="implementation">Implementation</h2>
<p>Once the communication channel has been chosen, we must determine <strong>how</strong> the data will be sent to the device. A technical approach would be to send an HTTP request with a POST containing the desired information. However, this is not an easy solution to explain to a non-technical user. For this reason, I decided that the ESP32 itself should host a small web page where the variables can be configured.</p>
<p>This solution will work as follows:</p>
<h3 id="hotspot">HotSpot</h3>
<p>First, we start the access point:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">//              Access Point
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="nf">wifi_init_softap</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="nf">esp_netif_create_default_wifi_ap</span><span class="p">();</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="kt">wifi_init_config_t</span> <span class="n">cfg</span> <span class="o">=</span> <span class="nf">WIFI_INIT_CONFIG_DEFAULT</span><span class="p">();</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="nf">ESP_ERROR_CHECK</span><span class="p">(</span><span class="nf">esp_wifi_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">cfg</span><span class="p">));</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="kt">wifi_config_t</span> <span class="n">wifi_config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="p">.</span><span class="n">ap</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">            <span class="p">.</span><span class="n">ssid</span> <span class="o">=</span> <span class="n">WIFI_SSID_AP</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">            <span class="p">.</span><span class="n">ssid_len</span> <span class="o">=</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">WIFI_SSID_AP</span><span class="p">),</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">            <span class="p">.</span><span class="n">channel</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">            <span class="p">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">WIFI_PASS_AP</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">            <span class="p">.</span><span class="n">max_connection</span> <span class="o">=</span> <span class="n">MAX_STA_CONN</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">            <span class="p">.</span><span class="n">authmode</span> <span class="o">=</span> <span class="n">WIFI_AUTH_WPA_WPA2_PSK</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">strlen</span><span class="p">(</span><span class="n">WIFI_PASS_AP</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">        <span class="n">wifi_config</span><span class="p">.</span><span class="n">ap</span><span class="p">.</span><span class="n">authmode</span> <span class="o">=</span> <span class="n">WIFI_AUTH_OPEN</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl">    <span class="nf">ESP_ERROR_CHECK</span><span class="p">(</span><span class="nf">esp_wifi_set_mode</span><span class="p">(</span><span class="n">WIFI_MODE_AP</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="nf">ESP_ERROR_CHECK</span><span class="p">(</span><span class="nf">esp_wifi_set_config</span><span class="p">(</span><span class="n">WIFI_IF_AP</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">wifi_config</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="nf">ESP_ERROR_CHECK</span><span class="p">(</span><span class="nf">esp_wifi_start</span><span class="p">());</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="nf">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;WiFi AP started. SSID=&#39;%s&#39;, IP=192.168.4.1&#34;</span><span class="p">,</span> <span class="n">WIFI_SSID_AP</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h3 id="web-pages">Web Pages</h3>
<p>Next, we create the web server, which will provide two pages, the credentials configuration page and the page responsible for saving them.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">//              WebServer
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span><span class="kt">httpd_handle_t</span> <span class="nf">start_webserver</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="kt">httpd_config_t</span> <span class="n">config</span> <span class="o">=</span> <span class="nf">HTTPD_DEFAULT_CONFIG</span><span class="p">();</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    <span class="kt">httpd_handle_t</span> <span class="n">server</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">httpd_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">server</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">config</span><span class="p">)</span> <span class="o">==</span> <span class="n">ESP_OK</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">        <span class="nf">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;HTTP server started&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="kt">httpd_uri_t</span> <span class="n">root</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">            <span class="p">.</span><span class="n">uri</span>      <span class="o">=</span> <span class="s">&#34;/&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">            <span class="p">.</span><span class="n">method</span>   <span class="o">=</span> <span class="n">HTTP_GET</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">            <span class="p">.</span><span class="n">handler</span>  <span class="o">=</span> <span class="n">root_get_handler</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">            <span class="p">.</span><span class="n">user_ctx</span> <span class="o">=</span> <span class="nb">NULL</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="nf">httpd_register_uri_handler</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">root</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">        <span class="kt">httpd_uri_t</span> <span class="n">submit</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">            <span class="p">.</span><span class="n">uri</span>      <span class="o">=</span> <span class="s">&#34;/submit&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">            <span class="p">.</span><span class="n">method</span>   <span class="o">=</span> <span class="n">HTTP_POST</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">            <span class="p">.</span><span class="n">handler</span>  <span class="o">=</span> <span class="n">submit_post_handler</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">            <span class="p">.</span><span class="n">user_ctx</span> <span class="o">=</span> <span class="nb">NULL</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">        <span class="p">};</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">        <span class="nf">httpd_register_uri_handler</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">submit</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">        <span class="nf">ESP_LOGE</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;Failed to start HTTP server&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">    <span class="k">return</span> <span class="n">server</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h4 id="credentials-page">Credentials Page</h4>
<p>This page is where the Wi-Fi credentials will be entered.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">//              HTML Website
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">char</span> <span class="n">html_page</span><span class="p">[</span><span class="mi">512</span><span class="p">];</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">build_html_page</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">current_ssid</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">current_pass</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="nf">snprintf</span><span class="p">(</span><span class="n">html_page</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">html_page</span><span class="p">),</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">        <span class="s">&#34;&lt;!DOCTYPE html&gt;&#34;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        <span class="s">&#34;&lt;html&gt;&#34;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">        <span class="s">&#34;&lt;head&gt;&lt;title&gt;ESP32 Config&lt;/title&gt;&lt;/head&gt;&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">        <span class="s">&#34;&lt;body&gt;&#34;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">        <span class="s">&#34;&lt;h2&gt;ESP32 Configuration Portal&lt;/h2&gt;&#34;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">        <span class="s">&#34;&lt;p&gt;Current Wi-Fi:&lt;/p&gt;&#34;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">        <span class="s">&#34;&lt;ul&gt;&lt;li&gt;SSID: %s&lt;/li&gt;&lt;li&gt;Password: %s&lt;/li&gt;&lt;/ul&gt;&#34;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">        <span class="s">&#34;&lt;form method=</span><span class="se">\&#34;</span><span class="s">POST</span><span class="se">\&#34;</span><span class="s"> action=</span><span class="se">\&#34;</span><span class="s">/submit</span><span class="se">\&#34;</span><span class="s">&gt;&#34;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="s">&#34;New SSID:&lt;br&gt;&#34;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">        <span class="s">&#34;&lt;input type=</span><span class="se">\&#34;</span><span class="s">text</span><span class="se">\&#34;</span><span class="s"> name=</span><span class="se">\&#34;</span><span class="s">ssid</span><span class="se">\&#34;</span><span class="s">&gt;&lt;br&gt;&lt;br&gt;&#34;</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">        <span class="s">&#34;New Password:&lt;br&gt;&#34;</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">        <span class="s">&#34;&lt;input type=</span><span class="se">\&#34;</span><span class="s">password</span><span class="se">\&#34;</span><span class="s"> name=</span><span class="se">\&#34;</span><span class="s">password</span><span class="se">\&#34;</span><span class="s">&gt;&lt;br&gt;&lt;br&gt;&#34;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">        <span class="s">&#34;&lt;input type=</span><span class="se">\&#34;</span><span class="s">submit</span><span class="se">\&#34;</span><span class="s"> value=</span><span class="se">\&#34;</span><span class="s">Save</span><span class="se">\&#34;</span><span class="s">&gt;&#34;</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">        <span class="s">&#34;&lt;/form&gt;&#34;</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">        <span class="s">&#34;&lt;/body&gt;&#34;</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">        <span class="s">&#34;&lt;/html&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">        <span class="n">current_ssid</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">?</span> <span class="nl">current_ssid</span> <span class="p">:</span> <span class="s">&#34;Not set&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">        <span class="n">current_pass</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">?</span> <span class="nl">current_pass</span> <span class="p">:</span> <span class="s">&#34;Not set&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="c1">//              HTTP Handlers
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="c1"></span><span class="k">static</span> <span class="kt">esp_err_t</span> <span class="nf">root_get_handler</span><span class="p">(</span><span class="kt">httpd_req_t</span> <span class="o">*</span><span class="n">req</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">33</span><span class="cl">    <span class="kt">char</span> <span class="n">ssid</span><span class="p">[</span><span class="mi">32</span><span class="p">],</span> <span class="n">password</span><span class="p">[</span><span class="mi">64</span><span class="p">];</span>
</span></span><span class="line"><span class="ln">34</span><span class="cl">    <span class="nf">load_saved_wifi</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">ssid</span><span class="p">),</span> <span class="n">password</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">password</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">35</span><span class="cl">
</span></span><span class="line"><span class="ln">36</span><span class="cl">    <span class="c1">// Print to serial
</span></span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="c1"></span>    <span class="nf">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;Current Wi-Fi: SSID=&#39;%s&#39;, PASSWORD=&#39;%s&#39;&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">38</span><span class="cl">
</span></span><span class="line"><span class="ln">39</span><span class="cl">    <span class="nf">build_html_page</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">40</span><span class="cl">
</span></span><span class="line"><span class="ln">41</span><span class="cl">    <span class="nf">httpd_resp_set_type</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="s">&#34;text/html&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">42</span><span class="cl">    <span class="nf">httpd_resp_send</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">html_page</span><span class="p">,</span> <span class="nf">strlen</span><span class="p">(</span><span class="n">html_page</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">43</span><span class="cl">    <span class="k">return</span> <span class="n">ESP_OK</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h4 id="storage-page">Storage Page</h4>
<p>This page executes the function responsible for storing the variables in the desired way. In this case, they will be saved in NVS memory, which will be explained later.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="k">static</span> <span class="kt">esp_err_t</span> <span class="nf">submit_post_handler</span><span class="p">(</span><span class="kt">httpd_req_t</span> <span class="o">*</span><span class="n">req</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="kt">char</span> <span class="n">content</span><span class="p">[</span><span class="mi">200</span><span class="p">];</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="nf">httpd_req_recv</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">content</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>  <span class="c1">// Get data from the last page
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">ret</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">        <span class="nf">httpd_resp_send_err</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">HTTPD_500_INTERNAL_SERVER_ERROR</span><span class="p">,</span> <span class="s">&#34;Failed to receive POST data&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        <span class="k">return</span> <span class="n">ESP_FAIL</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="n">content</span><span class="p">[</span><span class="n">ret</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39;\0&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="c1">// Parse form &#34;ssid=&lt;ssid&gt;&amp;password=&lt;pass&gt;&#34;
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span>    <span class="kt">char</span> <span class="n">ssid</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="kt">char</span> <span class="n">password</span><span class="p">[</span><span class="mi">64</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">    <span class="nf">sscanf</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="s">&#34;ssid=%31[^&amp;]&amp;password=%63s&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">ssid</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="n">ssid</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;+&#39;</span><span class="p">)</span> <span class="n">ssid</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">password</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="n">password</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;+&#39;</span><span class="p">)</span> <span class="n">password</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="sc">&#39; &#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="c1">// Save to NVS and print
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>    <span class="nf">save_wifi_credentials</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">    <span class="c1">// Confirmation page
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c1"></span>    <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="n">response</span> <span class="o">=</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">        <span class="s">&#34;&lt;html&gt;&lt;body&gt;&#34;</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">        <span class="s">&#34;&lt;h3&gt;Credentials Saved!&lt;/h3&gt;&#34;</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">        <span class="s">&#34;&lt;a href=</span><span class="se">\&#34;</span><span class="s">/</span><span class="se">\&#34;</span><span class="s">&gt;Go Back&lt;/a&gt;&#34;</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">        <span class="s">&#34;&lt;/body&gt;&lt;/html&gt;&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl">    <span class="nf">httpd_resp_sendstr</span><span class="p">(</span><span class="n">req</span><span class="p">,</span> <span class="n">response</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl">    <span class="k">return</span> <span class="n">ESP_OK</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h1 id="permanent-storage">Permanent Storage</h1>
<p>At this point we have a solution that can obtain the data entered by a user through a web interface. But how do we store this data? Using a variable that we pass between different functions could be a possible solution, but it would not survive an ESP restart, which would cause the information stored in memory to be lost.</p>
<p>For this reason, I decided to store the variables entered through the web interface in <strong>non-volatile memory</strong>, specifically the <a href="https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/storage/nvs_flash.html">NVS</a> memory. This memory resides in the ESP32’s flash and persists across system restarts.</p>
<p>To accomplish this, we will create two functions: one to read data from NVS memory and another to store new data.</p>
<h2 id="reading-from-nvs-memory">Reading from NVS Memory</h2>
<p>First, we implement a function responsible for reading the non-volatile memory to check whether variables are already stored inside the <code>wifi_creds</code> namespace. If no stored values are found, I considered it a good approach to return default values.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">load_saved_wifi</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">ssid</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">ssid_len</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pass</span><span class="p">,</span> <span class="kt">size_t</span> <span class="n">pass_len</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="kt">nvs_handle_t</span> <span class="n">nvs_handle</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="kt">esp_err_t</span> <span class="n">err</span> <span class="o">=</span> <span class="nf">nvs_open</span><span class="p">(</span><span class="s">&#34;wifi_creds&#34;</span><span class="p">,</span> <span class="n">NVS_READONLY</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">nvs_handle</span><span class="p">);</span>  <span class="c1">// Open non-volatile storage with a given namespace from the default NVS partition
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">err</span> <span class="o">==</span> <span class="n">ESP_OK</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Namespace Exists
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>        <span class="kt">size_t</span> <span class="n">required_size</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        <span class="n">required_size</span> <span class="o">=</span> <span class="n">ssid_len</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="nf">nvs_get_str</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">,</span> <span class="s">&#34;ssid&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">required_size</span><span class="p">)</span> <span class="o">!=</span> <span class="n">ESP_OK</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Get string value for given key
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>            <span class="nf">strncpy</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">WIFI_SSID</span><span class="p">,</span> <span class="n">ssid_len</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">        <span class="n">required_size</span> <span class="o">=</span> <span class="n">pass_len</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="nf">nvs_get_str</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">,</span> <span class="s">&#34;password&#34;</span><span class="p">,</span> <span class="n">pass</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">required_size</span><span class="p">)</span> <span class="o">!=</span> <span class="n">ESP_OK</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// Get string value for given key
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>            <span class="nf">strncpy</span><span class="p">(</span><span class="n">pass</span><span class="p">,</span> <span class="n">WIFI_PASSWORD</span><span class="p">,</span> <span class="n">pass_len</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">        <span class="nf">nvs_close</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">        <span class="c1">// If namespace does not exist
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span>        <span class="c1">// Set Default values as a constant
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1"></span>        <span class="nf">strncpy</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">WIFI_SSID</span><span class="p">,</span> <span class="n">ssid_len</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">        <span class="nf">strncpy</span><span class="p">(</span><span class="n">pass</span><span class="p">,</span> <span class="n">WIFI_PASSWORD</span><span class="p">,</span> <span class="n">pass_len</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="nf">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;Using -&gt; SSID=&#39;%s&#39;, PASS=&#39;%s&#39;&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">,</span> <span class="n">pass</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h2 id="writing-to-nvs-memory">Writing to NVS Memory</h2>
<p>On the other hand, when these variables need to be modified, we access the same memory region and store the new values.</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="k">static</span> <span class="kt">void</span> <span class="nf">save_wifi_credentials</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">ssid</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">pass</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    <span class="kt">nvs_handle_t</span> <span class="n">nvs_handle</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nf">nvs_open</span><span class="p">(</span><span class="s">&#34;wifi_creds&#34;</span><span class="p">,</span> <span class="n">NVS_READWRITE</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">nvs_handle</span><span class="p">)</span> <span class="o">==</span> <span class="n">ESP_OK</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">        <span class="nf">nvs_set_str</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">,</span> <span class="s">&#34;ssid&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">        <span class="nf">nvs_set_str</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">,</span> <span class="s">&#34;password&#34;</span><span class="p">,</span> <span class="n">pass</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        <span class="nf">nvs_commit</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">        <span class="nf">nvs_close</span><span class="p">(</span><span class="n">nvs_handle</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">        <span class="nf">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span> <span class="s">&#34;Saved credentials to NVS: SSID=&#39;%s&#39;, PASS=&#39;%s&#39;&#34;</span><span class="p">,</span> <span class="n">ssid</span><span class="p">,</span> <span class="n">pass</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="p">}</span></span></span></code></pre></div><h1 id="conclusion">Conclusion</h1>
<p>It is important to note that the solution presented here includes several vulnerabilities that should be taken into account. First, there is a Wi-Fi access point that remains constantly open, which may represent a security risk. Any user who obtains the credentials could interact with the web interface and retrieve the credentials currently being used.</p>
<p>For this reason, I recommend using a GPIO configured as a <strong>jumper</strong> to enable or disable this feature. An example of such a configuration would be:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="ln"> 1</span><span class="cl">    <span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span>    <span class="c1">//              HotSpot
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>    <span class="c1">// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span>    <span class="c1">// Initialize NVS
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>    <span class="nf">ESP_ERROR_CHECK</span><span class="p">(</span><span class="nf">nvs_flash_init</span><span class="p">());</span>                <span class="c1">// Initialize the default NVS partition and check for errors
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    <span class="c1">// Jumper that defines if the Hotspot should be active
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>    <span class="kt">gpio_config_t</span> <span class="n">io_conf</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">      <span class="p">.</span><span class="n">pin_bit_mask</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1ULL</span> <span class="o">&lt;&lt;</span> <span class="n">HOTSPOT_PIN</span><span class="p">),</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">      <span class="p">.</span><span class="n">mode</span> <span class="o">=</span> <span class="n">GPIO_MODE_INPUT</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">      <span class="p">.</span><span class="n">pull_up_en</span> <span class="o">=</span> <span class="n">GPIO_PULLUP_ENABLE</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">      <span class="p">.</span><span class="n">pull_down_en</span> <span class="o">=</span> <span class="n">GPIO_PULLDOWN_DISABLE</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">      <span class="p">.</span><span class="n">intr_type</span> <span class="o">=</span> <span class="n">GPIO_INTR_DISABLE</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">    <span class="nf">gpio_config</span><span class="p">(</span><span class="o">&amp;</span><span class="n">io_conf</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="kt">int</span> <span class="n">jumper_hotspot</span> <span class="o">=</span> <span class="nf">gpio_get_level</span><span class="p">(</span><span class="n">HOTSPOT_PIN</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">jumper_hotspot</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="c1">//Check if the jumper cable is active
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>        <span class="nf">wifi_init_softap</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">        <span class="nf">start_webserver</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">        <span class="k">while</span> <span class="p">(</span><span class="nf">gpio_get_level</span><span class="p">(</span><span class="n">HOTSPOT_PIN</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">            <span class="nf">vTaskDelay</span><span class="p">(</span><span class="nf">pdMS_TO_TICKS</span><span class="p">(</span><span class="mi">100</span><span class="p">));</span> <span class="c1">// Keep the code here while the user changes the nvs memory
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="c1"></span>        <span class="p">}</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">        <span class="c1">// If jumper removed → reboot cleanly
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="c1"></span>        <span class="nf">esp_restart</span><span class="p">();</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl">    <span class="p">}</span></span></span></code></pre></div><p>In addition to this, the ESP32 firmware is currently not encrypted, meaning that any user could read the device’s memory and extract its functionality or obtain stored credentials. The ESP’s flash memory can be encrypted for these types of scenarios, but that process will not be covered in this post.</p>
<p>With this approach, you now have a solution that allows a non-technical user to configure variables stored in an ESP32’s memory while ensuring that the data remains persistent.</p>
<p>Below is a diagram of the system that uses all the functions described above. When the device successfully connects to the Wi-Fi access point, it performs a sequence of actions until entering Deep Sleep (essentially a controlled restart).</p>
<p><img src="/esphotspotnvs.svg" alt="esphotspotnvs"></p>
]]></content:encoded></item></channel></rss>