My first experiments with touch pcbs went pretty well so I figured I'd move on to making something more ... complex and interesting. A little backstory, my sister is the more musically inclined one in our family so when she was young she took piano lessons for a number of years and she was very good at it. Every year for her birthday I make her something so I figured this year it would be something musical, specifically related to the piano.
Her bday isn't till September so that gives me plenty of time but I figured that my recent interest in touch sensing could be combined with my recent audio experimentation in my UV timer controller project (where I played with custom beeps played through a piezo when the timer went off). So what better project than a touch piano! I'm just hoping that she doesn't read my project posts or watch my videos :-) in the meanwhile.
The first step was to design a pcb using what I've learned in the last log. Here's the design I came up with:
I tried to keep the key size and spacing reasonable for a human sized finger. I also wanted to keep everything as thin/flat as possible so I opted for all surface mount components, including the speaker (a magnetic one, but a piezo would work as well). I opted for a CR2032 to provide power with one of those thin metal battery holders that can simply be directly soldered to the pcb. To round out the features/components I use my goto atmega328p, two leds to indicate power and button presses and finally a small slide power switch. I did think about doing soft power control either using a momentary button (to minimize power draw) or another touch button but figured I'd keep things simple and just use a switch. Other than that I added two header spots, one is for icsp in case I needed to flash the bootloader/fuses on a new chip and the second is a serial port for programming using a cheap usb serial dongle. I think in the next board revision I'll add these hidden on the other side to interface with a pogo adapter so they aren't visible on top.
So now I had a pcb designed and a reliably working touch sensing library. While I wait for the boards to be manufactured and sent from China I proceeded with the next step which was to tackle the rest of the software. I first started with the beep/bloop software I'd written for my UV timer controller project had some serious limitations. For starters it was really meant for playing preprogrammed tunes so it was blocking (meaning nothing else could run while playing), and also it could only play one note at a time.
I could just throw a single timer at each channel (the atmega328p has three timers), but that would only net me three channels and regular delays that rely on timer0 would stop working accurately. I needed a software solution.
To address this I knew I had to move the squarewave generation to use an interrupt. Since the human hearing range is specified to be around 20kHz I set that as my upper end. This meant I had to use at least a 40kHz interrupt (since one period of a squarewave requires two edge changes). Below is a little diagram I drew up to demonstrate how the interrupt and output frequency generation would work.