<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ESP8266 Tutorial | Microcontroller Tutorials</title>
	<atom:link href="https://www.teachmemicro.com/category/tutorials/esp8266-tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.teachmemicro.com/category/tutorials/esp8266-tutorial/</link>
	<description>Microcontroller Tutorials and Resources</description>
	<lastBuildDate>Sun, 28 Jun 2026 01:15:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.3</generator>

<image>
	<url>https://www.teachmemicro.com/wp-content/uploads/2019/04/blue-icon-65x65.png</url>
	<title>ESP8266 Tutorial | Microcontroller Tutorials</title>
	<link>https://www.teachmemicro.com/category/tutorials/esp8266-tutorial/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How To Use an ESP8266 WiFi Relay Board</title>
		<link>https://www.teachmemicro.com/how-to-use-an-esp8266-wifi-relay-board/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-use-an-esp8266-wifi-relay-board</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Tue, 16 Dec 2025 01:00:01 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=10191</guid>

					<description><![CDATA[<p>If you’re looking for a simple but powerful way to control AC or DC devices over Wi‑Fi, the ESP8266 relay board is one of the best places to start. I’ve used ESP8266‑based boards in many hobby and semi‑professional projects, and relay boards are usually the first real‑world application people build. In this tutorial, I’ll walk you through exactly how I use &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/how-to-use-an-esp8266-wifi-relay-board/">How To Use an ESP8266 WiFi Relay Board</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you’re looking for a <strong>simple but powerful way to control AC or DC devices over Wi‑Fi</strong>, the <strong>ESP8266 relay board</strong> is one of the best places to start. I’ve used ESP8266‑based boards in many hobby and semi‑professional projects, and relay boards are usually the first <em>real‑world</em> application people build.</p>
<p dir="auto" data-line="2"><span id="more-10191"></span></p>
<p>In this tutorial, I’ll walk you through <strong>exactly how I use an ESP8266 relay board</strong>, from understanding the hardware to writing the firmware and controlling a relay over Wi‑Fi. This is written as if I’m personally guiding you through the process.</p>
<hr />
<h3 id="what-is-an-esp8266-relay-board"><strong>What Is an ESP8266 Relay Board?</strong></h3>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-back.avif"><img data-dominant-color="c1ccbd" data-has-transparency="false" style="--dominant-color: #c1ccbd;" loading="lazy" decoding="async" class="aligncenter size-full wp-image-10195 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-back.avif" alt="" width="972" height="626" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-back.avif 972w, https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-back-300x193.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-back-768x495.avif 768w" sizes="auto, (max-width: 972px) 100vw, 972px" /></a></p>
<p>An <strong>ESP8266 relay board</strong> combines two things on one PCB:</p>
<ul>
<li><strong>ESP8266 Wi‑Fi microcontroller</strong> (usually ESP‑12 / ESP‑12F)</li>
<li><strong>One or more mechanical relays</strong> for switching higher‑voltage or higher‑current loads</li>
</ul>
<p>Because the ESP8266 has built‑in Wi‑Fi, the relay can be controlled:</p>
<ul>
<li>From a web browser</li>
<li>From a phone app</li>
<li>From another server or IoT platform</li>
</ul>
<p>This makes it perfect for:</p>
<ul>
<li>Home automation</li>
<li>Smart switches</li>
<li>Remote power control</li>
<li>IoT experiments</li>
</ul>
<hr />
<h3 id="typical-esp8266-1-channel-relay-board-features"><strong>Typical ESP8266 1-Channel Relay Board Features</strong></h3>
<p>This guide is specifically written for a <strong>1-channel ESP8266 relay board</strong>, which is the most common and beginner-friendly version.<a href="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-top-with-labels.avif"><img data-dominant-color="7f9d91" data-has-transparency="false" style="--dominant-color: #7f9d91;" loading="lazy" decoding="async" class="aligncenter size-full wp-image-10196 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-top-with-labels.avif" alt="esp8266-relay-module-top-with-labels" width="771" height="460" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-top-with-labels.avif 771w, https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-top-with-labels-300x179.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/12/esp8266-relay-module-top-with-labels-768x458.avif 768w" sizes="auto, (max-width: 771px) 100vw, 771px" /></a></p>
<ul>
<li>A: 7-30V+ DC power supply</li>
<li>B: Power supply ground</li>
<li dir="auto" data-line="38">C: ESP8266 Serial Port (Used to program the ESP8266)</li>
<li dir="auto" data-line="38">D: ESP8266 Boot Select</li>
<li>E: Normally closed (NC) relay contact</li>
<li>F: Common (COM) relay contact</li>
<li>G: Normally open (NO) relay contact</li>
<li>H: 5V+ out</li>
<li>I: ESP8266 GPIO5 Optocoupler Input</li>
<li>J: Ground (isolated optocoupler input)</li>
</ul>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Important:</strong> Even though the ESP8266 runs at 3.3V, the relay side may switch <strong>110V / 220V AC</strong>.</p>
<hr />
<h3 id="understanding-the-relay-terminals-very-important"><strong>Understanding the Relay Terminals (Very Important)</strong></h3>
<p>Each relay has three main terminals:</p>
<ul>
<li><strong>COM (Common)</strong> – the moving contact</li>
<li><strong>NO (Normally Open)</strong> – disconnected when relay is OFF</li>
<li><strong>NC (Normally Closed)</strong> – connected when relay is OFF</li>
</ul>
<h4 id="how-i-usually-wire-it"><strong>How I usually wire it</strong></h4>
<ul>
<li>For devices that should be <strong>OFF by default</strong> → I use <strong>COM + NO</strong></li>
<li>For devices that should be <strong>ON by default</strong> → I use <strong>COM + NC</strong></li>
</ul>
<hr />
<h3 id="powering-the-esp8266-relay-board"><strong>Powering the ESP8266 Relay Board</strong></h3>
<p>This is where many beginners make mistakes.</p>
<h4 id="common-power-options"><strong>Common power options</strong></h4>
<ol>
<li><strong>5V via Micro‑USB</strong> (recommended if available)</li>
<li><strong>5V to VIN pin</strong></li>
<li><strong>External regulated 5V supply</strong></li>
</ol>
<p>The onboard regulator converts 5V → 3.3V for the ESP8266.</p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I avoid powering relays from weak USB ports. Relays draw surge current when switching.</p>
<hr />
<h3 id="esp8266-gpio-pin-used-for-a-1-channel-relay"><strong>ESP8266 GPIO Pin Used for a 1-Channel Relay</strong></h3>
<p>On a <strong>1-channel relay board</strong>, only <strong>one GPIO</strong> is used to control the relay.</p>
<p>Before coding, I always:</p>
<ul>
<li>Check the <strong>board schematic or silkscreen</strong></li>
<li>Test the relay manually with a simple sketch</li>
</ul>
<p>My board uses GPIO4 to control the relay. This is shown in the schematic:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/12/wifi_relay_sch.avif"><img data-dominant-color="f6f3ed" data-has-transparency="false" style="--dominant-color: #f6f3ed;" loading="lazy" decoding="async" class="aligncenter size-full wp-image-10194 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/12/wifi_relay_sch.avif" alt="WiFi ESP8266 Relay" width="803" height="450" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/12/wifi_relay_sch.avif 803w, https://www.teachmemicro.com/wp-content/uploads/2025/12/wifi_relay_sch-300x168.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/12/wifi_relay_sch-768x430.avif 768w" sizes="auto, (max-width: 803px) 100vw, 803px" /></a></p>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Some GPIOs affect boot mode (GPIO0, GPIO2, GPIO15). Using the wrong pin can prevent booting.</p>
<hr />
<h3 id="programming-the-esp8266-relay-board"><strong>Programming the ESP8266 Relay Board</strong></h3>
<h4 id="what-i-use"><strong>What I use</strong></h4>
<ul>
<li><strong>Arduino IDE</strong></li>
<li>ESP8266 Board Package</li>
<li>USB‑to‑Serial driver (CH340 or CP2102)</li>
</ul>
<h4 id="adding-esp8266-to-arduino-ide"><strong>Adding ESP8266 to Arduino IDE</strong></h4>
<ol>
<li>Open <strong>Arduino IDE</strong></li>
<li>Go to <strong>Preferences</strong></li>
<li>Add this URL to <em>Additional Boards Manager URLs</em>: <em>https://arduino.esp8266.com/stable/package_esp8266com_index.json</em></li>
<li>Install <strong>ESP8266 Boards</strong> from Boards Manager</li>
</ol>
<hr />
<h3 id="simple-relay-control-code-my-go%E2%80%91to-test-sketch"><strong>Simple Relay Control Code (My Go‑To Test Sketch)</strong></h3>
<p>This is the first sketch I upload to confirm the hardware works.</p>
<pre><code class="code-line language-cpp" dir="auto" data-line="128">#define RELAY_PIN 4  // change based on your board

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  digitalWrite(RELAY_PIN, LOW); // relay OFF (some boards are inverted)
}

void loop() {
  digitalWrite(RELAY_PIN, HIGH); // relay ON
  delay(2000);
  digitalWrite(RELAY_PIN, LOW);  // relay OFF
  delay(2000);
}
</code></pre>
<p>If the relay clicks every 2 seconds, your board is working.</p>
<hr />
<h3 id="relay-logic-normal-vs-inverted"><strong>Relay Logic: Normal vs Inverted</strong></h3>
<p>Many ESP8266 relay boards are <strong>active‑LOW</strong>, meaning:</p>
<ul>
<li>LOW → Relay ON</li>
<li>HIGH → Relay OFF</li>
</ul>
<p>If your relay behaves backward, simply invert the logic in software.</p>
<hr />
<h3 id="controlling-the-relay-via-wi%E2%80%91fi-web-server-example"><strong>Controlling the Relay via Wi‑Fi (Web Server Example)</strong></h3>
<p>This is where the ESP8266 really shines.</p>
<h4 id="what-i-usually-do"><strong>What I usually do</strong></h4>
<ul>
<li>Run a small HTTP server</li>
<li>Add <em>/on</em> and <em>/off</em> endpoints</li>
<li>Control the relay from any browser</li>
</ul>
<pre><code class="code-line language-cpp" dir="auto" data-line="169">#include &lt;ESP8266WiFi.h&gt;
#include &lt;ESP8266WebServer.h&gt;

const char* ssid     = "YOUR_WIFI";
const char* password = "YOUR_PASSWORD";

ESP8266WebServer server(80);

// Pin definitions
#define RELAY_PIN 4   // Relay control (active LOW)
#define OPTO_PIN  5   // Optocoupler input (INPUT_PULLUP)

// State tracking
volatile bool relayState = false;
volatile bool optoState  = false;

// -------------------- Relay handlers --------------------

void handleOn() {
  relayState = true;
  digitalWrite(RELAY_PIN, LOW);   // active LOW
  server.send(200, "text/plain", "Relay ON");
}

void handleOff() {
  relayState = false;
  digitalWrite(RELAY_PIN, HIGH);
  server.send(200, "text/plain", "Relay OFF");
}

// -------------------- Optocoupler handler --------------------

bool readOptoDebounced() {
  // Read optocoupler (normally HIGH, pulled LOW when active)
  if (digitalRead(OPTO_PIN) == LOW) {
    delay(20); // debounce
    if (digitalRead(OPTO_PIN) == LOW) {
      return true;   // opto active
    }
  }
  return false;      // opto inactive
}

void handleInput() {
  optoState = readOptoDebounced();

  if (optoState) {
    server.send(200, "text/plain", "Opto INPUT: ON");
  } else {
    server.send(200, "text/plain", "Opto INPUT: OFF");
  }
}

// -------------------- Setup --------------------

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(OPTO_PIN, INPUT_PULLUP);

  // Relay OFF at boot (safe default)
  digitalWrite(RELAY_PIN, HIGH);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  // HTTP endpoints
  server.on("/on", handleOn);
  server.on("/off", handleOff);
  server.on("/input", handleInput);

  server.begin();
}

// -------------------- Main loop --------------------

void loop() {
  server.handleClient();
}
</code></pre>
<p>Now I can control the relay by opening:</p>
<ul>
<li><em>http://ESP_IP/on</em></li>
<li><em>http://ESP_IP/off</em></li>
</ul>
<hr />
<h3 dir="auto" data-line="216">Additional Notes:</h3>
<ol>
<li>You must connect a separate and appropriate power supply independent of the USB‑to‑Serial programmer when programming. The USB‑to‑Serial programmer probably has insufficient power.</li>
<li>P5 connector (labeled D in the guide image above) is meant to be jumped together only during programming. When programming is complete, remove the jumper and reboot.</li>
<li>Connect your USB‑to‑Serial RX to P6 (labeled C) TX, and USB‑to‑Serial TX to P6 RX, and USB‑to‑Serial ground to the ground.</li>
</ol>
<h3 id="common-problems-i-see-and-how-i-fix-them"><strong>Common Problems </strong></h3>
<h4 id="relay-clicks-randomly"><strong>Relay clicks randomly</strong></h4>
<ul>
<li>Power supply is weak</li>
<li>Add bulk capacitor (470µF–1000µF)</li>
</ul>
<h4 id="esp8266-keeps-rebooting"><strong>ESP8266 keeps rebooting</strong></h4>
<ul>
<li>Relay coil noise</li>
<li>Poor grounding</li>
<li>Use opto‑isolated relay board</li>
</ul>
<h4 id="board-wont-boot"><strong>Board won’t boot</strong></h4>
<ul>
<li>Wrong GPIO used</li>
<li>GPIO0 or GPIO2 held LOW at boot</li>
</ul>
<hr />
<h3 id="safety-notes-please-dont-skip-this"><strong>Safety Notes </strong></h3>
<p>When switching AC mains:</p>
<ul>
<li>Never touch the board while powered</li>
<li>Use proper enclosures</li>
<li>Keep high‑voltage and low‑voltage sides separated</li>
<li>If unsure, test with <strong>low‑voltage DC first</strong></li>
</ul>
<p>I always prototype with a 12V load before moving to AC.</p>
<hr />
<h3><strong>Home Assistant via REST (HTTP)</strong></h3>
<h4><strong>Relay as a Home Assistant switch</strong></h4>
<p>Add this to configuration.yaml:</p>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-yaml">switch:
  - platform: rest
    name: ESP8266 Relay
    resource: http://ESP_IP/on
    method: GET
    body_on: ""
    body_off: ""
    state_resource: http://ESP_IP/input
    is_on_template: "{{ value == 'Relay ON' }}"
