Download free music MP3s on genuine quality, the world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, The world’s largest online music catalogue, powered by your scrobbles. Free listening, videos, photos, stats, charts, biographies and concerts. stats, charts, biographies and concerts.
Thursday, June 26, 2025
Arduini Atari MIDI Keypad
This uses my Atari 2600 Controller Shield PCB and a pair of Atari 2600 keypad controllers to see if they can be used as some kind of MIDI controller. https://makertube.net/w/7VoDLuAWbiHuMr21XszyD4 Warning! I strongly recommend using old or secon…
The simplest way to do this is to set them up as per the Keypad library tutorial example as a 4xROW, 3xCOL matrix, mapping them onto the Arduino pins as follows:
And, as shown before, this works pretty well. And the keypad handling can be generalised to support multiple key presses too.
But there is a problem. If the two buttons on the same ROW from the two COLUMNS that include a hardware pull-up resistor in the Keypad are pressed, then the keypresses aren't registered.
Other combinations of buttons are fine, but not that one.
To understand what is going on, we need to look at how the Keypad library works and then go back to the original Atari keypad circuit diagram.
The keypad library works as follows:
Set all ROWS as INPUTS with PULLUPS Set all COLS as INPUTS (temporarily) to disable them FOREACH COLUMN: Set the COL as an OUTPUT Drive the COL LOW FOREACH ROW: IF ROW reads as LOW THEN Register this key as being pressed Set the COL HIGH Set the COL back to an INPUT to disable it
Looking at the original Atari circuit, we can see some of the potential problem.
The way the Keypad is wired, for two of the columns, the highlighted paths are connected via a 4K7 pull-up resistor to 5V. When each COL is scanned, the pin (5), (9) or (6) will be driven LOW in turn and pins (4), (3), (2), (1) are scanned as INPUTs (PULLED HIGH) to see if any of them are low indicating that a key has been pressed.
However, when both buttons are pressed and the pin (5) goes low, there are now two 4K7 pull-ups in parallel connected to 5V, one of which is connected via the second key being pressed. That makes a combined equivalent pull-up of around 2K4 which is a pretty strong pull-up. Strong enough to stop the INPUT pins (i.e. (4), etc) from reading LOW which means when scanned the keypresses won't be detected.
We can see this on a scope trace.
The left is the signal from the column without the pullup resistor. The right shows the trace for a key on the column with a 4K7 pull-up. Although not as clear, it still seems to just be enough still to register as a key press though. I can get away with this for a single keypress.
But things are a little different when two keys are pressed.
Here the left shows the signals when a key from the non-pull up column and a key from one of the pull-up columns is pressed. Again we can see both are just enough to register as keypresses.
The right however is the signal when both keys are from the pull-up columns. Now, with the much stronger (2K4) pull-up the signal is not enough to register as a keypress for either column.
So if those pull-ups are causing problems when the COLs are used as OUTPUTs for detecting LOW signals, would they work better as INPUTs if I swap the ROWS and COLS around?
That can be done by redefining the Keypad matrix as follows:
It turns out that this is even worse. Now, none of the keys on "ROWS" (which were previously the columns) with a hardware pull-up work at all. I'm not entirely clear of the reason, but I guess it is something to do with there being an internal Arduino PULLUP configured (which I seem to recall the ATmega328 datasheet states is between 20 and 50 M) and the external 4K7 pull-up. This will result in a pull-up resistance pretty close to the 4K7 value which is obviously 3 to 4 orders of magnitude lower than usually expected for INPUT_PULLUP.
Taking a scope trace of this situation, gives the following:
The left is a pretty noisy signal associated with the non-pullup "ROW" but we can still see a clear key press happening as the signal is pulled LOW. The right trace shows a pull-up "ROW" and we can see that the pull-up just won't allow the signal to drop anywhere near registering as a LOW when a key is pressed.
I have to be honest - I'm not entirely clear why this is different to the previous scenario. They both, to my mind, appear to be setting the 4K7 pull-up to the internal Arduino pull-up.
So now I'm mulling over the possibility that this is an interaction between those added capacitors for the paddle controllers and the scanning pulse period of the Keypad handling. Maybe the capacitor discharge is preventing a clear LOW reading.
So yes, if I use the REVERSE method of scanning on the PCB without the capacitors I get good clean signals for all keypresses! The following trace shows several keys being pressed at once and although there is still a little variation, it is a much clearer signal in all combinations I've tried.
There is still the possibility of ghosting when pressing lots of keys, but in my experiments so far, given the quirkiness of the controllers in the first place, I've not found that a particular problem.
The Code
So the final code has essentially the following structure:
loop(): IF any keys on Keypad 1 have changed: IF State changed to PRESSED THEN: Send corresponding NoteOn message IF state changed to RELEASED THEN: Send corresponding NoteOff message
REPEAT for Keypad 2
I've set the Keys to map to the pattern: C, E, F, G, A, Bb and repeated this over four octaves, with the lowest octave on the bottom row of keys.
I've left the option for either the "forward" or "reverse" mapping of the ROWS/COLS. The "forward" works best with the capacitor shield but has the issue of some two-key combinations not working. The "reverse" works best with the non-capacitor shield.
Find it on GitHub here.
Closing Thoughts
Once again, what I thought would be a relatively straight forward project actually turned out to be a lot more involved than I imagined.
But I'm quite pleased with the final result. Those keypads are not the easiest things to use - the buttons are quite hard to press. I do have one Video Touchpad which also works, so it would be interesting to try to get hold of a second one and use those.
But having the two keypads linked together by their casing gives a nice "hold in two hands" kind of playable feel, as shown in the video.
No comments:
Post a Comment