Concertina Update

2026-Feb-17

I’m going with an SAMD21, using GPIO expanders instead of diodes for multitouch, and a proximity sensor for the bellows.

Details

I’ve rewritten everything in tinygo, which is easier for me than C++. Since I’m already targetting an SAMD21 M0 ARM Cortex processor, the added firmware size isn’t going to be a problem, and I super doubt there will be any noticeable execution penalty since it’s compiling to binary (unlike, say, MicroPython).

I’ve also decided to eschew the typical “grid” layout in favor of using four PCF8574 16-port I²C GPIO expanders. Tinygo didn’t have a driver for this chip, but it was only like 12 lines of code: the chip is as simple as it gets. Using GPIO expanders means instead of soldering a diode for every switch, I just need to run a separate line to each switch from the port expander, and I can address 16 switches with a single 24-pin soldering job. I think you can get this in a DIP package so you can do big beefy through-hole soldering, but I’m good enough at surface mount soldering that I’ll use the much smaller TSSOP package. This means I’ll be soldering four 24-pin TSSOP chips, instead of 34 diodes, which I’m pretty happy about. I’m less happy that I’m using 64 GPIO ports for only 34 inputs, but for $2.50 for each of the four chips, I think I’ll be able to get over it.

Another neat thing I get with the I²C GPIO expanders is that I can use a JST SH 4-pin connector to join both halves. You may know this as a Sparkfun Qwiic, a Adafruit Stemma Qt connector, or a Wii Nunchuck cable. It’s going to make assembly and disassembly super easy.

My idea about the bellows using the two PCBs as a gigantic switch was cute, but since I’m waist deep in I²S anyway, I just threw in a VL6180X Time-Of-Flight sensor for the bellows. This is a little LIDAR slab that measures how far away something is, about the range of 5-100mm. I’ll mount this on the inside of the “book” that the device is going to be, and just ask it over and over how far away the other side is. I can then compute the velocity of the other side and determine whether the player is pulling the sides apart or pushing them together, and how quickly. On a real concertina, playing real Irish music, volume can be used for vibrato and to emphasize notes. This code seems to be working pretty well, although I may need to add some smoothing at some point. Because the only package for this is BGA or some other dumb thing, I’m again going to have to solder a PCB to my PCB, which I hate.

Right now the electronics looks like a rat’s nest of wires on a breadboard. I’ve got enough working that I can no longer put off working on the PCB. Fortunately, I found a PCB designer that makes more sense to me than KiCad: librepcb. Unfortunately, it has practically no library, so I’m going to have to custom-create everything, including the dual-sided switch footprints. Fortunately, I only have to make footprints for 7 different components: synthesizer, proximity sensor, switch, GPIO expander, headphone jack, Qt Py / XIAO M0, and a Qwiic connector to hook both halves together.

Giving up and soldering the microcontroller PCB onto my PCB is making this a lot easier. With the one board, I get a voltage regulator, a reset button, an LED, USB power, and USB MIDI output if I want to implement it. I’m glad I compromised on my vision.