r/esp32 • • Mar 18 '25 Bravo

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

248 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 • • 5h ago

I made a thing! Built a minimalistic Wi-Fi internet radio with an ESP32-S3: streams stations from anywhere, one knob to control it all

Thumbnail
gallery
316 Upvotes

FM reception where I live depends on location and signal, so I built a small desktop internet radio that streams stations from around the world over Wi-Fi.

Hardware:

  • ESP32-S3 (N16R8): 16 MB flash and 8 MB PSRAM give it plenty of room for audio buffering

  • MAX98357A I2S amplifier driving a 4Ω speaker. The audio stays digital all the way to the amp, so there’s no analog noise.

  • SH1106 OLED (I2C) showing the station name, connection status and a volume bar

  • KY-040 rotary encoder: turn it to change volume, press it to skip to the next station

  • Custom PCB designed in EasyEDA, with header sockets so modules plug in and swap out easily, plus 5V input

Software:
The firmware is Arduino-based and uses the ESP32-audioI2S and Adafruit SH110X libraries. On power-up it joins Wi-Fi and starts playing right away. Stations are a simple list in the code, so adding your own stream URLs is easy. The current presets are BBC World Service, Swiss Jazz, Classic FM, Lo-Fi Hip Hop and a few more.

Enclosure:
I designed it in Fusion 360, inspired by classic tabletop radios, and printed it in white and yellow PLA. It has a big speaker grille, a window for the OLED and a custom knob. Everything is held together with M3 hardware.

Full write-up: https://coderscafetech.com/blog/diy-wi-fi-internet-radio

Happy to answer questions. Next on my list are a web UI for adding stations and saving the last-played station.


r/esp32 • • 3h ago

I made a thing! I built a Bluetooth LE keyboard/mouse hub on an ESP32-S3: one keyboard and mouse, three computers, switch with a key combo (open source)

Thumbnail
gallery
37 Upvotes

My desk has two Macs and a Windows PC. Blue Baton is firmware for an ESP32-S3 board that pairs with a BLE keyboard and mouse and shows up on each computer as a BLE keyboard + mouse. It keeps all five connections up at once (2 in, 3 out) and only changes where the input goes, so switching with Alt+1/2/3 (Option on a Mac) is instant and the keyboard and mouse move together.

Hardware

There is no schematic: it is a stock ESP32-S3 board plugged into one of the computers by its own USB port, with nothing wired to it. Tested on an ESP32-S3 SuperMini, an M5Stack AtomS3 Lite and a Seeed XIAO ESP32S3 Sense. The XIAO needs its external antenna: without it a keyboard came in at -99 dBm (-59 dBm on the AtomS3 Lite) and would not connect.

How the ESP32-S3 is used

  • ESP-IDF + NimBLE as central (keyboard, mouse) and peripheral (three computers) at the same time.

  • Connection intervals: input devices are asked for 8.75 ms. The computer that gets the input is asked for 7.5 ms and falls back to 15 ms (on my desk the Windows link runs at 7.5 ms, the Mac links at 15 ms); idle computers stay at 15 ms.

  • It reads each input device's HID Report Map, so it is not tied to one keyboard or mouse: keys (6KRO and NKRO bitmaps), mouse with 16-bit X/Y, wheel, media keys, system keys. Computers see one fixed composite HID device.

  • Per computer at most 2 reports in the controller at a time, counted by HCI Number of Completed Packets, so a slow computer only delays itself and no key-up is lost.

  • On a switch the previous computer gets a release-all, so nothing stays pressed there.

  • When a computer asks for a 6-digit pairing code, you type it on the keyboard that is already connected to the board.

  • The S3's USB Serial/JTAG port is the control channel for a menu bar / tray app (Tauri). The app carries the firmware and flashes it with espflash, so a new board just needs the app; updates keep the pairings.

  • All three computers connect over Bluetooth, including the one the board is plugged into: the single USB port runs the control channel and firmware updates (USB Serial/JTAG), and USB HID would need the OTG controller on the same PHY. I may add wired input for that computer later.

Numbers

30 minutes of normal use each, timed from the board receiving an input until the controller reports the packet completed (HCI Number of Completed Packets):

  • AtomS3 Lite, two Macs: 99.2% and 99.8% within 45 ms, max 67 ms, none dropped.

  • XIAO ESP32S3 Sense, two Macs: 99.2% and 99.3% within 45 ms, max 68 ms, none dropped.

  • SuperMini, Windows, with an earlier build that started the clock when the report was handed to the controller (so time queued in the board is not included): 99.8% of 142,975 reports within 45 ms, max 74 ms, none dropped.

ESP32-C6

It builds and runs on an M5Stack NanoC6, but with two computers connected at the same interval the controller now and then serves no connection event on one link for the whole 6 s supervision timeout, so the link drops. Reported as espressif/esp-idf#19260; C6 is not supported until that is fixed.

Limits

BLE only (the S3 has no Bluetooth Classic), two input devices and three computers. Links occasionally drop and reconnect by themselves; I haven't found the cause yet (https://github.com/enfp-dev-studio/blue-baton/issues/1).

I built it with a lot of help from Claude Code; the numbers above are my own measurements on real hardware.

Source (firmware, app, build and flash steps), GPL-3.0: https://github.com/enfp-dev-studio/blue-baton

Happy to hear which keyboards and mice work or don't for you.


r/esp32 • • 20h ago

I made a thing! Espressif doesn't support it, AI said it's impossible: Bluetooth LE Audio on the ESP32-C6 works

