The brief this week was to measure something—add an input to a microcontroller board I designed and read it. I turned my custom XIAO ESP32-S3 board into a tactile instrument by using two copper pads as capacitive touch sensors. The goal was an input that feels delightful and works reliably as a button for the earphone product we are continuously working towards.
I reused my Week 6 board (XIAO ESP32-S3 core, broken-out headers, clean ground reference). Two nets are reserved for touch sensing: TOUCH_PLAY and TOUCH_VOL.
touchRead() values at idle vs touch; stability over time.
Last week I switched from a windows PC to a macbook so there was a bit of a learning curve in gettin gup and running again. I cleaned and reinstalled the Arduino IDE, installed the official Espressif ESP32 core, and enabled USB-CDC so Serial works immediately on boot.
Pro tip: picking a generic “ESP32 Family Device” hid CDC options and broke Serial. Installing the Espressif core fixed it.
Sanity check: a tiny heartbeat to confirm the board and IDE are speaking the same language.
void setup() {
Serial.begin(115200);
delay(1000);
while (!Serial) { delay(10); }
Serial.println("Hello ✨ ESP32S3 is alive!");
}
void loop() {
Serial.println("Still alive...");
delay(1000);
}
I started on the wrong pins (GPIO 4/5) and got the ESP32 sentinel 4194303 (= 2²²−1), which means “not a touch pin.”
Remapping to GPIO 8 (TOUCH8) and GPIO 9 (TOUCH9) fixed it instantly.
// XIAO ESP32S3 touch pads
const int touchPlayPin = 8; // D9 → TOUCH8
const int touchVolPin = 9; // D10 → TOUCH9
void setup() {
Serial.begin(115200);
delay(1000);
while (!Serial) { delay(10); }
Serial.println("Capacitive sensing 🎨");
}
void loop() {
int vPlay = touchRead(touchPlayPin);
int vVol = touchRead(touchVolPin);
Serial.print("Play: "); Serial.print(vPlay);
Serial.print("\tVol: "); Serial.println(vVol);
delay(200);
}
Typical readings on my setup: idle ~70–90, touched ~30–40 (exact values vary with copper area, wiring, humidity, and grounding).
I designed the pads as tiny PCBs so they can live where the human is, not where the MCU is. Each pad is:
F.Cu (the sensor).F.Mask to expose copper for touch.Icons (“▶︎∥” and “VOL”) were imported as SVG via File → Import → Graphics; vector art keeps edges crisp.
Once the designs looked good, I went to the mill, set up the jobs, and then soldered and reworked the boards as needed.
Most of the interesting behavior showed up directly in the Serial Monitor, so this section is more text and numbers than pretty plots.
Update or remove links based on what you actually used this week.