Finishing this project was a huge relief, to say the least. It is truly my first project in which I designed everything from the ground up instead of just building up schematics from the internet. Thus, it was also my longest running project yet, and the amount of work that has gone into it just blows my previous endeavours out of the water.
It is also my first ever project build log/writeup, so I apologize for any mistakes or shortcomings throughout this series. It is only after all of this that I realized writing build articles like this is not easy, massive respect to those on Instructables, Hackaday, etc. Please, if you spot any errors, leave them in the comments, I’d love to learn from my mistakes!
There are quite a few features that I planned to add to the unit, but ultimately didn’t because I felt it was good enough and wanted to spend my time working on other exciting projects. I do think, however, that these will be well worth the time to look into some other time.
USB MIDI input device
One of the reasons I chose to use the STM32F103 instead of, say, an Arduino Nano clone is because of the onboard USB peripheral. I have been looking into the protocol implementation of USB lately, and thought that this would be a great opportunity to try it out. Instead of the boring serial over USB approach, I initially wanted this to be detected as a generic MIDI input device by the computer, thus eliminating the need for serial to MIDI bridges and the like.
However, it eventually proved to be a much larger can of worms than I thought, setting up all the control messages, endpoints and stuff, so in the end, I just cheated and used ST’s USB CDC driver, which works ok-ish but is definitely not without its drawbacks.
For one, the USB CDC can be quite unreliable, sometimes requiring plugging in the MIDI controller multiple times to be able to successfully open the virtual COM port. Then there is the issue I talked about in part 7 where if multiple keys are pressed the CDC driver just ignores calls to send data while it is busy, so I had to hack on a FIFO buffer to get everything to work.
Code for this definitely exists online, and I believe there is a library for the Teensy boards ready to go, all that’s left to be done is to port it over.
To me, the lack of velocity control is the Achilles heel of this entire project, as it is super duper crucial for any sort of music production.
The only reason I felt OK omitting it is because I don’t really expect to use the project for note input; it was primarily built for me to have faders for orchestral programming.
That being said, I did give velocity control (and aftertouch) quite a bit of thought. There are a couple of ways people have successfully implemented velocity control in key matrices like this. One involved using hall effect sensors to sense how fast the magnetic field around the keyswitches changes when the user presses the keys, thus deducing the speed at which metal components in the switch travel throughout the stroke. You can find more info on this approach by googling “analog keyboard”.
I didn’t think this was a good approach for this project tho, because the hall effect sensors they used were really quite expensive. Also, there is the problem of needing multiple sensors, I think the best we can do is for 4 keyswitches to share 1 sensor, and thus we need 4 sensors. And well, even without the need to sample 4 additional analog values (at quite a significant sample rate), I’ve already run out of I/O pins, and the code was already a tangled mess.
Then, there was another approach of literally measuring the velocity of the keys by sticking tactile dome switches under the stems of the keyswitches. I believe I saw this being done with Cherry MX switches that had a “tail” that would stick out of the bottom when the switches are pressed, so by measuring the time interval between the keyswitch itself closing and the tactile dome being pressed, one can literally measure the travel velocity of the keys.
That idea is actually really cool and clever IMO, but from my very brief research it seems that Gateron yellow switches have no such stem in them (the stems aren’t accessible enough anyways), and I was really trying to slim down the unit, so I didn’t go this route either.
I came up with an idea that would use multiple piezo elements placed among the keyswitches to sense the vibrations in the chassis when keys are struck. Harder keypresses equals stronger vibrations, and in my mind, velocity can be sensed that way. Or maybe, an electret condenser microphone (or many) could be used to detect how loud the “thump” is when keyswitches are pressed and deduce how hard they were struck that way.
Unfortunately however, I ran out of physical space to add an additional veroboard containing the analog circuitry that would be required to process the signal from either of them. When I came up with this idea, I was excited because it meant I would get to try designing analog filters and maybe even do some dsp-ing, both of which I find really interesting. Not surprising I guess when you consider the fact that in my early days as a hobbyist, audio electronics was all I cared about.
Maybe one day, I will cobble together a janky yet small point to point wired circuit and shove it in somehow, but for now, that’s taking the back seat.
This is one of those things that makes all the Maschines and Launchpads and Ableton Pushes such beautiful devices IMO. That feeling when you are presented with a vivid palette of hues, and you interact with it, and sounds come out of your headphones, to me is just so magical and inspiring. And that’s not even considering the gorgeous Komplete Kontrol… Everything just feels so much more alive when colors dance before your eyes.
And ultimately that’s the most important thing right? Gear that inspires you to create, gear that gives you that extra spark when ideas can’t stop flowing in, gear that gives you that extra push when you are hopelessly stuck in a rut.
I’m pretty sure that implementing something like this won’t be too hard at all, since LEDs like the WS2812 exist. The DMA peripheral could be used to take care of the rather strict timing requirements of the protocol these devices use, and thus writing code to drive them shouldn’t be too painful once the low level hardware implementation has been taken care of.
To be honest, I don’t think I’ll get around to implementing these features in the foreseeable future, since I’m about to start university in just a couple of months, and that backlog of projects is really itching to be tackled. I do have a good enough MIDI controller at the moment, and I guess that means mission accomplished?
Projects like this are never going to be done; there will always be optimisation, bug fixes, new features that can make it better. At this point, I think its best to leave it ever so imperfect and move forward.