</code></pre>
</div>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Limitation:</p>
<ul>
<li>REST switch <strong>does not automatically know the relay state</strong></li>
<li>Home Assistant assumes success if HTTP 200 is returned</li>
</ul>
<h4><strong>When this is OK</strong></h4>
<ul>
<li>Manual switching</li>
<li>Simple dashboards</li>
<li>No complex automations</li>
</ul>
<hr />
<h4><strong>Optocoupler input as a binary sensor</strong></h4>
<p>Add this:</p>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-yaml">
binary_sensor:
  - platform: rest
    name: ESP8266 Opto Input
    resource: http://ESP_IP/input
    scan_interval: 1
    value_template: &gt;
      {{ 'ON' in value }}
</code></pre>
</div>
</div>
<p>Now Home Assistant sees the optocoupler as:</p>
<ul>
<li>Door sensor</li>
<li>Button</li>
<li>External trigger</li>
<li>Dry contact</li>
</ul>
<p>This is <strong>very powerful</strong>.</p>
<hr />
<h4><strong>Automation example (opto → relay)</strong></h4>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<pre><pre><code class="language-cpp">automation:
  - alias: &quot;Opto turns relay ON&quot;
    trigger:
      - platform: state
        entity_id: binary_sensor.esp8266_opto_input
        to: &quot;on&quot;
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.esp8266_relay</code></pre></pre>
</div>
<hr />
<h4><strong>REST drawbacks </strong></h4>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No guaranteed state<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No retain<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Polling overhead<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Hard to scale</p>
<p>That’s why <strong>MQTT exists</strong>.</p>
<hr />
<h3><strong>Home Assistant via MQTT (recommended)</strong></h3>
<p>This is how <strong>commercial IoT devices</strong> do it.</p>
<hr />
<h4><strong>MQTT concept (simple view)</strong></h4>
<pre><code class="whitespace-pre!">
Home Assistant ──&#x25b6; MQTT ──&#x25b6; ESP8266
Home Assistant &#x25c0;─ MQTT &#x25c0;── ESP8266
</code></pre>
<ul>
<li>Commands and state are <strong>decoupled</strong></li>
<li>Works even if HA restarts</li>
<li>Instant updates (no polling)</li>
</ul>
<hr />
<h4><strong>MQTT topics for your device</strong></h4>
<p>I recommend this structure:</p>
<div class="TyagGW_tableContainer">
<div class="group TyagGW_tableWrapper flex w-fit flex-col-reverse" tabindex="-1">
<table class="w-fit min-w-(--thread-content-width)">
<thead>
<tr>
<th data-col-size="sm">Purpose</th>
<th data-col-size="sm">Topic</th>
</tr>
</thead>
<tbody>
<tr>
<td data-col-size="sm">Relay command</td>
<td data-col-size="sm">home/relay1/set</td>
</tr>
<tr>
<td data-col-size="sm">Relay state</td>
<td data-col-size="sm">home/relay1/state</td>
</tr>
<tr>
<td data-col-size="sm">Opto state</td>
<td data-col-size="sm">home/relay1/opto</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr />
<h4><strong>Home Assistant MQTT config</strong></h4>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<pre><pre><code class="language-cpp">mqtt:
  switch:
    - name: &quot;ESP8266 Relay&quot;
      command_topic: &quot;home/relay1/set&quot;
      state_topic: &quot;home/relay1/state&quot;
      payload_on: &quot;ON&quot;
      payload_off: &quot;OFF&quot;
      state_on: &quot;ON&quot;
      state_off: &quot;OFF&quot;
      retain: true

  binary_sensor:
    - name: &quot;ESP8266 Opto Input&quot;
      state_topic: &quot;home/relay1/opto&quot;
      payload_on: &quot;ON&quot;
      payload_off: &quot;OFF&quot;</code></pre></pre>
</div>
<p>Now:</p>
<ul>
<li>Relay state is <strong>authoritative</strong></li>
<li>Opto input is <strong>event-driven</strong></li>
</ul>
<hr />
<h4><strong>ESP8266 MQTT behavior (logic summary)</strong></h4>
<p>Your ESP8266 should:</p>
<h5><strong>On boot</strong></h5>
<ul>
<li>Publish relay state</li>
<li>Publish opto state</li>
</ul>
<h5><strong>On relay change</strong></h5>
<ul>
<li>Publish <pre><code class="language-cpp">home/relay1/state</code></pre></li>
</ul>
<h5><strong>On opto change</strong></h5>
<ul>
<li>Publish <pre><code class="language-cpp">home/relay1/opto</code></pre></li>
</ul>
<p>This eliminates guesswork.</p>
<hr />
<h3><strong>ESPHome (cleanest long-term option)</strong></h3>
<p>If you’re OK reflashing firmware, <strong>ESPHome is unbeatable</strong>.</p>
<hr />
<h4><strong>ESPHome YAML for your board</strong></h4>
<div class="contain-inline-size rounded-2xl corner-superellipse/1.1 relative bg-token-sidebar-surface-primary">
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-yaml">
esphome:
  name: esp8266_relay

esp8266:
  board: esp12e

wifi:
  ssid: "YOUR_WIFI"
  password: "YOUR_PASSWORD"

switch:
  - platform: gpio
    pin:
      number: GPIO4
      inverted: true
    name: "Relay"

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO5
      mode: INPUT_PULLUP
      inverted: true
    name: "Opto Input"
