← Back to Home

Week 3 – Embedded Programming

September 24, 2025 | Assignment: Program a microcontroller development board

Assignment Brief

Program a microcontroller to interact with input and/or output devices, experimenting with different development environments.

Project: Kaio-ken Animation System

Built an interactive OLED display system with capacitive touch input, featuring animated graphics inspired by Dragon Ball's power-up effects. A deliberate side project to explore embedded programming fundamentals while traveling for work—no forced connection to the final project this week.

PCB with XIAO RP2040 and OLED display Close-up of Seeed Studio XIAO RP2040

Hardware

Milled PCB - copper traces back view PCB trace routing detail

Demo Video

Software Features

Capacitive Touch Sensing

Implemented resistor-less capacitive touch using GPIO discharge timing:

OLED Animation

Audio Feedback

Running animation - aura active Board with OLED display showing graphics

Key Code Sections

Capacitive Touch Measurement

unsigned long measureCapacitanceTick(uint8_t pin) {
  pinMode(pin, OUTPUT);
  digitalWrite(pin, HIGH);
  delayMicroseconds(10);  // Charge
  pinMode(pin, INPUT);     // High-impedance
  unsigned long start = micros();
  while (digitalRead(pin) == HIGH) {
    if ((micros() - start) > 3000) break;  // Timeout
  }
  return micros() - start;  // Discharge time
}

Animation Rendering

void drawAura(int cx, int cy, float phase, uint8_t level) {
  int baseR = 12 + (level-1)*3;  // Radius grows with level
  for (int r=0; r<3; r++) {
    int rr = baseR + r*2 + (int)(sin(phase*2.0)*2);  // Pulse
    display.drawCircle(cx, cy, rr, SSD1306_WHITE);
  }
}
Download Full Arduino Code

Technical Learnings

Challenges Solved

Touch pad false triggers: Initial touch detection was noisy. Solution: Added 40μs release hysteresis (separate thresholds for press/release) and averaged 5 samples during baseline calibration.

Screen tearing: Animation had visible horizontal tears. Solution: Moved display.clearDisplay() to start of frame, drew all graphics, then called display.display() once at end.

Why No Connection to Orbis?

This week I was traveling for work and wanted to keep the assignment focused on core embedded programming concepts rather than forcing a thematic link to the final project. Sometimes it's valuable to explore tangential ideas—capacitive sensing and display animation are useful skills, even if they don't directly map to Orbis.

That said, the I2C display code is directly reusable for Orbis's OLED, and understanding non-blocking timing will be critical for managing rotary encoder interrupts alongside display updates.


← Back to homepage | ← Week 2 | Week 4 →