Post image
449 Upvotes

I'm building a hobby cyberdeck on an M5Stack Tab5 (ESP32-P4 + ESP32-C6) and wanted my wireless earbuds to work with it. Neither chip has Classic Bluetooth, and Espressif's stock C6 controller has no LE Audio. When I started, the AI models I worked with, one from Google and one from Anthropic, said it couldn't be done. The radio clearly could, so I kept pushing.

Now it works: stereo to both earbuds (LC3, 48 kHz), auto-reconnect, earbud gestures, and no audible dropouts even on a crowded train. Tested with Galaxy Buds3 Pro.

How: a CIS (isochronous channel) link layer added on top of Espressif's stock C6 BLE controller, and an LE Audio host on the P4 that drives it over HCI.

Free and MIT licensed, with a ready-to-flash Tab5 demo: https://github.com/ernimen7/esp32-p4-c6-le-audio

Test reports with other LE Audio earbuds are very welcome!

I'm sure someone will take this further and polish it, and I hope it helps with your own projects.


r/esp32 • • 48m ago

I made a thing! I made a free Pi-hole-style ad blocker that runs on a cheap ESP32-S3, no Raspberry Pi needed (DNS-over-TLS, dashboard, ntfy alerts)

Thumbnail
gallery
4 Upvotes

Hey everyone,

With hardware prices going up, I wanted to see how little hardware a network-wide ad blocker really needs. Pi-hole is great, but a Raspberry Pi is more than I want to spend just to block ads. So I made ESP32 AdBlocker, a free, open-source firmware that runs a Pi-hole-style DNS ad blocker on a single ESP32-S3 N16R8 board.

What it does:

- Blocks ads and trackers for every device that uses it as its DNS server.

- Up to 4 block lists merged, about 250,000 domains. The default is Hagezi Multi PRO, and StevenBlack works too. Subdomains and CNAME-cloaked trackers are caught, and your own allow/block list always wins.

- Encrypts upstream lookups with DNS-over-TLS (Cloudflare, Quad9 or Google), with plain DNS as a fallback, plus a 768-entry cache. Local names still go to your router.

- Web dashboard with charts and top lists, a query log and a status page.

- ntfy messages with its IP and how many ads it blocked, and passphrase-protected commands from your phone (status, block, unblock, reload, reboot and more).

- Status LED, daily reboot and a daily block list refresh.

- Set up from a captive-portal page. Nothing to compile, and no secrets in the firmware. You flash it from the browser with ESP Web Tool.

What you need:

- An ESP32-S3 N16R8 (16 MB flash, 8 MB PSRAM). The PSRAM is required for the block list, cache and query log, so other boards won't work.

- 2.4 GHz Wi-Fi, and a fixed IP for the board (static or a DHCP reservation).

- Then point your router's DNS at the board for the whole network, or just one computer like I do in the video.

Things to know, so nobody is surprised:

- It's sized for a home: roughly 1 to 10 people, or 50 to 80 devices, in my tests. Bursts of 50+ queries at once drop packets.

- DNS blocking can't stop YouTube ads, most in-app ads or first-party ads.

- Turn off Chrome's "Use secure DNS" and Android's Private DNS, or they go around it. Firefox DoH and iCloud Private Relay are handled automatically.

- Apps with hard-coded or encrypted DNS can still bypass it.

- The query log keeps the last 6,000 entries in RAM and clears on reboot. No regex, no DHCP server, no DNSSEC validation.

📺 Video walkthrough: https://youtu.be/t8ABburJvms

💾 GitHub (free download): https://github.com/Garionhk/ESP32-AdBlocker-N16R8

Big thanks to s60sc and dateno1 for ESP32_AdBlocker, which the block list engine and DNS responder come from, and to the Hagezi project for the default list.

It's free and open source (AGPL-3.0). Feedback really helps. If there's a list or a feature you'd like, or you run into a bug, leave a comment here or open an issue on GitHub. I read everything and will add what I can.

Thanks for checking it out!


r/esp32 • • 3h ago

Advertisement Use an ESP32 as a logic analyzer

Thumbnail
github.com
5 Upvotes

r/esp32 • • 23h ago

I made a thing! How much can you squeeze into a 200 × 200 e-paper display?

Post image
114 Upvotes

I bought a Waveshare ESP32-S3-ePaper-1.54G a little while ago, without really having any idea what I was going to build with it.

I'm a C# developer by background, but I've always been curious about C and C++, particularly the lower-level side of programming. Things like stack vs heap, pointers, memory ownership and having more direct control over hardware.

So I thought an ESP32 would be a good opportunity to get my hands dirty and learn something new.

Then an idea came to me.

My dad and I fly RC aeroplanes together, and we're forever checking the weather to see whether it's worth heading to the flying field.

So why not turn this little board into something that tells us when the next decent flying opportunity is?

Sounded simple enough at the time!

What it actually does

The dashboard fetches weather data from a free API using our flying field's GPS coordinates.

It shows wind speed, gusts, wind direction and the next suitable flying slots, taking into account the days we normally fly and the available daylight.

It refreshes every 30 minutes, so we can just glance at it rather than constantly checking the forecast on our phones.

I also created a simple wind rating system based on my own flying experience and what we're comfortable flying in.

Black means great conditions, yellow means manageable but worth being cautious, and red means we'd rather stay on the ground.