</code></pre>
</div>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Automatic HA discovery<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Proper state handling<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> OTA updates<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Debouncing support</p>
<hr />
<h3 id="final-thoughts"><strong>Final Thoughts</strong></h3>
<p>For a <strong>1-channel ESP8266 relay board</strong>, the workflow is simple:</p>
<ol>
<li>Verify relay GPIO and logic</li>
<li>Test with a basic blink sketch</li>
<li>Add Wi-Fi control</li>
<li>Integrate with Home Assistant</li>
</ol>
<p>This setup scales well, and I’ve used the same pattern for lights, pumps, fans, and power control.</p>
<p>The <strong>ESP8266 relay board</strong> is one of the fastest ways I know to go from <em>code</em> to <em>real‑world control</em>. With just a few lines of code, you can switch devices from anywhere on your network.</p>
</div>
<p>The post <a href="https://www.teachmemicro.com/how-to-use-an-esp8266-wifi-relay-board/">How To Use an ESP8266 WiFi Relay Board</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Use L298N Motor Driver with ESP8266</title>
		<link>https://www.teachmemicro.com/how-to-use-l298n-motor-driver-esp8266/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-use-l298n-motor-driver-esp8266</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Sat, 09 Nov 2024 01:00:17 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7053</guid>

					<description><![CDATA[<p>Controlling a DC motor with an ESP8266, L298N motor driver module, and Arduino Cloud provides a flexible and efficient way to automate motor control remotely. This tutorial will guide you through the setup, wiring, and code needed to achieve this. Components Needed ESP8266 (NodeMCU or D1 Mini recommended) L298N Motor Driver Module DC Motor (6V-12V) &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/how-to-use-l298n-motor-driver-esp8266/">How to Use L298N Motor Driver with ESP8266</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Controlling a DC motor with an ESP8266, L298N motor driver module, and Arduino Cloud provides a flexible and efficient way to automate motor control remotely. This tutorial will guide you through the setup, wiring, and code needed to achieve this.</p>
<p><span id="more-7053"></span></p>
<h3>Components Needed</h3>
<ol>
<li><strong>ESP8266</strong> (NodeMCU or D1 Mini recommended)</li>
<li><strong>L298N Motor Driver Module</strong></li>
<li><strong>DC Motor</strong> (6V-12V)</li>
<li><strong>External Power Supply</strong> (for the motor, such as a 9V battery or a suitable DC adapter)</li>
<li><strong>Jumper Wires</strong></li>
<li><strong>Arduino Cloud account</strong></li>
</ol>
<h3></h3>
<h3>Set Up Your Arduino Cloud Account</h3>
<ol>
<li>Go to <a href="https://cloud.arduino.cc/">Arduino Cloud</a> and sign in or create an account if you haven’t already.</li>
<li>Once logged in, create a new <strong>thing</strong> in Arduino Cloud, which represents your device.</li>
<li>Add variables for controlling the motor:
<ul>
<li><em>motorState</em> (type: Boolean) – to turn the motor ON or OFF</li>
<li><em>motorSpeed</em> (type: Integer, 0-100) – to control the speed of the motor</li>
</ul>
</li>
<li>Go to <strong>Devices</strong> &gt; <strong>Add Device</strong> and select <strong>Set up an ESP8266 device</strong>. Follow the instructions to add your ESP8266 to your Arduino Cloud account. This will link your ESP8266 to the variables in the <strong>thing</strong>.</li>
</ol>
<h3></h3>
<h3>Connect the ESP8266 to the L298N Motor Driver and DC Motor</h3>
<h4>L298N Motor Driver Pinout:</h4>
<ul>
<li><strong>IN1 and IN2</strong> control the direction of the motor.</li>
<li><strong>ENA</strong> controls the speed of the motor.</li>
<li><strong>GND and VCC</strong> provide power to the L298N module.</li>
<li><strong>OUT1 and OUT2</strong> connect to the motor terminals.</li>
</ul>
<h4>Wiring:</h4>
<ol>
<li>Connect the <strong>IN1</strong> and <strong>IN2</strong> pins on the L298N to <strong>D1</strong> and <strong>D2</strong> pins on the ESP8266.</li>
<li>Connect the <strong>ENA</strong> pin on the L298N to <strong>D3</strong> on the ESP8266.</li>
<li>Connect <strong>OUT1</strong> and <strong>OUT2</strong> on the L298N to the motor terminals.</li>
<li>Connect the <strong>GND</strong> pin on the L298N to the <strong>GND</strong> pin on the ESP8266.</li>
<li>Provide power to the motor driver module:
<ul>
<li>Connect the <strong>+12V</strong> input on the L298N to an external 9V or 12V power supply (depending on your motor’s requirement).</li>
<li>Connect the <strong>GND</strong> of the external power supply to the <strong>GND</strong> of the ESP8266.</li>
</ul>
</li>
</ol>
<p><img loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2024/11/ESP8266-L298N-removebg.png" alt="" width="926" height="755" class="aligncenter wp-image-7497 size-full" srcset="https://www.teachmemicro.com/wp-content/uploads/2024/11/ESP8266-L298N-removebg.png 926w, https://www.teachmemicro.com/wp-content/uploads/2024/11/ESP8266-L298N-removebg-300x245.png 300w, https://www.teachmemicro.com/wp-content/uploads/2024/11/ESP8266-L298N-removebg-768x626.png 768w" sizes="auto, (max-width: 926px) 100vw, 926px" /></p>
<div class="box info  aligncenter" style="width:600px"><div class="box-inner-block"><i class="fa tie-shortcode-boxicon"></i>
			
<h4>Important Note</h4>
<p>Ensure that the motor power supply’s GND is shared with the ESP8266’s GND to avoid floating grounds.</p>

			</div></div>
<h3></h3>
<h3>Programming the ESP8266 in Arduino Cloud</h3>
<ol>
<li>In Arduino Cloud, open the code editor for your ESP8266.</li>
<li>Replace the generated code with the following code to control the motor through the Arduino Cloud variables.</li>
</ol>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">&lt;arduinoiotcloud.h&gt;&lt;arduino_connectionhandler.h&gt;&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&lt;ArduinoIoTCloud.h&gt;&lt;/span&gt;&lt;/span&gt; 
&lt;span class=&quot;hljs-meta&quot;&gt;#&lt;span class=&quot;hljs-keyword&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&lt;Arduino_ConnectionHandler.h&gt;&lt;/span&gt;&lt;/span&gt;

// Motor control pins
const int IN1 = D1;
const int IN2 = D2;
const int ENA = D3;

&lt;span class=&quot;hljs-comment&quot;&gt;// Replace with your network credentials&lt;/span&gt; 
&lt;span class=&quot;hljs-type&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;char&lt;/span&gt; SSID[] = &lt;span class=&quot;hljs-string&quot;&gt;&quot;your_SSID&quot;&lt;/span&gt;; 
&lt;span class=&quot;hljs-type&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;hljs-type&quot;&gt;char&lt;/span&gt; PASS[] = &lt;span class=&quot;hljs-string&quot;&gt;&quot;your_PASSWORD&quot;&lt;/span&gt;;

&lt;span class=&quot;hljs-comment&quot;&gt;// Initialize connection to Arduino IoT Cloud&lt;/span&gt; 
&lt;span class=&quot;hljs-function&quot;&gt;WiFiConnectionManager &lt;span class=&quot;hljs-title&quot;&gt;ArduinoIoTPreferredConnection&lt;/span&gt;&lt;span class=&quot;hljs-params&quot;&gt;(SSID, PASS)&lt;/span&gt;&lt;/span&gt;;

// Arduino Cloud variables
bool motorState;
int motorSpeed;

void setup() {
  // Initialize serial communication for debugging
  Serial.begin(115200);
  
  // Configure motor control pins
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(ENA, OUTPUT);
  
  // Arduino Cloud connection
  initProperties();
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  // Arduino Cloud loop
  ArduinoCloud.update();
  
  // Update motor control based on cloud variables
  if (motorState) {
    digitalWrite(IN1, HIGH);  // Set motor direction
    digitalWrite(IN2, LOW);
    analogWrite(ENA, map(motorSpeed, 0, 100, 0, 255));  // Adjust speed
  } else {
    digitalWrite(IN1, LOW);
    digitalWrite(IN2, LOW);
    analogWrite(ENA, 0);  // Turn off motor
  }
}

void initProperties() {
  ArduinoCloud.addProperty(motorState, READWRITE, ON_CHANGE, NULL);
  ArduinoCloud.addProperty(motorSpeed, READWRITE, ON_CHANGE, NULL);
}
&lt;/arduino_connectionhandler.h&gt;&lt;/arduinoiotcloud.h&gt;</code></pre></pre>
</div>
</div>
</div>
<h3></h3>
<h3>Upload the Code</h3>
<ol>
<li>Ensure your ESP8266 is connected to your computer and select the correct board and port in Arduino Cloud.</li>
<li>Upload the code from the Arduino Cloud editor.</li>
</ol>
<h3></h3>
<h3>Test Your Setup</h3>
<ol>
<li>In Arduino Cloud, navigate to the <strong>thing</strong> dashboard.</li>
<li>You should see the <strong>motorState</strong> and <strong>motorSpeed</strong> variables.</li>
<li>Toggle <em>motorState</em> to <strong>ON</strong> to start the motor.</li>
<li>Adjust <em>motorSpeed</em> (0-100) to change the motor’s speed.</li>
</ol>
<h3></h3>
<h3>Explanation of the Code</h3>
<ul>
<li><strong>motorState</strong> variable controls the motor’s ON/OFF state.</li>
<li><strong>motorSpeed</strong> variable (0-100) is mapped to the range 0-255, which is the PWM range for controlling speed on the ENA pin.</li>
<li>The <strong>loop()</strong> function reads the cloud variables and adjusts the motor’s behavior based on their values.</li>
</ul>
<h3></h3>
<h3>Additional Tips</h3>
<ul>
<li><strong>Motor Direction Control</strong>: You can reverse the motor direction by swapping <em>digitalWrite(IN1, HIGH)</em>  and <em>digitalWrite(IN2, LOW)</em> with <em>digitalWrite(IN1, LOW)</em> and <em>digitalWrite(IN2, HIGH)</em>.</li>
<li><strong>Add Indicators</strong>: Connect an LED to the ESP8266 to show when the motor is active or use the serial monitor to debug issues.</li>
</ul>
<h3></h3>
<h3>Conclusion</h3>
<p>With this setup, you can control your DC motor remotely via Arduino Cloud. This project can be expanded with additional features, such as a feedback system using sensors to monitor motor performance.</p>
<p>The post <a href="https://www.teachmemicro.com/how-to-use-l298n-motor-driver-esp8266/">How to Use L298N Motor Driver with ESP8266</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP8266 nRF24L01 Interfacing</title>
		<link>https://www.teachmemicro.com/esp8266-nrf24l01-interfacing/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp8266-nrf24l01-interfacing</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 14 Oct 2024 01:00:06 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7047</guid>

					<description><![CDATA[<p>In this tutorial, we will explore how to interface an ESP8266 with the nRF24L01 wireless module. The nRF24L01 is a low-power, 2.4GHz wireless transceiver module that is commonly used in short-range wireless communication. It communicates over SPI, while the ESP8266 is a Wi-Fi-enabled microcontroller that can be programmed using the Arduino IDE. We will walk &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-nrf24l01-interfacing/">ESP8266 nRF24L01 Interfacing</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="font-weight: 400;">In this tutorial, we will explore how to interface an ESP8266 with the nRF24L01 wireless module. The nRF24L01 is a low-power, 2.4GHz wireless transceiver module that is commonly used in short-range wireless communication. It communicates over SPI, while the ESP8266 is a Wi-Fi-enabled microcontroller that can be programmed using the Arduino IDE.</span></p>
<p><span id="more-7047"></span></p>
<p><span style="font-weight: 400;">We will walk through setting up an example project where the ESP8266 communicates with another nRF24L01 module, allowing wireless data transmission.</span></p>
<h2><b>Table of Contents</b></h2>
<ol>
<li style="font-weight: 400;" aria-level="1"><b>Understanding ESP8266 and nRF24L01</b></li>
<li style="font-weight: 400;" aria-level="1"><b>Wiring the ESP8266 and nRF24L01</b></li>
<li style="font-weight: 400;" aria-level="1"><b>Setting up the Arduino IDE</b></li>
<li style="font-weight: 400;" aria-level="1"><b>Writing the Code for the ESP8266</b></li>
<li style="font-weight: 400;" aria-level="1"><b>Example Project: Wireless Data Transmission</b></li>
<li style="font-weight: 400;" aria-level="1"><b>Testing the Project</b></li>
</ol>
<h2><b>Understanding ESP8266 and nRF24L01</b></h2>
<h3><b>ESP8266 Overview</b></h3>
<p><span style="font-weight: 400;">The ESP8266 is a low-cost microcontroller with built-in Wi-Fi, ideal for IoT projects. It can be programmed using the Arduino IDE or other platforms, and it has several GPIO pins that can be used for digital input/output, PWM, and communication protocols like SPI and I2C.</span></p>
<h3><b>nRF24L01 Overview</b></h3>
<p><span style="font-weight: 400;">The nRF24L01 is a 2.4GHz RF transceiver that uses SPI communication. It supports multiple data rates and has a range of up to 100 meters in line-of-sight conditions. It is ideal for short-range wireless communication between microcontrollers and other devices.</span></p>
<p><span style="font-weight: 400;">Key features:</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Frequency</b><span style="font-weight: 400;">: 2.4 GHz</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Data rate</b><span style="font-weight: 400;">: Up to 2 Mbps</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Range</b><span style="font-weight: 400;">: ~100 meters</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Power consumption</b><span style="font-weight: 400;">: Low (in microamperes when on standby)</span></li>
</ul>
<h2><b>Wiring the ESP8266 and nRF24L01</b></h2>
<p><span style="font-weight: 400;">The nRF24L01 uses SPI to communicate with the ESP8266. The pinout of both devices is as follows:</span></p>
<h3><b>nRF24L01 Pinout</b></h3>
<div class="plus tie-list-shortcode">
<ul>
<li style="font-weight: 400;" aria-level="1"><b>VCC</b><span style="font-weight: 400;">: 3.3V</span></li>
<li style="font-weight: 400;" aria-level="1"><b>GND</b><span style="font-weight: 400;">: Ground</span></li>
<li style="font-weight: 400;" aria-level="1"><b>CE</b><span style="font-weight: 400;">: Chip Enable (used to set the module in active mode)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>CSN</b><span style="font-weight: 400;">: Chip Select Not (active low, for SPI communication)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>SCK</b><span style="font-weight: 400;">: SPI Clock</span></li>
<li style="font-weight: 400;" aria-level="1"><b>MOSI</b><span style="font-weight: 400;">: Master Out Slave In (SPI data line)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>MISO</b><span style="font-weight: 400;">: Master In Slave Out (SPI data line)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>IRQ</b><span style="font-weight: 400;">: Interrupt (not required for this project)</span></li>
</ul>
</div>
<h3><b>Wiring to ESP8266 (NodeMCU/ESP-12E)</b></h3>
<div class="checklist tie-list-shortcode">
<ul>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 VCC</b><span style="font-weight: 400;"> → </span><b>ESP8266 3.3V</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 GND</b><span style="font-weight: 400;"> → </span><b>ESP8266 GND</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 CE</b><span style="font-weight: 400;"> → </span><b>ESP8266 GPIO4 (D2)</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 CSN</b><span style="font-weight: 400;"> → </span><b>ESP8266 GPIO15 (D8)</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 SCK</b><span style="font-weight: 400;"> → </span><b>ESP8266 GPIO14 (D5)</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 MOSI</b><span style="font-weight: 400;"> → </span><b>ESP8266 GPIO13 (D7)</b></li>
<li style="font-weight: 400;" aria-level="1"><b>nRF24L01 MISO</b><span style="font-weight: 400;"> → </span><b>ESP8266 GPIO12 (D6)</b></li>
</ul>
</div>
<h2><b>Setting up the Arduino IDE</b></h2>
<p><span style="font-weight: 400;">To program the ESP8266 using the Arduino IDE, follow these steps:</span></p>
<h3><b>Step 1: Install the ESP8266 Board Package</b></h3>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Open the </span><b>Arduino IDE</b><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Go to </span><b>File &gt; Preferences</b><span style="font-weight: 400;">.</span></li>
</ol>
<p style="padding-left: 40px;"><span style="font-weight: 400;">Add the following URL in the "Additional Boards Manager URLs":</span><span style="font-weight: 400;"><br />
</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">http://arduino.esp8266.com/stable/package_esp8266com_index.json</code></pre></pre>
</div>
<p style="padding-left: 40px;"><span style="font-weight: 400;">Go to </span><b>Tools &gt; Board &gt; Boards Manager</b><span style="font-weight: 400;">, search for </span><b>ESP8266</b><span style="font-weight: 400;">, and install the package.</span></p>
<h3><b>Step 2: Install the RF24 Library</b></h3>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">In the Arduino IDE, go to </span><b>Sketch &gt; Include Library &gt; Manage Libraries</b><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Search for </span><b>RF24</b><span style="font-weight: 400;"> by TMRh20 and install it. This library is necessary for interfacing with the nRF24L01 module.</span></li>
</ol>
<h2><b>Writing the Code for the ESP8266</b></h2>
<p><span style="font-weight: 400;">We will now write the code to transmit data from the ESP8266 to another nRF24L01 module.</span></p>
<h3><b>Transmitter Code for ESP8266</b></h3>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SPI.h&gt;&lt;spi.h&gt;
#include &lt;RF24.h&gt;&lt;rf24.h&gt;

// Define nRF24L01 pins
#define CE_PIN 4  // GPIO4 (D2)
#define CSN_PIN 15 // GPIO15 (D8)

// Create an RF24 object
RF24 radio(CE_PIN, CSN_PIN);

// Define the address (must match on both transmitter and receiver)
const byte address[6] = &quot;00001&quot;;

// Data to send
const char text[] = &quot;Hello from ESP8266!&quot;;

void setup() {
  // Start the serial communication for debugging
  Serial.begin(115200);

  // Initialize the radio
  radio.begin();
  
  // Set the communication address
  radio.openWritingPipe(address);
  
  // Set the data rate and power level (can be adjusted for range)
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_1MBPS);

  // Ensure radio is in transmit mode
  radio.stopListening();
}

void loop() {
  // Send the data
  bool success = radio.write(&amp;text, sizeof(text));

  // Check if data was sent successfully
  if (success) {
    Serial.println(&quot;Data sent successfully&quot;);
  } else {
    Serial.println(&quot;Failed to send data&quot;);
  }

  // Delay before sending the next data
  delay(1000);
}
&lt;/rf24.h&gt;&lt;/spi.h&gt;</code></pre></pre>
</div>
<h3><b>Receiver Code (Arduino/ESP8266)</b></h3>
<p><span style="font-weight: 400;">You can also use an Arduino or another ESP8266 as a receiver for the data. The wiring for the nRF24L01 will remain the same.</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;SPI.h&gt;&lt;spi.h&gt;
#include &lt;RF24.h&gt;&lt;rf24.h&gt;

#define CE_PIN 9   // Use appropriate pin for your board
#define CSN_PIN 10 // Use appropriate pin for your board

RF24 radio(CE_PIN, CSN_PIN);
const byte address[6] = &quot;00001&quot;;
char receivedText[32] = &quot;&quot;; // Buffer to hold received data

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_LOW);
  radio.setDataRate(RF24_1MBPS);
  radio.startListening();
}

void loop() {
  if (radio.available()) {
    radio.read(&amp;receivedText, sizeof(receivedText));
    Serial.print(&quot;Received data: &quot;);
    Serial.println(receivedText);
  }
}
&lt;/rf24.h&gt;&lt;/spi.h&gt;</code></pre></pre>
</div>
<h2><b>Example Project: Wireless Data Transmission</b></h2>
<p><span style="font-weight: 400;">In this example project, the ESP8266 acts as a transmitter that sends data to another device (either an Arduino or another ESP8266) equipped with an nRF24L01 module. The data is sent wirelessly at intervals of one second.</span></p>
<h3><b>Steps:</b></h3>
<ol>
<li style="font-weight: 400;" aria-level="1"><b>Wire the components</b><span style="font-weight: 400;"> as shown in the wiring diagram.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Upload the transmitter code</b><span style="font-weight: 400;"> to the ESP8266.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Upload the receiver code</b><span style="font-weight: 400;"> to the second ESP8266 or Arduino.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Open the Serial Monitor</b><span style="font-weight: 400;"> on both devices to see the data being sent and received.</span></li>
</ol>
<h2><b>Testing the Project</b></h2>
<p><span style="font-weight: 400;">After uploading the code, open the Serial Monitor on both the transmitter and receiver. You should see the message "Data sent successfully" on the transmitter and the message "Received data: Hello from ESP8266!" on the receiver.</span></p>
<h3><b>Troubleshooting:</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Ensure the wiring is correct.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Make sure both the transmitter and receiver have matching communication addresses.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Check if the power supply to the nRF24L01 module is stable. You may need a capacitor (10µF) across the VCC and GND of the nRF24L01 module to prevent power fluctuations.</span></li>
</ul>
<h2><b>Conclusion</b></h2>
<p><span style="font-weight: 400;">In this tutorial, you learned how to interface an ESP8266 with the nRF24L01 wireless module for wireless communication. We set up a simple project where the ESP8266 transmits data to another nRF24L01 module. This setup is useful for short-range wireless communication between ESP8266 devices, such as in IoT projects or sensor networks.</span></p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-nrf24l01-interfacing/">ESP8266 nRF24L01 Interfacing</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP8266 UDP: Sending Data Between Two ESPs</title>
		<link>https://www.teachmemicro.com/esp8266-udp-sending-data-between-two-esps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp8266-udp-sending-data-between-two-esps</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 09 Oct 2024 01:00:51 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7049</guid>

					<description><![CDATA[<p>I have shown how you can use ESP8266 to host a web server via HTTP and via WebSocket, use MQTT and ThingSpeak for sensor data, and even use Google Sheets. This time, I will be sharing with you how I send data between two ESP8266. The ESP8266 is a popular Wi-Fi microcontroller that enables wireless &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-udp-sending-data-between-two-esps/">ESP8266 UDP: Sending Data Between Two ESPs</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="font-weight: 400;">I have shown how you can use ESP8266 to host a web server via HTTP and via <a href="https://www.teachmemicro.com/web-server-nodemcu-websocket/">WebSocket</a>, use <a href="https://www.teachmemicro.com/nodemcu-mqtt-tutorial/">MQTT</a> and <a href="https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/">ThingSpeak</a> for sensor data, and even use <a href="https://www.teachmemicro.com/log-data-nodemcu-google-sheets/">Google Sheets</a>. This time, I will be sharing with you how I send data between two ESP8266. </span></p>
<p><span id="more-7049"></span></p>
<p>The ESP8266 is a popular Wi-Fi microcontroller that enables wireless communication between devices. One of the most efficient ways to transfer data between two ESP8266 modules is using the UDP protocol (User Datagram Protocol). UDP is a connectionless protocol that sends data packets without needing an established connection, making it fast and lightweight—ideal for real-time communication in IoT projects.</p>
<p>In this article, we’ll create a project where one ESP8266 collects sensor data and sends it to another ESP8266 using UDP. The second <a href="https://www.teachmemicro.com/simple-nodemcu-web-server/">ESP8266 hosts a web server</a> that displays the sensor data in real-time.</p>
<h2>How UDP Communication Works</h2>
<p>UDP is a simple communication protocol that sends packets called datagrams between devices on a network. Unlike TCP, it doesn't require a connection to be maintained, so it's faster but less reliable since there's no guarantee that packets will be delivered. This makes UDP suitable for use cases where speed is critical, and occasional packet loss can be tolerated.</p>
<h3>Advantages of Using UDP</h3>
<ul>
<li><strong>Fast</strong>: No need to establish or maintain a connection, reducing overhead.</li>
<li><strong>Efficient</strong>: Ideal for real-time applications where speed is more important than reliability.</li>
<li><strong>Lightweight</strong>: Lower memory and processing requirements compared to TCP.</li>
</ul>
<h3>Disadvantages</h3>
<ul>
<li><strong>No reliability</strong>: Packets can get lost or arrive out of order.</li>
<li><strong>No error checking</strong>: UDP doesn't ensure the data is intact.</li>
</ul>
<h2>Project Overview</h2>
<p>In this project, two ESP8266 modules will communicate over Wi-Fi using UDP:</p>
<ol>
<li><strong>Sender ESP8266</strong>: Reads data from a sensor (e.g., temperature or humidity sensor) and sends it via UDP.</li>
<li><strong>Receiver ESP8266</strong>: Hosts a web server, receives the UDP packets, and displays the sensor data on a web page.</li>
</ol>
<h3>Components Needed</h3>
<ul>
<li>Two <strong>ESP8266</strong> modules (e.g., ESP-01 or NodeMCU)</li>
<li>A <strong>DHT11</strong> or <strong>DHT22</strong> sensor (for temperature and humidity)</li>
<li>Jumper wires</li>
<li>Breadboard</li>
</ul>
<h3>Wiring Diagram</h3>
<ol>
<li><strong>Sender ESP8266 (with DHT sensor)</strong>
<ul>
<li>Connect the <strong>DHT sensor</strong> as follows:
<ul>
<li>VCC → 3.3V on ESP8266</li>
<li>GND → GND</li>
<li>DATA → GPIO 2 (D4 on NodeMCU)</li>
</ul>
</li>
</ul>
</li>
<li><strong>Receiver ESP8266</strong>: No additional connections needed, as it only serves to host the webserver.</li>
</ol>
<h3>Setting Up UDP Communication Between Two ESP8266 Modules</h3>
<p>We'll first write code for the <strong>sender</strong> ESP8266, which reads data from the sensor and sends it via UDP. Then, we'll create a <strong>receiver</strong> ESP8266 that listens for incoming UDP packets and displays the data on a web page.</p>
<h3>Code for Sender ESP8266</h3>
<p>The sender reads data from a DHT sensor and sends it as a UDP packet to the receiver ESP8266.</p>
<h4>Install the DHT Sensor Library</h4>
<p>In the Arduino IDE, go to <strong>Sketch</strong> &gt; <strong>Include Library</strong> &gt; <strong>Manage Libraries</strong> and install the <strong>DHT sensor library by Adafruit</strong>.</p>
<div class="dark bg-gray-950 contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative">
<div dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiUdp.h&gt;
#include &quot;DHT.h&quot;

#define DHTPIN 2 // Pin where the DHT sensor is connected
#define DHTTYPE DHT11 // DHT 11 or DHT22, change accordingly

// Your network credentials
const char* ssid = &quot;your_SSID&quot;;
const char* password = &quot;your_PASSWORD&quot;;

// Receiver ESP8266 IP address and port
const char* receiverIP = &quot;192.168.1.100&quot;; // Replace with the actual IP of the receiver
const unsigned int receiverPort = 4210; // The UDP port number

DHT dht(DHTPIN, DHTTYPE);
WiFiUDP udp;

void setup() {
   Serial.begin(115200);
   dht.begin();

// Connect to Wi-Fi
   WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED) {
      delay(1000);
      Serial.println(&quot;Connecting to WiFi...&quot;);
   }
   Serial.println(&quot;Connected to WiFi&quot;);
}

void loop() {
// Read temperature and humidity
   float h = dht.readHumidity();
   float t = dht.readTemperature();

   if (isnan(h) || isnan(t)) {
      Serial.println(&quot;Failed to read from DHT sensor!&quot;);
      return;
   }

// Prepare the UDP message
   String message = &quot;Temperature: &quot; + String(t) + &quot; C, Humidity: &quot; + String(h) + &quot; %&quot;;
   Serial.println(&quot;Sending message: &quot; + message);

// Send the message to the receiver ESP8266
   udp.beginPacket(receiverIP, receiverPort);
   udp.print(message);
   udp.endPacket();

   delay(2000); // Wait 2 seconds before sending the next packet
}</code></pre></pre>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr"><strong>Code Breakdown (Sender):</strong></div>
</div>
<ol>
<li><strong>WiFi Setup</strong>: The ESP8266 connects to the local Wi-Fi network using your SSID and password.</li>
<li><strong>DHT Sensor</strong>: Reads temperature and humidity from the DHT sensor.</li>
<li><strong>UDP Communication</strong>: The data is formatted as a string and sent via UDP to the receiver ESP8266 using <em>WiFiUDP</em>.</li>
</ol>
<h3>Code for Receiver ESP8266 (Web Server)</h3>
<p>The receiver listens for UDP packets and displays the sensor data on a web page.</p>
<div class="dark bg-gray-950 contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiUdp.h&gt;
#include &lt;ESP8266WebServer.h&gt;

// Your network credentials
const char* ssid = &quot;your_SSID&quot;;
const char* password = &quot;your_PASSWORD&quot;;

// UDP settings
WiFiUDP udp;
unsigned int localPort = 4210; // The port to listen on
char incomingPacket[255]; // Buffer to hold incoming packets

// Web server object
ESP8266WebServer server(80);

String sensorData = &quot;No data received&quot;;

void setup() {
   Serial.begin(115200);

// Connect to Wi-Fi
   WiFi.begin(ssid, password);
   while (WiFi.status() != WL_CONNECTED) {
      delay(1000);
      Serial.println(&quot;Connecting to WiFi...&quot;);
   }
   Serial.println(&quot;Connected to WiFi&quot;);
   Serial.print(&quot;IP Address: &quot;);
   Serial.println(WiFi.localIP());

// Start UDP
   udp.begin(localPort);
   Serial.printf(&quot;Listening on UDP port %d\n&quot;, localPort);

// Start the web server
   server.on(&quot;/&quot;, handleRoot);
   server.begin();
   Serial.println(&quot;Web server started&quot;);
}

void loop() {
// Listen for incoming UDP packets
   int packetSize = udp.parsePacket();
   if (packetSize) {
      int len = udp.read(incomingPacket, 255);
      if (len &gt; 0) {
         incomingPacket[len] = 0;
      }
      Serial.printf(&quot;UDP packet received: %s\n&quot;, incomingPacket);
      sensorData = String(incomingPacket);
   }

// Handle web server requests
   server.handleClient();
}

// Function to handle the web page
void handleRoot() {
   String html = &quot;&lt;html&gt;&lt;body&gt;&lt;h1&gt;Sensor Data&lt;/h1&gt;&quot;;
   html += &quot;&lt;p&gt;&quot; + sensorData + &quot;&lt;/p&gt;&quot;;
   html += &quot;&lt;/body&gt;&lt;/html&gt;&quot;;
   server.send(200, &quot;text/html&quot;, html);
}</code></pre></pre>
</div>
</div>
</div>
<h4>Code Breakdown (Receiver):</h4>
<ol>
<li><strong>UDP Listener</strong>: The ESP8266 listens for incoming UDP packets on a specified port. When a packet is received, the sensor data is extracted and stored.</li>
<li><strong>Web Server</strong>: Hosts a simple web server that serves a page displaying the latest sensor data. The data is refreshed every time the user accesses the page.</li>
</ol>
<h3>Setting Up the IP Address of the Receiver</h3>
<p>To ensure communication between the two ESP8266 modules, you need to know the IP address of the <strong>receiver</strong> ESP8266. After uploading the code, open the Serial Monitor to find the IP address of the receiver. Then, update the <strong>receiverIP</strong> in the sender code with this address.</p>
<h3>Viewing the Sensor Data</h3>
<ol>
<li>Power up both ESP8266 modules. The sender will read data from the DHT sensor and send it to the receiver via UDP.</li>
<li>Open a web browser on a device connected to the same Wi-Fi network and enter the IP address of the receiver ESP8266 (as shown in the Serial Monitor).</li>
<li>The web page will display the current sensor readings (temperature and humidity), which are updated every 2 seconds.</li>
</ol>
<h3>Conclusion</h3>
<p>By using UDP communication between two ESP8266 modules, you can efficiently send real-time sensor data from one ESP to another and visualize the data via a web server. This project demonstrates how easy it is to set up wireless communication for IoT applications, offering a foundation to build more complex systems such as remote monitoring, smart home devices, or industrial sensors.</p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-udp-sending-data-between-two-esps/">ESP8266 UDP: Sending Data Between Two ESPs</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Controlling a Water Pump with WeMos D1 Mini</title>
		<link>https://www.teachmemicro.com/controlling-water-pump-via-wifi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=controlling-water-pump-via-wifi</link>
					<comments>https://www.teachmemicro.com/controlling-water-pump-via-wifi/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 03 Feb 2021 01:58:18 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<category><![CDATA[gardening]]></category>
		<category><![CDATA[mosfet]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=4904</guid>

					<description><![CDATA[<p>I recently bought a mini Arduino water pump that runs on 3 to 6 V. Since it consumes very little current (130 mA @ 3V according to its specs), it seems perfect to be used for small projects featuring the ESP8266. In this tutorial, I will share how I managed to create a WiFi-controlled mini &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/controlling-water-pump-via-wifi/">Controlling a Water Pump with WeMos D1 Mini</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>I recently bought a mini <a href="https://sea.banggood.com/custlink/KGDhIOdRrv">Arduino water pump</a> that runs on 3 to 6 V. Since it consumes very little current (130 mA @ 3V according to its specs), it seems perfect to be used for small projects featuring the <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a>. In this tutorial, I will share how I managed to create a WiFi-controlled mini water pump.</p>
<p><span id="more-4904"></span></p>
<h3><strong>Mini Water Pump Specification</strong></h3>
<p>Here's some information about the pump:</p>
<ul>
<li>Operating Current : 130 ~ 220mA</li>
<li>Flow Rate : 80 ~ 120 L/H</li>
<li>Maximum Lift : 40 ~ 110 mm</li>
<li>Continuous Working Life: 500 hours</li>
<li>Driving Mode: DC, Magnetic Driving</li>
<li>Material: Engineering Plastic</li>
<li>Outlet Outside Diameter: 7.5 mm</li>
<li>Outlet Inside Diameter : 5 mm</li>
</ul>
<p>It is a <em>submersible</em> pump and should be used that way. It tends to heat too much that there's a risk of overheating if you turn it on unsubmerged.</p>
<h3><strong>Water Pump and WeMos D1 Mini Connection</strong></h3>
<p>The first thing I noticed is that it requires a wider tube pipe compared to the ones used by aquarium air pumps so I had to <a href="https://sea.banggood.com/custlink/3DDESLERCr">purchase one separately</a>. The operating current also makes it impossible to connect the wires directly to one of the GPIO pins of the ESP8266 (which maxes out at 12 mA). So naturally, I had to design a way to turn on/off the pump with enough power for it.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2021/02/basic-esp8266-pump-circuit.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4905" src="https://www.teachmemicro.com/wp-content/uploads/2021/02/basic-esp8266-pump-circuit.jpg" alt="arduino water pump" width="633" height="455" srcset="https://www.teachmemicro.com/wp-content/uploads/2021/02/basic-esp8266-pump-circuit.jpg 633w, https://www.teachmemicro.com/wp-content/uploads/2021/02/basic-esp8266-pump-circuit-300x216.jpg 300w" sizes="auto, (max-width: 633px) 100vw, 633px" /></a></p>
<p>Here I have a <a href="https://sea.banggood.com/custlink/3m3hZlEdca">2N7000 MOSFET</a> switch triggered by a signal coming from the WeMos D1. With this, the power through the pump is from the external power supply and not from the WeMos D1.</p>
<p>Next, I created a <a href="https://www.teachmemicro.com/wemos-d1-mini-wifi-server/">WiFi server application</a> so that I may able to control the pump through my smartphone. Basically, the WeMos D1 Mini broadcasts an access point and then I connect to that access point. I then visit an IP address using a web browser and there an interface is shown for controlling the water pump.</p>
<p>As of now, the only thing I can do is turn on or turn off the water pump. Inside this Arduino water pump is a motor so I may try to control it by using PWM. That would be an update in the days to come.</p>
<h3><strong>Full Sketch</strong></h3>
<p>Here's the full sketch for the WiFi server:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;

const char* ssid = &quot;Pump Controller&quot;;
const char* password = &quot;12345678&quot;;

ESP8266WebServer server(80);

const int pump = 8;
static const String page PROGMEM = &quot;&lt;h1&gt;Water Pump Controller&lt;/h1&gt;&lt;p&gt;&lt;a href=\&quot;PumpOn\&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;&nbsp;&lt;a href=\&quot;PumpOff\&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;&quot;;
 
void setup(void) {
  
  pinMode(pump, OUTPUT);
  digitalWrite(pump, 0);
  Serial.begin(115200);
 
  WiFi.softAP(ssid, password);
  Serial.println(&quot;&quot;);

  Serial.println(ssid);
  Serial.print(&quot;WiFi Server started at IP address: &quot;);
  Serial.println(WiFi.softAPIP());


  server.on(&quot;/&quot;, [](){
    server.send(200, &quot;text/html&quot;, page);
  });
  
  server.on(&quot;/PumpOn&quot;, [](){
    server.send(200, &quot;text/html&quot;, page);
    digitalWrite(pump, HIGH);
    delay(1000);
  });
  
  server.on(&quot;/PumpOff&quot;, [](){
    server.send(200, &quot;text/html&quot;, page);
    digitalWrite(pump, LOW);
    delay(1000);
  });

  server.begin();
  Serial.println(&quot;HTTP server started&quot;);
}

void loop(void) {
  server.handleClient();
}</code></pre></pre>
<p>The interface is just simple HTML but I'm planning more things for it in the future.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui.jpg"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4910" src="https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui-1024x644.jpg" alt="water pump controller ui" width="618" height="389" srcset="https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui-1024x644.jpg 1024w, https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui-300x189.jpg 300w, https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui-768x483.jpg 768w, https://www.teachmemicro.com/wp-content/uploads/2021/02/pump-controller-ui.jpg 1242w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>If you're interested in this project, updates will be made on its <a href="https://github.com/kurimawxx00/esp8266_water_pump_controller">repository</a>.</p>
<p>The post <a href="https://www.teachmemicro.com/controlling-water-pump-via-wifi/">Controlling a Water Pump with WeMos D1 Mini</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/controlling-water-pump-via-wifi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WeMos D1 Mini WiFi Server</title>
		<link>https://www.teachmemicro.com/wemos-d1-mini-wifi-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wemos-d1-mini-wifi-server</link>
					<comments>https://www.teachmemicro.com/wemos-d1-mini-wifi-server/#comments</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Thu, 28 Jan 2021 02:38:12 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=4889</guid>

					<description><![CDATA[<p>Now that you've set up your WeMos D1 Mini to be programmable using the Arduino IDE, it's time to build a project. I'm a huge believer in active learning and project-making does just that. For this tutorial, I will guide you on how to build a WeMos D1 Mini WiFi server. There are two ways &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/wemos-d1-mini-wifi-server/">WeMos D1 Mini WiFi Server</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<div>Now that you've <a href="https://www.teachmemicro.com/getting-started-wemos-d1-mini/">set up your WeMos D1 Mini</a> to be programmable using the Arduino IDE, it's time to build a project. I'm a huge believer in active learning and project-making does just that. For this tutorial, I will guide you on how to build a WeMos D1 Mini WiFi server.</div>
<p><span id="more-4889"></span></p>
<div>There are two ways for the WeMos D1 Mini to host a server: as a station and as an access point. I've already shown <a href="https://www.teachmemicro.com/simple-nodemcu-web-server/">a tutorial on the former</a> using NodeMCU so I will now use an access point server instead. Basically, an access point server doesn't need another WiFi router - the WeMos D1 mini itself is the router. It broadcasts a WiFi connection and the user connects to it through SSID and password.</div>
<h3><strong>Required Libraries</strong></h3>
<div>You'll need three libraries for this project, all of which are already included in the <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a> core for Arduino.</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;</code></pre></pre>
<h3><strong>Define Access Point SSID and Password</strong></h3>
<p>Next, we define the SSID and password for the WiFi connection:</p>
</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">const char* ssid = &quot;&lt;YOUR WIFI SSID&gt;&quot;;
const char* password = &quot;&lt;YOUR WIFI PASSWORD&gt;&quot;;</code></pre></pre>
<h3><strong>Initialize Server Object</strong></h3>
<p>Then we create the server object:</p>
</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">ESP8266WebServer server(80);</code></pre></pre>
<h3><strong>Create Access Point</strong></h3>
<p>Inside setup, we initialize the WiFi connection through:</p>
</div>
<div>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">WiFi.softAP(ssid, password);</code></pre></pre>
<p>This should start the access point, making the SSID visible to would-be clients.</p>
<h3><strong>Write HTML Page</strong></h3>
</div>
<div>Now we need to create an interface for the client. For starters, we'll build a web page that allows the user to control the on-board LED on the WeMos D1. For this, we create a page with the following HTML:</div>
<div>
<pre class="lang:xhtml decode:true"><pre><code class="language-cpp">&lt;h1&gt;WeMos D1 Mini Web Server&lt;/h1&gt;&lt;p&gt;&lt;a href=\&quot;LEDOn\&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;&nbsp;&lt;a href=\&quot;LEDOff\&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;</code></pre></pre>
<p>This is a very simple HTML and could be improved with CSS and Javascript. For the purpose of this tutorial, we will stick with this one.</p>
</div>
<div>We place the HTML inside a string variable <i>index</i></div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">String index = &quot;&lt;h1&gt;Simple NodeMCU Web Server&lt;/h1&gt;&lt;p&gt;&lt;a href=\&quot;LEDOn\&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;&nbsp;&lt;a href=\&quot;LEDOff\&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;&quot;;</code></pre></pre>
<p>And have it shown to the client who visits the home page:</p>
</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">server.on(&quot;/&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
});</code></pre></pre>
<h3><strong>Bind to LED Control</strong></h3>
<p>Notice that on the HTML page, we have links to two pages: <em>/LEDOn</em> and <em>/LEDOff.</em></p>
</div>
<div>When the client visits these links, that is when we are supposed to turn on or off the on board LED:</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">server.on(&quot;/LEDOn&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
    digitalWrite(13, HIGH);
    delay(1000);
});

server.on(&quot;/LEDOff&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
    digitalWrite(13, LOW);
    delay(1000);
});</code></pre></pre>
<p>Finally, we start the server by calling the begin function.</p>
</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">server.begin();</code></pre></pre>
<p>The above code needs to be executed only once and hence will be inside setup(). The loop() function will only have one line of code and that is:</p>
</div>
<div>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">server.handleClient();</code></pre></pre>
<p>This makes the WeMos D1 Mini always listening to clients that visit the server.</p>
<h3><strong>WeMos D1 Mini WiFi Server Full Sketch</strong></h3>
</div>
<div>Here's the full code for our WeMos D1 Mini WiFi Server:</div>
<div>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;


// Replace with your network credentials
const char* ssid = &quot;&lt;YOUR WIFI SSID&gt;&quot;;
const char* password = &quot;&lt;YOUR WIFI PASSWORD&gt;&quot;;
ESP8266WebServer server(80);   //instantiate server at port 80 (http port)


void setup(void){

  //the HTML of the web page
  String index = &quot;&lt;h1&gt;Simple NodeMCU Web Server&lt;/h1&gt;&lt;p&gt;&lt;a href=\&quot;LEDOn\&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;&nbsp;&lt;a href=\&quot;LEDOff\&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;&lt;/p&gt;&quot;;
  //make the LED pin output and initially turned off
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  
  delay(1000);
  Serial.begin(115200);
  WiFi.softAP(ssid, password); //begin WiFi access point
  Serial.println(&quot;&quot;);
  
  server.on(&quot;/&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
  });
  server.on(&quot;/LEDOn&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
    digitalWrite(13, HIGH);
    delay(1000);
  });
  server.on(&quot;/LEDOff&quot;, [](){
    server.send(200, &quot;text/html&quot;, index);
    digitalWrite(13, LOW);
    delay(1000);
  });
  server.begin();
  Serial.println(&quot;Web server started!&quot;);
}
void loop(void){
  server.handleClient();
}</code></pre></pre>
<p>Upload the code above to your WeMos D1 Mini. If successful, the device should be visible as a WiFi access point with the SSID and password you specified in the code above.</p>
</div>
<p>The post <a href="https://www.teachmemicro.com/wemos-d1-mini-wifi-server/">WeMos D1 Mini WiFi Server</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/wemos-d1-mini-wifi-server/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>ESP8266 SPIFFs &#124; File System for NodeMCU</title>
		<link>https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp8266-spiffs-web-server-nodemcu</link>
					<comments>https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Sat, 19 Sep 2020 10:55:08 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=4714</guid>

					<description><![CDATA[<p>SPIFFS or Serial Peripheral Interface Flash File System is a system that utilizes extra flash memory on the ESP8266 and ESP32 for storing files. It’s so named because the user reads, writes or deletes files in the memory using the serial interface. In this article, I will show you how to set up SPIFFS for &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/">ESP8266 SPIFFs | File System for NodeMCU</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><strong>SPIFFS</strong> or <strong>Serial Peripheral Interface Flash File System</strong> is a system that utilizes extra flash memory on the <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a> and ESP32 for storing files. It’s so named because the user reads, writes or deletes files in the memory using the <a href="https://www.teachmemicro.com/microcontroller-serial-communication/">serial interface</a>. In this article, I will show you how to set up SPIFFS for your NodeMCU or <a href="https://www.teachmemicro.com/getting-started-wemos-d1-mini/">WeMos D1 Mini</a> board. Also, an example is presented on how to take advantage of this feature.</p>
<p><span id="more-4714"></span></p>
<h3>Video Tutorial</h3>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/A9cXvDWv-og" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<h3><strong>Why Use SPIFFS?</strong></h3>
<p>In my <a href="https://www.teachmemicro.com/simple-nodemcu-web-server/">NodeMCU web server article</a>, I used a sketch that presents a simple web page for controlling an external LED.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-esp8266-web-server-sketch.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4716" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-esp8266-web-server-sketch.png" alt="old web server sketch" width="597" height="909" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-esp8266-web-server-sketch.png 597w, https://www.teachmemicro.com/wp-content/uploads/2020/09/old-esp8266-web-server-sketch-197x300.png 197w" sizes="auto, (max-width: 597px) 100vw, 597px" /></a></p>
<p>When this sketch is uploaded to an ESP8266 board, the server page is now viewable in the local network through the device's IP address. This how to server page looks like on a desktop browser:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page.png"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4715" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page-1024x546.png" alt="old web server page" width="618" height="330" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page-1024x546.png 1024w, https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page-300x160.png 300w, https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page-768x410.png 768w, https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page-310x165.png 310w, https://www.teachmemicro.com/wp-content/uploads/2020/09/old-nodemcu-web-server-page.png 1363w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>Clicking the ON button turns on the LED while the OFF button turns off the LED. It looks super simple because the HTML for this page is just this:</p>
<pre class="lang:xhtml decode:true" title="Simple Web Server HTML"><pre><code class="language-cpp">&lt;h1&gt;Simple NodeMCU Web Server&lt;/h1&gt;
&lt;p&gt;
  &lt;a href=\&quot;LEDOn\&quot;&gt;&lt;button&gt;ON&lt;/button&gt;&lt;/a&gt;
  &lt;a href=\&quot;LEDOff\&quot;&gt;&lt;button&gt;OFF&lt;/button&gt;&lt;/a&gt;
&lt;/p&gt;</code></pre></pre>
<p>A much better looking web page is one with styling, images or scripts. We could do that but we are always mindful of the memory limitations of the ESP8266. Defining a long HTML in sketch means using a long string which jumps from one memory location to another for every compilation. This proves an inefficient memory management scheme and more likely to crash your ESP8266.</p>
<p>The best solution is to store the page files outside of the sketch memory location. The ESP8266 flash memory has the following allocations for the Arduino platform:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-memory-map.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4717" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-memory-map.jpg" alt="ESP8266 memory map" width="669" height="411" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-memory-map.jpg 669w, https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-memory-map-300x184.jpg 300w" sizes="auto, (max-width: 669px) 100vw, 669px" /></a></p>
<p>Note that the File System and EEPROM size may vary as per user allocation. You can use EEPROM to store data but it still limited. The SPIFFS (File System) size, in contrast, is up to 3 MB. That’s 75% of the total flash size of the ESP8266.</p>
<h3><strong>Setting up SPIFFS</strong></h3>
<p>To start using SPIFFS, download this file: <a href="https://github.com/esp8266/arduino-esp8266fs-plugin/releases/download/0.5.0/ESP8266FS-0.5.0.zip">https://github.com/esp8266/arduino-esp8266fs-plugin/releases/download/0.5.0/ESP8266FS-0.5.0.zip</a></p>
<p>Inside this zip file is a folder named <em>ESP8266FS.</em> Extract this to <em>/tools</em> inside your Arduino sketchbook location. Create the tools folder if you don’t have one. By default, the sketchbook location is at <em>Documents/Arduino</em> for Windows and Mac or <em>/home/Sketchbook</em> for Linux.</p>
<p>After this, open your Arduino IDE. A new option should appear in Tools:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-sketch-data-upload.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4718" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-sketch-data-upload.png" alt="New tool: ESP8266 Sketch data upload" width="589" height="579" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-sketch-data-upload.png 589w, https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-sketch-data-upload-300x295.png 300w, https://www.teachmemicro.com/wp-content/uploads/2020/09/esp8266-sketch-data-upload-65x65.png 65w" sizes="auto, (max-width: 589px) 100vw, 589px" /></a></p>
<p>This tool allows you to add files to your device’s SPIFFS. To add the files, open or create a sketch and place a <em>data folder</em> inside the sketch folder. For example, if I would add an HTML file, that html file is inside a data folder in the same location as my <em>.ino</em> file.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/data-folder-spiffs.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4719" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/data-folder-spiffs.png" alt="Data folder for SPIFFS" width="253" height="113" /></a></p>
<p>To store the contents of the data folder to SPIFFS, just click the <em>Tools &gt; ESP8266 Sketch Data Upload.</em> Of course you’ll still need to upload the sketch to your NodeMCU because that’s in another location.</p>
<p>In addition, you can specify how much memory you want to allocate to SPIFFS. This is one of the options as you select your ESP8266 board type:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/select-SPIFFS-size.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4720" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/select-SPIFFS-size.jpg" alt="Select SPIFFS size" width="725" height="551" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/select-SPIFFS-size.jpg 725w, https://www.teachmemicro.com/wp-content/uploads/2020/09/select-SPIFFS-size-300x228.jpg 300w" sizes="auto, (max-width: 725px) 100vw, 725px" /></a></p>
<h3><strong>Modifying the Simple Web Server Page</strong></h3>
<p>Now that we have SPIFFS set up, we modify the old HTML to make it more pleasing. I created three HTML pages: <em>index.html</em>, <em>LEDOn.html</em>, <span style="text-decoration: underline;"><em>LEDOff.html</em></span>. I also added some images and a css file for styling. These are all the contents of my data folder:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/data-files-spiffs.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4721" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/data-files-spiffs.png" alt="Data files for New Web Server page" width="249" height="159" /></a></p>
<p>When writing HTML, it’s best to code it on text-editor first and view it on a local browser. This way, you can finalize what the pages look like before uploading them to SPIFFS. Here’s my index.html file:</p>
<pre class="lang:xhtml decode:true" title="Web server index.html"><pre><code class="language-cpp">&lt;html&gt;
&lt;head&gt;
&lt;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1.0&#039;&gt;
&lt;link rel=&#039;stylesheet&#039; href=&#039;style.css&#039;&gt; 
&lt;/head&gt;
&lt;body&gt;
      &lt;h1&gt;ESP8266 Web Server with SPIFFS&lt;/h1&gt;
      &lt;p&gt;&lt;a href=&#039;https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/&#039;&gt;Full tutorial&lt;/a&gt;&lt;/p&gt;
      &lt;p&gt; Example showing how to host a web server using ESP8266 Flash File System. This controls the on-board LED. Click button to begin.&lt;/p&gt;
      &lt;a href=&quot;LEDOff.html&quot;&gt;&lt;button id=&#039;start-button&#039;&gt;START!&lt;/button&gt;&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></pre>
<p>This is the first file the client reads on the server.</p>
<p>Here’s the LEOn and LEDOff html files:</p>
<pre class="lang:xhtml decode:true" title="LEDOn.html"><pre><code class="language-cpp">html&gt;
&lt;head&gt;
&lt;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1.0&#039;&gt;
&lt;link rel=&#039;stylesheet&#039; href=&#039;style.css&#039;&gt; 
&lt;/head&gt;
&lt;body&gt;
      &lt;h1&gt;ESP8266 Web Server with SPIFFS&lt;/h1&gt;
      &lt;p&gt;&lt;a href=&#039;https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/&#039;&gt;Full tutorial&lt;/a&gt;&lt;/p&gt;
      &lt;a href=&quot;LEDOff.html&quot;&gt;&lt;img id=&quot;LED-ON&quot; src=&quot;led-on-img.jpg&quot;&gt;&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></pre>
<pre class="lang:xhtml decode:true " title="LEDOff.html"><pre><code class="language-cpp">&lt;html&gt;
&lt;head&gt;
&lt;meta name=&#039;viewport&#039; content=&#039;width=device-width, initial-scale=1.0&#039;&gt;
&lt;link rel=&#039;stylesheet&#039; href=&#039;style.css&#039;&gt; 
&lt;/head&gt;
&lt;body&gt;
      &lt;h1&gt;ESP8266 Web Server with SPIFFS&lt;/h1&gt;
      &lt;p&gt;&lt;a href=&#039;https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/&#039;&gt;Full tutorial&lt;/a&gt;&lt;/p&gt;
      &lt;a href=&quot;LEDOn.html&quot;&gt;&lt;img id=&quot;LED-OFF&quot; src=&quot;led-off-img.jpg&quot;&gt;&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre></pre>
<p>Here's my CSS file:</p>
<pre class="lang:css decode:true " title="style.css"><pre><code class="language-cpp">body{
  background-color:white;
  font-family: &#039;Roboto&#039;, sans-serif;
  border: 1px solid;
  border-color: gray;
  border-radius: 20px;
  margin-left: 35%;
  width: 30%;
  height: 50%;
  padding: 20px;
}

#LED-ON, #LED-OFF{
  margin-left: 25%;
}

#start-button{
  width: 40%;
  height: 20%;
  background-color: darkseagreen;
  border: 1px solid forestgreen;
  border-radius: 10px;
  margin-left: 30%;
  margin-top: 10%;
}</code></pre></pre>
<p>The two images are for showing on and off bulbs:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-off-img.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4723" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-off-img.jpg" alt="" width="264" height="349" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-off-img.jpg 264w, https://www.teachmemicro.com/wp-content/uploads/2020/09/led-off-img-227x300.jpg 227w" sizes="auto, (max-width: 264px) 100vw, 264px" /></a> <a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-on-img.jpg"><img loading="lazy" decoding="async" class="aligncenter size-large wp-image-4724" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-on-img.jpg" alt="" width="264" height="349" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/led-on-img.jpg 264w, https://www.teachmemicro.com/wp-content/uploads/2020/09/led-on-img-227x300.jpg 227w" sizes="auto, (max-width: 264px) 100vw, 264px" /></a></p>
<p>All in all these files are around 56 kB. Still too small for our 3 MB SPIFFS!</p>
<p>As for the sketch, there are also some changes to the original.</p>
<pre class="lang:arduino decode:true" title="ESP8266 WiFi server with SPIFFS"><pre><code class="language-cpp">/*

ESP8266 WiFi Server with SPIFFS
by Roland Pelayo

Full tutorial: https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/

Rev 1.0 - Initial code - September 19, 2020

*/

