I've upgraded slot-through slit-sensor PCB design with hc238 muxing too.
Now it effectively draw less than 200mA, which means it can easily be directly powered from USB alone.
And requires only 3 resistors instead of 32 previously, only one hc238 IC per 8keys (instead of two shift registers per 8keys), 1 decoupling cap. This reduces part count and simplifies assembly (matters alot if hand placed).
A single Raspberry Pi Pico is wholly sufficient as main USB-MIDI device too, with tinyusb library. RP2040 is 70cents @ 100qty, compatible QPSI flash around 25cents. Ready made original Raspberry Pico boards are 4.2-5€, WeActStudio rp2040 is 3-4€, YD-RP2040 modules go for as low as 1.5-2.5€ a piece.
Total effective electronics BOM of this slot through design ends up being roughly 50-60€, including PCBs, but excluding assembly. No external power supplies necessary either. This is as simple as it gets, but it does require a mechanical element to move through the slit, the only downside of this approach.
I suspect a wholly analog version can also be built in roughly same electronics BOM budget, but it is highly dependent on built in ADCs of stm32 mcus to be "good enough".
My first experiences with programming stm32 via SWD has been thoroughly positive, debugger and breakpoints work great, while also being able to see peripheral registers and their state as machine is running. This is great for troubleshooting. (not using cubeIDE)
stm32 has two vendor specific APIs, stm32 HAL (high level) and stm32 LL (low level). STM32 LL are just thin wrapper over peripheral registers that are memory mapped into flat address space. Interfacing with peripherals is essentially taking 32bit addresses (as pointers) and reading/writing to values to them. Reference manuals have descriptions in detail where each peripheral is in memory space. I find stm32 LL API particularly pleasant and easy to understand.
Other than vendor specific peripherals, both rp2040, stm32g431, stm32h7, teensy4.1, they all have arm cortex m0/m4/m7 cores . RP2040 is a cortex m0 (no floating point unit), teensy4.1 and stm32h7 are cortex m7 (have floating point units), just clocked at 600mhz(teensy) vs 480mhz (stm32h750). They are programmed and debugged in the same way via SWD/JTAG.
I have weact stm32g431 (2x 12bit 0.25us adcs) devboard on hand with weact stlink probe. DMA DAC works well (very useful as signal generator!), sending ADC readings via UART using DMA works well too. ADC conversions thus far seem to work great via DMA too (ADC conversions automatically get written in buffers).
I wrote a small app for streaming and displaying ADC values over UART, works easily up to 1mbit baud rate (haven't tested higher)
![]()
(ignore ENOB readings, those are rough estimates if the signal is not "moving")
This is capable of also generating MIDI signals to be routed to Piano VIs. Which means that I can develop and test velocity calculation algorithms fully on PC before porting it over to a MCU.
The "tricky part" is setting up the peripherals/timers/DMA and buffers such that almost nothing is blocking (or calling interrupts as interupts also take cycles to switch in and out of).
For h7 480mhz / 88keys * 20khz sampling = 272 cpu cycles per key. This is only slightly less than teensy at 340 cpu cyles per key.