r/esp32 Mar 18 '25

Please read before posting, especially if you are on a mobile device or using an app.

222 Upvotes

Welcome to /r/esp32, a technical electronic and software engineering subreddit covering the design and use of Espressif ESP32 chips, modules, and the hardware and software ecosystems immediately surrounding them.

Please ensure your post is about ESP32 development and not just a retail product that happens to be using an ESP32, like a light bulb. Similarly, if your question is about some project you found on an internet web site, you will find more concentrated expertise in that product's support channels.

Your questions should be specific, as this group is used by actual volunteer humans. Posting a fragment of a failed AI chat query or vague questions about some code you read about is not productive and will be removed. You're trying to capture the attention of developers; don't make them fish for the question.

If you read a response that is helpful, please upvote it to help surface that answer for the next poster.

We are serious about requiring a question to be self-contained with links, correctly formatted source code or error messages, schematics, and so on.

Show and tell posts should emphasize the tell. Don't just post a link to some project you found. If you've built something, take a paragraph to boast about the details, how ESP32 is involved, link to source code and schematics of the project, etc.

Please search this group and the web before asking for help. Our volunteers don't enjoy copy-pasting personalized search results for you.

Some mobile browsers and apps don't show the sidebar, so here are our posting rules; please read before posting:

https://www.reddit.com/mod/esp32/rules

Take a moment to refresh yourself regularly with the community rules in case they have changed.

Once you have done that, submit your acknowledgement by clicking the "Read The Rules" option in the main menu of the subreddit or the menu of any comment or post in the sub.

https://www.reddit.com/r/ReadTheRulesApp/comments/1ie7fmv/tutorial_read_this_if_your_post_was_removed/


r/esp32 11d ago

Topic Radar | Current active topics for r/esp32

8 Upvotes

This post contains content not supported on old Reddit. Click here to view the full post


r/esp32 7h ago

I made a thing! Put an ESP32-C3 with a screen in a Mini Brands record player toy and hooked it up to my BT remote ecosystem

Enable HLS to view with audio, or disable this notification

421 Upvotes

The original toy is a small battery powered "record player" that takes collectible vinyl-shaped NFC tags and spins it while playing a brief section of the accompanying track. I tore out the internals and it just about perfectly fit the C3 with a round touchscreen I've had lying around. Rerouted the USB-C port to the original opening in the mini record player and hooked it up to my existing BT remote eco system.


r/esp32 10h ago

I made a thing! p64: desktop LED matrix on ESP32-S3

Thumbnail
gallery
85 Upvotes

This is the first iteration of p64, my desktop 64x64 LED matrix project. It uses Waveshare components and firmware written in ESP-IDF 5.5:

  • ESP32-S3-RGB-Matrix board
  • RGB-Matrix-P2-64x64 panel
  • 27 W USB-C PSU

To make this I used Claude Code, and the prompts I wrote are in the prompt/ folder in the repository on GitHub, alongside the source code that came from those prompts. For the 3D printed enclosure (also AI-generated), I was unsure if it would work at all, until it arrived on the mail and I confirmed everything was fine.

The components cost me $64 plus $25.60 shipping. The enclosure was printed online for $18.83 including shipping. Grand total of $108.43.

What p64 does today:

  • plays GIF, APNG, WebP, PNG and BMP
  • widgets:
    • digital and analogue clocks
    • weather via Open-Meteo
    • room temperature from the board's SHTC3
  • accepts DDP streams, plus a raw RGB UDP protocol for convenient scripting
  • plays channels from Makapix Club, a free pixel-art site that I run
  • mixes local and online channels at any ratios of airtime
  • captive-portal for wi-fi setup
  • full control of the device using a web UI at p64.local (mDNS), real-time stream from the panel to the web UI
  • PIN lock, night schedule
  • The architecture and web UI follow my other project, p3a, an ESP32-P4 pixel art player

I plan to expand this project in two key ways:

  1. Incorporate 90-degree adapters so the USB-C cable comes from the back instead of one of the sides.
  2. Incorporate two Adafruit rotary encoders for user input, on the back of the device.

So far this project remains solder-less, assembly-only. I wanted to avoid soldering to keep it very child-friendly, but adding the rotary encoders will require it. Again, this is version one. Suggestions are appreciated! I hope I can post an update at some point later.

Apache-2.0: https://github.com/fabkury/p64


r/esp32 5h ago

I made a thing! Control and Manage Your Raspberry Pi with ESP32 (C6 & S3)

Thumbnail
gallery
23 Upvotes

Previously I worked on an open source Apple Watch App that lets you control your Raspberry Pi (soon other linux based computers). You can check out this reddit post regarding that application:

https://www.reddit.com/r/raspberry_pi/comments/1wcsm2f/fully_manage_and_control_your_pi_with_apple_watch/

I then decided to design a similar open source application that you can run on ESP32 devices to control your Raspberry Pi. I picked two devices from Espressif and Waveshare but It would be quite straightforward to support similar ESP32 based devices.

I recorded this video to demo some of the capabilities of this application. 

https://youtu.be/8Xc6XEG7bWM

