Project: Microelectronic Birthday Card

39.29% relative
7.00% relative

Began in June 2026

This project is a card that, when opened, plays music and blinks LEDs for a certain duration. Just like a store-bought one, only cheaper (not including labor) and much thicker (~10 mm... some of my components were a little big for the job).

Software

To manage pseudo-multithreading where logic can be written separately but run in parallel (e.g., an LED turning on/off on a timer and a piezo buzzing on a different schedule), I used the arkhipenko/TaskScheduler library. It ended up being quite useful, with functionality like "run this if this is the first time that this schedule has run" and "gracefully cancel all schedules by having them complete the current iteration and stop". It was nice for simple debouncing, too.

To detect opening/closing the card via the reed switch with low idle current draw, I used the Arduino library's interrupts.

For the note output, I wrote a small library that lets you easily swap out the song played over the piezo. It provides helpful macros like A4 and QUARTER to help you define an array of frequencies and an array of delays, allowing you to set a TEMPO value. This way, you can create separate .h files with this format and change the song to play. I had an LLM try to generate these arrays, which was interesting with very mixed success. (It sounded like something.)

Avoiding Arduino

I got a bunch of ATMEGA328P chips (the model typically found on Arduino UNOs) a while back, but I hadn't used them much because most projects I work on require 802.11. But, the ATMEGA328P is good when you have a simpler application (that really doesn't need data logging). They are hardy enough to take a variable voltage input without an external power regulator (2.7V to 5.5V), and the built-in clock is fast enough for me. This makes it a nice chip to use bare in a project.

I set this project up using PlatformIO. At first, I flashed the code directly onto the chip using a USBTinyISP so that I could use the slimmer MiniCore bootloader, but I later decided that it wasn't worth the slower flash times so I reverted to the default Arduino bootloader (which allows direct programming over serial).

I planned at first to avoid the big Arduino library altogether; after all, the logic for this project seemed pretty simple. However, once I got to working with the buzzer, I quickly conceded and #include <Arduino.h>.

Hardware challenges

Originally, I was going to use a gutted mini flashlight as a power source. I thought that it would be cool to re-use its housing but strip out the button and LED, leaving only the button-cell battery supply, which was 4.5V: perfect for the chip I was using.

However, after loosely assembling the wiring, I tested triggering the reed switch, and the LEDs would come on for a second but then cut off, right when the piezo was supposed to start playing. Sometimes the LEDs wouldn't turn on at all. I noticed that the battery voltage drained a lot after each test (at least more than I would have suspected from only powering a few LEDs). I thought that there must be a short across the piezo or something, because that seemed to be the component that wasn't working.

I tried switching the power source for testing on the semi-assembled component An external 5V power source held fine, but maybe it could sustain some amount of overcurrent. AAs worked, too. And AAAs. But not larger button-cell batteries.

It turns out, the button-cell batteries in the flashlight that I was reworking were to weak for the current draw required for the piezo. I swapped the power supply on the final product for a set of three AAAs, and all worked well.