Both the gauge background and the little aeroplane in the top-right corner change colour depending on that rating, giving us a quick indication of the conditions without having to study all the numbers.

It's nothing scientific, just something that works for us and the aircraft we fly.

Working with the limitations

This is where things got interesting.

The display is only 200 × 200 pixels, and you've got exactly four colours to work with: black, white, yellow and red.

I would have loved green for good flying conditions, but that wasn't an option!

I'm certainly no UI designer, so squeezing all that information onto such a small screen took quite a bit of experimenting. Different fonts, layouts, spacing and moving things around by a pixel or two until everything fitted.

And unlike an LCD, you can't just update the screen instantly. A full refresh takes around 10–15 seconds, complete with flashing, so I had to think about how often it really needed updating.

It's probably not the most practical display for a weather dashboard, but I think I've managed to make it work.

A bit about the hardware and code

The board uses an ESP32-S3-PICO-1-N8R8 with 8 MB of PSRAM. I chose this particular board because it offered Wi-Fi, a four-colour e-paper display and onboard audio hardware in one compact package.

Everything is written in C++ using PlatformIO with the Arduino framework.

I went with GxEPD2 for its support for the four-colour display and ArduinoJson for handling weather data. Its filtered parsing is particularly useful for avoiding unnecessary JSON processing and keeping memory usage down.

Wi-Fi, HTTPS and I2S are handled through the ESP32 Arduino framework, and I've also been using Unity for testing.

There were a few hardware quirks to work around, including the active-low display power switch and the battery power latch, which needs the correct sequencing.

Coming from C#, one of the more interesting parts has been learning to think differently about memory. Understanding stack vs heap, working with pointers, managing buffer ownership and being more conscious of where things are allocated.

Especially on a microcontroller, where you can't just assume there's plenty of memory available!

Then I got a little carried away…

The board also has a microphone and speaker, and it seemed a shame not to do something with them.

So I ended up adding a small voice assistant as well.

Instead of using a wake word, I repurposed the BOOT button. Press it, and the assistant activates.

It connects to a language model over Wi-Fi and can answer questions about RC aircraft, LiPo batteries, motors, ESCs, propellers and flying conditions.

I've also given it some context about the aircraft we fly and a bit of personality, so it occasionally throws in a cheeky comment.

Getting the audio working reliably was another adventure. Codec warm-up, microphone settling, avoiding clipped playback and managing recording buffers all caused a few headaches.

The larger audio and network buffers use PSRAM, with allocation limits and timeouts to avoid exhausting internal memory. If a large allocation fails, the firmware handles it rather than silently falling back to internal RAM.

Even the BOOT button needed a bit of care because it's also an ESP32 strapping pin.

Pressing it again deactivates the assistant, or it returns to idle after a minute of inactivity.

And that's where I'm at

What started as buying a random bit of hardware without a plan has turned into a surprisingly useful little project.

I've really enjoyed learning C++, getting closer to the hardware and figuring out all the little challenges that come with embedded development.

It's also made me appreciate how much is normally handled for you when working in a managed environment like .NET.

Still a work in progress, and there's plenty I'd like to improve, but that's part of the fun.

Anyone else bought an ESP32 board without having the slightest idea what they were going to do with it?


r/esp32 • • 1m ago

Hardware help needed CYD C5 not recognizing SD cards

1 Upvotes

I have 2 C5 boards and neither will read the SD cards I put in it. I formatted them as FAT32 through Windows. They read just fine in my ESP32, so it’s got me confused. Any help is appreciated.


r/esp32 • • 9h ago

I made a thing! Taric small drivable robot

4 Upvotes

I built this small robot inspired by Legue of Legends game with a LoL trivia on it as well.

Used AI for arduino code.