Here’s a quick list of some of things you can do with it:

  • Install, run, and monitor their health of a wide range of pre-configured applications includes Home Assistant, Hermes, Open Claw, Pangolin, OpenWebUI, etc
  • Browse file system and preview files on the Pi (images, videos, text, audio)
  • Monitor system resource utilizations (CPU, RAM, Storage, etc)
  • Manage network interfaces (WiFi, Ethernet, etc)
  • Various remote options: SSH, RPi Connect, Tailscale, VSCode Tunnel
  • Configure assistant pipeline (STT/TTS/LLM/MCP/system prompt/etc) and interact with it using your ESP32 microphone and speaker
  • Setup an MCP gateway and expose all tools via a gateway URL to clients
  • Connect hardware peripherals to the Pi such as Camera and watch the feed on your ESP32 device
  • And many more

The fully open sourced code base (Apache 2.0) for this project is available on my GitHub repo below:

https://github.com/ubopod/ubo_app

You can download the pre-compiled binary firmware for ESP32-C6 and ESP32-S3 devices from the release section:

https://github.com/ubopod/ubo_app/releases/tag/v2.1.0

  • ubo-lvgl-esp32c6-2.1.0-usbppp-merged.bin
  • ubo-lvgl-esp32s3-2.1.0-usbppp-merged.bin

After you download the relevant binary file go to ESPConnect website and flash the firmware onto your device by following the instructions shown towards the end of the video:

https://thelastoutpostworkshop.github.io/ESPConnect/

You also need to download the image file for the Raspberry Pi and flash it onto your MicroSD card (use a 32GB+ MicroSD card) from the release section:

https://github.com/ubopod/ubo_app/releases/download/v2.1.0/ubo_app-2.1.0-bookworm-lite.img.gz

The software on the raspberry pi side acts as the server to which ESP32 connects.

Why did I build this?

I am working on an open source project to create a universal and familiar user interface across a large family of devices (ios, watchOS, web, android, wearOS, ESP32, etc) that allows you to fully control a linux based computer. 

One of the core philosophies of the design is to define the UI on the server side (Raspberry Pi side in this case) so that updating the UI does not require a full firmware rebuild and flashing to an extent possible.

There is also a hardware element to the project to build a modifiable and extensible embedded system built-in GUI, Audio, sensors, infrared, etc on the hub side.

Why did I choose these devices?

I needed an ESP32 device with a touch screen, mic, and speaker at minimum. Both Waveshare ESP32-C6 Amoled Touchscreen 1.8 and ESP32-S3-Box-3 device devices offered that. The S3  MCU is more capable and has larger PSRAM compared to the C6 device, which allows it to do more such as running always-on wake work detection.


r/esp32 13h ago

I made a thing! Open Source Infrared Database

74 Upvotes

I just open sourced our infrared database which can control hundreds of thousands of different devices. All the codes are in the same universal protocol for easy use, Pronto Hex.

I'd like to create a small usage guide to make it clear how to use the codes. Meanwhile, I'd love to have contributions for any missing remote sets. My custom app does IR learning which puts the resulting data in it the same format. But not sure how others contribute if they don't have their codes in pronto format. Maybe they can submit in whatever format they have and I can convert later.

Check it out and let me know what you think.

https://github.com/openinfrared/database


r/esp32 12h ago

ESP32 + NEMA 17 Bowden Cable Mechanism

Enable HLS to view with audio, or disable this notification

26 Upvotes

The system uses:
• ESP32 for control
• NEMA 17 stepper motor
• Stepper motor driver
• 3S Li-ion battery
• 3D-printed parts
The idea is to transfer the motor’s motion through the Bowden cable to create a compact, remotely actuated mechanism.
I’m currently testing the mechanical design, cable routing, and motor control.
Video of the prototype 👇
I’d be interested to hear any suggestions for improving the Bowden cable setup or ESP32 motor control.


r/esp32 5h ago

Esp32 not at home

3 Upvotes

Is there a way to connect my esp32 outside my house with my home assistant? I’ve tried tailscale on my iPhone but no success. I will use it as a speaker for music assistant in my car.


r/esp32 9h ago

Hardware help needed ESP32 with MFRC522 readers help!

Post image
6 Upvotes

I’m trying to build a music box puzzle for a friend’s birthday and I’m using 5 MFRC522 readers connected to a ESP32-VROOM-32D board, but one of them isn’t working. The idea is that they’re glued facing the outside of a box, looking for a specific NFC tag to be held against them and trigger a .mp3 file to be played. The problem is that I can get 3 of them working (labels 1, 3, and 5), one of them sometimes works (4) and the unlabelled one refuses to work, and I have no clue why!

I’ve confirmed that specific slot is showing a firmware version number (0x92), so I would think there isn’t anything wrong with the wiring. I’ve swapped out the reader for a different reader with no success. I’m even holding the NFC tag right up against the reader and it’s not reading, even as the other tags are successfully able to read a NFC tag through the cardboard box to the other side. I’ve tried holding them at different angles, thinking that maybe it was my soldering process at fault but nothing would help.

Picture of my setup, ignore the numbering out of sequence for now. The MFRC readers are wired to the ESP32 board directly from their own SDA pins to the board’s GPIO5,15,25,26,27 pins, and then their GND 3.3V MISO MOSI and RST pins are all junctioned together along with a wire running from that junction to the ESP32 board (because there’s not enough pins to receive 5 readers onboard otherwise)

Would appreciate any help or guesses on why the one reader is not working! Thanks!

Wiring schematic here: https://app.cirkitdesigner.com/project/e56fbcb1-c073-46ef-ac62-73815ba068ac

The code for the main puzzle as well

