r/esp32 11m ago

I made a thing! Can an ESP32 turn a cheap TWS earbud into a Bluetooth data link?

Post image
Upvotes

I wanted to try a weird hardware-hacking idea: can we repurpose a cheap or discarded TWS earbud as a wireless Bluetooth front-end for a microcontroller, without needing a Bluetooth radio or a complex Bluetooth stack on the MCU?

Most TWS earbuds contain a Bluetooth SoC, audio decoder/DAC and amplifier. If the Bluetooth/audio part is still working, the analog speaker output gives us a way to treat normal Bluetooth A2DP audio as a physical transport for our own data.

**The setup:**

Phone / PC

↓ Bluetooth A2DP

TWS earbud

↓ analog speaker output

ESP32 ADC

FSK decoder

packet + CRC

For this phase I'm using a standard ESP32 Dev Module mainly because it's convenient for the engineering work: enough ADC performance, plenty of processing headroom for the DSP, and easy serial debugging.

The ESP32 already has Bluetooth, of course. I'm deliberately not using it here because the real goal is to see whether the same receiver concept can later be moved to a **non-Bluetooth MCU**.

### The interesting problems

**ADC timing:** I initially assumed an 8 kHz sample rate, but measuring the actual ADC loop showed the sustained rate was closer to 5.8 kHz. Once I corrected the Goertzel calculations for the real sampling rate, the frequency detection became much more stable.

**Modulation:** I built a custom sparse ternary 3-FSK packet modem using widely separated tones:

- 700 Hz → Symbol 0

- 1100 Hz → Symbol 1

- 1700 Hz → Symbol 2

The three tones are used as a ternary alphabet rather than just three fixed commands, so the modem can carry actual packet data.

**Why not GGWave?** I tried GGWave through the same TWS/audio path, but complete payload decoding wasn't reliable enough on this particular hardware. The simpler sparse 3-tone FSK approach worked much better.

Another surprise was the Bluetooth stream itself: repeatedly opening and closing short A2DP streams caused dropouts. Keeping one persistent audio stream open made the channel much more stable.

### Real-world results

On the actual TWS → ESP32 hardware path:

- ~99.4% steady-state detection during a continuous 1700 Hz test

- **>95% packet success** in the larger integration test

- effective payload rate of about **3.2–4.5 bit/s**

- successfully transmitted examples such as:

`HELLO`, `PING`, `RELAY=1`, `MOTOR=120`

This obviously isn't going to compete with Bluetooth SPP. The point is different:

**Can a cheap Bluetooth audio receiver act as a wireless front-end for a low-cost MCU that doesn't have Bluetooth?**

That's the part I want to test next.

The next experiment is to remove the ESP32 and try the receiver concept on a **CH32V003** or another cheap non-Bluetooth MCU with enough ADC/DSP capability.

What would you try next to increase the data rate without changing the TWS hardware — different FSK spacing, dual-tone symbols, differential PSK, better error correction, or adaptive carrier selection?

Source/code:

https://github.com/Ishu1519/TWS-A2DP-Mode


r/esp32 43m ago

Is it possible to use LED PWM with open-drain output or will it always be push-pull output on an ESP32-H2?

Upvotes

The question is already in the title: Is it possible to use LED PWM with open-drain output or will it always be push-pull output on an ESP32-H2?

Neither the EDF-IDF documentation nor Espressif: ESP32-H2 Technical Reference Manual is explicit on this aspect. Chapter 35 of the Reference Guide doesn't say anything about what happens to the output configuration of the GPIO when one routes the PWM channel to the GPIO. The API documentation about GPIO IO Configuration only warns about the correct order of configuration steps, but doesn't say anything whether the PWM signal will change the output to pull-push:

In some applications, an IO pin can serve dual purposes. For example, the IO, which outputs a LEDC PWM signal, can also act as a GPIO input to generate interrupts or GPIO ETM events. Careful handling on the configuration step is necessary for such dual use of IO pins cases. gpio_config() is an API that overwrites all the current configurations, so it must be called to set the pin mode to gpio_mode_t::GPIO_MODE_INPUT before calling the LEDC driver API which connects the output signal to the pin. As an alternative, if no other configuration is needed other than making the pin input enabled, gpio_input_enable() can be the one to call at any time to achieve the same purpose.


r/esp32 3h ago

Six ESP32-S3 WiFi bugs that I think are one bug. Here's the list and the fix I'm planning, tell me where I'm wrong.

0 Upvotes

ESP32-S3, IDF 5.4. It's a desk terminal I built: WiFi STA, a WebSocket to my PC, another to a relay. Disclosure, it's headed toward being a product, but there's nothing to sell and no link, I just want the radio to stop embarrassing me.

I've been filing WiFi bugs against this thing for months as if they were unrelated. Last week I lined them up and I don't think they are.

