Train Wreck
The last time I watched a high school band nearly fall apart mid-performance was when the relatively new, certainly nervous band director started the piece off much faster than what the students could play.
I felt bad for the students, the director, and the audience. I cringed watching it, and I sat there silently hoping that the group could keep control of the piece until finally barreling through to the end. As they did, I could feel the audience let out a sigh of relief as we applauded for not witnessing a complete train wreck.
This experience sparked the idea to build a discreet metronome that could be embedded in the handle of a conducting baton. It would pulse vibrations into the conductor's fingertips and palm, discreetly indicating the correct tempo.
A traditional baton and its eventual technological replacement.
This post outlines the challenges I encountered and the steps I took to turn this idea into reality.
Cramming in All the Parts
From the outset I knew this would be a challenge to build because I would have to fit a lot of components into a small footprint:
- Input(s) to set the tempo.
- A way to display the selected tempo.
- Some type of motor to vibrate the baton handle.
- A button(?) to turn the device on/off.
- A chip to run the code and connect all the components.
- A rechargeable battery, and USB-C plug for charging.
After ordering a variety of components to play around with and seeing what felt best, I settled on: - A rotary encoder with push switch to handle dialing in the tempo and turning the device on/off. - An OLED display for showing the tempo. - A LiPo battery and prebuilt USB-C LiPo charging board. - An ATtiny84 to run the show.
Coding Blind: When Agents Can't See the Hardware
While I regularly use Claude Code for developing websites and python scripts, this was the first project I'd use it to write, compile, and flash the code onto a microcontroller. My setup didn't let me debug directly on the microcontroller, so the coding agent never knew whether its changes worked.
Normally when I use a coding agent to help me, I instruct it what the expected outcome should be and it can keep throwing metaphorical spaghetti against the wall until it sees what sticks (because it knows what the definition of success is). In this scenario, it would develop the code and then I would have to physically push some buttons on the hardware to test whether the code worked or not. I was part of the feedback loop back to Claude Code, updating it with what behaviors were happening on the physical device. This was a slow process, taking up to 30 seconds to write code, flash it, and test whether the changes were working.
Another challenge with this project was that even though the code running on the ATtiny is simple, getting Claude Code to correctly understand how the various hardware components were wired together was a nightmare.
Initially I tried providing data sheets to Claude so it could understand the pinouts of each part. That didn't work great, so eventually I used that information to populate the CLAUDE.md file with both component pinouts and how they were all wired to each other. I didn't keep track of exactly how many times I was burned by Claude hallucinating an incorrect connection between component pins, but it was frequent enough to be frustrating.
Trying to get this information as clear as possible in CLAUDE.md eventually helped, but it still was not perfect. Every time Claude modified the code, I had to check that the working pin numbers stayed put.
First Time Trusting a $5 PCB
Breadboard prototype.
With the breadboard working, I started packing everything into the smallest footprint I could. I've never used custom PCBs (sometimes to my detriment), but for this project I thought it would be necessary in order to cut down on the bulk of wires between the components.
I chose KiCad for developing the board, since it seemed popular and capable of doing everything I needed it to do. This video on YouTube by HTM Workshop was amazing at walking me through the whole process from drawing the schematic to submitting the order to the PCB manufacturer.
The schematic in KiCad.
The first thing I needed to create was the schematic. Picking components and wiring them was straightforward, including creating custom components that weren't in the KiCad built-in library. Once I completed the schematic, I printed it out and had my 8-year-old son build it on breadboard to ensure the schematic was accurate. He had fun building a "real circuit," and I got a free QA tester to double check my work.
3d render of the board from KiCad.
With the schematic complete, I then had to select the packaging of parts for my circuit. I chose all through-hole parts (because that's what I had available from breadboarding the design), and it was at this stage I realized the final device would probably be too bulky. I pressed ahead anyway, figuring I should reserve judgement until I held an assembled board.
After labelling the components on the board for easier assembly, I sent the design to JLCPCB and a couple of weeks later the custom-made PCBs arrived in the mail:
Look at all those connections I don't need to run wires between.
Assembling, Printing, and Rethinking
Front of the device displaying the tempo.
Back of the device with everything crammed in. The tape is temporarily holding down the battery.
Soldering the components to the PCB was easy (for $5 shipped, I think this is worth doing for all of my future projects) and soon I had a working device.
The last step was to 3d print a handle enclosure. I struggled to get the design I wanted in Fusion 360 because I only have experience modeling boxes. For the handle to be comfortable to hold, it would need to be a little bit more organic:
Trying to design something that will be comfortable to hold and 3d print well.
Eventually I got an acceptable version and printed it:
I didn't bother cleaning up this print since it was throwaway, but it confirmed that the printing quality would be good enough for what I wanted.
I knew this design would be too large for most hands, so I didn't finish fully modeling it. I did want to test the new wood PLA I bought for this project however, so I still printed the unfinished model to test its ability to be sanded smooth (it took to sanding well).
Things to Change in V2
While this first version is functional, it still needs to be smaller. To achieve this, I want the next iteration to include the following improvements:
- Integrate the open source Adafruit LiPo battery charging circuit directly onto my PCB to save space.
- Use SMD components where I can to save space.
- Maybe look into a linear resonant actuator instead of a pager motor. This might end up being easier to fit into the enclosure than the motor.
- Add mounting holes to the PCB. I thought I could 3d model a perfect fit, but quickly realized this is a giant pain. It's way easier to model some screw posts and mount the board to those.
- Plan to attach the vibrating motor and encoder dial to the enclosure instead of mounting them directly to the PCB.
Overall I'm thrilled with how this initial version came out and I'm excited to begin working on the next version.




All three LLMs caught the error, but Gemini had the cleanest output.