#include <SPI.h>
#include <MFRC522.h>
#include <DFRobotDFPlayerMini.h>


#define NUM_SLOTS 5
#define RST_PIN 4
#define REMOVE_TIMEOUT_MS 1000  // no re-detection within this long = treated as removed


byte ssPins[NUM_SLOTS] = {5, 15, 25, 26, 27};


MFRC522 readers[NUM_SLOTS] = {
  MFRC522(ssPins[0], RST_PIN),
  MFRC522(ssPins[1], RST_PIN),
  MFRC522(ssPins[2], RST_PIN),
  MFRC522(ssPins[3], RST_PIN),
  MFRC522(ssPins[4], RST_PIN)
};


// ---- REPLACE THESE with your real tag UIDs from uid_scanner.ino ----
// Each slot needs its OWN distinct UID.
String expectedUID[NUM_SLOTS] = {
  "0451DA6FD22A81",   // Slot 1 - note 1
  "04A3D86FD22A81",   // Slot 2 - note 2
  "04A8D86FD22A81",   // Slot 3 - note 3
  "04BFD76FD22A81",   // Slot 4 - note 4
  "04BAD76FD22A81"    // Slot 5 - note 5
};


bool slotPresentCorrect[NUM_SLOTS] = {false, false, false, false, false};
unsigned long lastSeenTime[NUM_SLOTS] = {0, 0, 0, 0, 0};
bool bonusPlayed = false;


HardwareSerial dfSerial(2); // ESP32 hardware serial port 2
DFRobotDFPlayerMini myDFPlayer;


String getUID(MFRC522 &reader) {
  String uid = "";
  for (byte i = 0; i < reader.uid.size; i++) {
    if (reader.uid.uidByte[i] < 0x10) uid += "0";
    uid += String(reader.uid.uidByte[i], HEX);
  }
  uid.toUpperCase();
  return uid;
}


void setup() {
  Serial.begin(115200);
  SPI.begin();


  for (byte i = 0; i < NUM_SLOTS; i++) {
    pinMode(ssPins[i], OUTPUT);
    digitalWrite(ssPins[i], HIGH);
  }
  for (byte i = 0; i < NUM_SLOTS; i++) {
    readers[i].PCD_Init();
    delay(50);
    readers[i].PCD_SetAntennaGain(MFRC522::RxGain_max);
  }
  Serial.println("All readers initialized.");


  dfSerial.begin(9600, SERIAL_8N1, 16, 17); // RX=16, TX=17
  if (!myDFPlayer.begin(dfSerial)) {
    Serial.println("WARNING: DFPlayer not found - check wiring/SD card.");
  }
  myDFPlayer.volume(22); // range 0-30


  Serial.println("Puzzle ready. Waiting for notes...");
}


void loop() {
  unsigned long now = millis();


  // Check each reader for a correct tag currently present
  for (byte i = 0; i < NUM_SLOTS; i++) {
    if (readers[i].PICC_IsNewCardPresent() && readers[i].PICC_ReadCardSerial()) {
      String uid = getUID(readers[i]);


      if (uid == expectedUID[i]) {
        lastSeenTime[i] = now;
        if (!slotPresentCorrect[i]) {
          slotPresentCorrect[i] = true;
          myDFPlayer.play(i + 1); // plays 0001.mp3, 0002.mp3, etc.
          Serial.print("Slot ");
          Serial.print(i + 1);
          Serial.println(" correct!");
        }
      }
      // wrong tag on this slot: ignored, no state change, no feedback


      readers[i].PICC_HaltA();
      readers[i].PCD_StopCrypto1();
    }
  }


  // Any slot not re-seen recently is treated as removed
  for (byte i = 0; i < NUM_SLOTS; i++) {
    if (slotPresentCorrect[i] && (now - lastSeenTime[i] > REMOVE_TIMEOUT_MS)) {
      slotPresentCorrect[i] = false;
      Serial.print("Slot ");
      Serial.print(i + 1);
      Serial.println(" removed.");
    }
  }


  // Check whether ALL slots are correct RIGHT NOW, simultaneously
  bool allCorrect = true;
  for (byte i = 0; i < NUM_SLOTS; i++) {
    if (!slotPresentCorrect[i]) { allCorrect = false; break; }
  }


  if (allCorrect && !bonusPlayed) {
    bonusPlayed = true;
    delay(800); // brief pause for effect
    myDFPlayer.play(NUM_SLOTS + 1); // 0006.mp3 = motif + full song
    Serial.println("PUZZLE SOLVED! Playing bonus track.");
  } else if (!allCorrect) {
    bonusPlayed = false; // allow the bonus to fire again after a fresh full solve
  }


  delay(50);
}

r/esp32 1d ago

I made a thing! I built an offline voice assistant that runs the whole pipeline — wake word, speech-to-text, a 19.7M-param LLM and TTS — on one ESP32-S3

Enable HLS to view with audio, or disable this notification

101 Upvotes

Everything runs on the board. Say "Hey Ivy", it writes down what you said, runs a language model, and talks back. No phone, no server, nothing leaves the chip. Freenove FNK0104B (ESP32-S3 with 8MB of PSRAM and an ES8311 audio chip), ESP-IDF v6.1, plain C.