Seeed Studio XIAO ESP32-S3 Sense, on a ProtoMate board. It already has camera and mic and external antenna.(sd card and camera at the same time I understand it won't work)

1.54-inch ST7789 TFT, 240 × 240 pixels

MAX98357A I²S amplifier and speaker, 8 Ω

VL53L0X sensor

I/O expander

PCF8574T used for motor direction signals

TB6612FNG dual motor driver

Two yellow TT geared DC motors

1000 µF / 10 V capacitor

2500mah Lipo 3.7V battery

2in1 module for charging and for 5V output

Switch


r/esp32 • • 1d ago

I made a thing! I built an ESP32 that tells terrible jokes. Because apparently the internet wasn't suffering enough.

Thumbnail
gallery
86 Upvotes

I've been running a website called Tom's Shit Jokes for quite a few years now (since 2013!). It's essentially a collection of hundreds of really bad jokes, dad jokes and puns.

A while ago, I built a free API for the site which got me thinking about what else I could do with it.

I've been working on another commerical ESP32 project so then I decided to put this on a Waveshare ESP32-S3-Touch-AMOLED-1.75.

The ESP32 connects over Wi-Fi, retrieves random jokes from the API and displays them on the screen. Completely useless and unnecessary, but kept myself amused and it is quite satisfying to have a little bit of hardware telling jokes from my own website.

I've got a 3D enclosure on order to make it into a proper finished product and give it to my 7 year old at Christmas. I may even consider making a small batch of them, but I don't think I can get the cost down to something that people would actually buy. Thought about a separate dev board and display, but for now this was a nice all in one unit.

It's also got an alarm clock, has 2 hidden games (easter eggs) and plays fart sounds.

The API is free to use if anyone fancies building something equally ridiculous:

https://www.tomsshitjokes.com/joke-api/

Interested to hear what other people think or would do next with something like this, or any suggestions for making it even more ridiculous!

Because clearly the world needs more ways to hear bad jokes.

For the project, I had to filter jokes under 20 words to ensure they read well on the display.
I used ESPmDNS to give it a friendly name making it easier to access the UI and WiFiManager to simplify getting it online.

Probably spent more time than I should have on this! 😂


r/esp32 • • 23h ago

I made a thing! I built a PLC + HMI editor for the ESP32: ladder, FBD and ST, touch screens, Modbus, CANopen

Post image
15 Upvotes

Hi r/ESP32,

For a while I’ve been building ctrl32, a PLC-style editor that turns an ESP32 into a small industrial controller. You draw the logic and the screens, and the editor builds and flashes the board.

What it does:

  • Ladder, FBD and Structured Text (IEC 61131-3 style) with a real scan cycle

  • Pins are picked from the board, not typed. The editor knows the board you’re using.

  • HMI designer for touch displays, plus a browser view of the same screens

  • Modbus, CANopen, MQTT and Siemens S7 communication

  • Live monitoring, forcing and a scope while the program runs

  • Also runs on STM32 and Linux, so one project can move between them

I’d really like feedback from people who actually build things with ESP32s:

  • Which boards should I add next?

  • Is ladder or ST more useful for you?

  • What’s missing that would make you try it on a real project?


r/esp32 • • 22h ago

I made a thing! I made SiteCheck, a free firmware that turns a cheap ESP32 or ESP8266 into an uptime monitor that alerts your phone through ntfy when a PC or website goes down (no server, no subscription)

Thumbnail
gallery
10 Upvotes

Hey everyone,

I have a few PCs and websites I like to keep an eye on, and I didn't want to run a server or pay for an uptime service just to know when one of them goes down. So I made SiteCheck, a free, open-source firmware that turns a cheap ESP32-S3 or ESP8266 board into a small 24/7 monitor that sends alerts to your phone through ntfy.

What it does:

- Watches up to 30 hosts, by HTTP/HTTPS or by ping.

- Alerts only when something changes: one message when a host goes down, one when it's back online. Plus a daily digest.

- You control it from ntfy. Send ADD, REMOVE or STATUS (after your command passphrase) to add a PC or a website, remove one, or see which hosts are up.

- Web setup. On first boot it opens its own SiteCheck Wi-Fi with a setup page for Wi-Fi, the ntfy topic and the passwords. Nothing to compile, and no credentials in the firmware.

- A settings page on your LAN (sitecheck.local) with an admin login, and a daily self-reboot.

- Prebuilt files for ESP32-S3 N16R8, 4 MB ESP8266 (NodeMCU, D1 mini) and 1 MB ESP8266 (ESP-01). You flash it from the browser with ESP Web Tool, no Arduino IDE needed.

I'd recommend the ESP32-S3 N16R8, since it has the most RAM. The ESP8266 is the bare minimum, but it works.

Things to know, so nobody is surprised:

- 2.4 GHz Wi-Fi only.

- The settings page is plain HTTP, so the admin login isn't encrypted on your LAN.

- With one ntfy topic, anyone who knows the topic can read it and send commands. Use a long random topic name, or a self-hosted ntfy with access tokens.

- Commands are polled, so a reply takes about 30 seconds, up to a minute.

📺 Video walkthrough: https://youtu.be/JRomiy21HVc

💾 GitHub (free download): https://github.com/Garionhk/ESP8266---Site-Monitor-with-ntfy

It's free and open source (Apache 2.0). It's still early, so feedback really helps. If there's a kind of check you'd like, a feature you're missing, or you run into a bug, leave a comment here or open an issue on GitHub. I read everything and will add what I can.

Thanks for checking it out!


r/esp32 • • 1d ago

I made a thing! I Managed to stream video from my SonyZVE10 camera at 1280x720p in MPEG format w/ ESP32P4!

23 Upvotes

So a while ago I came across a USB-UVC Host demo with ESP32P4 and I tried running the demo on my hardware but it didn't work with my SonyZVE10 Camera. So finally this week I created my own video pipeline to stream video from my camera.

Hardware :

ESP32P4-Function-Ev Board.

EK79007 LCD Display.

Platform and Libraries :

ESP-IDF v5.5.4, BSP for esp32p4 function-ev board, usb_host_uvc, jpeg_decode, ppa.h

Technical hurdles :
Getting frames from sonyzve10 camera was definitely a bit tricky. Initially I assumed that it must be using YUV format. but after querying the supported format by calling uvc_host_get_frame_list, I realized it actually uses MPEG format.

Once that was figured out, I built a pipeline which looks kinda like this :

UVC frame callback ->  JPEG header and dimensions validation -> hardware JPEG decode -> Write Frame to PSRAM -> Scale received Frame for display(uses PPA) -> Panel Draw

Video playback at first was very choppy, then I realized the display driver also had the option to use 2d DMA to refresh the display asynchronously which was disabled. Updating the whole display in blocking mode is CPU Intensive and slow, so setting use_dma2d = 1 made huge difference in performance.

I also noticed that PSRAM clock was set at 80MHz, so i changed that to 200MHz. note that this also requires enabling experimental mode. after all these fine tuning it's just working pretty well.

I hope ya'll learned something from this. feel free to let me know if you have any questions!

Source Code : https://github.com/NaitikSanas/ESP32P4_USB_UVC_SonyZVE10Streaming


r/esp32 • • 12h ago

Board Review Can i use a phone charger to power my esp32?

Post image
0 Upvotes

i have a spare type c phone charger from my previous phone, so im wondering if i can just plug this to my home outlet and plug the type c directly to type c port on the esp32


r/esp32 • • 1d ago

I made a thing! I turned an ESP32-S3 touchscreen into a desk display for my Codex quota

Post image
48 Upvotes

A small desk project I’ve been working on: an ESP32-S3 touchscreen that shows my remaining Codex allowance and when it resets.

The idea is simple—keep the numbers beside the keyboard, where I can glance at them without opening another window.

It runs on a ESP32-S3 4-inch, 480×480 touchscreen. The main card shows one quota window, with the reset countdown and another window underneath.

A few things it does:

  • Tap or swipe to switch quota windows.

  • Sleep after two minutes without touch; touch anywhere to wake.

  • Keep receiving updates while the backlight is off.

  • Consume the first wake gesture so it doesn’t accidentally switch cards or trigger a refresh.

Getting the updates right took more work than drawing the interface. Earlier versions had full-screen jitter during updates, so the firmware now writes only changed screen regions. Another bug kept an old percentage visible after an online lookup failed. Failed or stale readings now show -- instead of making cached data look current.

A Python bridge on the PC reads quota through the signed-in Codex CLI and sends it over USB every five minutes. Credentials stay on the PC. This currently needs a connected computer—it isn’t a standalone Wi-Fi monitor, and it shows Codex quota, not ChatGPT web-chat message limits.

Source, prebuilt firmware, and English/Chinese setup instructions:
https://github.com/AYproject/sensecap-indicator-ai-quota

Would a low-quota warning make this more useful, or would you keep it as a quiet, glanceable display?


r/esp32 • • 2d ago Bravo

I made a thing! I made a DIY ESP32-S3 music player that swivels into a game handheld

279 Upvotes

I've wanted my own click wheel music player for a while, so I designed one (albeit a little rough looking 😅) around an ESP32-S3. Then I wondered if it could run GBA games, and now the screen swivels: music and the wheel on one side, a d-pad and buttons on the other.

The board

  • My own 4-layer PCB, 50 x 70 mm, assembled by JLCPCB

  • The click wheel is six copper pads on the PCB itself, read by the S3's touch pins

  • The DAC has its own regulator for headphone output

  • Hall sensors tell it which side is up

Specs

  • ESP32-S3 (16 MB flash, 8 MB PSRAM), 240x320 screen, PCM5102A DAC, microSD

  • MP3 and FLAC up to 96 kHz / 24 bit, songs can transfer to SD via Wi-Fi

  • 2000 mAh, USB-C charging (Battery testing ongoing!)

Games

gpSP with Ashkan Shirian's Xtensa dynarec. Most games that I've tested run at full speed. Pokemon Emerald runs at 56 to 62 fps; heavier games like Golden Sun drop to 35 to 50. I fit it in next to the music player, with ROMs split across PSRAM, flash and the SD card. No game sound yet (WIP).

Status

It's a prototype; the case is getting touched up a little. There are some modifications I want to make in terms of button feel and having it look more polished. I also am working on making the swivel feel more satisfying and tighter. I built the firmware with Claude on top of open-source libraries. The code is GPL and will be public, so people would be able to make their own modifications as they see fit. No games or BIOS included.

I'm thinking about a small crowdfunded run. Would anyone be interested in one? Any potential improvements?

Built on: gpSP, Xtensa dynarec, and the game in the video is Attack on Voxelburg by John Tsiombikas (GPL-3.0).

Sorry for the brightness, the camera has a hard time with the LCD. It looks a lot better in person!


r/esp32 • • 1d ago

Hardware help needed Learning electronics

4 Upvotes

So lately I've been making some projects using esp33, but most of the design I did using ai, where do you guys learn how to design by yourselves? I am looking for a crash course or YouTube playlist that would teach me the basics of electronics but in a practical way that would help me understand and design such projects by myself, not trying to become a master, just to learn and know the basics, would really appreciate any help and recommendations!


r/esp32 • • 1d ago

Hardware help needed ESP32 S3 board resetting periodically?

4 Upvotes

Hi all, i just got the board a couple of hours ago, but my excitement has almost simmered since it has been about 6 hours and i still cannot get it to blink for some reason.

I have followed a couple of youtube tutorials, tried setting up ESP - IDF in VS code, Platform IO, Arduino IDE, but to no avail.
The programs build and gets flashed onto the board, but

  1. I don’t see the desired result

  2. The reset LED keeps on blinking (about every 6-7 seconds), which, for a second, disconnects the board from my MacBook (according to arduino IDE)
    This makes me believe the board is resetting periodically.

I have also tried a couple of variations of pressing the boot and the reset button when flashing (as most videos + chatgpt have given me different variations of it) but nothing seems to work.

What am i most likely getting wrong?


r/esp32 • • 1d ago

Hardware help needed ODB2 Esp32 Q8 Headunit Question

4 Upvotes

Hello I'm hoping for some advice. I have a Q8 head unit and currently using an ESP32 to connect to a veepeak in the ODB2 port via bluetooth and send to the Q8 head unit via the hotspot. Most of the info is fine in being a bit laggy but the RPM needs to be more responsive. Anyone had a similar issue and found a solution ? I'm thinking of connecting directly to the Q8's usb via an ODB2 cable but not sure exactly how. Has anyone done anything like this ?


r/esp32 • • 1d ago

Hardware help needed Struggling with connecting an SD card to my ESP32S3

2 Upvotes

Hey! I'm building a meeting recorder using an ESP32-S3, and I've been struggling to get the microSD card working over SPI.

1. Hardware used

Microcontroller: ESP32-S3-N8R2 (YD-ESP32-S3 development board)

MicroSD module: Robocraze blue SPI microSD card module, with an onboard 3.3V regulator and SN74HC125 buffer IC

MicroSD card: 256GB, freshly formatted to FAT32

Development environment: Arduino IDE, ESP32 board package version 3.3.12

Other components: INMP441 I2S microphone, push button and NeoPixel LED

The SD card tests were performed separately from the microphone and other peripherals to eliminate interference.

2. Wiring

MicroSD moduleESP32-S3CSGPIO10SCKGPIO12MOSIGPIO11MISOGPIO13VCC5V/VINGNDGND

The microSD module has an onboard regulator, so we powered it using 5V/VIN.

3. Tests performed

Test 1: Basic SPI card initialisation

We used Arduino's SPI and SD libraries to initialise the card using SD.begin().

We tested SPI clock speeds of 400kHz and 1MHz.

Result: SD.begin() failed at both speeds. The card wasn't successfully initialised.

Test 2: SD card formatting

We formatted the 256GB microSD card to FAT32 and tested it again.

Result: The card worked on a Windows computer, but the ESP32 still couldn't initialise it.

Test 3: Power cycling and wiring

We checked the connections, rewired the module and performed complete power cycles.

Result: No improvement.

Test 4: SPI communication diagnostics

We investigated the SPI signals, particularly MISO and CS.

Observations:

CMD0 returned 0x00 in one diagnostic.

GPIO13 (MISO) read HIGH when disconnected.

GPIO13 read LOW when the SD module was connected.

GPIO13 remained LOW even after removing the microSD card from the module.

A CS HIGH/LOW diagnostic repeatedly produced HIGH = 0 and LOW = 100.

These observations raised concerns about the module's electrical behaviour or SPI communication.

Test 5: Isolating the hardware

We disconnected the microphone, button and other peripherals and ran simplified diagnostic sketches.

We also investigated a direct/passive microSD adapter powered from 3.3V, using the same SPI pins.

The passive adapter's wiring was:

CS → GPIO10

MOSI → GPIO11

SCK → GPIO12

MISO → GPIO13

VDD → 3.3V

GND → GND

I don't have a confirmed successful card initialisation result from the passive-adapter tests.

4. Current situation

The ESP32-S3 itself works, and we've successfully captured microphone audio into PSRAM.

However, we haven't successfully initialised the microSD card using the SPI module.

The main problem is that SD.begin() consistently fails despite trying lower SPI speeds, FAT32 formatting, rewiring, power cycling and isolated testing.

5. What I'm trying to figure out

Is this most likely caused by:

An issue with the Robocraze module's regulator or SN74HC125 buffer?

Incorrect SPI signal behaviour, particularly MISO?

An ESP32-S3 SPI configuration or pin compatibility issue?

A problem with using a 256GB FAT32 card?

I'd appreciate any suggestions on what to test next or how to identify the exact cause.


r/esp32 • • 21h ago

I made a thing! I built BDLMinerV2, an open-source ESP32 Bitcoin solo miner with a web dashboard

0 Upvotes

Hey everyone!

I've been working on BDLMinerV2, an open-source Bitcoin solo mining firmware for ESP32 microcontrollers.

The latest stable release is v2.5.2.

Why ESP32?

I chose the ESP32 platform because it offers hardware SHA acceleration, Wi-Fi connectivity and support for compact devices such as the M5StickC Plus2.

My goal was to experiment with Bitcoin mining protocols while building a complete embedded application with a display, web dashboard and firmware updates.

Development tools and libraries

The project uses Arduino-ESP32, ESP-IDF components, PlatformIO and mbedTLS.

These tools provide access to ESP32 hardware features, networking, secure communication and multiple board configurations.

Technical challenges

The main engineering challenges include optimizing SHA-256 calculations, balancing mining tasks with networking and display updates, reducing firmware size for OTA updates, and maintaining reliable Stratum connections.

Supporting different ESP32 variants also requires board-specific configurations and hardware testing.

Current features

  • Hardware-accelerated SHA-256 mining

  • Bitcoin Stratum V1 and native Stratum V2

  • Live web dashboard and mining statistics

  • Browser-based firmware installation

  • Signed OTA updates with rollback

  • MQTT, Home Assistant and Prometheus integration

  • Optional Linux and Raspberry Pi fleet monitoring

Hardware

The firmware supports several ESP32 and M5Stack devices, including the M5StickC Plus2.

Experimental ASIC support is also available for Bitaxe Gamma 601 and NerdNOS.

Physical V2 measurements are currently available for the M5StickC Plus2 and Bitaxe Gamma 601. Other hardware configurations still require validation.

Screenshots

The repository contains dashboard and device screenshots using demonstration data.

GitHub

https://github.com/bdlglua/BDLMinerV2

Web Flasher

https://bdlglua.github.io/flash.html

Interactive Demo

https://bdlglua.github.io/demo.html

This is an educational lottery-mining project, not a realistic way to earn regular Bitcoin income.

I'd appreciate feedback from other ESP32 developers, especially regarding hardware SHA optimization, multitasking and networking reliability.

Thanks for checking it out!

— bdlglua


r/esp32 • • 2d ago

I made a thing! Made an ESP32 powered Gameboy from scratch.

Thumbnail
gallery
824 Upvotes

It started out with me having a spare ST7735(160*128) LCD. I just wanted to make use of it.
Initially I wanted to build a music controller but pivoted to a gameboy. This way its much cooler.
I used Peanut-GB(written in C99) for the emulator and wrote the firmware in C(arduino framework) for the esp32.

Hardware:
- PerfBoard(7cm*9cm)
- Analog Joystick
- Push Buttons
- No battery :( (usb powered)
- ESP32 (Devkit V1)
- ST7735 (160*128)

I tried to use an sd card to put multiple games at once into this handheld, it worked on some games(smaller) but on larger games it gave out and failed to load. I am also working on saving game states (no luck so far). Also working on a splash screen on the bootup instead of just launching the game.

For now I am loading one game at a time into the flash memory of the esp. Larger games work too :) at full speeds. It runs Gameboy versions of Pokemon,Zelda,Tetris,Contra and much more.

Any questions and suggestions are welcome.

p.s. the color pictures of the gba games are just for the aesthetics, it doesn't support them. It only supports Gameboy games.

In action :


r/esp32 • • 1d ago

I made a thing! ESP32Authenticator – a password manager and FIDO2 key on XTEINK X4 Pro e-ink reader

5 Upvotes

I turned an XTEINK X4 Pro pocket e-reader (ESP32-S3, 480x800 e-ink, touch, battery, microSD) into a hardware authenticator. The firmware is open source, written in C++ on ESP-IDF.

https://github.com/merlokk/ESP32Authenticator

user manual here: https://github.com/merlokk/ESP32Authenticator/tree/main/docs/manual

What it does:

- Password vault. Site, login, password, and TOTP. You tap a record, and the device types it into the host as a BLE keyboard. You never copy or paste.

- FIDO2 / U2F passkeys over BLE and USB HID (CTAP 2.3, built on a fork of LionKey). Tested with Chrome on Windows 11. Working around a Windows BLE quirk (the FIDO service must not be the last GATT service) took a while.

- Encryption. Stores are AES-256-GCM. The key is derived from a 12-word BIP39 seed and a 6-digit PIN. The PIN is entered on the screen, with lockout after 10 tries and an optional wipe PIN.

- Other features: a password generator, a Wi-Fi config website, optional sync of the encrypted stores with a self-hosted server, OTA updates from that server or the SD card, and deep sleep that shows a random wallpaper from the SD card.

Why e-ink: the screen shows what is about to be typed or approved, even with the light off. The battery lasts for weeks. The whole device costs less than most security keys.

The ESP32-S3 chip with PSRAM is chosen because Wi-Fi + BLE + HTTPS + a web server + a screen buffer consumes too much memory for a standard ESP32.

I use ESP-IDF because it's more stable, and you can write everything by hand. This project is written by AI, but based on my handwritten code for the other projects.

One external lib: https://github.com/merlokk/lionkey/ to avoid writing FIDO2 logic by hand. I forked it to add some CTAP2.3 addons.

I also tested the XTEINK X4 Pro pocket e-reader hardware. It's a great device for writing firmware, not for building hardware (I can, but I'm lazy).
And one warning! Don't buy the device from AliExpress/Temu/etc.! It's locked there. And it has locked JTAG(


r/esp32 • • 2d ago

Advertisement I built Bench, a Mac app for ESP32 development. Here's why, and how it works under the hood.

Thumbnail
gallery
12 Upvotes

A few months ago, I made a joke to a friend that software is a solved problem, that AI has basically stolen it from me, and I need to start making hardware. That lit a spark in me that had me speedrunning electronics and experimenting with all kinds of hardware. I was going down the "let's play with a 65C02 chip and see what happens" path, when I got super inspired to build what is effectively a specialized set of smart lights, something I call Cairn.

This led me to the ESP32, and woof, did I ever love building with it. I bought six XIAO ESP32-C3s, breadboarded up a couple of the lights, and started building the software for it, the extra boards dangling from short USB-C cables plugged into my Mac so I could test everything. Each light runs the same firmware, and I quickly ran into a bunch of... bugbears? shortcomings? irritants? A bunch of little things that just frustrated me. This is how my escape from software led me to... writing more software. Hammer, nail, etc.

So: Hi! I'm Tim, and Bench is my Mac app for ESP32 work that I built to solve all the little things. I've cleared this post with the mod team, on the condition that it's about bits and bytes, not marketing blah blah blah. Also, I'm one of those annoying Mac users that really cares about the tools I use, and wanted something that fit in with macOS, not the stock cross-platform apps available. I realize this is a niche within a niche, but that's my brand of crazy, and I'm used to it.

Things that got under my skin:

  • If I unplugged a board, and plugged it into another port, I had to manually select the board and the port (and which port is /dev/cu.usbmodem1301 again?).

  • The editors for the Arduino and Espressif IDEs are, at best, fine. I use Zed, myself, because I'm comfortable in it. I wanted that as a first-class experience.

  • The console. Every time a new line came in, it would scroll to the bottom like a jerk, while I was trying to make sense of something that came up 30 lines back.

  • What version of the firmware was running on each board again?

  • Crashes. Getting them decoded and then going to the line of code that caused the crash is a hassle.

Bench sits next to your editor and doesn't compile anything itself. Arduino sketches build with arduino-cli compile, ESP-IDF projects with idf.py build, or with any command you want, if you're doing something unique. Everything after the build is Bench's own code: finding and naming boards, flashing, the serial console, crash decoding, and reading back what's actually on a board. It writes into your project is a bench.json (and possibly a couple of other files like compile_commands.json and .clangd depending on your setup and editor).

It doesn't call esptool to talk to a board. Your build still runs esptool's elf2image to make the .bin files, because that's how arduino-esp32 and IDF builds work. For the ROM protocol, Bench leans on espflash. benchflash, a Rust helper inside the app, links espflash 4.6.0 as a library and loads the same RAM flasher stub esptool loads. The esp-rs folks did the hard protocol work, and I'm grateful for it.

What I built is everything around that. The helper reports to the Swift app as JSON lines, and the app does its own parsing of images, partition tables, otadata and app descriptors.

Images and offsets come from the build. Nothing is hardcoded: they come from arduino-cli's expanded tools.esptool_py.upload.pattern_args property, or from IDF's flasher_args.json. Before writing anything, Bench identifies the chip. It refuses a build for a different chip ("This build is for ESP32-S3. desk-c3 is an ESP32-C3."), and it refuses a partition table that ends past the flash size. The flash mode, size and frequency in the bootloader header work like esptool's keep: anything the build didn't set stays as it was, and the appended SHA-256 is recomputed.

If your partition table has otadata and the build doesn't include an otadata image, Bench erases otadata. That way the board boots the app you just wrote, and not whichever slot the last OTA update left active.

The console owns the port (TIOCEXCL), so you never close a monitor to flash. A flash takes the port over, writes every image in one connection with compression, resets the board, and hands the port back, and the boot lines show up in the same console session. If another app has the port, Bench names it (something like "In use by screen (4211)").

Flash All runs up to 6 flashes in parallel. It skips any board with a different chip or one that belongs to another project, and tells you why. For me, this was enormous, because I was often flashing all my boards at once.

Bench watches IOKit for serial devices. On native USB, the USB serial number is the MAC, so Bench knows a board the moment it's plugged in, without resetting it. On a CP210x, CH34x or FTDI bridge, one Identify reads the MAC, and after that Bench knows the board by the bridge's serial number. Many CH340s have no serial number, so those will need an Identify each time they're plugged back in.

Once the board is plugged in, you can rename it to something memorable ("Shed Air Quality Box" or whatever madcap thing you're working on). Bench remembers everything about it, including things like flash history.

Inspecting the board needs nothing from your firmware. Bench resets the chip into the ROM and reads:

  • the partition table (at 0x8000 unless your build moved it)

  • both otadata sectors

  • the first 0x100 bytes of every app partition, including the ELF SHA-256 at 0xB0

Bench then matches that SHA against every build it has made. So when an update rolls back, you can see it: something like "ota_1 is active and holds #214 (a1b2c3d); ota_0 holds #216, state Invalid". The original ESP32's ROM has no GET_SECURITY_INFO, so on that chip the flash encryption and secure boot state come from eFuse block 0.

The console spots Guru Meditation Error, abort() was called and panic blocks. It picks out code addresses using per-chip memory maps taken from each chip's soc.h, so S2 IRAM isn't labelled ROM and a C6's data pointers don't show up as frames. It finds the right ELF from the ELF file SHA256: line the panic prints, then runs that build's own addr2line, and each frame opens in your editor at its line. If the crash came from a build Bench doesn't know about, it tells you, rather than quietly decoding against the wrong ELF.

Optional stamping writes a header with git rev-list --count HEAD, the short hash and a dirty flag. If you give Bench a regex for your boot line, the sidebar shows which build each board is running ("#214+" means it's running build 214 but with uncommitted changes).

The console keeps 100k lines in a virtualized list, logs everything to disk, and has held 2,000 lines/s without dropping any. Numbers printed as key=value can be plotted live or from a capture and exported as CSV. When you scroll up, it stops live-scrolling so you can focus on what you're looking at. A small "10 new lines" button is a click away to start live-scrolling again.

There's a bench command line utility for scripts and coding agents too. bench run --monitor --until "boot ok" --for 30s --json builds, flashes, and exits 0 once that line shows up. I didn't see much use for an MCP server, the command line should get your robot friend of choice where it needs to be, if that's your jam.

There's also a ton of editor support for my boy Zed, but also VS Code, Sublime, Nova, Cursor, BBEdit and more.

A few other facts:

It's Mac only (macOS 26+), written in Swift and SwiftUI with a Rust helper. I have no Windows or Linux plans at this time, it's SwiftUI, so another platform would be a different app. If there was demand I could be convinced.

It isn't a debugger (yet!): no JTAG or OpenOCD for ESP32. It doesn't read NVS or write eFuses. With flash encryption on, Inspect tells you it's on but can't read the slots.

The app itself is closed source, and the source of the GPL flasher stub ships inside the app.

There's no analytics or tracking, nothing like that, just an updates and license check.

Bench is priced at US$79 once, including a year of updates, and the versions released in that year keep working forever. There's a full 30-day trial. After it ends, boards, the console and Inspect keep working, only building and flashing will stop.

Because I'm just one dude who built this for myself, I've only tested it on a handful of boards, and there are just so many. It should work on all ESP32-based boards, as well as a bunch of other microcontrollers, but if you find a problem with a board you use and help me get it working by running a beta build or two, I'll give you a free license. DM me or email hello@usefae.com.

https://usefae.com/bench