<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arduino ESP32 Raspberry Pi Tutorials</title>
    <description>The latest articles on DEV Community by Arduino ESP32 Raspberry Pi Tutorials (@arduino_getstarted_f52a1a).</description>
    <link>https://dev.to/arduino_getstarted_f52a1a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4193036%2F66bf7469-f054-435d-ae5a-bc6740df819c.png</url>
      <title>DEV Community: Arduino ESP32 Raspberry Pi Tutorials</title>
      <link>https://dev.to/arduino_getstarted_f52a1a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/arduino_getstarted_f52a1a"/>
    <language>en</language>
    <item>
      <title>ESP32 - LED Matrix via Web</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Thu, 22 Oct 2026 10:30:59 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/esp32-led-matrix-via-web-3nbl</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/esp32-led-matrix-via-web-3nbl</guid>
      <description>&lt;p&gt;This build turns an ESP32 into a web-controlled signboard. You type text into a web page, it travels over WebSocket to the ESP32, and the ESP32 scrolls it across an FC-16 LED matrix. It's a neat way to see how a browser, a web server running on a microcontroller, and a physical display can talk to each other in real time.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://esp32io.com/tutorials/esp32-led-matrix-via-web" rel="noopener noreferrer"&gt;ESP32 - LED Matrix via Web&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DRBKM49W" rel="noopener noreferrer"&gt;38-pin ESP32 ESP-WROOM-32 Dev Module - Narrow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GQXZ2RK1" rel="noopener noreferrer"&gt;38-pin ESP32 ESP-WROOM-32 Dev Module - Wide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWN1K4P5" rel="noopener noreferrer"&gt;30-pin ESP32 ESP-WROOM-32 Dev Module - Wide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5P177F8" rel="noopener noreferrer"&gt;ESP32 Uno-form board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5NCCHSH" rel="noopener noreferrer"&gt;ESP32 S3 Uno-form board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BXKKT72V" rel="noopener noreferrer"&gt;FC-16 LED Matrix 32x8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPGC5GTQ" rel="noopener noreferrer"&gt;DC Power Jack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0F5GJWPPZ" rel="noopener noreferrer"&gt;Screw Terminal Expansion Board for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DYDN7LSZ" rel="noopener noreferrer"&gt;Breakout Expansion Board for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMVJNS" rel="noopener noreferrer"&gt;Power Splitter for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DZXCNJTP" rel="noopener noreferrer"&gt;DIYables ESP32 Starter Kit (ESP32 included)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H8XVCLSJ" rel="noopener noreferrer"&gt;DIYables ESP32 S3 Starter Kit (ESP32 S3 included)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;The FC-16 LED matrix connects to the ESP32 over a few data lines, with its CS (chip select) pin going to GPIO21 as set by &lt;code&gt;CS_PIN&lt;/code&gt; in the sketch. If you're not sure how to power the ESP32 and the matrix together, it's worth checking a dedicated guide on powering ESP32 and displays before wiring things up, since a matrix made of multiple LED blocks can draw more current than the ESP32's own pins can supply.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The ESP32 runs two things at once: a web server that serves a page to your browser, and a WebSocket server that keeps a live connection open. When you type text on the page and send it, the message travels over the WebSocket to the ESP32 instead of as a regular HTTP request, which keeps things fast and responsive. On the ESP32 side, the &lt;code&gt;MD_Parola&lt;/code&gt; library takes that text and scrolls it across the LED matrix, while the ESP32 sends a short confirmation message back to the browser over the same WebSocket connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The sketch is split into two files: an &lt;code&gt;.ino&lt;/code&gt; file with the ESP32 logic, and an &lt;code&gt;index.h&lt;/code&gt; file holding the webpage's HTML, CSS and JavaScript. The &lt;code&gt;.ino&lt;/code&gt; file sets up the web server and WebSocket server using the &lt;code&gt;DIYables_ESP32_WebServer&lt;/code&gt; library, initializes the LED matrix with &lt;code&gt;MD_Parola&lt;/code&gt;, and defines handlers for when a WebSocket connection opens, receives a message, or closes. The message handler clears the display and scrolls the incoming text with &lt;code&gt;displayScroll()&lt;/code&gt;, then broadcasts a reply to connected clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;esp32-led-matrix-via-web.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * This ESP32 code is created by esp32io.com
 *
 * This ESP32 code is released in the public domain
 *
 * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-led-matrix-via-web
 */&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;DIYables_ESP32_WebServer.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;"index.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;MD_Parola.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;MD_MAX72xx.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4  // 4 blocks
#define CS_PIN 21      // ESP32 pin GPIO21
&lt;/span&gt;
&lt;span class="c1"&gt;// WiFi credentials&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;WIFI_SSID&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR_WIFI_SSID"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;WIFI_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"YOUR_WIFI_PASSWORD"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create web server instance&lt;/span&gt;
&lt;span class="n"&gt;DIYables_ESP32_WebServer&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;DIYables_ESP32_WebSocket&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;webSocket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// create an instance of the MD_Parola class&lt;/span&gt;
&lt;span class="n"&gt;MD_Parola&lt;/span&gt; &lt;span class="n"&gt;ledMatrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MD_Parola&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HARDWARE_TYPE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CS_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MAX_DEVICES&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// Web Page handlers&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleHome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WiFiClient&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;QueryParams&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTML_CONTENT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// WebSocket event handlers&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketOpen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"New WebSocket connection"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Send welcome message&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Connected to ESP32 WebSocket Server!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;DataType&lt;/span&gt; &lt;span class="n"&gt;dataType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebSocket Received ("&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" bytes): "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayClear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// clear led matrix display&lt;/span&gt;
  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayScroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PA_CENTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PA_SCROLL_LEFT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Broadcast response to all connected clients using the library&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webSocket&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Displayed: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"on LED Matrix"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;webSocket&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;broadcastTXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebSocket sent ("&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" bytes): "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onWebSocketClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CloseCode&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"WebSocket client disconnected"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ESP32 Web Server and WebSocket Server"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;           &lt;span class="c1"&gt;// initialize the object&lt;/span&gt;
  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setIntensity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// set the brightness of the LED matrix display (from 0 to 15)&lt;/span&gt;
  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayClear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// clear led matrix display&lt;/span&gt;

  &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayScroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"esp32io.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PA_CENTER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PA_SCROLL_LEFT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="c1"&gt;// Configure web server routes&lt;/span&gt;
  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;handleHome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Start web server with WiFi connection&lt;/span&gt;
  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;WIFI_SSID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WIFI_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Enable WebSocket functionality&lt;/span&gt;
  &lt;span class="n"&gt;webSocket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enableWebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;webSocket&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Set up WebSocket event handlers&lt;/span&gt;
    &lt;span class="n"&gt;webSocket&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;onOpen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onWebSocketOpen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;webSocket&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onWebSocketMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;webSocket&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;onClose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onWebSocketClose&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to start WebSocket server"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Then handle HTTP requests&lt;/span&gt;
  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Handle WebSocket&lt;/span&gt;
  &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handleWebSocket&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayAnimate&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ledMatrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayReset&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that go wrong