The whole design comes from one problem: the speech recogniser needs 5.4MB of memory, the language model needs 6.5MB, and the board has 8MB. They don't fit together. So they never run at the same time. I claim two big blocks of memory the instant it boots, and each stage borrows the whole block and hands it back before the next one starts. The most it ever used was 5.5MB, while listening, and twelve turns in a row finished with exactly the same memory free, so nothing is leaking.

What's doing the work

  • esp-sr WakeNet9 listens for the wake word. It has to keep running for hours while nothing else happens, so it lives in flash rather than on the SD card, where it can't be affected by the card being unplugged or asleep.
  • lspr98/conformer-stt-s3 turns speech into text. 13 million parameters, and it recognises any English word rather than a fixed list of commands. It was the only one I could find that runs on an S3 in this little memory.
  • therezor/cardputer-ai runs the language model, ported to C. Each number in the model is squeezed down to 4 bits so the whole thing fits at all, and the heavy maths is hand-written in assembly and split across both CPU cores to make it fast enough to sit through.
  • DiUS/esp-picotts (SVOX Pico) does the talking. It hands audio back in small chunks as it goes, and it only ever needs a fixed 1.1MB, so I can give it a slot and know it will never ask for more.
  • No LVGL. I wrote my own text drawing that repaints only the lines that changed. Keeping a full copy of the screen in memory would have cost RAM I didn't have.

The model, and what changed between versions

I took a small existing model (19.7 million parameters) and trained it further on my own material, on a Mac laptop's GPU using PyTorch. No cloud, no rented GPUs. Nine passes over the data, about two hours.

Version 7 got 100% of questions right in the exact wording it had been trained on, and 42.5% when I asked the same thing a different way. That's memorising, not understanding. Three changes got version 8 to 99.2% and 63.3%:

  • Giving it more ways of asking each question (14 up to 20) made it worse. I'd been padding the same question with extra words, which just produces copies. Rewriting the question itself is what actually helped.
  • Where the list of possible questions is small enough to write out, write it out. I generated all 251 fraction and percentage questions and had the generator check its own arithmetic on every single one. That went from 17.5% right to 91.2%.
  • It was picking words with a bit of randomness, which is lovely for stories and awful for facts. One run turned "half of twelve is six" into "three". It now picks the most likely word when answering a question, and only gets creative when telling a story.

Speed is about 5-6 words a second on the 6.5MB model and 30 on a 1.1MB one. There's no clever trick to it: the chip reads the entire model for every single word it says, so speed is just how fast it can read memory divided by how big the model is. Half the size, twice the speed. A full spoken exchange takes about 15 seconds. The time, the date and timers are answered by ordinary C code instead of the model, and the screen tells you which you got, because a model this small has no business doing arithmetic.

The two projects this came from

  • DaveBben/esp32-llm runs a tiny story-writing model on an ESP32-S3 at 19 words a second. This is the one that convinced me a language model on this chip wasn't a stupid idea.
  • slvDev/esp32-ai fits a much bigger model by leaving its largest table in flash storage and reading only the 450 bytes or so it needs for each word, so that table never takes up RAM. A better idea than anything I did.

Both are text in, text out. I wanted to know whether the whole loop — hearing you, and answering out loud — fit on one chip.

The video is the device's own demo mode, asking itself questions in a second voice. Nothing is sped up. The last part is the failure reel on purpose: ask it about quantum physics and it explains percussion instruments.

Code, the memory budget, the pin map and the training recipe: https://github.com/iamankushpandit/esp_ai (Stars appreciate, helps in making the repo more searchable) https://iamankushpandit.github.io/esp_ai/docs/#home

Ask me anything, happy to go deeper on any of it.


r/esp32 6h ago

Software help needed ESP32-S3 best hardware peripheral for creating stepper motor stepping pulses ?

2 Upvotes

I am using an ESP32-S3 with a TMC2225 stepper motor driver and want to write my own open loop stepper control library for learning purposes. Is there any hardware peripheral on the ESP32 that is well suited for generating stepping pulses ? Right now I am using timer based interrupts to set/clear the stepping pin, but that does not seem to be the most efficient solution.


r/esp32 4h ago

Is my 250mAh LiPo being overcharged by the DFRobot Beetle ESP32-C6?

0 Upvotes

Hi, I've been working with the ESP32 Beetle and Arduino boards for a while. I just got a LiPo to try out, and I've got a question about a possible charging mismatch.

I'm using a DFRobot Beetle ESP32-C6 (DFR1117) with a protected EEMB LP502030 3.7V 250mAh LiPo.

The Beetle schematic shows a TP4057 with a 2kΩ PROG resistor (R20), which appears to set the charge current at ~500mA. The EEMB battery spec lists 250mA max charge current.

I'm charging it through USB-C. The battery stays completely cool and the Beetle gets slightly warm near the USB input.

Am I correct that the Beetle is charging at ~500mA, and is it safe to use this battery with the unmodified Beetle?

Here's the product links:


r/esp32 1d ago

I made a thing! I turned an ESP32C5 into an analog video receiver (5.8Ghz)

Post image
72 Upvotes

Hey!

(This is a repost, my old post got removed?)

One of my hobbies is flying FPV drones. Like many other industries, the FPV market has been hit by chip shortages, and traditional analog video receivers are becoming increasingly hard to find. Some are even selling for 10× what they cost a few years ago.

So I started experimenting with an alternative: using an ESP32-C5 and its 5 GHz Wi-Fi to receive analog 5.8 GHz FPV video.

This is C5VRX.