//Declare libraries
#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;
#include &lt;FS.h&gt;

//provide your own WiFi SSID and password
const char* ssid = &quot;&lt;Your WiFi SSID&gt;&quot;;
const char* password = &quot;&lt;Your WiFi Password&gt;&quot;;

//Create WebServer instance
ESP8266WebServer server(80);

void setup() {
  //Setup on-board LED
  pinMode(2, OUTPUT);
  //For debugging
  Serial.begin(115200);
  //Initiate WiFi Connection
  WiFi.begin(ssid, password);
  Serial.println(&quot;&quot;);
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(&quot;.&quot;);
  }
  Serial.println(&quot;&quot;);
  Serial.print(&quot;Connected to &quot;);
  //Print your WiFi&#039;s SSID (might be insecure)
  Serial.println(ssid);
  Serial.print(&quot;IP address: &quot;);
  //Print your local IP address (needed for browsing the app)
  Serial.println(WiFi.localIP());

  if(!SPIFFS.begin())
  {
    // Serious problem
    Serial.println(&quot;SPIFFS Mount failed&quot;);
  } else {
    Serial.println(&quot;SPIFFS Mount succesfull&quot;);
  }

  server.onNotFound([]() { // If the client requests any URI
    if (!handleFileRead(server.uri())) // send it if it exists
      server.send(404, &quot;text/plain&quot;, &quot;404: Not Found&quot;); // otherwise, respond with a 404 (Not Found) error
  });

  //start web server
  server.begin();
  //Just stating things
  Serial.println(&quot;HTTP server started&quot;);
}