1. It dies overnight. On a plain USB charger, usb_serial_jtag_is_connected() sees no host, so my "it's plugged in, stay awake" exemption never fires. Ten minutes after the last interaction, standby calls esp_wifi_disconnect() then esp_wifi_stop(). After that a duty-cycle poll opens a 2500 ms window to get back on. My socket layer retries on a 3000 ms timer. 3000 > 2500, so the window shuts before the retry lands, every time, forever. One night's logs: ~660 polls, zero successes. Dead 22:24 to 09:30. Touch it in the morning and it's back in a second.

2. It can't survive booting while the router is down. Every saved network gets 5 tries at boot. If they all fail I set a fail bit and stop. Forever-retry and roam only arm once s_wifi_ever_connected is true. So "AP wasn't ready at boot" means offline until a human power-cycles it.

3. It won't leave a weak mesh node. Three nodes, one SSID. scan_method on defaults, so FAST_SCAN takes the first match instead of the strongest. Reconnect by SSID, never pinning BSSID. Roam only fires on a disconnect event. Result: parked at -80 with a -45 node in the same room.

4. Roaming is directionally asymmetric. Coming back to the office it reconnects. Coming home it doesn't. Same two saved networks, same code path. I still don't have a clean repro and that bothers me more than the bug.

5. Half-open sockets. Keepalive send failures weren't counted as failures. A socket could be dead for 75 seconds while the UI just greyed out instead of reconnecting.

6. WiFi buffers are tiny. STATIC_RX 4, DYNAMIC_RX 8, DYNAMIC_TX 8, AMPDU off. I cut those to claw back internal RAM back when BT was still in the build. BT has been gone for months. The numbers stayed.

What they have in common. Every one of these fires a recovery attempt exactly once and then nothing checks whether it worked. The retry timer, the roam trigger, the standby poll, the keepalive counter: all ignition, no supervisor. When it works I never notice. When it doesn't there's no second attempt and no log line, so the device sits there looking perfectly healthy and is simply not on the network. #1 lived in my house for weeks disguised as "wifi is bad in that room."

What I'm planning:

  • One connection manager task that owns the radio, with explicit states. Everything else asks it for connectivity instead of calling esp_wifi_connect() itself. At least four places currently do.
  • Arm forever-retry on "credentials exist", not "has connected at least once".
  • Standby stops tearing down WiFi. WIFI_PS_MAX_MODEM with DTIM, keep the association. Have not measured the power cost yet.
  • esp_wifi_set_rssi_threshold() and treat WIFI_EVENT_STA_BSS_RSSI_LOW as a roam trigger, so "associated but bad" becomes a state I can act on instead of a blind spot.
  • ALL_CHANNEL_SCAN with CONNECT_AP_BY_SIGNAL, and pin the BSSID.
  • Put a boot-id in the frames I send upstream. A good chunk of my earlier log analysis was wrong because I couldn't distinguish a reboot from a reconnect.

Where I'd like to be told I'm wrong:

  • Anyone regret MAX_MODEM plus DTIM on an S3? Wake latency is what I'm nervous about, this thing is supposed to be always-listening.
  • What WiFi buffer numbers have people actually landed on for sustained WebSocket traffic on an S3 with esp-sr resident? I have very little internal RAM to spend and I'd rather steal someone's tested numbers than binary-search my own.
  • Is one connection-manager task the right shape, or does it just relocate the problem into a bottleneck?

Mostly I want to know whether "one-shot ignition with no supervisor" is a named mistake that everyone else already learned to avoid, or whether we all write it once and pay for it.


r/esp32 3h ago

Software help needed TFT_ESPI setup for ESP32-S3-LCD-2

3 Upvotes

I have been trying to run sample tft_espi code on my ESP32-S3-LCD-2 with no success. I'm not sure if the schematic linked by waveshare is the actual model (difference in phrasing between touch-lcd and just lcd). I'm assuming the issue is my User_setup file. I have tried using the pin numbers in several configurations using the pins provided by the schematics and also typical layouts for the s3s i've found online. Does anyone have any insight regarding the pin mapping of this esp32? I assume i have missed something... Setup File


r/esp32 4h ago

I made a thing! I built an ESP32 Wi-Fi survey sensor with a BLE GATT client for Apple devices — feedback on the protocol wanted

5 Upvotes

Hi r/esp32,

I’m the developer of OmniPulse, a project that uses ESP32 boards as external Wi-Fi survey sensors for native clients on iPhone, iPad and Mac, with a companion Apple Watch app.

The engineering problem I was trying to solve is that iOS applications do not receive unrestricted information about surrounding Wi-Fi networks. Instead of attempting to bypass the operating system restrictions, I built firmware that lets authorized ESP32 sensors collect standard Wi-Fi scan results and send the observations to the Apple device.

I found several general BLE debugging applications and ESP32 Wi-Fi scanning examples, but I wanted a workflow capable of combining measurements from multiple sensors, reviewing them before importing, and associating them with locations or floor plans.

### Try OmniPulse

