genuinequality

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…
Read on blog or Reader
Site logo image Simple DIY Electronic Music Projects Read on blog or Reader

Arduini Atari MIDI Keypad

By Kevin on June 26, 2025

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.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key Arduino tutorials for the main concepts used in this project:

  • Atari 2600 Controller Shield PCB Design
  • Arduino MIDI Library

If you are new to Arduino, see the Getting Started pages.

Parts list

  • Arduino Uno
  • Atari 2600 Controller Shield PCB
  • 2x Atari 2600 Keypad, Video Touchpad or other keypad like controllers
  • Arduino MIDI interface, (Ready-Made MIDI Modules, DIY MIDI Interfaces, etc)

The Circuit

Once again I'm using my Arduino MIDI Proto Shield which makes connecting everything up pretty straight forward.

Note: I started off with the V0.3 version of the PCB (as shown below) but then swapped to the capacitor-less V0.2 version of the PCB.

Reading the Atari Keypads

As already shown in my Atari 2600 Controller Shield PCB Build Guide I can use the Arduino Keypad library to read the Keypads directly.

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:

const byte ROWS = 4;
const byte COLS = 3;
char hexaKeys[ROWS][COLS] = {
{'3','2','1'},
{'6','5','4'},
{'9','8','7'},
{'#','0','*'}
};
byte rowPins1[ROWS] = {11,10,9,8};
byte colPins1[COLS] = {12,A0,A1};
byte rowPins2[ROWS] = {6,5,4,3};
byte colPins2[COLS] = {2,A2,A3};
Keypad kp1=Keypad(makeKeymap(hexaKeys),rowPins1,colPins1,ROWS,COLS);
Keypad kp2=Keypad(makeKeymap(hexaKeys),rowPins2,colPins2,ROWS,COLS);

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:

const byte ROWS = 3;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'3','6','9','#'},
{'2','5','8','0'},
{'1','4','7','*'},
};
byte rowPins1[ROWS] = {12,A0,A1};
byte colPins1[COLS] = {11,10,9,8};
byte rowPins2[ROWS] = {2,A2,A3};
byte colPins2[COLS] = {6,5,4,3};
Keypad kp1=Keypad(makeKeymap(hexaKeys),rowPins1,colPins1,ROWS,COLS);
Keypad kp2=Keypad(makeKeymap(hexaKeys),rowPins2,colPins2,ROWS,COLS);

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.

But I have a way to test that, as my original Atari 2600 Controller Shield PCB Design didn't include them at all.

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.

Kevin

Comment
Like
You can also reply to this email to leave a comment.

Simple DIY Electronic Music Projects © 2025.
Unsubscribe or manage your email subscriptions.

WordPress.com and Jetpack Logos

Get the Jetpack app

Subscribe, bookmark, and get real‑time notifications - all from one app!

Download Jetpack on Google Play Download Jetpack from the App Store
WordPress.com Logo and Wordmark title=

Automattic, Inc.
60 29th St. #343, San Francisco, CA 94110

Posted by BigPalaceNews at 7:37 AM
Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest

No comments:

Post a Comment

Newer Post Older Post Home
Subscribe to: Post Comments (Atom)

Search This Blog

About Me

BigPalaceNews
View my complete profile

Blog Archive

  • June (88)
  • May (105)
  • April (95)
  • March (131)
  • February (111)
  • January (104)
  • December (98)
  • November (87)
  • October (126)
  • September (104)
  • August (97)
  • July (112)
  • June (113)
  • May (132)
  • April (162)
  • March (150)
  • February (342)
  • January (232)
  • December (260)
  • November (149)
  • October (179)
  • September (371)
  • August (379)
  • July (360)
  • June (385)
  • May (391)
  • April (395)
  • March (419)
  • February (356)
  • January (437)
  • December (438)
  • November (400)
  • October (472)
  • September (460)
  • August (461)
  • July (469)
  • June (451)
  • May (464)
  • April (506)
  • March (483)
  • February (420)
  • January (258)
  • December (197)
  • November (145)
  • October (117)
  • September (150)
  • August (132)
  • July (133)
  • June (117)
  • May (190)
  • January (48)
Powered by Blogger.