Program a microcontroller to interact with input and/or output devices, experimenting with different development environments.
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.
Implemented resistor-less capacitive touch using GPIO discharge timing:
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
}
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);
}
}
display.display()
once per frame to avoid flicker.delay()
blocking animation.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.
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.