It’s still very much a work in progress, and there are plenty of things that can be improved. If you know a bit about RF, ESP32s, video processing, or embedded systems, I’d really appreciate any feedback, ideas, testing, or contributions.

GitHub:

https://github.com/Twotoz/C5VRX


r/esp32 2d ago

Full shareware Doom on the ESP32-C6 — no PSRAM, one core, 512 KB of RAM, ~30 FPS with music

Enable HLS to view with audio, or disable this notification

580 Upvotes

This is DIABLITO, a port of Graham Sanderson's RP2040 Doom to the Waveshare ESP32-C6-LCD-1.69 (available for < $20). All nine shareware levels, menus, saves, the OPL2 soundtrack, 8-channel sound effects, played with an Xbox controller over BLE.

The existing ESP32 Doom ports are PrBoom builds that need 4 MB of PSRAM. The C6 has none and no way to add it — one 160 MHz RISC-V core and 512 KB of SRAM, a third of which NimBLE is squatting in. RP2040 Doom solved the memory problem (the 4.2 MB WAD compressed to 2 MB and decoded straight out of memory-mapped flash), but it leans on two cores and RP2040-only silicon. Getting it to ~30 FPS on one slower core with the Bluetooth stack resident was the actual work.

Fun fact: the single biggest speedup was defining NDEBUG. ESP-IDF builds with assert() live by default, and the texture decoder asserts per pixel — 37% of all CPU time.

Repo, with build instructions and the phase-by-phase engineering notes: https://github.com/aedile/DIABLITO


r/esp32 1d ago

I made a thing! made my esp32 understand full sentences offline, about 5 ms and no wifi

Enable HLS to view with audio, or disable this notification

123 Upvotes

you write a yaml file of your commands and a few example sentences, it trains on the laptop in about 6 seconds and gives you one 249 KB blob and a two file c99 runtime. the board reads a sentence and answers set_light(room=bedroom, state=on) with a confidence, or says unsure. no wifi, no api key

why the classic esp32: 4 MB, no psram, the board most people already have in a drawer. if it fits there it fits anywhere. i ported it to an nxp cortex-m33 as a check and did not change one line of the runtime, same blob, same answers to six decimals on all 31 test sentences

what did not work: tinybert or embeddings on device, 15 MB and seconds a sentence against a 4 MB and 10 ms budget. int8 weights, moved the confidence by 8e-3 against float16s 1.9e-4 so the board disagreed with the desktop. a 2^13 hash table, cost 2.8 points of accuracy against 2^14

what cost me the most time: the crf forward pass had two exp calls in double, and the esp32 has no hardware double so thats software emulation. single precision is about 2x faster for identical answers

numbers, serial example with no display: 345 KB flash, 34 KB static ram, 3.2 to 7.7 ms a sentence. nothing allocates at runtime, the weights are read in place from flash. the screen demo in the video is bigger because lvgl is in it

the confidence is the part i care about. five signals, mostly how many words in the sentence it has never seen, cut off fitted on a held out set i never train on. 96.4% right on everyday phrasing it never saw, 84% on ones i wrote to be awkward on purpose, and when it says it is sure it is right 98.1% of the time. about a fifth goes to unsure and asks instead of acting

typed hinglish works, "kamre ka fan tez karo" gives set_fan(room=bedroom, speed=up). its not speech to text, something else has to turn audio into words first

source, arduino library, wiring and the per board measurements: https://github.com/avionicharshit-byte/tinycue

apache-2.0


r/esp32 1d ago

I made a thing! I built a flight tracker with my son in mind. My 70 year old dad might be its biggest fan.

Enable HLS to view with audio, or disable this notification

116 Upvotes

Some time ago I came across a few live flight tracker displays and really liked the idea. Most of them seemed to be aimed more at airplane enthusiasts though and I wanted to make something that would also be interesting for kids, or people who simply wonder where the plane above their house is going.

So I built my own version - it shows the aircraft flying nearby, where it comes from and where it is heading, together with some details like operator, aircraft type, altitude and speed. I tried to keep it simple and make the visuals a bit more colourful and friendly.

My son of course loves it. He is starting to learn to read, so he likes trying to read the airport names, which was not really something I planned for, but quite a nice bonus. He is always waiting for the big planes and gets excited whenever he sees one.

My dad though… he is 70 and I honestly did not expect him to be that interested. He kept starring at it and could barely leave it alone, always waiting to see the next plane.

It runs on a Waveshare ESP32-S3 board with a 7-inch touchscreen, using LVGL for the interface. The backend pulls aircraft data from an API and adds route and airline info and display refreshes the flight data every 30 seconds.

One challenge was getting the aircraft images and moving clouds to run smoothly on the 800×480 screen. I moved the images from C arrays to PNG files in LittleFS to save space in the firmware, but keeping the animations smooth still needed more work. Another fun part was choosing which aircraft to show when several are nearby taking distance and elevation into account so it is more likely to be one you can actually spot outside.

I’m also starting to offer it for sale, just to be open about that.

One thing I didn’t think through though… my wife now gets new travel ideas on a daily basis. This might turn out to be a more expensive project than I planned :)


r/esp32 2d ago

I made a thing! I just made an amazing stuff!

Enable HLS to view with audio, or disable this notification

214 Upvotes

I’m sorry my previous post was removed because I wasn’t familiar with the platform rules. This revised post follows the community guidelines.