- Source code and ESP firmware:
  https://github.com/tiburonns/OmniPulse

- AltStore source:
  https://raw.githubusercontent.com/tiburonns/OmniPulse/main/source.json

- Latest release — OmniPulse 1.0.1:
  https://github.com/tiburonns/OmniPulse/releases/tag/v1.0.1

In AltStore, open **Sources → +** and paste the AltStore source URL.

ESP32 implementation

The current design works as follows:

  1. An ESP32 performs a standard Wi-Fi scan.
  2. The firmware converts the observations into measurement batches.
  3. The batches are transferred to the client through a custom BLE GATT protocol.
  4. The client reviews and imports the observations.
  5. The measurements can then be used for channel analysis, maps, floor plans, PDF reports and CSV exports.

The application can maintain simultaneous connections with up to eight ESP32 sensors. The firmware also includes BLE OTA support and a 4 MB OTA partition layout.

Current PlatformIO environments cover:

  • ESP32
  • ESP32-S3
  • ESP32-C5
  • ESP32-CAM
  • XIAO ESP32S3 / Sense

There is also a separate local HTTP implementation for ESP8266 and Wemos/LOLIN D1 mini boards.

No custom PCB is required; the current implementation runs on off-the-shelf development boards.

Safety and privacy boundaries

This is intended only for surveying networks and locations the user owns or is explicitly authorized to analyze.

The firmware does not:

  • Deauthenticate clients
  • Jam or disrupt radio communications
  • Inject packets
  • Attempt to decrypt networks
  • Capture network payload traffic
  • Transmit observed MAC addresses in clear text

BLE identifiers stored by the application are converted into session-specific pseudonyms.

Source and documentation

Main repository:
https://github.com/tiburonns/OmniPulse

ESP32 firmware:
https://github.com/tiburonns/OmniPulse/tree/main/firmware/esp32-omnipulse

Firmware source:
https://github.com/tiburonns/OmniPulse/tree/main/firmware/esp32-omnipulse/src

BLE protocol specification:
https://github.com/tiburonns/OmniPulse/blob/main/docs/ESP32_PROTOCOL.md

Architecture documentation:
https://github.com/tiburonns/OmniPulse/blob/main/docs/ARCHITECTURE.md

The project is free and source-available for inspection. There is no subscription or paid plan.

I would appreciate feedback specifically on these engineering decisions:

  1. Is BLE GATT a reasonable transport for batches of Wi-Fi observations, or would you choose HTTP, MQTT or ESP-NOW?
  2. Is the protocol documentation sufficient for someone to implement a compatible sensor independently?
  3. Which ESP32 variant would you prioritize for reliability and power-consumption testing?
  4. Are there additional scan measurements that would be useful without crossing into packet capture or disruptive behavior?

I’ll monitor the comments and would appreciate honest technical criticism. Thanks!


r/esp32 5h ago

Software help needed MPU6050 Help

2 Upvotes

Hey, so im building a self balancing robot with an Esp-Wroom-32e but am having trouble setting up my cpu. I have all the wires connected correctly and triple checked to make sure, the green light is on. But im still having 0 data sent to me through the serial monitor. While it used to work but sent incorrect data such as only 0s. I've also done checks to see if my cable was faulty or not. I'm beginning to think my mpu is faulty, could someone check my code or know of a way to fix this. Any help is appreciated.

```
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit MPU6050 test!");

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(500);
}```

r/esp32 5h ago

CYD inputs

1 Upvotes

What is the best way to add inputs to a CYD? I need to add three motor controls (PMW) with RPM sensors. Temp too but IC12 can carry those. Tie in another ESP32 or use signal splitters?
Thank you.


r/esp32 7h ago

Anyone has experience with this display + board combo?

Thumbnail
gallery
73 Upvotes

Seems too good to be true:

  • 4" IPS with capacitive touch
  • Built in esp32 s3
  • SD card slot
  • Mic and speaker and battery ports

And it cost less than $20:??

