Embedded Programming: An Introduction
This week's focus is on embedded programming, a core skill in the "How to Make Almost Anything" curriculum. Embedded programming involves writing code for microcontrollers, the tiny computers that power countless electronic devices. Unlike general-purpose computers, microcontrollers are designed for specific tasks, reading sensor data, and controlling outputs like motors, lights, and sound. This week, we learn to program a board to do something, which involves setting up a programming environment, loading code onto a microcontroller, and debugging the system.
PCB Assembly: The Soldering Process
My journey this week began with assembling a custom PCB centered around the Seeed Studio XIAO microcontroller. The soldering process was a significant learning experience. My first attempt at soldering the XIAO to the board was unsuccessful, likely due to insufficient heat or a poor connection. However, I persevered, desoldered the components, and tried again. My second attempt was successful, resulting in a fully functional board ready for programming. This experience highlighted the importance of patience and precision in electronics assembly.
A special thanks to Alan for helping me troubleshoot a floating screen issue by placing a capacitor underneath to stabilize the connection. This small fix made a significant difference in the board's reliability.
Project Plan: Touch-Controlled Subwoofer
For my embedded programming project, I plan to create a haptic feedback interface using a touchpad to control a subwoofer. The goal is to map different inputs from the touchpad to generate distinct vibration frequencies. Each button or sensor area on the touchpad will correspond to a specific frequency, allowing for a simple but effective way to produce a range of tactile sensations. This project will explore sensor input processing and output signal generation, fundamental concepts in embedded systems.
Implementation: Code and Wiring
The core of the project involves wiring the touch sensor to the XIAO RP2040 and programming it to send OSC-style messages over USB serial. A script on a computer will then interpret these messages to generate sound, which is sent through an amplifier to the subwoofer, creating vibrations in the water.
Wiring Details
The five touch pads are wired as digital inputs to the XIAO RP2040:
- Pad 1 → D1
- Pad 2 → D2
- Pad 3 → D3
- Pad 4 → D4
- Pad 5 → D5
- Module VCC → 3V3 on XIAO
- Module GND → GND on XIAO
For local sound feedback during testing, a piezo speaker can be connected to pin D0 and GND.
Arduino Code
The following Arduino code reads the state of the five touch pads. When a pad is touched, it sends an OSC-style message over serial (e.g., /pad 2 392.00 1) and plays a corresponding tone on the local piezo speaker. Releasing the pad sends a message with state 0.
// XIAO RP2040 — 5 touch pads → OSC-style messages + local sound
const int NUM_PADS = 5;
const int padPins[NUM_PADS] = {D1, D2, D3, D4, D5};
bool padState[NUM_PADS] = {false, false, false, false, false};
// Example frequencies (C major pentatonic)
float padFreq[NUM_PADS] = {
261.63, // Pad 0 -> C4
329.63, // Pad 1 -> E4
392.00, // Pad 2 -> G4
523.25, // Pad 3 -> C5
659.25 // Pad 4 -> E5
};
const int SPEAKER_PIN = D0;
void setup() {
Serial.begin(115200);
for (int i = 0; i < NUM_PADS; i++) {
pinMode(padPins[i], INPUT_PULLDOWN);
}
pinMode(SPEAKER_PIN, OUTPUT);
}
void loop() {
for (int i = 0; i < NUM_PADS; i++) {
bool reading = digitalRead(padPins[i]); // true = touched
if (reading != padState[i]) {
padState[i] = reading;
float f = padFreq[i];
// Local sound (only when pressed)
if (reading) {
tone(SPEAKER_PIN, (unsigned int)f);
} else {
noTone(SPEAKER_PIN);
}
// OSC-style message:
// /pad
// e.g. "/pad 0 261.63 1"
Serial.print("/pad ");
Serial.print(i); // pad index 0–4
Serial.print(" ");
Serial.print(f, 2); // frequency
Serial.print(" ");
Serial.println(reading ? 1 : 0);
delay(5); // small debounce
}
}
delay(5);
}