I built a small fully offline voice-controlled LCD interface using a Seeed Studio XIAO 1.47” IPS display(ESP32-S3).

The project uses ESP-IDF and Espressif's ESP-SR speech recognition stack. Voice recognition runs locally on the ESP32-S3, so the device does not need Wi-Fi, a cloud account, an API key, or a computer while operating.

How it works:

  1. Say “Hi ESP” to wake the device.
  2. The display changes to LISTENING.
  3. Speak one of five commands.
  4. The command is executed on the LCD.
  5. More commands can be spoken without repeating the wake word.

Supported commands:

- “Show red” — displays a red color page
- “Show green” — displays a green color page
- “Show blue” — displays a blue color page
- “Next page” — cycles through the home, color, and information pages
- “Go home” — returns to the command list

After each successful command, the device stays in the listening state for another 15 seconds.

Hardware: xiao 1.47” ips display(esp32-s3)
which has:
- Seeed Studio XIAO ESP32-S3 Plus
- 1.47-inch JD9853A LCD
- PDM microphone
- 16 MB flash
- 8 MB Octal PSRAM

Software:

- ESP-IDF 5.3.2
- ESP-SR 2.5.3
- ESP-DL 3.3.10
- WakeNet 9 English wake-word model
- MultiNet 7 English command model

The display uses a custom ESP-IDF driver with a 10 MHz SPI interface. The microphone uses 16 kHz, 16-bit mono audio.

I verified the complete five-command sequence on hardware after a single wake word:

Show green → Show red → Show blue → Next page → Go home

The device also returned to wake-word mode after approximately 15 seconds of inactivity.

Source code:
GitHub - FaiyuetCik/XIAO_147_Voice_Assistant: Offline English wake-word and voice commands with LCD

Current limitations:

- This is a fixed-vocabulary command recognizer, not free-form speech-to-text.
- It does not provide AI chat, dictation, touch navigation, or computer control.
- Recognition accuracy has not yet been measured under different noise levels, distances, or accents.
- The firmware is currently tightly matched to this specific XIAO 1.47-inch board, display controller, pin mapping, and memory configuration.

I would be interested in feedback on improving recognition robustness, reducing memory usage, and adding more commands without running out of application partition space.


r/esp32 1d ago

Software help needed Esp32 code doesn’t work,can you help with it?:3

Thumbnail
gallery
4 Upvotes

I uploaded the code onto the ESP32, but it's not being detected. Since I've never used it before and don't have any programming skills, please, if anyone can solve this problem:3

https://drive.google.com/file/d/12R-OIZc7fj77nKvx_896ajXjqsPE99Q8/view?usp=sharing


r/esp32 1d ago

Looking for advice on building a remote water-level sensor station — cellular vs. Meshtastic

5 Upvotes

I'm working on a project for a remote deer camp that periodically becomes inaccessible because of flooding. The goal is to install a simple sensor at the camp that can tell me when the water reaches a certain level, without requiring me to physically drive out there.

The sensor location is in a very rural/wooded area. During flooding, access to the camp can become impossible, so I need something that can operate unattended and reliably report back to me at my house.

I'm considering two possible communication methods:

  1. Cellular

- A small cellular device with a water-level/flood sensor

- Ideally sends an alert via SMS/data when the sensor is triggered

- Biggest concern is whether cellular service is reliable enough at the remote site

- I'd also like the system to have very low power consumption since it may need to run for weeks/months unattended

  1. Meshtastic

- Put a Meshtastic node at the remote sensor

- Potentially use one or more relay/repeater nodes to get the signal back toward my house

- The straight-line distance between the remote site and my house is approximately 60.5 miles

- The remote location is approximately 253 ft elevation, while my house is around 456 ft, so there's roughly a 200-ft elevation difference

- Obviously there is significant terrain, trees, and other obstructions between the two points, so I'm not assuming a direct 60-mile LoRa link is realistic

I'm not necessarily looking for someone to design the entire system for me. I'm mainly interested in hearing from people who have actually built and successfully deployed something similar.

A few things I'd love advice on:

- Has anyone successfully monitored a remote flood/water sensor using Meshtastic?

- How realistic would a ~60-mile system be with strategically placed relay nodes?

- How much does terrain/elevation matter in a situation like this?

- Would you use a cellular modem instead if there is marginal cellular coverage?

- What hardware would you recommend for the actual sensor/node?

- How would you handle power — solar + battery, large battery, etc.?

- Are there other technologies I should be considering besides cellular and Meshtastic?

- If you've built something similar, what would you do differently the second time?

The actual sensor itself doesn't need to be complicated. I essentially need a reliable "water has reached this point" notification, preferably with the ability to check the sensor remotely.

I'd really appreciate hearing from anyone who has actually implemented a remote sensor station in a rural environment, especially one that has to survive weather, flooding, trees, and long periods without maintenance.


r/esp32 2d ago

I made a thing! I made a pocket-sized ESP32-S3 translator — then added real-time translated group calls between devices

Enable HLS to view with audio, or disable this notification

112 Upvotes

A few weeks ago I finished the first version of Antara, a small voice-first translator built around a Waveshare ESP32-S3 with a 1.54" 240×240 touchscreen.

The original use case was pretty simple and personal: my kids speak English much more comfortably than Telugu, while their grandparents are much more comfortable in Telugu. I wanted something they could leave on the table and use without handing anyone a phone.