&lt;/h2&gt;

&lt;p&gt;Before uploading, replace the placeholder &lt;code&gt;WIFI_SSID&lt;/code&gt; and &lt;code&gt;WIFI_PASSWORD&lt;/code&gt; values with your actual network credentials, otherwise the ESP32 never gets online. Make sure you've installed both the &lt;code&gt;DIYables ESP32 WebServer&lt;/code&gt; library and &lt;code&gt;MD_Parola&lt;/code&gt; through the Arduino IDE Library Manager, and that you've selected the correct ESP32 board and COM port, since a mismatched board selection is a common reason uploads fail silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://esp32io.com/tutorials/esp32-led-matrix-via-web" rel="noopener noreferrer"&gt;https://esp32io.com/tutorials/esp32-led-matrix-via-web&lt;/a&gt;&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>electronics</category>
      <category>iot</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>ESP32 C3 Super Mini - Switch</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Thu, 22 Oct 2026 04:00:47 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/esp32-c3-super-mini-switch-36ah</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/esp32-c3-super-mini-switch-36ah</guid>
      <description>&lt;p&gt;An ON/OFF switch, also called a toggle switch, flips between two stable states each time you press it and stays there until you press it again - unlike a button, which only reports ON while you hold it down. This tutorial wires a two-pin ON/OFF switch to the ESP32 C3 Super Mini and reads its state in code, a pattern you'll reuse for lamp switches, mode selectors, or any on/off control in a project.&lt;/p&gt;

&lt;p&gt;It also shows the debouncing trick that keeps switch-reading code short and reliable.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/esp32-c3/esp32-c3-super-mini-switch" rel="noopener noreferrer"&gt;ESP32 C3 Super Mini - Switch&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GQXF1NH2" rel="noopener noreferrer"&gt;ESP32 C3 Super Mini&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0D8BBZ6ML" rel="noopener noreferrer"&gt;Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CN8SLLPQ" rel="noopener noreferrer"&gt;ON/OFF Square Switch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CN8VRSRF" rel="noopener noreferrer"&gt;ON/OFF Round Switch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GF7BK7MD" rel="noopener noreferrer"&gt;On/Off Switch Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPGC5GTQ" rel="noopener noreferrer"&gt;DC Power Jack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;Connect one pin of the switch to GPIO7 and the other pin to GND - the two pins have no polarity, so it doesn't matter which goes where. Stick to 3.3V logic; never feed 5V into any GPIO pin on the ESP32 C3 Super Mini. Avoid GPIO8 and GPIO9, since those are boot strapping pins used during startup. For a sturdier connection, solder the wires to the switch pins and cover the joints with heat shrink tubing.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The ESP32 C3 Super Mini has an internal pull-up resistor you can enable in software, so you don't need an external resistor - this tutorial relies on that built-in pull-up. With it enabled, the pin reads HIGH when the switch is open and LOW when it's closed. Because the switch is latching, each press flips the state and it holds there until you press it again, unlike a momentary button that only stays active while held.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The sketch uses the ezButton library, which handles debouncing - filtering the brief electrical noise a mechanical contact produces when it opens or closes - and turns on the internal pull-up resistor for you. It reads the switch on GPIO7 with a 50 ms debounce filter, prints OFF -&amp;gt; ON or ON -&amp;gt; OFF whenever the state changes, and prints the current state as ON or OFF on every loop through the Serial Monitor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;esp32-c3-super-mini-switch.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * This ESP32 C3 Super Mini code was developed by newbiely.com
 *
 * This ESP32 C3 Super Mini code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/esp32-c3/esp32-c3-super-mini-switch
 */&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ezButton.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;ezButton&lt;/span&gt; &lt;span class="nf"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// create ezButton object that attach to the ESP32 C3 SuperMini pin GPIO7&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;115200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setDebounceTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// set debounce time to 50 milliseconds&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// MUST call the loop() function first&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isPressed&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The switch: OFF -&amp;gt; ON"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isReleased&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The switch: ON -&amp;gt; OFF"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onOffSwitch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The switch: OFF"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The switch: ON"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/esp32-c3/esp32-c3-super-mini-switch" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/esp32-c3/esp32-c3-super-mini-switch&lt;/a&gt;&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Arduino Mega - Piezo Buzzer</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Wed, 21 Oct 2026 10:31:05 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/arduino-mega-piezo-buzzer-1d62</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/arduino-mega-piezo-buzzer-1d62</guid>
      <description>&lt;p&gt;A piezo buzzer is one of the cheapest ways to give an Arduino Mega a voice. It turns electrical signals into sound, so you can add beeps, alarms, or melodies to a project without needing a speaker, amplifier, or audio circuit. This guide covers the two main types of buzzer, how they're wired to the Mega, and how the code turns a pin into a sound source.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/arduino-mega/arduino-mega-piezo-buzzer" rel="noopener noreferrer"&gt;Arduino Mega - Piezo Buzzer&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Arduino MEGA&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GTPSYSTZ" rel="noopener noreferrer"&gt;DIYables MEGA Development Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPFZNST2" rel="noopener noreferrer"&gt;USB 2.0 cable type A/B (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMJ1RM" rel="noopener noreferrer"&gt;USB 2.0 cable type C/B (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CM63HJHQ" rel="noopener noreferrer"&gt;3-24V Active Piezo Buzzer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0D8BBPV2S" rel="noopener noreferrer"&gt;Active Piezo Buzzer Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGP95K4" rel="noopener noreferrer"&gt;Passive Piezo Buzzer Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPG2H4V2" rel="noopener noreferrer"&gt;Screw Terminal Block Shield for Arduino Uno/Mega&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWNBDSCX" rel="noopener noreferrer"&gt;Sensors/Servo Expansion Shield for Arduino Mega&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard Shield for Arduino Mega&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ47G4GN" rel="noopener noreferrer"&gt;Enclosure for Arduino Mega&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewbiely.com%2Fimages%2Ftutorial%2Farduino-mega-piezo-buzzer-wiring-diagram.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewbiely.com%2Fimages%2Ftutorial%2Farduino-mega-piezo-buzzer-wiring-diagram.jpg" alt="Arduino Mega - Piezo Buzzer wiring diagram" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A piezo buzzer has two terminals: a negative/ground pin and a positive/signal pin. The negative pin goes to the Arduino Mega's &lt;code&gt;GND&lt;/code&gt;, and the positive pin connects to a digital output pin, such as pin 2 or 4. On wired buzzers the black or shorter wire is usually ground and the red or longer wire is signal; on PCB-mounted modules these are marked with &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;+&lt;/code&gt;. For buzzers in the 3-5V range you can drive them directly from an Arduino digital pin with no extra driver circuitry needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Buzzers split into active and passive types. An active buzzer has its own internal oscillator, so applying a steady HIGH signal makes it produce a fixed tone (typically 2-4 kHz) automatically, just like turning on an LED - no frequency control needed. A passive buzzer has no oscillator; it stays silent under a plain &lt;code&gt;digitalWrite(HIGH)&lt;/code&gt; and needs an alternating signal to vibrate the piezo element and produce sound. Piezo buzzers themselves use a ceramic crystal that flexes when voltage is applied, giving a wide frequency range, very low current draw, and no moving parts to wear out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;For an active buzzer, the code is just digital on/off control: &lt;code&gt;digitalWrite(buzzerPin, HIGH)&lt;/code&gt; starts a continuous tone and &lt;code&gt;digitalWrite(buzzerPin, LOW)&lt;/code&gt; silences it. Because the tone's pitch is fixed by the buzzer's internal oscillator, you shape the sound by timing the pulses instead, for example looping short HIGH/LOW delays to produce a sequence of beeps rather than one long tone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;arduino-mega-piezo-buzzer.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simple continuous beep&lt;/span&gt;
&lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buzzerPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Turn on&lt;/span&gt;
&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                    &lt;span class="c1"&gt;// Beep for 1 second&lt;/span&gt;
&lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buzzerPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LOW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// Turn off&lt;/span&gt;

&lt;span class="c1"&gt;// Beep pattern example&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   &lt;span class="c1"&gt;// Three short beeps&lt;/span&gt;
  &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buzzerPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buzzerPin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LOW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/arduino-mega/arduino-mega-piezo-buzzer" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/arduino-mega/arduino-mega-piezo-buzzer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>arduino</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ESP8266 - Rotary Encoder</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Wed, 21 Oct 2026 04:00:52 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/esp8266-rotary-encoder-1h67</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/esp8266-rotary-encoder-1h67</guid>
      <description>&lt;p&gt;A rotary encoder is the clicky knob you find on volume dials and 3D printer menus: turn it and it reports how far and which way it moved, plus it usually has a built-in pushbutton. This tutorial wires one up to an ESP8266 and reads direction and click count over serial, a nice building block for menus, speed controls or servo positioning.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/esp8266/esp8266-rotary-encoder" rel="noopener noreferrer"&gt;ESP8266 - Rotary Encoder&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GYQTMRV7" rel="noopener noreferrer"&gt;ESP8266 NodeMCU ESP-12F&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GYQNH2JH" rel="noopener noreferrer"&gt;ESP8266 D1 Mini NodeMCU ESP-12F&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5P2JDR8" rel="noopener noreferrer"&gt;ESP8266 NodeMCU ESP-12E (Uno-form)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ43NLS4" rel="noopener noreferrer"&gt;Micro USB Cable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H4V3S8VQ" rel="noopener noreferrer"&gt;ESP8266 NodeMCU ESP-12F (SMD-form)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF57FT4J" rel="noopener noreferrer"&gt;Rotary Encoder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CSD1KYZW" rel="noopener noreferrer"&gt;Screw Terminal Expansion Board for ESP8266&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;The encoder module has four pins. CLK goes to &lt;code&gt;D7&lt;/code&gt;, DT goes to &lt;code&gt;D6&lt;/code&gt;, and SW (the pushbutton output) goes to &lt;code&gt;D5&lt;/code&gt;. VCC connects to the ESP8266's 3.3V (or up to 5V) supply and GND to ground. SW is normally open and relies on a pull-up so it reads HIGH when the knob isn't pressed and LOW when it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Inside the encoder, a slotted disc connects two pins, A (CLK) and B (DT), to a shared ground pin as you turn the knob. Because A and B touch ground at slightly different times, their signals are 90 degrees out of phase, known as quadrature encoding. Turning clockwise makes A go LOW before B; counter-clockwise makes B go LOW before A. By watching what DT is doing at the moment CLK changes from LOW to HIGH, you can tell which direction the knob just turned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The sketch reads &lt;code&gt;CLK_PIN&lt;/code&gt; on every loop and compares it to its previous state. On a LOW-to-HIGH transition it checks &lt;code&gt;digitalRead()&lt;/code&gt; on &lt;code&gt;DT_PIN&lt;/code&gt;: DT HIGH means counter-clockwise (decrease the counter), DT LOW means clockwise (increase it). The direction and running count print to Serial. The &lt;code&gt;ezButton&lt;/code&gt; library handles the SW pin with built-in debouncing, calling &lt;code&gt;button.isPressed()&lt;/code&gt; to report clicks. An interrupt-based version of the same logic avoids polling CLK on every loop, so the ESP8266 won't miss fast turns while busy doing other work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;esp8266-rotary-encoder.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * This ESP8266 NodeMCU code was developed by newbiely.com
 *
 * This ESP8266 NodeMCU code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/esp8266/esp8266-rotary-encoder
 */&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;ezButton.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // The library to use for SW pin&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define CLK_PIN D7  // The ESP8266 pin D7 connected to the rotary encoder's CLK pin
