Teensy 4.0 Joystick with 40+ buttons

Status
Not open for further replies.

Jeprin

New member
I am in the process of designing a PCB for a button box I am building and have realised that it has more that the 32 buttons that are supported by Teensy, is it possible to alter the code behind the joystick program so that I can use all my buttons or is it back to the drawing board for me?
 
Teensy supports eleventy hundred trillion buttons if you use shift registers. :)

See this for an example: https://www.pjrc.com/teensy/td_libs_ShiftPWM.html

That project drives output, you want input, but other than that it's the same idea... you want more lines, all you have to do is chain in more shift registers. Four 16-line registers will more than take care of your project, and all you need is two pins on the MCU! The example uses three lines, but only because of the specifics of the register ICs used. I think it's bi-directional, and there has to be a third "latch" line so all the registers activate their transistors at the same instant. If you are only reading, you only need two lines. On the other hand, if you want to drive LEDs, bi-directional knocks out two problems at once.

You can also see how much easier this is going to make your PCB routing. The registers can be placed good and close to the buttons, and then you only have to figure out two traces to the Teensy. Imagine the alternative: gnarly fan-out, possibly crazy vias or even jumpers. This way, you might get away with a two-layer board.
 
I am not sure if I understand how this works, I see that I will need to add another chip to handle the shifting in the registers but I am unsure of how to do this since I am not very used to programing, especially in c++ which I think is the programing language that I need to use. I was also more thinking going the easy way and doing a button matrix, so would this be compatible with that?
 
That could work, if the buttons are in a matrix. I haven't done that before, but I think you also need some diodes in there somewhere. If your matrix is 7x7, you need ground + 14 lines. 8x8, ground + 16 lines. In this way, there is no external chip, but you gotta route a LOT of lines to the MCU.

If you use 8-line shift registers, each row (or column, whatever's easier) gets one register; or if you get 16-line registers, each can handle two rows or two columns. Each shift register is one chip. No additional chips go between the registers and the MCU; it looks like this: MCU -> shift register 0 -> shift register 1 -> shift register 2 -> (etc...)

To make it easier to understand, imagine you have just 8 buttons, and they're wired to a shift register. The conversation looks like this:

* Teensy raises clock pin
* Teensy reads data pin
* Teensy lowers clock pin

...done eight times, because there are eight pins. You can write the data pin's state to a char[] array long enough to hold the output of all the shift registers. (Or you can pack the data into binary form, where 1 byte tells you the state of 8 buttons, but this MCU has so much memory that I wouldn't bother.)

Once you get it working, you will see that it's incredibly easy. Some example code is here: https://forum.pjrc.com/threads/48730-SN74HC165-shift-register-revisited

Shift registers cost more than diodes, and you have to decide what the trade-off is. I think you'll find the code to scan a matrix is no less complex than the code to pull stuff out of a shift register. If you want to run LEDs, you can do both input and output on three lines, and chain as many devices as you want.
 
If you are referring to the 32-button limit per USB Joystick, I recommend making your Teensy an USB Keyboard + Joystick pair, with the extra buttons producing standard keypresses.

This thread has a custom Joystick that can support up to 128 buttons, but a lot of OSes and programs have issues with joysticks having that many buttons.

(I think the first microcontroller project I ever did was this arcade joystick with a couple of buttons with a Teensy 2.0++, that I used to produce configurable keyboard key codes so I could play SuperTux and online Flash games with it. I had a rotary switch to select between preprogrammed sets.)

If you use a Schottky diode (for the low voltage drop) per button (or a diode pair per button pair), you need R digital outputs and C digital inputs for R×C buttons. The diode allows you to detect each button/key separately. 100 BAT54W-HG3 Schottky diodes in SOD123 package (first one that popped up in a Mouser search; so definitely just an example) should cost less than $10 USD. I'd add a current-limiting resistor on each output, say 10 kOhm, for safety; and those are always useful to have around.

The idea is that the R outputs each select one "row" of buttons, with a diode each between the row and the button, and the button connected to the corresponding "column" input. Only one of the rows is selected at a time, so the inputs directly read the states of the buttons on that row.

If you connect the diodes from the row to the button, with anodes on the rows, and cathodes (lines/bars) on the buttons, then a high output selects a row, and the column inputs are inputs with internal pulldowns enabled. (That way, when a line "floats", it reads as low; and high when connected to the row via a pressed button and the diode.)

When you have multiple buttons pressed, the diodes stop the other columns from being pulled high through the other buttons. Without the diodes, combinations of buttons cause other buttons to look like they're being pressed also. The voltage is 3.3V or so, and with a 10kOhm current-limiting resistor on each row, the current is at most 0.33mA. Not much.

If you are running out of pins, you can instead use a 3-to-8-line decoder/multiplexer chip, like a 74VHC238, to use just 3 output pins to control 7 or 8 rows of buttons. (The extra row, usually row 0, is a special "not connected" row with no buttons, so that when not being actively scanned, the decoder/multiplexer does not need to source/sink any current. Also note that the direction of the diodes also dictates the type of decoder/multiplexer; here, you'd want one that pulls only one output high at a time. The other type pulls one output low, and all others high. That type would also work if you reverse the diodes, and enable the internal pullups on the inputs.)
With say three of those (so 9 row selector output pins for 7+7+7 = 21 rows) and 10 column input pins you get 210 individually detectable buttons.

If you don't need the pins on Teensy 4.0 for anything else, you can do e.g. 10×13 for 130 buttons. (I'd use dual common anode diodes then for sure, maybe BAS40 or BAT54A in SOT-23-3 packages, just to reduce the component count!)

I've designed a couple of example boards using EasyEda for Teensy LC, this one for through-hole components, 32 buttons and 9 pots, and this one using surface-mount components. I'm only a hobbyist, and haven't even had any of these made (feel free to, if you like, though), but perhaps they give you some ideas!
 
Status
Not open for further replies.
Back
Top