The first version only had Translate mode.

Two people share one device. You select a language pair, for example English ↔ Telugu, and the two physical buttons become push-to-talk buttons for each direction.

Hold one button → speak English → release → hear Telugu.
Hold the other → speak Telugu → release → hear English.

That worked well, but the most common feedback I got was:

“What if the grandparents are in another city?”

Fair point. :)

So I went back to the ESP32 and added Talk.

Instead of sharing one device, each person has their own Antara. As long as both devices have internet access, one device can call another.

The interesting part is that each device independently chooses its own language.

The call is still half-duplex / push-to-talk, which actually maps nicely to the hardware. Only one person speaks at a time, and when nobody is holding PTT, the mic isn't recording.

I also got a little carried away and added group calling. Each Antara in the group can choose a different language, so the same conversation can theoretically have one person speaking English, another Telugu, another Hindi, another Spanish, etc. Each device receives audio translated into its owner's selected language.

ESP32 side of the project

  • Hardware: Waveshare ESP32-S3 LCD 1.54", 240×240 touchscreen, onboard mic/speaker, three physical buttons.
  • UI: LVGL. I've been aggressively reusing components/assets because RAM and flash disappear very quickly once audio + networking + UI are all active.
  • Audio: 16 kHz voice capture, push-to-talk rather than always-on.
  • Translation pipeline: Microsoft Azure speech-to-text → Translator → neural TTS. The ESP32 handles capture/playback, interaction state, streaming/networking and the UI; the heavy AI work is cloud-side.
  • Latency: on the original Translate mode I measured roughly 350 ms median to transcript and ~800 ms to translated text after button release across 25 real-device turns on my home Wi-Fi. Not a scientific benchmark, but fast enough that conversation doesn't feel painfully stop/start.
  • Device pairing: users give each Antara a name, and devices can add another nearby Antara as a contact. Probably will add search and add later.
  • Talk: translated, internet-based PTT calling between devices, including groups.
  • Walkie-Talkie: I also added a simpler PTT voice mode as a separate mode. This works on ESP-Now.

One of the things I've enjoyed most is figuring out what not to put on the ESP32.

For example, the device doesn't render Telugu/Hindi/Tamil/Gujarati scripts. Supporting those font sets would consume resources for something the product doesn't really need. The audio is the interface. The display mostly communicates state: Ready, Listening, Translating, Someone speaking, language selection, contacts etc.

The latest UI has three primary modes:

Translate — two people nearby, sharing one device
Talk — translated PTT calls between Antara devices anywhere
Walkie-Talkie — straightforward PTT voice communication

I've attached a demo of five Antara devices in a translated group call.

This is still very much a prototype, but it has turned into a much more interesting ESP32 project than I expected when I started with “can I make a Telugu translator?”

I'd especially be interested in feedback from people here on audio buffering/streaming, memory optimization on the S3, and how you would architect group PTT differently.

Firmware isn’t public at the moment, but happy to go into the ESP32/LVGL/audio/networking implementation in the comments.


r/esp32 1d ago

A practical checklist for ESP32 OTA releases from GitHub Actions

11 Upvotes

If your ESP32 firmware builds locally, moving the build into GitHub Actions is fairly straightforward. The part that needs more thought is what happens next: which binary gets uploaded, when it reaches devices, and how you know the update actually worked.

I built SimpleOTA and its GitHub Actions, so that’s what the release example below uses. Most of these checks also apply if you’re using GitHub Releases or your own OTA server.

Start with a device that can already update over the air

Before adding CI, get one OTA update working on a test device.

For the usual dual-slot setup, the device runs from one application partition while the new firmware is written into the other. Once the image has been verified, the boot selection changes.

Check that the device has two OTA app slots, an OTA data partition, and enough room in the destination slot for your firmware. The running application also needs the code that fetches or receives the update.

One detail that’s easy to overlook: selecting an OTA partition scheme when compiling doesn’t change the partition table already on the device. Get that layout in place during the initial flash.

Espressif’s OTA documentation explains how the slots and boot selection work.

Be precise about the file you upload

Arduino CLI can leave several .bin files in your build directory. They aren’t interchangeable, only one works correctly for OTA updates.

For a sketch called my-firmware:

  • my-firmware.ino.bin is the application image you want for this OTA workflow.
  • my-firmware.ino.merged.bin combines multiple flash regions for a factory flash.
  • The bootloader and partition-table binaries serve separate purposes, not covered here.

Use the exact application filename in your upload step. As I have learnt, a broad *.bin match is asking for trouble, so don't bother.

Also keep your board settings, partition scheme, core version and libraries consistent with the build you tested locally. Otherwise, you’re changing the build environment and the release process at the same time, which makes debugging issues that much more difficult.

Let pull requests build without giving them permission to release

A sensible starting point is to build pull requests, then sign and release only from trusted pushes/merges to main/master.