#define DT_PIN D6   // The ESP8266 pin D6 connected to the rotary encoder's DT pin
#define SW_PIN D5   // The ESP8266 pin D5 connected to the rotary encoder's SW pin
&lt;/span&gt;
&lt;span class="cp"&gt;#define DIRECTION_CW 0   // clockwise direction
#define DIRECTION_CCW 1  // counter-clockwise direction
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DIRECTION_CW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;CLK_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;prev_CLK_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;ezButton&lt;/span&gt; &lt;span class="nf"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SW_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// create ezButton object for pin 7;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9600&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Configure encoder pins as inputs&lt;/span&gt;
  &lt;span class="n"&gt;pinMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CLK_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;INPUT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;pinMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DT_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;INPUT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setDebounceTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// set debounce time to 50 milliseconds&lt;/span&gt;

  &lt;span class="c1"&gt;// read the initial state of the rotary encoder's CLK pin&lt;/span&gt;
  &lt;span class="n"&gt;prev_CLK_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CLK_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// MUST call the loop() function first&lt;/span&gt;

  &lt;span class="c1"&gt;// read the current state of the rotary encoder's CLK pin&lt;/span&gt;
  &lt;span class="n"&gt;CLK_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CLK_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// If the state of CLK is changed, then pulse occurred&lt;/span&gt;
  &lt;span class="c1"&gt;// React to only the rising edge (from LOW to HIGH) to avoid double count&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CLK_state&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;prev_CLK_state&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;CLK_state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// if the DT state is HIGH&lt;/span&gt;
    &lt;span class="c1"&gt;// The encoder is rotating in counter-clockwise direction =&amp;gt; decrease the counter&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digitalRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DT_PIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DIRECTION_CCW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// The encoder is rotating in clockwise direction =&amp;gt; increase the counter&lt;/span&gt;
      &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DIRECTION_CW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Rotary Encoder:: direction: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;DIRECTION_CW&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"CLOCKWISE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ANTICLOCKWISE"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" - count: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// save last CLK state&lt;/span&gt;
  &lt;span class="n"&gt;prev_CLK_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CLK_state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isPressed&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The button is pressed"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/esp8266/esp8266-rotary-encoder" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/esp8266/esp8266-rotary-encoder&lt;/a&gt;&lt;/p&gt;

</description>
      <category>esp8266</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ESP32 MicroPython DRV8833 DC Motor Driver</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Tue, 20 Oct 2026 10:30:44 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/esp32-micropython-drv8833-dc-motor-driver-2ia6</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/esp32-micropython-drv8833-dc-motor-driver-2ia6</guid>
      <description>&lt;p&gt;A GPIO pin on the ESP32 can't drive a DC motor directly - it only gives a few milliamps at 3.3 volts, and a motor needs hundreds of milliamps plus the ability to reverse current. The DRV8833 driver solves both problems with two built-in H-bridges, letting you run one or two brushed DC motors from MicroPython using nothing but machine.PWM.&lt;/p&gt;

&lt;p&gt;This walks through wiring one motor, then two, so you end up with basic forward, reverse and turn control for something like a small robot car.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-drv8833-dc-motor-driver" rel="noopener noreferrer"&gt;ESP32 MicroPython DRV8833 DC Motor Driver&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DRBKM49W" rel="noopener noreferrer"&gt;38-pin ESP32 ESP-WROOM-32 Dev Module - Narrow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GQXZ2RK1" rel="noopener noreferrer"&gt;38-pin ESP32 ESP-WROOM-32 Dev Module - Wide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWN1K4P5" rel="noopener noreferrer"&gt;30-pin ESP32 ESP-WROOM-32 Dev Module - Wide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5P177F8" rel="noopener noreferrer"&gt;ESP32 Uno-form board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5NCCHSH" rel="noopener noreferrer"&gt;ESP32 S3 Uno-form board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BXKLH5WK" rel="noopener noreferrer"&gt;5V DC Motor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;5V Power Adapter&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPGC5GTQ" rel="noopener noreferrer"&gt;DC Power Jack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0F5GJWPPZ" rel="noopener noreferrer"&gt;Screw Terminal Expansion Board for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DYDN7LSZ" rel="noopener noreferrer"&gt;Breakout Expansion Board for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMVJNS" rel="noopener noreferrer"&gt;Power Splitter for ESP32&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DZXCNJTP" rel="noopener noreferrer"&gt;DIYables ESP32 Starter Kit (ESP32 included)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H8XVCLSJ" rel="noopener noreferrer"&gt;DIYables ESP32 S3 Starter Kit (ESP32 S3 included)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewbiely.com%2Fimages%2Ftutorial%2Fesp32-micropython-drv8833-dc-motor-driver-one-motor-wiring-diagram.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnewbiely.com%2Fimages%2Ftutorial%2Fesp32-micropython-drv8833-dc-motor-driver-one-motor-wiring-diagram.jpg" alt="ESP32 MicroPython DRV8833 DC Motor Driver wiring diagram" width="799" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;IN1 and IN2 go to two PWM-capable GPIOs on the ESP32 and drive motor A; IN3 and IN4 do the same for motor B. OUT1/OUT2 and OUT3/OUT4 connect to the motor wires. VCC takes motor power from an external supply (2.7V to 10.8V), such as a 5V adapter through a DC power jack, never from the ESP32's 3.3V or 5V pin.&lt;/p&gt;

&lt;p&gt;GND from the supply, the DRV8833 and the ESP32 all need to tie together, otherwise the IN signals have no reference and the motor behaves strangely. Tie EEP (nSLEEP) to the ESP32's 3.3V so the driver stays awake. If a motor spins the wrong way, swap its two OUT wires - no code change needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The DRV8833 has no separate enable pin like the L298N - you send PWM straight into the IN pins to set speed. For channel A, driving IN1 with PWM while IN2 stays LOW spins the motor forward; swapping which pin gets PWM reverses it. Both IN pins LOW lets the motor coast to a stop, and both HIGH brakes it quickly.&lt;/p&gt;

&lt;p&gt;In MicroPython, duty_u16() takes 0 to 65535, so 0 means LOW, 65535 means HIGH, and anything in between sets the speed. The chip's output MOSFETs have low resistance, so little power turns into heat and the motor gets nearly the full battery voltage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The one-motor script sets up GPIO27 and GPIO26 as 1 kHz PWM outputs with machine.PWM and wraps the logic in a motor_a(speed) function that takes -100 to 100, converts it to a duty value, and picks which IN pin gets PWM based on the sign. motor_a_brake() drives both pins HIGH. The main loop ramps the motor up in 20% steps, holds full speed, coasts, reverses at 60%, then brakes, printing each step to the Shell.&lt;/p&gt;

