It isn’t as simple as Sam’s project, and isn’t a direct tutorial. This is using a “matrix” method to decode a few octaves of music keyboard - but the general principles might map over. There are lots of tutorials for how to read buttons from CircuitPython for example to help fill in the gaps.
Aside, I’ve used a Pro Micro as a USB device too, and a USB (mini) Host Shield with an “ordinary” Arduino to act as a USB host, but these are far from simple projects, but all do-able. All details are on my site somewhere if you want to know more…
Ok I’ve built a “”“simple”"" midi keyboard. I debated posting here, despite it being inspired by this idea.
This is a concept ive had since before i knew how to make midi controllers (maybe as far back as like 2010), and I don’t know why but now seemed like a good time to develop this idea!
I call it the "Harmo-Key" (Like harmony, but with like, keys i dont know)
Still need to code the functionality and finish the 3d printed enclosure, but i thought i would post my progress. I might need to put the shift key on a pin that supports interrupts, but i wont know till I try!
The design is focused on interval selection for the 4 big buttons. The rop row of black buttons select from diatonic chords of a mode to assign to the big buttons (defaults being the appropriate 7th chord). The far left red button is “Shift”, it accesses additional functions when you press it along with another key. The top right red buttons are “octave up/octave down” or with shift held down, its “midi channel up/midi channel down”. The big knob on the left is key select, its a 12 position switch that selects what note you want your key to be. Holding shift + the top row of black buttons changes the mode (Ionian (major), Aeolean (Natural Minor), Lydian, etc etc). The bottom row is what I’m calling “chord modifiers”. The three black buttons select from changing the default 7ths chord into a suspended2 suspended4, and augmented
chord. The two red buttons are really neat, and swap the chord to the secondary dominant / secondary leading tone (this is a stretch goal of the project). All and all, i have my work cut out for me coding wise
but i’m pretty sure i know how i will do it.
Here are some (out of focus) pics of the gubbins which are subject to change:
If all goes according to plan, I was also planning on having a mode select that changes from chord interval mode to pseudorandom note mode. Essentially, the big buttons would play notes of that mode, but with probability weightings on notes that make that mode distinct, like the sharp 4th of lydian, and the flat 2nd of Phrygian. The first button would always be the tonic, the second would be the 2nd or the 3rd, depending on weights, and the third button would be 4th - 6th depending on weights, and the last button is the 7th. Tonic and the 7th are isolated because they are important for making the more unstable modes stay sounding like they do.
If I have the space on the eeprom after all this, I’d like to squeeze in the modes of harmonic minor, but this is ambitious as it is!
Also, I’m going to not be a purist here and hack the diatonic diminished chords into 7b5. I’m sure someone is going to wish I implemented diminished chords, but not on this thing thanks.
Its going to be hooked to an analog input, and the different voltages from the voltage divider will get run through the ADC on the arduino to produce values from 0-127. With these sorts of things, you are going to want to check if its a value ± what the expected value would be because of imperfections.
Here is my variation, I built it to play my Circuitbender CB-55 that is boxed with a midimuso, I use Midi channel 16 for it and mapped the keys accordingly. Works great, though i do get a fair few key bounces, do any coders know anything I can add to stop this happening ? Ot is it best to make a debounce circuit out of some logic ? Matt. PS yes I know I should have waited longer for the hammerite to dry!!
#define DEBOUNCEMILLIS 5 // For button debouncing, wait this long before
// // handling any new button presses.
void tick() // function called on button push
{
// Debouncing
int nowTime = millis();
if (nowTime - lastClockTime < DEBOUNCEMILLIS)
{
lastClockTime = nowTime;
return; // last interrupt was very recent, don't process it
}
lastClockTime = nowTime;
... // handle button push
}
(Probably needs a little explanation. If the button bounces it generates several signals. The first of these is presumably more than DEBOUNCEMILLIS milliseconds after the last time the button was pushed, so that signal gets processed. Then the rest of the signals occur less than DEBOUNCEMILLIS milliseconds apart, and they get ignored.)
I confirm that I use similar code to debounce my buttons for ages and it works fine
In hardware, I prefer Schmitt triggers with a capacitor.
I liked the video @lookmumnocomputer! The target audience is (as the title suggests “super simple”) of course bloody beginners but that’s totally fine. I loved the fact that you wrote that “horrible” code, since I think that’s the proper way of teaching coding for absolute beginners. There is no point to introduce structs, for-loops or other basic concepts, in my opinion it’s much better to let the students first suffer a little bit so that they learn and appreciate that computers are there to solve repetitive tasks
One thought for the follow-up video since you mentioned: you could show how to add a MIDI-in and thrugh, so that the device can be daisy-chained, but maybe it’s a bit too advanced
Yea it done play loads of times but I get a double thud if I don’t press the button cleanly I’m guessing not the best switch contacts in using prolly doesn’t help it’s a lot better with Sams new code but still not perfect !!
If I wanted to build one of these with 14 buttons, could I still use an Arduino Nano, or would I need to get one of the bigger ones? Specs say the Nano has 14 digital pins, but I’m assuming Midi Tx uses one, so I’d need the Micro which has 20 digital pins, is that right…?
You can use all of the analog pins as digital as well!
Keep in mind, one of the digital pins (d1) is needed for tx ( it’s used to send midi data out serially)
So, that gives you d0, d2-d13, a0-a5. Or 19 pins that can be used as digital pins.
-edit-
Analog pins a6-a7 are only able to be used as analog pins on the nano.
Digital pin 13 can have some issues with INPUT_PULLUP because the onboard led and series resistor pulls the voltage down a bit, down to 1.7v. If you experience issues with D13, then you will need to use your own pullup resistor and use INPUT pinmode instead of INPUT_PULLUP, and invert the logic for button presses being down.
Basically, the analog pins just have extra functionality that can be used to translate analog voltage readings to a digital reading from 0-127 (using an adc analog to digital converter) but if you just use them like digital pins it just works so just use the analog pin name just like a0 a1 … Etc, and you will be fine.
Even discounting D0, D1, D13, A6 and A7 though, there’s still 17 potential inputs, which is enough for 14 buttons. Might have to buy one to have a play with, as I have got this idea in my head now and it wont leave…