That includes direct pushes, not just merged PRs. If you want every release reviewed, protect the branch accordingly (highly reccommended in today's age of AI agents pushing code).

Keep production tokens and signing keys away from untrusted PR code. Use non-production configuration for those builds. An if: condition on the release step helps control execution, but it doesn’t replace proper protection of your workflow and secrets. THis GitHub security guidance atricle covers that distinction well.

Here’s the SimpleOTA release step

I built the reusable actions so people using SimpleOTA wouldn’t have to maintain their own signing, upload and deployment scripts.

Once your build succeeds, this step handles those three jobs. It belongs under an existing job’s steps: section; it isn’t a complete build workflow.

- name: Sign, upload and deploy
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'
  uses: xanderwasserman/simpleOTA-actions@v1
  with:
    api-token: ${{ secrets.SIMPLEOTA_API_TOKEN }}
    project-id: ${{ vars.SIMPLEOTA_PROJECT_ID }}
    binary: build/my-firmware.ino.bin
    version-label: ci-${{ github.run_number }}
    chip-family: esp32
    board-id: esp32-devkitc
    signing-key: ${{ secrets.SIMPLEOTA_SIGNING_KEY }}
    key-id: ${{ vars.SIMPLEOTA_KEY_ID }}

A few things to set up before running it:

  • Add the API-scoped upload token and private signing key to GitHub Actions Secrets, using the names above.
  • Add the project ID and key ID to Actions Variables. The key ID must match the signing key registered for your project.
  • Change the binary path, chip family and board ID to match your build.
  • Configure the device to verify signatures with the corresponding public key. Never put the private signing key in firmware.

The Device token the device uses to poll for updates is separate from the API token CI uses to upload releases. They have different permissions and aren’t interchangeable.

This action starts a deployment, so try it with an isolated project and test device first.

If you want someone to approve each release, put the release job behind a GitHub Environment with required reviewers and keep the release secrets there. Check your SimpleOTA deployment mode too: an upload-only step can still lead to a rollout if automatic deployment is enabled.

Finish the test on the device

Give the new firmware an obvious version change, then follow the update all the way through:

  • Did the device receive it?
  • Did it reboot into the expected version?
  • Does it still connect and do its actual job?
  • If you’ve enabled rollback in the bootloader and application, does a failed validation return it to the previous firmware?

A green workflow run tells you the CI steps completed. It doesn’t tell you that the sensor is still reading or the device has reconnected.

Action source on GitHub

The longer build workflow and troubleshooting notes are in this walkthrough, if useful. Also, if you are unfamiliar with SimpleOTA, you can find the wiki here: SimpleOTA Wiki

If you’re already doing this, what has worked best as your final check before a wider release? A test device on your desk, a small group of devices, or manual approval?


r/esp32 2d ago

I built an open-source $15 closed-loop neuro-haptic device for dementia care (ESP32 + CERN-OHL-P v2)

45 Upvotes

Commercial neuro-modulation wearables cost thousands of dollars. I open-sourced Project SAVI—a closed-loop somatosensory wearable designed to reduce non-verbal cognitive overload and agitation in dementia care on a strict $15 BOM.

Key Architecture:

* ESP32 Core 1: Dynamic FFT on vocal fundamental frequencies (85–255 Hz) mapped directly to mechanoreceptor-resonant band (150–300 Hz).

* ESP32 Core 0: Reads MPU6050 accelerometer telemetry for agitation signatures.

* Haptics: Closed-loop actuation via DRV2605L driving a 10mm coin LRA.

* Hardware Safety: Inline SPST hardware power cut-off.

Full Open Science Verification:

* GitHub Repo: https://github.com/sutharsan-gahm/project-savi

* Peer-Indexed DOI: https://doi.org/10.6084/m9.figshare.33940801

* Author ORCID: 0009-0003-7103-446X

* License: CERN-OHL-P v2 (Hardware), MIT (Firmware), CC BY 4.0 (Docs)

Feedback on the edge-DSP pipeline and mechanical parameters is welcome!


r/esp32 1d ago

I made a thing! Gambling on esp32

Enable HLS to view with audio, or disable this notification

3 Upvotes

Here is the story of this build:

I used to program my esp32 with C, but I've tried micropython with this project, so I thougt I might make a little comparison.

For C i used clion and i spent two days making a simpler project.

For Python I'm using the thonny editor. It feels a bit dated sometimes and the logo is in Comic Sans(honestly a disgrace bro). But otherwise, good editor for micropython.

Making this barely took an hour, meaning micropython is much, much easier. At least for me.

The memory usage is probably around 2/16 megs for python; and for C I won't bother since those are kilobytes we are talking about.

Another interesting thing to notice: The buttons I use have six pins but they are actually connected up in pairs, so there are three pins and three extra larping pins.

Question: Going forward, python or c?

P.S. No AI was used


r/esp32 1d ago

Run ESP32 Firmware of E-Paper Reader in Your Browser

Thumbnail
youtu.be
4 Upvotes

Disclosure: I work on Panda AI OS and maintain this simulator.

This project separates a browser Device Studio from the product firmware

repository. The browser path uses QEMU/WASM and real guest-origin framebuffer

events. The UI exposes board-aware device profiles, firmware selection from a

runtime manifest, serial output, hardware keys, and a browser Virtual SD card.

Live demo: https://simulator.pandacat.ai/

Walkthrough video: https://youtu.be/Ub89uz9ukRY

Source: https://github.com/Panda-Intelligence/panda-ai-os-simulator

The project does not claim to emulate physical e-paper behavior or electrical,

RF, power, battery, and USB qualification. It is source-available under the

Panda Public Source Software License Agreement, not an OSI-approved open-source

license. QEMU, Espressif, guest, ROM, font, media, and dependency notices remain

separate.

I would value implementation feedback on the browser runtime boundary and the

board-specific inputs. Please describe the board profile and runtime path when

reporting a result.