&lt;p&gt;The two-motor version adds GPIO33 and GPIO32 for channel B, generalizes the logic into set_channel(), and layers on forward(), backward(), turn_left(), turn_right() and stop() helpers built around one DRIVE_SPEED value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;esp32-micropython-drv8833-dc-motor-driver.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This ESP32 MicroPython code was developed by newbiely.com
This ESP32 MicroPython code is made available for public use without any restriction
For comprehensive instructions and wiring diagrams, please visit:
https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-drv8833-dc-motor-driver
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;machine&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PWM&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="c1"&gt;# ESP32 pins connected to channel A of the DRV8833 module
&lt;/span&gt;&lt;span class="n"&gt;IN1_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;  &lt;span class="c1"&gt;# ESP32 GPIO27 connected to the IN1 pin of the DRV8833
&lt;/span&gt;&lt;span class="n"&gt;IN2_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;26&lt;/span&gt;  &lt;span class="c1"&gt;# ESP32 GPIO26 connected to the IN2 pin of the DRV8833
&lt;/span&gt;&lt;span class="n"&gt;PWM_FREQ&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;  &lt;span class="c1"&gt;# 1 kHz PWM, the DRV8833 accepts up to 50 kHz
&lt;/span&gt;
&lt;span class="c1"&gt;# Both IN pins use PWM, because the DRV8833 has no separate speed (enable) pin
&lt;/span&gt;&lt;span class="n"&gt;in1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PWM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN1_PIN&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PWM_FREQ&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;in2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PWM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IN2_PIN&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PWM_FREQ&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;in1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# start with the motor stopped (coast)
&lt;/span&gt;&lt;span class="n"&gt;in2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;FULL_DUTY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;65535&lt;/span&gt;  &lt;span class="c1"&gt;# duty_u16() range is 0 to 65535
&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;percent_to_duty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;percent&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;FULL_DUTY&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;  &lt;span class="c1"&gt;# convert 0-100% to 0-65535
&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;motor_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# speed: -100 to 100 (%). Positive = forward, negative = reverse, 0 = coast
&lt;/span&gt;    &lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;in1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;percent_to_duty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# PWM on IN1
&lt;/span&gt;        &lt;span class="n"&gt;in2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;# IN2 LOW
&lt;/span&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;in1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                       &lt;span class="c1"&gt;# IN1 LOW
&lt;/span&gt;        &lt;span class="n"&gt;in2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;percent_to_duty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# PWM on IN2
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;in1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# IN1 LOW + IN2 LOW = coast (motor rolls to a stop)
&lt;/span&gt;        &lt;span class="n"&gt;in2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;motor_a_brake&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;in1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FULL_DUTY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# IN1 HIGH + IN2 HIGH = brake (fast stop)
&lt;/span&gt;    &lt;span class="n"&gt;in2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;duty_u16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FULL_DUTY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# forward: raise the speed step by step
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Forward: speeding up&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;speed&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;motor_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  speed = {}%&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Forward: full speed for 2 seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Coast: motor rolls to a stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;motor_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Reverse: 60% speed for 2 seconds&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;motor_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Brake: fast stop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;motor_a_brake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;motor_a&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# release the brake before the next loop
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;----&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that go wrong
&lt;/h2&gt;

&lt;p&gt;Both IN pins for a channel must sit on PWM-capable GPIOs - almost all ESP32 output pins qualify, but check this first if a motor ignores commands. If nothing moves at all, check EEP: it has to be HIGH or the chip sleeps and ignores every input.&lt;/p&gt;

&lt;p&gt;A motor spinning the wrong direction just needs its two OUT wires swapped. Two motors draw more current than one, so size the 5V adapter at 2A or more. Test with the wheels free to spin, since a stalled motor can pull far more current than a spinning one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-drv8833-dc-motor-driver" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/esp32-micropython/esp32-micropython-drv8833-dc-motor-driver&lt;/a&gt;&lt;/p&gt;