void loop() {
  server.handleClient(); //make the ESP32 respond to web clients
}

bool handleFileRead(String path) { // send the right file to the client (if it exists)
  Serial.println(&quot;handleFileRead: &quot; + path);
  if (path.endsWith(&quot;/&quot;)) path += &quot;index.html&quot;; // If a folder is requested, send the index file
  String contentType = getContentType(path); // Get the MIME type
  if (SPIFFS.exists(path)) { // If the file exists
    File file = SPIFFS.open(path, &quot;r&quot;); // Open it
    size_t sent = server.streamFile(file, contentType); // And send it to the client
    if(path == &quot;/LEDOn.html&quot;){
      digitalWrite(2, LOW);
    }else if(path == &quot;/LEDOff.html&quot;){
      digitalWrite(2, HIGH);
    }
    file.close(); // Then close the file again
    return true;
  }
  Serial.println(&quot;\tFile Not Found&quot;);
  return false; // If the file doesn&#039;t exist, return false
}

String getContentType(String filename){
  if(filename.endsWith(&quot;.htm&quot;)) return &quot;text/html&quot;;
  else if(filename.endsWith(&quot;.html&quot;)) return &quot;text/html&quot;;
  else if(filename.endsWith(&quot;.css&quot;)) return &quot;text/css&quot;;
  else if(filename.endsWith(&quot;.jpg&quot;)) return &quot;image/jpeg&quot;;
  return &quot;text/plain&quot;;
}</code></pre></pre>
<p>First is the inclusion of the FS library:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">#include &lt;FS.h&gt;</code></pre></pre>
<p>This already comes with the ESP8266 core so no need to install it.</p>
<p>Then we start SPIFFS like this:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">if (!SPIFFS.begin())
{
  // Serious problem
  Serial.println(&quot;SPIFFS Mount failed&quot;);
} else {
  Serial.println(&quot;SPIFFS Mount succesfull&quot;);
}</code></pre></pre>
<p>This way, if SPIFFS fail, we will know via serial monitor.</p>
<p>We will not be using <em>server.on()</em> as before. Instead, we’ll do the opposite:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">server.onNotFound([]() { // If the client requests any URI
  if (!handleFileRead(server.uri())) // send it if it exists
    server.send(404, &quot;text/plain&quot;, &quot;404: Not Found&quot;); // otherwise, respond with a 404 (Not Found) error
});</code></pre></pre>
<p>The way the server works now is that it will search for files that a client requests. When the client accesses a URL on the server, the file associated with that URL is read from SPIFFS. If the file is not found, a “404:Not Found” is shown on the page. File reading is in a function I call handleFileRead():</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">bool handleFileRead(String path) { // send the right file to the client (if it exists)
  Serial.println(&quot;handleFileRead: &quot; + path);
  if (path.endsWith(&quot;/&quot;)) path += &quot;index.html&quot;; // If a folder is requested, send the index file
  String contentType = getContentType(path); // Get the MIME type
  if (SPIFFS.exists(path)) { // If the file exists
    File file = SPIFFS.open(path, &quot;r&quot;); // Open it
    size_t sent = server.streamFile(file, contentType); // And send it to the client
    if(path == &quot;/LEDOn.html&quot;){
       digitalWrite(2, LOW);
    }else if(path == &quot;/LEDOff.html&quot;){
       digitalWrite(2, HIGH);
    }
    file.close(); // Then close the file again
    return true;
  }
  Serial.println(&quot;\tFile Not Found&quot;);
  return false;
}</code></pre></pre>
<p>This is also where we control the LED. When the user accesses the file <em>LEDOn.html</em>, we turn on the LED by making it LOW (the LED is active LOW). Alternatively, when the user accesses the file <em>LEDOff.html</em>, we turn off the LED.</p>
<p>You’ll also notice this function:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">String getContentType(String filename){
  if(filename.endsWith(&quot;.htm&quot;)) return &quot;text/html&quot;;
  else if(filename.endsWith(&quot;.html&quot;)) return &quot;text/html&quot;;
  else if(filename.endsWith(&quot;.css&quot;)) return &quot;text/css&quot;;
  else if(filename.endsWith(&quot;.jpg&quot;)) return &quot;image/jpeg&quot;;
  return &quot;text/plain&quot;;
}</code></pre></pre>
<p>This returns the <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types">MIME type</a> of the file being accessed. This is important as browsers need to know what type of file they are presenting. This is similar to how operating systems view different file extensions.</p>
<p>Upload the sketch, open the serial monitor to acquire the IP address and use that in your browser. This should appear:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-1.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4725" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-1.png" alt="" width="588" height="517" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-1.png 588w, https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-1-300x264.png 300w" sizes="auto, (max-width: 588px) 100vw, 588px" /></a></p>
<p>Click START and you’ll be on the LEDOff page:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-2.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4726" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-2.png" alt="" width="573" height="509" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-2.png 573w, https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-2-300x266.png 300w" sizes="auto, (max-width: 573px) 100vw, 573px" /></a></p>
<p>Click the bulb image to turn on the on-board LED!</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-3.png"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4727" src="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-3.png" alt="" width="561" height="506" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-3.png 561w, https://www.teachmemicro.com/wp-content/uploads/2020/09/spiffs-web-server-3-300x271.png 300w" sizes="auto, (max-width: 561px) 100vw, 561px" /></a></p>
<p>With a dedicated file system, we have improved our basic ESP8266 web server!</p>
<p>The post <a href="https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/">ESP8266 SPIFFs | File System for NodeMCU</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/esp8266-spiffs-web-server-nodemcu/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WiFi Servo Controller using WeMos D1 Mini</title>
		<link>https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wifi-servo-controller-using-wemos-d1-mini</link>
					<comments>https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Tue, 02 Jun 2020 05:34:42 +0000</pubDate>
				<category><![CDATA[ESP8266 Projects]]></category>
		<category><![CDATA[ESP8266 Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=4380</guid>

					<description><![CDATA[<p>In this article, I will guide you to the steps on how to build a WiFi servo controller project using the WeMos D1 Mini ESP8266 breakout board. Materials WeMos D1 Mini Tower Pro SG90 Micro Servo Connecting wires, power source The WeMos D1 Mini is one of the smallest breakout boards for the ESP8266. In &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini/">WiFi Servo Controller using WeMos D1 Mini</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this article, I will guide you to the steps on how to build a WiFi servo controller project using the WeMos D1 Mini <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a> breakout board.</p>
<p><span id="more-4380"></span></p>
<h3><strong>Materials</strong></h3>
<ul>
<li>WeMos D1 Mini</li>
<li>Tower Pro SG90 Micro Servo</li>
<li>Connecting wires, power source</li>
</ul>
<p>The WeMos D1 Mini is one of the smallest breakout boards for the ESP8266. In this project, I will <a href="https://www.teachmemicro.com/getting-started-wemos-d1-mini/">write the code for the WeMos D1 using the Arduino IDE</a>.</p>
<p>All digital pins of the WeMos D1 Mini support PWM so there’s a lot of options in connecting the servo motor. I will presume that you already know <a href="https://www.teachmemicro.com/arduino-servo-motor-tutorial/">how a servo motor</a> works with a microcontroller.</p>
<p>The SG90 servo motor was chosen primarily because of its lower power consumption. I haven’t tried a larger servo motor but I presume using it, with the WeMos D1 on WiFi, will strain the device.</p>
<h3>Wiring Diagram</h3>
<p>The WeMos D1 Mini connects to the servo motor as shown:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller_bb.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4381" src="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller_bb.jpg" alt="WeMos D1 Mini Servo Controller Wiring" width="834" height="420" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller_bb.jpg 834w, https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller_bb-300x151.jpg 300w, https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller_bb-768x387.jpg 768w" sizes="auto, (max-width: 834px) 100vw, 834px" /></a></p>
<p>As previously mentioned, all digital pins of the WeMos D1 Mini supports PWM. I chose D4 because it’s the closest one to the power pins.</p>
<h3><strong>WiFi Servo Controller App</strong></h3>
<p>Most WiFi servo controllers I see use buttons to move the servo motor arm between positions. For this project, I decided to use a rotating wheel to move the servo motor arm.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller-app.jpg"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-4383" src="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller-app.jpg" alt="wemos servo controller app" width="285" height="455" srcset="https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller-app.jpg 285w, https://www.teachmemicro.com/wp-content/uploads/2020/06/wemos-servo-controller-app-188x300.jpg 188w" sizes="auto, (max-width: 285px) 100vw, 285px" /></a></p>
<p>To achieve this, I need to use <a href="https://jqueryui.com/">JQuery UI</a> to make the wheel rotatable and then <a href="https://api.jquery.com/jquery.ajax/">AJAX</a> to send the angle of the wheel to be read by the WeMos D1 server. JQuery UI is for desktop web applications so I also needed to <a href="https://www.jqueryscript.net/other/CSS3-Rotatable-jQuery-UI.html">add a plugin</a> for the app to work on touch devices. Finally, I also used <a href="https://www.w3schools.com/bootstrap/default.asp">bootstrap</a> to position the elements on the app.</p>
<p>All in all, these were the needed Javascript libraries:</p>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">&lt;script src=&#039;https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js&#039;&gt;&lt;/script&gt;
&lt;script type=&#039;text/javascript&#039; src=&#039;https://code.jquery.com/ui/1.11.4/jquery-ui.js&#039;&gt;&lt;/script&gt;
&lt;script type=&#039;text/javascript&#039; src=&#039;https://www.jqueryscript.net/demo/jQuery-UI-Rotatable-Elements/jquery.ui.rotatable.js&#039;&gt;&lt;/script&gt;
&lt;script src=&#039;https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js&#039;&gt;&lt;/script&gt;
&lt;script src=&#039;https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js&#039;&gt;&lt;/script&gt;</code></pre></pre>
<p>These are all in the <em>&lt;head&gt;</em> tag of the app.</p>
<p>Here’s the HTML code for the <em>&lt;body&gt;</em> of the app:</p>
<div class="container">
<div class="row">
<div class="col-xs-12">
<pre class="lang:xhtml decode:true "><pre><code class="language-cpp">&lt;div class=&#039;container&#039;&gt;
  &lt;h1&gt;WeMos D1 Servo Controller&lt;/h1&gt; &quot;
  &lt;h4&gt;Rotate wheel to rotate servo&lt;/h4&gt;&quot;
  &lt;a href=&#039;https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini&#039;&gt;Full tutorial&lt;/a&gt;&quot;
  &lt;div class=&#039;row&#039;&gt;
     &lt;div class=&#039;col-xs-12&#039;&gt;
       &lt;div id=&#039;wheel&#039;&gt;&lt;/div&gt;
     &lt;/div&gt;
     &lt;div class=&#039;col-xs-12&#039;&gt;
        &lt;img id=&#039;tmm-logo&#039; src=&#039;https://i.imgur.com/G80eVhL.png&#039; /&gt;
      &lt;/div&gt;
   &lt;/div&gt;
&lt;/div&gt;</code></pre></pre>
<p>The wheel is the background image of the ‘wheel’ <em>&lt;div&gt;</em>. It is tied to a JQuery script and is rotatable thanks to the <a href="https://github.com/godswearhats/jquery-ui-rotatable">Rotatable library</a>. Here’s the script:</p>
</div>
</div>
</div>
<div>
<pre class="lang:js decode:true"><pre><code class="language-cpp">$(document).ready(function(){
            $(&#039;#wheel&#039;).draggable({handle: &#039;.ui-rotatable-handle&#039;}).rotatable({
               rotate: function(e, ui){
               var degrees = ui.angle.current * 180/Math.PI;
               if ( degrees &gt; 90 ) {    
                  ui.angle.current = Math.PI/2;    
               } else if ( degrees &lt; -90) {        
                  ui.angle.current = -1*Math.PI/2;  
               }
               degrees = degrees + 90;
               console.log(degrees);
               var s = String(degrees);
            $.ajax({
               type: &#039;POST&#039;,
               url: &#039;dataHandler&#039;,
               data: s,
               contentType: &#039;application/x-www-form-urlencoded&#039;
            });
           },snap: true   //for the wheel to snap at discrete angles
          });
});;</code></pre></pre>
<p>Every time the wheel rotates, the angle in radians is returned. Degrees is easier to imagine so I converted it:</p>
<pre class="lang:js decode:true "><pre><code class="language-cpp">$(&#039;#wheel&#039;).draggable({handle: &#039;.ui-rotatable-handle&#039;}).rotatable({
               rotate: function(e, ui){
               var degrees = ui.angle.current * 180/Math.PI;
               ...</code></pre></pre>
<p>Since servo motors rotate from 0 to 180 degrees, I also needed to limit the rotation of the wheel.</p>
<pre class="lang:js decode:true"><pre><code class="language-cpp">if ( degrees &gt; 90 ) {    
      ui.angle.current = Math.PI/2;    
  } else if ( degrees &lt; -90) {        
      ui.angle.current = -1*Math.PI/2;  
  }
  ...</code></pre></pre>
<p>Then I passed the angle to the server, converting it to 0 to 180 degrees to match that of the Arduino library.</p>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">...
    degrees = degrees + 90;
    console.log(degrees);    //for debugging on the browser
    var s = String(degrees);
    $.ajax({
         type: &#039;POST&#039;,
         url: &#039;dataHandler&#039;,
         data: s,
         contentType: &#039;application/x-www-form-urlencoded&#039;
    });</code></pre></pre>
<h3><strong>Arduino Code/Sketch</strong></h3>
<p>Besides the main Arduino sketch, the project includes the headers “mainpage.h” and “jscript.h”. Both header files contain <a href="https://www.arduino.cc/reference/en/language/variables/utilities/progmem/">PROGMEM</a> constants containing the HTML and Javascript for the app. I believe it’s easier to debug if they are separated from the main Arduino code.</p>
<p>As for the Arduino sketch, I used the same code snippets for establishing a WiFi server. The relevant parts are:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">//Home page. Contents of &#039;page&#039; is in mainpage.h
server.on(&quot;/&quot;, []() {
  server.send(200, &quot;text/html&quot;, page);
});
//JavaScript! Contents of &#039;javascript&#039; is in jscript.h
server.on(&quot;/jscript.js&quot;, []() {
  server.send(200, &quot;text/javascript&quot;, javascript);
});
//POST data handler
server.on(&quot;/dataHandler&quot;,HTTP_POST,dataHandler);
//start web server
server.begin();
//Just stating things
Serial.println(&quot;HTTP server started&quot;);
}</code></pre></pre>
<p>When a client visits the home page (the IP address of the WeMos D1), the client sees the contents of the ‘page’ constant which is the HTML of the app. The ‘page’ constant is inside ‘mainpage.h’.</p>
<p>In the HTML, a line calls <em>jscript.js</em>:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">&lt;script type=&#039;text/javascript&#039; src=&#039;jscript.js&#039;&gt;&lt;/script&gt;</code></pre></pre>
<p>Since <em>jscript.js</em> is a file inside the server, it must pass the client to the relevant file. This is done by passing the contents of the constant ‘javascript’ which is inside ‘jscript.h’</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">//JavaScript! Contents of &#039;javascript&#039; is in jscript.h
server.on(&quot;/jscript.js&quot;, []() {
  server.send(200, &quot;text/javascript&quot;, javascript);
});</code></pre></pre>
<p>Finally, since the AJAX call inside the script was a POST request, the server must also handle it:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">//POST data handler
server.on(&quot;/dataHandler&quot;,HTTP_POST,dataHandler);</code></pre></pre>
<p><em>dataHandler</em> is a function for handling the data from the POST request:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">void dataHandler(){
  String angle = server.arg(&quot;plain&quot;);
  Serial.print(&quot;Received: &quot;);
  Serial.println(angle);
  server.sendHeader(&quot;Location&quot;,&quot;/&quot;);
  server.send(303);
  int pos = angle.toInt();
  myservo.write(pos);
  delay(15);
}</code></pre></pre>
<p>The angle from the AJAX POST is read through:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">String angle = server.arg(&quot;plain&quot;);</code></pre></pre>
<p>For debugging, I printed the received angle to the serial monitor:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">Serial.print(&quot;Received: &quot;);
Serial.println(angle);</code></pre></pre>
<p>According to protocol, servers must respond to the client after a POST request, thus:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">server.sendHeader(&quot;Location&quot;,&quot;/&quot;);
server.send(303);</code></pre></pre>
<p>This is simply sending back the client to the home page with status 303.</p>
<p>The received angle is a string, so it’s converted to int and then used to rotate the servo motor:</p>
<pre class="lang:arduino decode:true "><pre><code class="language-cpp">int pos = angle.toInt();
myservo.write(pos);
delay(15);</code></pre></pre>
<p>The full code can be downloaded in <a href="https://github.com/kurimawxx00/wemos-d1-servo-controller">my repository</a>.</p>
<h3>Output Video</h3>
<p>Once the code is uploaded to the WeMos D1 Mini, the serial monitor will give its IP address. The app is viewable through that IP address using a web browser.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/SD_A8o55lZE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="allowfullscreen"></iframe></p>
<p>Honestly, I was expecting an almost real-time reaction by the servo motor but it can’t be helped; the ESP8266 has processing limitations as a web server. Using a small delay between turns seems to overwhelm the ESP8266. I presume the ESP32 will have a much better reaction time.</p>
<p>Edit: Surprisingly, using the app on a desktop computer results in a much faster reaction time. So maybe the phone is having trouble connecting through WiFi.</p>
<p>Nevertheless, I hope someone found this WiFi servo controller project useful. For questions, or suggestions, kindly drop a comment below.</p>
</div>
<p>The post <a href="https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini/">WiFi Servo Controller using WeMos D1 Mini</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/wifi-servo-controller-using-wemos-d1-mini/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Send Sensor Data to ThingSpeak via ESP8266</title>
		<link>https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=send-sensor-data-thingspeak-esp8266</link>
					<comments>https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 06 Dec 2019 23:50:10 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<category><![CDATA[Sensor Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=3903</guid>

					<description><![CDATA[<p>In the previous tutorial, we set up a soil moisture sensor and have its data readable via WiFi. However, that data is only accessible if the NodeMCU ESP8266 and the client (smartphone, PC, etc.) is in the same network. In this tutorial, we will use a service that allows us to read the data from &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/">Send Sensor Data to ThingSpeak via ESP8266</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In the <a href="https://www.teachmemicro.com/wifi-soil-moisture-arduino/">previous tutorial</a>, we set up a soil moisture sensor and have its data readable via WiFi. However, that data is only accessible if the NodeMCU <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a> and the client (smartphone, PC, etc.) is in the same network. In this tutorial, we will use a service that allows us to read the data from the sensor from any device connected to the Internet.</p>
<p><span id="more-3903"></span></p>
<p>The service I’m talking about is <a href="https://thingspeak.com/">ThingSpeak by MathWorks</a>. Most engineering students and professors might be familiar with MathWorks which is the same company behind MATLAB. ThingSpeak has already been featured in <a href="https://www.teachmemicro.com/send-data-sim800-gprs-thingspeak/">one of my projects</a>. However, in that project, I used cellular data to connect to the Internet. This tutorial will use the WiFi connection through the ESP8266 NodeMCU.</p>
<h3><strong>Video Tutorial</strong></h3>
<p><iframe loading="lazy" src="https://www.youtube.com/embed/nLtDd3k-Eyg" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>
<h3><strong>Setting Up a ThingSpeak Account</strong></h3>
<p>ThingSpeak requires a MathWorks account for login. So before anything else, go to <a href="https://www.mathworks.com/mwaccount/register"><b><i>mathworks.com/mwaccount/register</i></b></a> and provide the required information:</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh3.googleusercontent.com/ZkuMUCao3YyvJSfLF_HsoIYe2TDFwYX1vmOXKaJegtWMxDJwdNV70LxmuwiYFnG_sh1pP6BteE6tKD8BKyGH1_NLc-ciiHjEdQzJ0ag2WhUghELV2g3XKVjxdPLOx9OzKOv_7e0b" alt="create-mathworks-account" width="1119" height="591" /></p>
<p>Make sure you can access the email you provided as it's required to verify your email:</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh4.googleusercontent.com/2WNJNqrZJoGalTFmBRnIk8b_otRRDeSyC6LjbyqLbE4rnISuJoHKI-6wtxsNSDRK963D1ObGDrH0lwZ-S03GCo-imcyXDDuZh4UmCpaIlulolWlNV9jPK9RZBogQzSXRfvp7mHem" alt="verify-mathworks-email" width="1119" height="597" /></p>
<p class="c1"><span class="c4">Open your email and click on the “verify” button. You will then be redirected to this page which asks for additional information:<br />
</span></p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh6.googleusercontent.com/kB0rgoY4MsFX7KZ98HiSc5XxeFz9OSzPCFKnJBeDbgApitJt0m1ueqRFcYfeK2JyKYWYSivYqyiOKyxgQrmVitoIHwImhpkE8LHv1ojPws-OL3utkmi92YHijKrx8W8xS6OMIXu0" alt="mathworks-additional-info" width="1123" height="595" /></p>
<p id="tirgFvq"><span class="c4">If you or your university owns a licensed MATLAB software, you can enter the activation key or license number on the form shown:</span></p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh3.googleusercontent.com/-QWRr6MVNUGPMgoTuaHnF92IjzHtReEau_P7hXBItzQ_OTW3G73bzfbloFFxMs14BIVek4N6Bd3RToP4a4GlxFGXQKlxlMoybYhXIwWe3fpznLO3pU_d-V4dKzBmZ5f3IlPK9V2n" alt="mathworks-add-matlab-license" width="1125" height="595" /></p>
<p>If you don't have any MATLAB license, just skip this part. I haven't explored the benefits of adding a MATLAB license here but <em>maybe</em> your account gets upgraded.</p>
<p id="ijBRhDB"><span class="c0">After this, your MathWorks profile is now ready!</span></p>
<h3><strong>Creating a ThingSpeak Channel</strong></h3>
<p>Now that you have a MathWorks account, go to <span class="c7 c8"><a href="http://thingspeak.com/login">thingspeak.com/login</a>:</span></p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh3.googleusercontent.com/CVsK606eRY6uj4wJkxk2AsiRvLmuMfOhX78gUTDGFIdE7h5mj38XUvodDxB5lIjAh8nQQby065nMBtwupinaP3RgRk5FQQRiqLF3hQJKToo23fGId9dg1ZaqG1VkElFk2kfEZ8VW" alt="thingspeak-login" width="1121" height="597" /></p>
<p id="zMfMUaI"><span class="c0">Enter your MathWorks email and password to sign in. A pop-up window will appear. Select one of the options; the other field is optional.</span></p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh3.googleusercontent.com/0PFdB3vd_bVM0CyOiPgiDafNIGnZGGqbO3-l22ZNyLbsV1hh51riNkqAPB-kjfBegVXqqGPWkk8uN8-SD7DenXzJRXwDjrdkgo5Iz9CzLdJa2bGcDBP5OwkxF04yKL0dI9y0aVGL" alt="thingspeak-usage" width="1123" height="595" /></p>
<p>You should now be in the "channels" page. ThingSpeak requires you to create a <span class="c7">channel </span>with up to 8 <span class="c7">fields</span><span class="c0">. Free users are limited to 4 channels and 255 characters per field.</span></p>
<p>Clicking the "New Channel" button directs you to this page:</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh3.googleusercontent.com/sW-rupD4-8ZeGLZdojPKylSexCRw41l5Ozg0FDRen3_QTwc6EVDbN497wVaGr3dMODb_nxxOmsL1O7k-iCiuKtE-XCYVz_jU8KXi6E7XIf8DMcdOdcJPbLs5_xn6xDQbxOV4EJre" alt="thingspeak-create-channel" width="1127" height="597" /></p>
<p id="fVbSKRN">Here, I named my channel Soil Moisture, gave a brief description and named 1 field. After creating the channel, you’ll be on a page where you’ll see an empty time plot of your created field.</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh4.googleusercontent.com/Jdco29d3CXjMNqtqIOZfZgaauAYkq-Bjc3DCmlqtbop0m120ZVPyEn0sfamVMQx6onmLngg4RXc5imKyo9smwGlFGH6EifXnAtjTwcOz6AAZtM3l_7Y_awPoUeyCTlhX0mXPWGtd" alt="thingspeak-empty-field" width="1123" height="599" /></p>
<p>Updating the field requires simple HTTP GET requests. For free accounts, the field updates every 15 seconds.</p>
<p>Click the API Keys tab:</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh4.googleusercontent.com/n-esy9svxI3o3T88wSFRamBehWVd3Y2N8-z4mABEszljWN2VvBnkxkudxjQKUWwYm10b-NiDSPFNigTr3X9ZJfnHfbmqIZb0ZqJ3qsvj2vauSunvoLc6gTRorZkofA-iIAb2vd5R" alt="thingspeak-api-keys" width="1123" height="597" /></p>
<p class="c1">Here we can see the possible API requests. For example, to update the field <em>SoilMoisture</em>, I copy the URL <span class="c11"><a class="c5" href="https://api.thingspeak.com/update?api_key%3DUTB05H415R3M0SIX%26field1%3D0">https://api.thingspeak.com/update?api_key=UTB05H415R3M0SIX&amp;field1=0</a></span></p>
<p class="c1">The last part of this URL is the updates to the <em>SoilMoisture</em> field. We can test this by copy-pasting the URL above to a browser and just change the last number to any number. Here, I changed the number to 100 and pressed enter:</p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh5.googleusercontent.com/u1fJ5wqvnWeH26lzRAazwkvFtnullAXFs2tA-O6VIlqloIugwIJuAmWOYoMhQtbsx1Bi6-YIga-PdDtIkyZMfD9n1mWq77JXnDFOLZf2X0P1PGLvFCWEQMov-uytezNy_GxD_wEp" alt="test-api-browser" width="1121" height="593" /></p>
<p id="fPKCuSn"><span class="c0">The time plot on the “private view” tab now updates:</span></p>
<p><img loading="lazy" decoding="async" class="alignnone" src="https://lh5.googleusercontent.com/bWa_hZ-b1nA1_Mk591T9Z8B4n7KBE6H2w90MXigokUZUUArXsgfpvVFyLLUmn-sS6A3uIEZCidGpqTdjXsZ5nOKNeVT4Vykv9trvKBycGL-CxcanaU0B4u2Jw8jKl1_OmPx0SRlc" alt="updated-thingspeak-field" width="1127" height="595" /></p>
<h3><b>Uploading Sketch to NodeMCU</b></h3>
<p>Now that we know how to send data to ThingSpeak through HTTP GET request, it’s time to create a sketch for the ESP8266 NodeMCU board.</p>
<p>Modify the sketch below at lines 5 &amp; 6 to your own WiFi SSID and password. Also, modify line 9 to your own ThingSpeak API key.</p>
<pre class="lang:arduino decode:true " title="Soil Moisture Sensor to ThingSpeak"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;

const char* ssid     = &quot;your-ssid&quot;;
const char* password = &quot;your-password&quot;;

const char* host = &quot;api.thingspeak.com&quot;;
const char* APIKey = &quot;UTB05H415R3M0SIX&quot;;

void setup()
{
    Serial.begin(115200);
    delay(10);

    // We start by connecting to a WiFi network

    Serial.println();
    Serial.println();
    Serial.print(&quot;Connecting to &quot;);
    Serial.println(ssid);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(&quot;.&quot;);
    }

    Serial.println(&quot;&quot;);
    Serial.println(&quot;WiFi connected&quot;);
    Serial.println(&quot;IP address: &quot;);
    Serial.println(WiFi.localIP());
}

int value = 0;

void loop()
{
    delay(5000);
    value = analogRead(A0);

    Serial.print(&quot;connecting to &quot;);
    Serial.println(host);

    // Use WiFiClient class to create TCP connections
    WiFiClient client;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
        Serial.println(&quot;connection failed&quot;);
        return;
    }

    // We now create a URI for the request
    String url = &quot;/update&quot;;
    url += &quot;?api_key=&quot;;
    url += APIKey;
    url += &quot;&amp;field1=&quot;;
    url += value;

    Serial.print(&quot;Requesting URL: &quot;);
    Serial.println(url);

    // This will send the request to the server
    client.print(String(&quot;GET &quot;) + url + &quot; HTTP/1.1\r\n&quot; +
                 &quot;Host: &quot; + host + &quot;\r\n&quot; +
                 &quot;Connection: close\r\n\r\n&quot;);
    unsigned long timeout = millis();
    while (client.available() == 0) {
        if (millis() - timeout &gt; 5000) {
            Serial.println(&quot;&gt;&gt;&gt; Client Timeout !&quot;);
            client.stop();
            return;
        }
    }

    // Read all the lines of the reply from server and print them to Serial
    while(client.available()) {
        String line = client.readStringUntil(&#039;\r&#039;);
        Serial.print(line);
    }

    Serial.println();
    Serial.println(&quot;closing connection&quot;);
}</code></pre></pre>
<p>This sketch sends reading from the sensor with about 5 seconds interval. The sensor, from the previous tutorial, connects to the A0 pin of the NodeMCU.</p>
<p>The graph on the ThingSpeak private view now updates regularly (see video for output).</p>
<p>For the next part of this tutorial, we will embed the data from ThingSpeak to a website.</p>
<p>The post <a href="https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/">Send Sensor Data to ThingSpeak via ESP8266</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/send-sensor-data-thingspeak-esp8266/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>WiFi Soil Moisture Sensor with Arduino Program</title>
		<link>https://www.teachmemicro.com/wifi-soil-moisture-arduino/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wifi-soil-moisture-arduino</link>
					<comments>https://www.teachmemicro.com/wifi-soil-moisture-arduino/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 02 Dec 2019 06:30:15 +0000</pubDate>
				<category><![CDATA[ESP8266 Tutorial]]></category>
		<category><![CDATA[Sensor Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=3896</guid>

					<description><![CDATA[<p>Plants need enough water to survive. But what if you forgot to water the plants? This multi-part ESP8266 tutorial aims to provide a simple soil moisture sensor that reminds you, via WiFi, that your flora needs a shower. Soil Moisture Sensor The soil moisture sensor for this project is an inexpensive sensor that reads the &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/wifi-soil-moisture-arduino/">WiFi Soil Moisture Sensor with Arduino Program</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Plants need enough water to survive. But what if you forgot to water the plants? This multi-part <a href="https://www.win-source.net/products/detail/espressif/esp8266ex.html">ESP8266</a> tutorial aims to provide a simple soil moisture sensor that reminds you, via WiFi, that your flora needs a shower.</p>
<p><span id="more-3896"></span></p>
<h3><b>Soil Moisture Sensor</b></h3>
<p>The soil moisture sensor for this project is an inexpensive sensor that reads the resistance of the soil.</p>
<p><img decoding="async" class="aligncenter" title="" src="https://lh3.googleusercontent.com/ya85ozgrHgSJw2-g11com9NQap7JxYeQhDMWB5Xzq_5gnNaaDu7l3GQrCRuZuqG463yYxlflEY6OqGt1vZJJeorEyTxkRJ04EXAZ8Mz46IyikfYG_qXmtOb4maB9oYbSffpL5vPb" alt="" /></p>
<p>Soil moisture is inversely proportional to its resistance, i.e., the higher the water content in the soil, the lower its resistance. The sensor is designed as an electrode whose resistance varies with both the moisture and how deep it is plunged into the soil.</p>
<p>The type of soil and temperature are other factors that determine soil moisture. Thus, reading soil moisture through this sensor might not be enough for more complex applications or scientific researches. However, for our intended purpose -- which is to simply notify the user if the plant needs watering -- this sensor fits the bill.</p>
<p>The sensor comes with a LM393 module that helps give out a digital or an analog signal. If the soil moisture reaches a value (adjustable through the potentiometer on the module), the digital pin (D0) goes high and the D0-LED on the module turns on. On the other hand, the analog pin (A0) gives a voltage proportional to the soil moisture. The higher the soil moisture, the lower this voltage goes.</p>
<p>&nbsp;</p>
<h3><b>Sending  Sensor Values through WiFi</b></h3>
<p>For a user to be able to read the soil moisture through WiFi, a microcontroller with wireless network capabilities is required. For this project, I will be using the ESP8266 microcontroller, particularly the <a href="https://en.wikipedia.org/wiki/NodeMCU">NodeMCU</a> V2.0 board.</p>
<p>The soil moisture sensor connects to the NodeMCU like this:</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb.png"><img loading="lazy" decoding="async" class="size-large wp-image-3898 aligncenter" src="https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb-1024x491.png" alt="Soil moisture sensor to ESP8266" width="640" height="307" srcset="https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb-1024x491.png 1024w, https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb-300x144.png 300w, https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb-768x369.png 768w, https://www.teachmemicro.com/wp-content/uploads/2019/12/soilmoisture_esp8266_bb.png 1488w" sizes="auto, (max-width: 640px) 100vw, 640px" /></a></p>
<p>Next, load the sketch below to the NodeMCU. Modify lines 6 and 7 according to your WiFi SSID and password. Make sure your <a href="https://www.teachmemicro.com/intro-nodemcu-arduino/">NodeMCU can be programmed with the Arduino IDE</a>.</p>
<pre class="lang:arduino decode:true"><pre><code class="language-cpp">#include &lt;ESP8266WiFi.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;ESP8266WebServer.h&gt;

// Replace with your network credentials
const char* ssid = &quot;&lt;Your WiFI SSID&gt;&quot;;
const char* password = &quot;&lt;Your WiFI Password&gt;&quot;;

ESP8266WebServer server(80);   //instantiate server at port 80 (http port)

String page = &quot;&quot;;
double data; 
void setup(void){

  pinMode(A0, INPUT);
  
  delay(1000);
  Serial.begin(115200);
  WiFi.begin(ssid, password); //begin WiFi connection
  Serial.println(&quot;&quot;);
  
  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(&quot;.&quot;);
  }
  Serial.println(&quot;&quot;);
  Serial.print(&quot;Connected to &quot;);
  Serial.println(ssid);
  Serial.print(&quot;IP address: &quot;);
  Serial.println(WiFi.localIP());
  server.on(&quot;/&quot;, [](){
    page = &quot;&lt;h1&gt;Soil Moisture Sensor with ESP8266&lt;/h1&gt;&lt;h3&gt;Value:&lt;/h3&gt; &lt;h4&gt;&quot;+String(data)+&quot;&lt;/h4&gt;&quot;;
    server.send(200, &quot;text/html&quot;, page);
  });
  
  server.begin();
  Serial.println(&quot;Web server started!&quot;);
}
 
void loop(void){
  data = analogRead(A0);
  delay(1000);
  server.handleClient();
}</code></pre></pre>
<p>Upload the sketch and if successful, open serial monitor (make sure baud rate is set to 115200!). The serial monitor displays the IP address of the NodeMCU.</p>
<p>Using your preferred browser, visit that IP address. The soil moisture value is now on the web page!</p>
<p>The disadvantage of the given sketch is that you need to refresh the page to get updates. You can check out my <a href="https://www.teachmemicro.com/nodemcu-ajax-dynamic-sensor-data-web-page/">AJAX tutorial</a> for dynamically changing sensor values on a web page. Also, what does those numbers mean? We'll make our project better in the next part of this tutorial!</p>
<p>The post <a href="https://www.teachmemicro.com/wifi-soil-moisture-arduino/">WiFi Soil Moisture Sensor with Arduino Program</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/wifi-soil-moisture-arduino/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: www.teachmemicro.com @ 2026-08-07 23:12:29 by W3 Total Cache
-->