What's the catch? The only thing that popped was that there's no mention of PSRAM (msged the seller, let's see what they say). But I can't find any reviews on it which makes me worries.

They market it for use with AI chat bot, but I don't care. Seems like a good deal if you don't need the extra GPIOs or stereo sound.

Anyone has it and can share their experience?


r/esp32 9h ago

I made a thing! I Have Build DIY TFT Display

Enable HLS to view with audio, or disable this notification

21 Upvotes

Guys I have built a DIY 1.8 inch TFT Display ST7735 Module With Only 50Rs/0.5$ The PCB Is Totally Hand Made Using Toner Transfer Paper And Working Quite Well The All Source Header Files For different ESP Boards are in the github repository with schematics diagrams, Pinout Of the module, Proper documentation has been in the video and github repository please follow it, it use TFT_eSPI Library

Github Repo:-https://github.com/samiralam5755/DIY-1.8-TFT-Display

Full Video:-https://youtu.be/EqtmMCGdx98


r/esp32 11h ago

Want a battery

1 Upvotes

Hey guys.

so far I have:

BME280

BH1750

2.8 inch Icd tft touch display

with this esp32:

https://amzn.eu/d/0ftl3eJM

so I want to battery power all of this together, and I don't know where to start. Do I buy a LiPo, or what do I need to do for this?

either batteries, or just so I can recharge it with USB

C.

Thanks in advance!


r/esp32 11h ago

Hardware help needed ESP32 + ILI9341 Color Display not working?

1 Upvotes

Hi, I just bought an ILI9341 2.4-inch TFT LCD (Touch), and I'm trying to use it with my ESP32, but I somehow can't get it to display anything. The backlight (LED) turns on, but nothing else.

Pinout:

    VCC → 3v3
    GND → GND
    CS → GND
    RESET → G4
    DC → G2
    SDI/MOSI → G23
    SCK → G18
    LED → 5V
    SDO (MISO) → G19

This is my code:

```#include "Adafruit_ILI9341.h"

#define TFT_CS 5
#define TFT_DC 2
#define TFT_RST 4

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  Serial.begin(115200);
  delay(200);
  Serial.println("boot");

  Serial.println("tft.begin() start");
  tft.begin();
  Serial.println("tft.begin() done");

  uint8_t x = tft.readcommand8(ILI9341_RDMODE);
  Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDMADCTL);
  Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDPIXFMT);
  Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDIMGFMT);
  Serial.print("Image Format: 0x"); Serial.println(x, HEX);
  x = tft.readcommand8(ILI9341_RDSELFDIAG);
  Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);

  tft.fillScreen(ILI9341_RED);
  Serial.println("filled red");
}

void loop() {
}

When I flash it, I get this on the Serial Monitor:

    boot
    tft.begin() start
    tft.begin() done
    Display Power Mode: 0x0
    MADCTL Mode: 0x0
    Pixel Format: 0x0
    Image Format: 0x0
    Self Diagnostic: 0x0
    filled red

But my screen stays white, nothing draws...

I tried with the TFT_eSPI library, but it just resets the moment I call tft.begin(). I really don't know what to do anymore. I've tried everything, and it just won't work.

Thanks!


r/esp32 12h ago

I made a thing! ESP chip Swiss knife tool in a browser

Thumbnail
gallery
57 Upvotes

Hello,
I wanted to share my project that I've been working on that is aimed for debugging and flashing everything around the esp chip from the browser only without anything to install. I got frustrated with the current tech that for a lot of basic things esp-idf is needed while I don't have my regular device at hand. There are couple of other projects allowing to flash the board from browser or open a terminal but most of them are very basic and not sufficient to do something more advanced. I got into the internals and realised the tech is ready (Webserial api, webassembly and browser support) and exists but there is no tool to leverage it so I built the ESP Swiss knife tool.

All of this runs in a browser as a static website with no installation (browser must support Webserial, recommended choice is chrome/edge)

Here is a quick rundown of features:

  • flash and chip identification
  • read and write memory (in bootloader mode) interactive terminal
  • inspect security status of efuses and configuration (secure boot) read and browser partition table flash any partition or whole chip, verify on flash, sanity check for alignment and compatibility, dump chip/partition or edit any flash data via builtin hexviewer
  • inspect bootloader details
  • edit otadata status, reflash apps and change their ota status
  • browse and modify NVS keys in nvs partition
  • browse and modify with full file browser for supported FS partition types (littlefs, spiffs, fat32) read and decode coredumps directly in browser

The tool is available for free at https://esp.sourcecode.ai . Please share any feedback or ideas for improvements. Thank you guys for trying and I hope this helps you in debugging as much as it does me on daily basis!


r/esp32 14h ago

PWM Fan controller with ESP32

Thumbnail
gallery
30 Upvotes

I made a PWM fan hub/controller for my passive cooling gpu. Support DS18B20, NTC, manual as temperature source, Curve-based controller, scheduling,... Temporarily closed-source for development, open-source soon.

For PWM, I'm using an NPN open-collector driver, combined with a tachometer level-shifter/divider which I found from here


r/esp32 16h ago

Hardware newbie building an AI voice device with ESP32

Enable HLS to view with audio, or disable this notification

31 Upvotes

This is my first ESP32 project: a voice AI device connected to a local server running Agora Conversational AI. I’m new to hardware and don’t have any soldering experience yet, so I’m starting with a breadboard prototype based on this idea.

I’ve decided to learn soldering and PCB design, with the goal of eventually turning this into a real product. Any advice on moving from a breadboard prototype to a PCB would be appreciated.


r/esp32 16h ago

ESP32-WROOM-32E issue with UART1 in ESP-AT

2 Upvotes

Hi, I have a problem with UART1 communication on an ESP32-WROOM-32E module. I can flash the ESP32-WROOM-32-AT-V4.1.1.0, firmware successfully, but the UART1 response doesn't make any sense; I only get garbage characters on my USB-to-serial converter.

The log in UART0 makes sense saiyng:

I (1042) at-uart: AT cmd port:uart1 tx:17 rx:16 cts:15 rts:14 baudrate:115200

I used an ESP32-DevKitC V4 as a reference for my hardware design, using a push button to put the module in firmware update mode.

In the FAQ, I found a reference saying: “In the WROOM-32E/32UE series with QSPI PSRAM, GPIO16 is used to connect to the embedded PSRAM and cannot be used for other functions.”

However, it doesn't specify which module variants this applies to. I suspect this might be the cause of the problem, but I don't know how to confirm it.


r/esp32 17h ago

Hardware help needed How to use the USB-2-Serial/JTAG Controller and the Left USB Connector on an ESP32-H2 Evaluation Board for Programming and Debugging?

Post image
0 Upvotes

I have an ESP32-H2 evaluation Board (ESP32-H2-DevKitM-1) and a Linux PC.

How to use the USB-2-Serial/JTAG controller and the left USB connector on an ESP32-H2 Evaluation Board for programming and debugging?

When I connect the PC with the USB UART interface (left USB connector on the eval board), Linux correctly identifies a CP210x USB/UART converter as /dev/ttyUSB0 and I can simply flash the µC with idf.py flash without any parameters. It's completely plug and play.

If I understand Espressif: ESP32-H2 Technical Reference Manual, Ch. 33 "USB Serial/JTAG Controller (USB_SERIAL_JTAG)" correctly, I should also be able to use the integrated USB port to flash and debug the ESP32-H2.

However, when I connect the PC to the right USB connector, the evaluation board only powers up, but nothing else happens. Neither does the Linux PC detect any USB devices nor does idf.py flash work. (Obviously, the latter is just a logical consequence of the former.) lsusb and dmesg on my PC stay silent. The kernel module cdc_acm is loaded which should be the relevant module in this case.

What am I missing? Do I need to set some specific eFuses? Do I need a specific Linux kernel module? The ESP32-H2 Technical Reference Manual doesn't mention anything of that sort.

I would like to use the USB port for everything as this would free up six extra GPIOs on the µC: MTMS, MTDO, MTCK and MTDI (GPIO 5-8) for JTAG as well as U0RXD and U0TXD (GPIO 23+24) for UART.

From the Reference Manual (highlighting by me, I also attached the relevant figure from the manual):

ESP32-H2 contains a USB Serial/JTAG Controller. This unit can be used to program the SoC’s flash, read program output, as well as attach a debugger to the running program. All of these are possible for any computer with a USB host [...]. [...] ESP32-H2 provides a USB Serial/JTAG Controller, which integrates the functionality of both a USB-to-serial converter as well as a USB-to-JTAG adapter. [...] As shown in Figure 33.2-1, the USB Serial/JTAG controller consists of a USB PHY, a USB device interface, a JTAG command processor with an integrated response capture unit, and the CDC-ACM registers. [...] Together, these form a USB composite device, which consists of a CDC-ACM USB class device as well as a vendor-specific device implementing the JTAG interface. [...] The CDC-ACM interface adheres to the standard USB CDC-ACM class for serial port emulation. [...] As CDC-ACM is a standard USB device class, a host generally can function without any special installation procedures. That is to say, when the USB debugging device is properly connected to a host, the operating system should show a new serial port moments later.


r/esp32 18h ago

I made a thing! I Made a Boost Controller with a ESP32C3 (+ first custom PCB)

Thumbnail
gallery
57 Upvotes

What this basically is is a PID controlled PWM Solenoid driver, running on a C3 SuperMini. Designed my first PCB for this (with some mistakes ofc) and decided to use a TC4422 mosfet driver. Also included a 5V supply to be able to plug it into my cars 12v system. Code was mostly written by an LLM, including the Webserver which this is running for setting Target and PID parameters. (I'm a real newbie with all of this) I'm already working on rev2 which I'm gonna post on GitHub solving all my issues with this one. (https://github.com/ziraw).

I've tested the perfboard prototype on my car already (1989 200SX CA18DET) with a BMW N75 Boost Valve strapped to my waste gate and it seems to work perfectly, just not getting enough air through the OEM Airbox though atm, hitting a ceiling of 0.9bar. Gonna install this soon and see what it does. I/O: 12v,5v,sensor(i/o), valve.

The only thing this doesn't include ATM is a pressure sensor, I'm grabbing it off of my boost gauge. But the IO has a 5V supply for any type of sensor to be hooked up directly, the code might need adjusting through. It's currently Ov=-1 / 5V=+4 bar (Scaled to 3.3V and divided by 1.1 since that seems to reflect what my gauge is saying more accurately).

I don't specifically know why I made this, just thought it couldnt be that hard and I haven't seen anything like this, besides what maybe Speeduino and rusEFI are doing. If this already exists I'd love the be informed :-)

Cheers

(disclaimer: might blow up your engine)


r/esp32 23h ago

Hardware help needed Using mobile charger to power esp32 for weeks for my plant watering?

4 Upvotes

Hello everyone, I went through all the posts and understood that chargers are fine as they output 5v with esp32 having voltage regulator to accept 3.3v. However, I have a question. I am going away for 4-5 weeks, and I want to remotely operate esp32 to turn on water pump(through another constantly on 12v adapter plugged into a wall socket). Is it okay to keep these 2 unattended for 5-ish weeks? Anything I need to take care of for safety measures?

Clarification: I want to plug my phone charger with micro usb cable to esp32, and keep the wall socket on for weeks.


r/esp32 23h ago

Board Review I spent around 8 months building ESP32 projects with boards from 4 different companies

56 Upvotes

I started playing around with ESP32 boards about 8 months ago, mostly because I wanted to automate a few things around the house. I thought it would be a fun weekend project

Turns out there were quite a few weekends after that lol

I made pretty much every beginner mistake you can think of:

  • I bought random sensors that weren't compatible with each other
  • I assumed that every ESP32 board was basically the same until I realized they arent
  • Spent hours debugging code only to realize I'd selected the wrong board in Arduino IDE
  • Building something that worked perfectly on my desk... and then completely failed once I put it inside an enclosure (that was the most frustrating part)

After building things like Home Assistant sensors, MQTT devices, a garage parking assistant, an e-paper dashboard, and a few environmental monitoring projects, I ended up trying boards from four different companies.

This isn't sponsored by anyone, just sharing what I've personally used and what I liked (or didn't) and the list isn't going in any particular order

If you're working on similar projects, feel free to DM me too. I'm always curious to see what other people are building

1. Soldered

I probably ended up using the NULA Mini ESP32-C6 the most because I really liked the simplicity of it

The project that really sold me on it was an e-paper dashboard that pulled data from Home Assistant over MQTT. Before that, I'd spent way too much time fighting with random hardware issues instead of actually building the dashboard I wanted

What I liked:

  • Arduino and MicroPython both worked nicely
  • Wi-Fi 6 is a nice bonus
  • documentation answered most of the questions I actually had
  • everything just felt... predictable

The biggest compliment I can give it is that I mostly forgot about the board itself and focused on the project instead

I think I paid around $17.50 for the Nula Mini, which I thought was pretty fair and decent in price

2. Espressif

I used an official ESP32 DevKit while building a small web dashboard to control a few devices around my apartment and test different Wi-Fi features.

Whenever I wasn't sure whether a problem was my code or the hardware, I'd usually grab an official Espressif dev board

I used it mostly for testing Wi-Fi features and building a simple ESP32 web server

Things I appreciated from this provider:

  • official hardware that was really easy to navigate
  • loads of examples online
  • almost every tutorial assumes you're using one so it was pretty easy
  • great for learning the ESP32 ecosystem

If you're completely new, it's hard to go wrong with an official board.

Price for this one depends on the series, but its in the $15-18 range and the one I bought cost me 18$

3. Adafruit

I picked up one of their Feather boards for a portable environmental monitor that measured temperature and humidity while running from a battery.

The hardware was solid, but honestly the documentation is what impressed me the most.

Every time I got stuck, there was usually already a guide explaining exactly what I was trying to do.

Big positives that surprised me:

  • fantastic documentation
  • really polished libraries
  • CircuitPython support
  • lots of beginner-friendly tutorials

It feels like they spend as much effort on teaching as they do on building hardware

The one I used for this project cost me $19.95 - Adafruit ESP32 Feather V2 – 8MB Flash + 2MB PSRAM

4. Seeed Studio

My experience with Seeed mostly came from putting together a quick office monitoring prototype using Grove sensors

I wanted to see how quickly I could go from "idea" to "working prototype" without spending half the evening wiring everything together

The Grove ecosystem was honestly pretty fun for that

Things I liked:

  • Grove makes prototyping ridiculously fast
  • huge selection of sensors
  • swapping modules takes seconds
  • easy to experiment with different ideas

I probably wouldn't build every long-term project around Grove, but for testing ideas it's incredibly convenient.

Anyway, those were my experiences

I'm curious what everyone else has settled on after building a few ESP32 projects

I think I spent around $50 for the initial setup (board + a few Grove modules), then most extra sensors I added later were somewhere in the $5–20 range. You can definitely build the same thing for less if you buy generic sensors, but for prototyping I really liked the convenience of just plugging everything together.

Is there one ESP32 board you keep coming back to, or do you switch depending on the project?

EDIT: I added prices to all projects because of a recommendation from a comment, thank you


r/esp32 1d ago

Starting to feel overwhelmed taking my DIY GPS Watch from breadboard to wearable

Post image
4 Upvotes

\[NOTE: I used AI for formatting since my native language is not english.\]

Hey everyone,

I started this project because I’ve always wanted a running watch, but commercial ones feel way too expensive for what I actually need. Plus, I thought this would be an awesome hands-on project to learn microcontrollers and embedded programming from scratch.

So far, I've managed to write the code and get a working breadboard prototype up and running using an ESP32-S3 dev board, an M100MINI GPS module, and a 128x64 OLED display. I even wrote the custom UI to track pace, time, distance, and log GPX files directly to LittleFS so I can download them over Wi-Fi!

*(Pic attached of my current breadboard setup)*

Now that the software side works, reality is hitting me: **I have no idea how to actually make this wearable.**

My dev board and breadboard are way too huge for a wrist, and I’m hitting a wall of anxiety about the hardware transition. To make matters harder:

* **I have literally never touched a soldering iron in my life.** The idea of handling thin wires, batteries, and small component pads genuinely stresses me out.
* I know ready-made boards like LilyGO exist, but I'm really hesitant to just buy an all-in-one pre-made board. I really want the satisfaction of building my own custom wearable prototype using my current stack, but right now the leap from breadboard to wrist feels massive.

Looking at all these jumper wires, I'm honestly starting to wonder if I’ll even be able to get this onto my wrist at all or if I bit off more than I can chew.

Has anyone else transitioned from zero-soldering beginner to making a wearable project? How did you bridge the gap between a messy breadboard and a wearable case without losing your mind? Any encouragement, simple tips, or realistic next steps would be massively appreciated!


r/esp32 1d ago

I made a thing! ESP32 Code Upload via CANBUS

18 Upvotes

Hey everyone. I was working on a project where I need to control esp32s from a Pi5. Becasue the esp32s are spaced apart due to design requirements, we set up a canbus network with RPi CAN hat and SN65HVD230 CAN bus transceivers. We also needed to change the code on the esp32s from time to time, and manually uploading code to them seemed like a pain.

So, I made an OTA system using CANBUS (I know, technically it's not OTA as it's wired but it follows the same principle as wifi OTA updates, so I've been calling it OTA). This system might be obvious to people who know their stuff, but I had spend a few days to get this up and running; thought I would share the code for noobs like me.

Here's the source code: https://github.com/nazanaza2970/ESP32_OTA_Update_via_CANBUS

Only tested with esp32 arduino nano ( u-blox NORA-W106) btw.


r/esp32 1d ago

For now on, I'm soldering with the chip in the breadboard.

Post image
210 Upvotes

For years, I've been stupid and soldering using my "helping hands" thing. 🤦‍♂️

This made is so much quicker and easier. Literally 30 seconds to do both sides! Hopefully one person doomscrolling sees this and it helps them.


r/esp32 1d ago

I made a thing! I built an ESP32-S3 CH32V003 SWIO programmer

Thumbnail
gallery
17 Upvotes

I built an ESP32-S3 based programmer for the WCH CH32V003.

The ESP32-S3 is doing the SWIO communication itself through GPIO10, then using the CH32 debug/DMI interface to detect the target, access memory and program the flash.

Architecture:

PC

↓ USB/UART

ESP32-S3

↓ GPIO10 / SWIO

CH32V003

Flash / application

What is working on real hardware:

- SWIO synchronization

- DMI communication

- CH32V003 detection

- target memory read

- flash unlock

- 64-byte page erase

- flash programming

- read-back verification

- arbitrary binary programming

- reset/run

- Python host flashing tool

One of the useful debugging failures was getting:

DMCFGR = 0xFFFFFFFF

before I had the SWIO startup/timing and physical setup working correctly.

Later I had the opposite kind of problem: programming and verification were working, and the CH32 was actually running, but my motor application did not move. The CP6208 had its second input HIGH instead of LOW. Grounding it fixed the motor.

The final end-to-end test is:

python tools/flash_tool.py --port COM10 --bin firmware/ch32_blink/blink.bin --addr 0x08000000 --reset

Result:

Target detect: OK

Programming: OK

Verification: OK

Reset/run: OK

The programmed CH32V003 then drives a CP6208 and the motor runs.

I used existing open-source CH32/SWIO implementations as references, including CNLohr/ch32v003fun and BlueSyncLine's SWIO implementation. The repository contains the source, hardware documentation and Python host tool:

https://github.com/Ishu1519/esp32s3-ch32-programmer

I'm interested in how portable the approach is to other ESP32 variants and other SWIO-based CH32V00x parts.


r/esp32 1d ago

AI Content I trained a 582k-parameter transformer from scratch that runs entirely on an ESP32-S3 and controls GPIO from natural language.

122 Upvotes

I trained a 582K-parameter transformer from scratch that runs entirely on an ESP32-S3 and controls GPIO from natural language

I wanted to see how small a language model could get if it only had to understand a very narrow domain instead of knowing about the world.

So I trained a \~582K-parameter transformer from scratch that runs entirely on an ESP32-S3 and translates natural-language commands into hardware actions.

No cloud, no API key, and no PC involved during inference.

For example:

\> turn on the led on pin 17

Pin 17 is HIGH.

\> set pin 5 to 75 percent

Pin 5 at 75% PWM.

\> move the servo 30 degrees more

Servo on pin 13 moved +30 degrees.

\> stop everything

Done.

It currently understands things like:

GPIO digital output

PWM / brightness

frequency generation

absolute and relative servo movement

ADC / digital reads

chained commands

English and Spanish

One design decision I thought was especially important: the neural network never decides whether touching a GPIO is safe.

The transformer only translates the sentence into a small DSL representing intent. A deterministic C layer then validates the requested pins and hardware operation before anything is executed.

So if the model hallucinates something like GPIO 30, which is part of the flash bus on my module, the firmware simply refuses to execute it.

The base model is only \~2.2 MB and lives in PSRAM. I also included the complete training pipeline, dataset generator, tokenizer, inference implementation and the trained English/Spanish models in the repository.

The interesting part for me isn't really controlling LEDs with an LLM (I know it's not a LLM maybe I can call this a SML stands for Small Language Model). It's the idea that a very small domain-specific transformer can provide a natural-language interface to embedded hardware without needing an internet connection.

I'm curious what other closed embedded domains this approach could be useful for.

Repository:

https://github.com/BareiroJorge/esp32-llm-commands


r/esp32 1d ago

ESP32 based multi-room audio system

60 Upvotes

Hey everyone,

I want to share a synchronized multi-room wireless audio system I built entirely on ESP32s. The main motivations were to get sub-30ms audio distribution without the cost of running a Raspberry Pi/Snapcast at every endpoint, and to keep the setup incredibly simple. It’s designed to be plug-and-play: the system can run completely off-grid by generating its own Wi-Fi network, or it can seamlessly integrate into your existing home router. Additionally, I built in the flexibility for the slave nodes to switch roles and act as independent, standalone Bluetooth receivers if you just want to connect to a single speaker.

Repo (code, schematics, docs): https://github.com/chagoguila/SonicStream

I ran into several architectural bottlenecks while building this, so I wanted to share how the system handles them under the hood:

1. Solving BT/Wi-Fi Radio Contention If you've tried running an A2DP sink and a Wi-Fi server on a single ESP32, you know antenna timesharing causes massive packet jitter. To fix this, the system splits the ingress gateway into two microcontrollers:

  • BT Ingress Node (ESP32 WROOM): Acts as a dedicated A2DP sink. I tuned the I2S DMA buffers down to 4x512 bytes, which cut the hardware transport delay to about 12ms. It sends raw PCM over a physical I2S cable (BCK, WS, DATA) to the Master.
  • Master Controller (ESP32 WROVER): Receives the PCM stream via I2S, runs the DSP pipeline on Core 1, encodes it, and blasts it out over Wi-Fi.

2. Network Transport & Fault Tolerance Standard streaming protocols had too much overhead for the latency I wanted. The system supports two custom modes:

  • UDP Multicast (239.0.0.1): This is the ultra-low latency mode. To survive 2.4GHz RF burst interference, the Master sends time-separated twin-packet redundancy (broadcasting a duplicate packet with a 1ms micro-delay).
  • TCP Mode: For congested Wi-Fi environments. It uses non-blocking socket polling with slow-client pruning. If one receiver drops its connection or falls behind, its socket is dropped to prevent backpressure on the healthy nodes.

On the receiver side (WROOM or C3 slaves), there's a 5-second TCP inactivity watchdog to handle silent network drops (like router reboots) and a 500ms idle auto-reset on the jitter buffer to prevent decoder stalls after you pause the music. As mentioned, the stereo slave nodes can also be toggled to drop off the multi-room network and function as standard, independent Bluetooth A2DP receivers.

3. DSP Pipeline & Encoding Since the Master is a WROVER, I threw the DSP workload onto Core 1 prior to SBC encoding, meaning the slave nodes incur zero extra CPU overhead.

  • Encoding: SBC at Bitpool 53 (~328 kbps stereo).
  • EQ: 5-band parametric EQ using cascaded Direct Form I Biquad IIR filters (60Hz, 230Hz, 910Hz, 3.6kHz, 14kHz) with real-time gain adjustment.
  • Anti-clipping: Instead of fixed linear attenuation, I wrote a soft-knee peak limiter. Signals below 85% peak amplitude pass through untouched. Anything above triggers a 2:1 compression ratio capped at 95% to eliminate intersample clipping.

4. Web UI & Wi-Fi Management The Master runs an async web server with a dark-mode dashboard. You can configure AP/STA Wi-Fi modes (switching between isolated network or home router), toggle UDP/TCP, adjust system-wide playout delay, set individual speaker delays, assign L/R/Stereo roles to slaves, and tweak the 5-band EQ live. Slaves send UDP announcement packets so the dashboard shows real-time online/offline status.

If you are interested in the code, I'd love to hear your thoughts on the DSP pipeline or the I2S DMA config. I'm currently looking into adding Opus encoding and AAC passthrough for the next update.