</description>
      <category>micropython</category>
      <category>esp32</category>
      <category>electronics</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Arduino MicroPython Potentiometer</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Tue, 20 Oct 2026 04:00:48 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/arduino-micropython-potentiometer-4ho1</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/arduino-micropython-potentiometer-4ho1</guid>
      <description>&lt;p&gt;A potentiometer is the simplest way to get a variable input into your code - turn a knob, get a number. This tutorial walks through wiring one up to an Arduino Giga R1 WiFi and reading it with MicroPython, converting the raw ADC reading into a voltage you can print to the console.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/arduino-micropython/arduino-micropython-potentiometer" rel="noopener noreferrer"&gt;Arduino MicroPython Potentiometer&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://store.arduino.cc/products/giga-r1-wifi" rel="noopener noreferrer"&gt;Arduino Giga R1 WiFi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Potentiometer&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0F4PRHWNH" rel="noopener noreferrer"&gt;10k Ohm Trimmer Potentiometer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GF7FKPVB" rel="noopener noreferrer"&gt;Potentiometer Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DLNDDL4H" rel="noopener noreferrer"&gt;Potentiometer Module with Knob&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPG2H4V2" rel="noopener noreferrer"&gt;Screw Terminal Block Shield for Arduino Uno/Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWNBDSCX" rel="noopener noreferrer"&gt;Sensors/Servo Expansion Shield for Arduino Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard Shield for Arduino Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Enclosure for Arduino Giga&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMVJNS" rel="noopener noreferrer"&gt;Power Splitter for Arduino Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;A potentiometer has three pins. The GND pin goes to the board's GND (0 volts), the VCC pin goes to 3.3 volts, and the output pin (the wiper) connects to one of the Arduino's analog input pins, in this case A0. The board reads whatever voltage shows up on that middle pin.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Inside the potentiometer, turning the shaft moves a wiper along a resistive track between the GND and VCC pins. At 0 degrees the output pin sits at GND, so you read 0 volts. At the maximum angle it sits at VCC, so you read the full 3.3 volts. Anywhere in between, the output voltage scales with the angle: angle times VCC divided by the maximum angle. The Arduino's analog-to-digital converter (ADC) turns that voltage into a number between 0 and 4095, which you can then map into an angle, a voltage, or any other range your application needs, like a volume or brightness level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The script sets up an ADC on pin A0 and loops forever. Arduino's &lt;code&gt;read_u16()&lt;/code&gt; returns a 16-bit reading, so the code shifts it right by 4 bits to get back the 12-bit range (0 to 4095) matching the hardware. A small &lt;code&gt;map_value()&lt;/code&gt; helper rescales that number into a 0 to 3.3 volt range, and the loop prints both the raw ADC value and the computed voltage once per second using &lt;code&gt;time.sleep(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;arduino-micropython-potentiometer.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This Arduino MicroPython script was developed by newbiely.com
This Arduino MicroPython script is made available for public use without any restriction
For comprehensive instructions and wiring diagrams, please visit:
https://newbiely.com/tutorials/arduino-micropython/arduino-micropython-potentiometer
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;machine&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ADC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="c1"&gt;# Define a function to map a value from one range to another
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;out_max&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;in_min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;out_max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;out_min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;in_max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;in_min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;out_min&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the analog pin for reading
&lt;/span&gt;&lt;span class="n"&gt;adc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ADC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;A0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# The Arduino Giga WiFi pin A0 connected to the S pin of water sensor
&lt;/span&gt;
&lt;span class="c1"&gt;# Infinite loop
&lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Retrieve analog value from pin A0:
&lt;/span&gt;    &lt;span class="n"&gt;adc_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_u16&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="c1"&gt;# Read the 16-bit analog value from the sensor and convert back to 12-bit ADC
&lt;/span&gt;    &lt;span class="c1"&gt;# Convert the analog value to a voltage (0-3.3V range):
&lt;/span&gt;    &lt;span class="n"&gt;voltage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;map_value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adc_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4095&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Output the analog value and corresponding voltage to the console:
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Analog: {}, Voltage: {:.2f}V&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adc_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voltage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Wait for a second before repeating the loop:
&lt;/span&gt;    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/arduino-micropython/arduino-micropython-potentiometer" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/arduino-micropython/arduino-micropython-potentiometer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>micropython</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Raspberry Pi - ADC</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Mon, 19 Oct 2026 10:30:42 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/raspberry-pi-adc-8mn</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/raspberry-pi-adc-8mn</guid>
      <description>&lt;p&gt;The Raspberry Pi has no analog input pins, so it can't read a potentiometer or a gas sensor directly - every GPIO pin only knows about &lt;code&gt;HIGH&lt;/code&gt; and &lt;code&gt;LOW&lt;/code&gt;. The fix is an external Analog-to-Digital Converter. This walks through wiring an ADS1115 module to a Pi and reading sensor values over I2C from Python.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-adc" rel="noopener noreferrer"&gt;Raspberry Pi - ADC&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi 5&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0D8BF6KRF" rel="noopener noreferrer"&gt;ADS1115 ADC Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Potentiometer&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DL2RCCJG" rel="noopener noreferrer"&gt;Screw Terminal Block Shield for Raspberry Pi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Raspberry Pi Prototyping Base Plate &amp;amp; Breadboard Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DIYables USB Type-A to Type-B Cable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;The ADS1115 is a 16-bit, 4-channel ADC that talks to the Pi over I2C, so it only needs a handful of connections for power and data plus one input pin per sensor. This tutorial wires up a potentiometer as the example analog source, but the same module and setup work for a light sensor, a water sensor, or a soil moisture sensor since they all just output a varying voltage between 0 and 3.3V.&lt;/p&gt;

&lt;p&gt;Because the ADS1115 has four input channels, you can wire up to four analog sensors to one module at the same time and read them independently. If your breadboard wiring gets messy, a screw terminal block shield for the Pi makes the connections more secure and easier to manage.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The ADS1115 measures an analog voltage between 0 and 3.3V and converts it into a 16-bit digital number, giving you much finer resolution than a simple on/off reading. It communicates with the Raspberry Pi over I2C, a two-wire protocol that lets multiple devices share the same data lines, which is why the module needs so few connections.&lt;/p&gt;

&lt;p&gt;Before any of this works, I2C has to be turned on in the Pi's configuration, since it's disabled by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;On the software side, the &lt;code&gt;Adafruit_ADS1x15&lt;/code&gt; library handles the I2C communication with the module. The script creates an ADS1115 object, reads the 16-bit value from the channel the sensor is wired to, and prints it out once a second in a loop, so you get a continuous stream of readings in the terminal as you turn the potentiometer or change the sensor's conditions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;raspberry-pi-adc.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
This Raspberry Pi code was developed by newbiely.com
This Raspberry Pi code is made available for public use without any restriction
For comprehensive instructions and wiring diagrams, please visit:
https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-adc
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;


&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Adafruit_ADS1x15&lt;/span&gt;

&lt;span class="c1"&gt;# Create an ADS1115 ADC object
&lt;/span&gt;&lt;span class="n"&gt;adc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Adafruit_ADS1x15&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ADS1115&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;analog_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;adc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_adc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Read from channel 0
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Analog Value: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;analog_value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that go wrong
&lt;/h2&gt;

&lt;p&gt;If you see no output or errors instead of readings, double check that I2C is actually enabled in &lt;code&gt;raspi-config&lt;/code&gt; under Interfacing Options, and that you rebooted the Pi afterward for the change to take effect. Also confirm the Pi has internet access the first time you run the script, since the &lt;code&gt;Adafruit_ADS1x15&lt;/code&gt; library needs to be installed before it can be imported.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-adc" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/raspberry-pi/raspberry-pi-adc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>ESP32 S3 - Soil Moisture Sensor</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Mon, 19 Oct 2026 01:46:01 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/esp32-s3-soil-moisture-sensor-5c1p</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/esp32-s3-soil-moisture-sensor-5c1p</guid>
      <description>&lt;p&gt;A capacitive soil moisture sensor lets your ESP32 S3 tell you when soil is dry and needs water, without the corrosion problems of the cheap resistive probes you often see bundled with starter kits. This walkthrough covers wiring the sensor, reading raw values over serial, and calibrating a threshold so your code can report WET or DRY instead of just numbers.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor" rel="noopener noreferrer"&gt;ESP32 S3 - Soil Moisture Sensor&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GYQLV7HT" rel="noopener noreferrer"&gt;ESP32 S3 WROOM N16R8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWN6F8VT" rel="noopener noreferrer"&gt;ESP32 S3 SuperMini Dev Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0G5NCCHSH" rel="noopener noreferrer"&gt;ESP32 S3 Uno-form Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GQXW2L9G" rel="noopener noreferrer"&gt;ESP32 S3 Camera Board&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Capacitive Soil Moisture Sensor&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPGC5GTQ" rel="noopener noreferrer"&gt;DC Power Jack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H74TX2QZ" rel="noopener noreferrer"&gt;Screw Terminal Expansion Board for ESP32 S3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H74NFV38" rel="noopener noreferrer"&gt;Breakout Expansion Board for ESP32 S3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMVJNS" rel="noopener noreferrer"&gt;Power Splitter for ESP32 S3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H8XVCLSJ" rel="noopener noreferrer"&gt;DIYables ESP32 S3 Starter Kit (ESP32 S3 included)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;The sensor has three pins: GND, VCC, and AOUT. Connect GND to the ESP32 S3's GND, VCC to the 3.3V pin, and AOUT to GPIO6. The sensor runs happily on 3.3V, so there's no need for a level shifter or any extra components between it and the board.&lt;/p&gt;

&lt;p&gt;Keep the circuit board part of the sensor, the bit with the electronics, above the soil or water line at all times. Only the probe itself should go into the soil.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Capacitive sensors measure moisture by sensing capacitance changes in the soil around the probe, rather than passing current between exposed metal contacts like resistive sensors do. That means nothing touches the soil electrically, so there's no corrosion over time.&lt;/p&gt;

&lt;p&gt;The output on AOUT is inversely proportional to moisture: wetter soil gives a lower voltage, drier soil gives a higher voltage. The ESP32 S3 reads that voltage through its ADC, so lower readings mean wet soil and higher readings mean dry soil.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The sketch sets GPIO6 as an analog input, configures the ADC attenuation to handle inputs up to about 3.3V, then reads the pin every 500 milliseconds with &lt;code&gt;analogRead()&lt;/code&gt; and prints the value to the Serial Monitor at 115200 baud. Run this version first, before soil, to watch raw numbers and figure out your own thresholds.&lt;/p&gt;

&lt;p&gt;Once you've calibrated, you swap in a version that compares the reading against a &lt;code&gt;THRESHOLD&lt;/code&gt; constant and prints WET or DRY accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;esp32-s3-soil-moisture-sensor.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * This ESP32 S3 code was developed by newbiely.com
 *
 * This ESP32 S3 code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor
 */&lt;/span&gt;

&lt;span class="cp"&gt;#define AOUT_PIN 6 // The ESP32 S3 pin GPIO6 that connects to AOUT pin of moisture sensor
&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;begin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;115200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// set the ADC attenuation to 11 dB (up to ~3.3V input)&lt;/span&gt;
  &lt;span class="n"&gt;analogSetAttenuation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ADC_11db&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;analogRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AOUT_PIN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// read the analog value from sensor&lt;/span&gt;

  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Moisture value: "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Serial&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that go wrong
&lt;/h2&gt;

&lt;p&gt;If your readings seem inconsistent regardless of sensor version, you may have a low-quality unit; the TLC555I-based capacitive sensor is the one confirmed to behave reliably. If you're testing in liquid rather than soil, use salt water, since pure water barely conducts and won't change the reading.&lt;/p&gt;

&lt;p&gt;Thresholds also aren't universal: typical dry readings land around 2200–2500 and wet readings around 1200–1500, but your exact numbers depend on soil type, salinity, and probe depth, so recalibrate for your actual soil rather than reusing someone else's threshold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/esp32-s3/esp32-s3-soil-moisture-sensor&lt;/a&gt;&lt;/p&gt;

</description>
      <category>esp32</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Raspberry Pi Pico - Button</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Mon, 19 Oct 2026 01:31:55 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/raspberry-pi-pico-button-431k</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/raspberry-pi-pico-button-431k</guid>
      <description>&lt;p&gt;A push button looks simple but trips up a lot of beginners because it has four pins instead of two, and because the way you wire it changes whether a press reads as HIGH or LOW in code. This walks through connecting a button to a Raspberry Pi Pico the easy way, using the Pico's internal pull-up resistor, and reading its state with MicroPython.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/raspberry-pico/raspberry-pi-pico-button" rel="noopener noreferrer"&gt;Raspberry Pi Pico - Button&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi Pico W&lt;/li&gt;
&lt;li&gt;Raspberry Pi Pico&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ43NLS4" rel="noopener noreferrer"&gt;Micro USB Cable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard-mount Button with Cap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard-mount Button Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CM63R39Q" rel="noopener noreferrer"&gt;Panel-mount Button&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3WM7K1" rel="noopener noreferrer"&gt;Push Button Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;A breadboard button actually has four legs, but they're internally paired, so only two of them are electrically distinct. Pick one pin from each pair: connect one to a Pico GPIO pin and the other to GND. With the internal pull-up enabled in code you don't need an external resistor at all.&lt;/p&gt;

&lt;p&gt;If you're using a button module instead, it exposes three labeled pins: GND goes to ground, VCC goes to the Pico's 3.3V supply, and OUT goes to a digital input pin. That module's output idles LOW and goes HIGH when pressed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;Inside a push button are two contacts, call them pin A and pin B. While the button is untouched they're disconnected, so no current flows between them. Pressing the button physically bridges A and B together, completing the circuit.&lt;/p&gt;

&lt;p&gt;What that means for the Pico's GPIO pin depends on how you wired it. With the internal pull-up setup used here, the pin reads HIGH when the button is untouched and drops to LOW the moment it's pressed, because pressing connects the pin to GND.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The pin is configured with &lt;code&gt;Pin(BUTTON_PIN, Pin.IN, Pin.PULL_UP)&lt;/code&gt;, which tells the Pico to hold that pin HIGH internally until something pulls it LOW. From there the code just reads the pin's state to know whether the button is currently pressed.&lt;/p&gt;

&lt;p&gt;You can extend this same reading logic to detect press and release as distinct events, rather than just polling the current state, which is useful if you want to react once per press instead of continuously while held.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;raspberry-pi-pico-button.py&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;machine&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;BUTTON_PIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# The Raspberry Pi Pico pin connected to the button (GP0)
&lt;/span&gt;
&lt;span class="c1"&gt;# Set up the button pin. The Pin.PULL_UP enables the internal pull-up resistor.
&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BUTTON_PIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PULL_UP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Read the state of the button
&lt;/span&gt;    &lt;span class="n"&gt;button_state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Print the button's state
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;button_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Wait for half a second before reading the button again
&lt;/span&gt;    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Things that go wrong
&lt;/h2&gt;

&lt;p&gt;Mechanical contacts don't settle cleanly the instant they touch, they tend to bounce and register as several rapid presses before stabilizing. This is called chattering, and it mostly matters if your code is counting button presses, where a single press might get counted multiple times. For simple on/off state checks it's usually not worth worrying about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/raspberry-pico/raspberry-pi-pico-button" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/raspberry-pico/raspberry-pi-pico-button&lt;/a&gt;&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Arduino Giga R1 WiFi LED Blink</title>
      <dc:creator>Arduino ESP32 Raspberry Pi Tutorials</dc:creator>
      <pubDate>Mon, 19 Oct 2026 01:16:42 +0000</pubDate>
      <link>https://dev.to/arduino_getstarted_f52a1a/arduino-giga-r1-wifi-led-blink-458l</link>
      <guid>https://dev.to/arduino_getstarted_f52a1a/arduino-giga-r1-wifi-led-blink-458l</guid>
      <description>&lt;p&gt;This tutorial walks through blinking an LED with the Arduino Giga R1 WiFi, using a digital output pin to switch it on and off. It is the simplest possible way to see GPIO control in action, and the same technique scales to turning any device on or off through a driver circuit.&lt;/p&gt;

&lt;p&gt;The full tutorial, with every detail and the line-by-line code explanation, is on our site: &lt;a href="https://newbiely.com/tutorials/arduino-giga/arduino-giga-r1-wifi-led-blink" rel="noopener noreferrer"&gt;Arduino Giga R1 WiFi LED Blink&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://store.arduino.cc/products/giga-r1-wifi" rel="noopener noreferrer"&gt;Arduino Giga R1 WiFi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CF575PW9" rel="noopener noreferrer"&gt;USB Cable Type-A to Type-C (for USB-A PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DQ3V1TFM" rel="noopener noreferrer"&gt;USB Cable Type-C to Type-C (for USB-C PC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BXKM8PN3" rel="noopener noreferrer"&gt;LED Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DLNDH4Z8" rel="noopener noreferrer"&gt;LED (red)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0F6T2RTQ6" rel="noopener noreferrer"&gt;LED Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0H29526SX" rel="noopener noreferrer"&gt;Button and LED Kit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0D2KH3GP1" rel="noopener noreferrer"&gt;220Ω Resistor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/jumper-wires" rel="noopener noreferrer"&gt;Jumper Wires&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0BPG2H4V2" rel="noopener noreferrer"&gt;Screw Terminal Block Shield for Arduino Uno/Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0GWNBDSCX" rel="noopener noreferrer"&gt;Sensors/Servo Expansion Shield for Arduino Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/categories/breadboard" rel="noopener noreferrer"&gt;Breadboard Shield for Arduino Mega/Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Enclosure for Arduino Giga&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0DHGMVJNS" rel="noopener noreferrer"&gt;Power Splitter for Arduino Giga&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://diyables.io/dp/B0CWZQ13M1" rel="noopener noreferrer"&gt;DIYables Sensor Kit (18 sensors/displays)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

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

&lt;p&gt;Connect the LED's cathode (-), the shorter lead with the flat edge on the case, to GND. Connect the anode (+), the longer lead, through a 220Ω resistor to a GPIO pin such as pin 9. The resistor limits current so the LED does not draw more than the Arduino's pins or the LED itself can handle. Getting the polarity backwards will not let current flow, so the LED just stays off rather than damaging anything at these voltages, but a module with a built-in resistor simplifies the wiring if you want to skip the standalone resistor.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;An LED only lets current through in one direction, from anode to cathode, once the voltage across it is high enough to forward-bias its internal junction. Setting the GPIO pin HIGH applies 3.3V, which exceeds that threshold and lets current flow through the resistor and LED, lighting it. Setting the pin LOW drops the voltage to 0V, so there is no potential difference and the LED turns off. The resistor value is chosen so the current stays around a few milliamps, well within what the pin can safely source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The sketch sets the pin as an output with &lt;code&gt;pinMode(pin, OUTPUT)&lt;/code&gt;, then uses &lt;code&gt;digitalWrite()&lt;/code&gt; to drive it HIGH or LOW with delays in between, which is what makes the LED blink. The same approach works for the board's built-in LED and for an external one; you just point the code at a different pin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;arduino-giga-r1-wifi-led-blink.ino&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * This Arduino Giga R1 WiFi code was developed by newbiely.com
 *
 * This Arduino Giga R1 WiFi code is made available for public use without any restriction
 *
 * For comprehensive instructions and wiring diagrams, please visit:
 * https://newbiely.com/tutorials/arduino-giga/arduino-giga-r1-wifi-led-blink
 */&lt;/span&gt;

&lt;span class="c1"&gt;// the setup function runs once when you press reset or power the board&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// initialize digital pin LED_BUILTIN as an output.&lt;/span&gt;
  &lt;span class="n"&gt;pinMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LED_BUILTIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OUTPUT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// the loop function runs over and over again forever&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LED_BUILTIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// turn the LED on (HIGH is the voltage level)&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                      &lt;span class="c1"&gt;// wait for a second&lt;/span&gt;
  &lt;span class="n"&gt;digitalWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LED_BUILTIN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LOW&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// turn the LED off by making the voltage LOW&lt;/span&gt;
  &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;                      &lt;span class="c1"&gt;// wait for a second&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Full tutorial
&lt;/h2&gt;

&lt;p&gt;The complete tutorial - wiring diagram, code explanation and troubleshooting - is here: &lt;a href="https://newbiely.com/tutorials/arduino-giga/arduino-giga-r1-wifi-led-blink" rel="noopener noreferrer"&gt;https://newbiely.com/tutorials/arduino-giga/arduino-giga-r1-wifi-led-blink&lt;/a&gt;&lt;/p&gt;

</description>
      <category>arduino</category>
      <category>electronics</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
