Key Matrix
I have been trying to add more buttons to my 3d printer (both RAMPS and RADDS) . I like to think I have a pretty good understanding of how to setup my uiconfig.h to get the LCDs working and I have been able to setup standard buttons and map them to UI_ACTIONS with success. I am definitely using FEATURE_CONTROLLER 1, and my LCD/SD are using the settings in there to work.
But it is never enough buttons, so I am trying a 4x4 matrix, starting on the RAMPS. Well first I tried it on just a MEGA 2560 using this tutorial to make sure my key matrix was understood and working:
https://playground.arduino.cc/Main/KeypadTutorial
using this 4x4 matrix
www.ebay.com/itm/US-Ship-4-x-4-Matrix-Array-16-Key-Botton-Switch-Keypad-Keyboard-Arduino-etc/322170968077
Once I go that working, this is what I did:
Aux4 and Aux3 are taken up by the LCD/SD connector
D11 is used by zprobe servo
XMIN is used for zprobe button
XMAX YMAX ZMAX are used for endstops
This leaves All of AUX1, AUX2 free
D6, D5, D4 in the servo area free
and YMIN and ZMIN are free
I am using the default UI_MATRIX_ACTIONS in the sample uiconfig.h file
first I tried using the digital pins in AUX2, but this not only doesn't use thekey matrix, but it kills the encoder wheel.
////////////////////////////////////////////////////////////////////////////////
UI_KEYS_INIT_MATRIX(66,44,64,59,1,6,5,4);
&
UI_KEYS_MATRIX(66,44,64,59,1,6,5,4);
but had no more success. I wanted to try the same pins free on RAMPS using the keypad tutorial but I don't see any pins over 53 on the Mega2560 so they must be doing something to the analog pins to use them....maybe this is "no bueno" for keypad?
I think I am either underconfiging something, or using the wrong pins.
But it is never enough buttons, so I am trying a 4x4 matrix, starting on the RAMPS. Well first I tried it on just a MEGA 2560 using this tutorial to make sure my key matrix was understood and working:
https://playground.arduino.cc/Main/KeypadTutorial
using this 4x4 matrix
www.ebay.com/itm/US-Ship-4-x-4-Matrix-Array-16-Key-Botton-Switch-Keypad-Keyboard-Arduino-etc/322170968077
Once I go that working, this is what I did:
Aux4 and Aux3 are taken up by the LCD/SD connector
D11 is used by zprobe servo
XMIN is used for zprobe button
XMAX YMAX ZMAX are used for endstops
This leaves All of AUX1, AUX2 free
D6, D5, D4 in the servo area free
and YMIN and ZMIN are free
I am using the default UI_MATRIX_ACTIONS in the sample uiconfig.h file
first I tried using the digital pins in AUX2, but this not only doesn't use thekey matrix, but it kills the encoder wheel.
////////////////////////////////////////////////////////////////////////////////
void uiInitKeys() {
UI_KEYS_INIT_CLICKENCODER_LOW(UI_ENCODER_A, UI_ENCODER_B);
UI_KEYS_INIT_BUTTON_LOW(UI_ENCODER_CLICK);
//init -> UI_KEYS_INIT_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4);
UI_KEYS_INIT_MATRIX(63,40,42,65,59,64,44,66);
}
void uiCheckSlowKeys(uint16_t &action) {
UI_KEYS_MATRIX(63,40,42,65,59,64,44,66);;
}
////////////////////////////////////////////////////////////////////////////////
When using the Keypad Tutorial (https://playground.arduino.cc/Main/KeypadTutorial) I found that that if I used pin 13 for the 4th column, it didn't work but it worked when I used pin5. I'm not sure why, but I thought maybe using different pins might help so I tried:////////////////////////////////////////////////////////////////////////////////
UI_KEYS_INIT_MATRIX(66,44,64,59,1,6,5,4);
&
UI_KEYS_MATRIX(66,44,64,59,1,6,5,4);
but had no more success. I wanted to try the same pins free on RAMPS using the keypad tutorial but I don't see any pins over 53 on the Mega2560 so they must be doing something to the analog pins to use them....maybe this is "no bueno" for keypad?
I think I am either underconfiging something, or using the wrong pins.
Comments
I don't have the resistors yet, but I have been careful to not push more than 1 pin at a time to avoid possible short.
I will attempt to try a smaller 1 row 1 col matrix and see if that helps.
using:
UI_KEYS_INIT_MATRIX(6,5);
UI_KEYS_MATRIX(6,5);
I get:
exit status 1
so I tried :
UI_KEYS_INIT_MATRIX(6,44,64,59,5,66,1,4);
and changed actions to:
made the proper mods to ui.cpp like:
Some of the keys worked like this so I know I'm getting close, It looks like only lower numbers seem to work. I tried different combo of pins until this:
UI_KEYS_INIT_MATRIX(11,6,5,4,1,0,14,18);
UI_KEYS_MATRIX(11,6,5,4,1,0,14,18);
Every key works now except R1C1 which should trigger UI_ACTION_IDENT01, I am not sure why. I tried switiching it to UI_ACTION_HOME_ALL but it didn't work.
Why can't I use any of the pins in the AUX2 area? with servo and zprobe, I am a pin short unless I can get AUX2 pins to work in matrix.
Also, any idea's how only 1 button could be not working?
In ui.h you see how keys get queried:
As you see a row or column pin id of -1 would disable that part so you can have any matrix up to 4x4.
Columns are inputs with pullup and rows are outputs with outputs to gnd.
First it gets tested if any button is pressed at all by querying columns. If a button is pressed gnd pulls at least one column to low, so if one of them is low the condition fails and keys get tested.
Next we try to determine the row. All rows except the tested row get put high. So colums get high from pullup but the column with gnd will be low. Since all other are high having one low column means that is the row. We set r to 0/4/8/12 depending on row. If the line is not hit it is set high and we test next one.
Now that we know the row, we test columns 2-4 of they are low and add 1-3 to r. So depending on combination we have r = 0..15.
So since every row and column was detected at least in 3 cases it should also work for R1C1. For testing add a write command inside this condition
if(r<16) {action = pgm_read_word(&(matrixActions[r]));}\
e.g.
if(r<16) {Com::printFLN(PSTR("key:"),(int)r);action = pgm_read_word(&(matrixActions[r]));}\
that should write the detected id. You could also use it to write the assigned action instead if you put after action computation.
One error I see is that first row should be
#define UI_KEYS_MATRIX(r1,r2,r3,r4,c1,c2,c3,c4) {uint8_t r = (c1>=0?READ(c1):1) && (c2>=0?READ(c2):1) && (c3>=0?READ(c3):1) && (c4>=0?READ(c4):1);\
but in your case with 4 columns it makes no difference.
D11 for servo
X_MIN for zprobe button
matrix pins, this part was very picky, as not all pins worked for each role (row, col)
(r1,r2,r3,r4,c1,c2,c3,c4);
(18,14,42,40,0,4,5,6);
All the other pins seem to work for yet more buttons, except 1 if you init pin1 it breaks the matrix (glitch in the matrix?)
Now I need to do the same thing for my RADDS
(r1,r2,r3,r4,c1,c2,c3,c4);
(18,14,42,40,0,4,5,6);
using pin1 anywhere in there could cause either a row or col to not work. Also though, if you try to:
UI_KEYS_INIT_BUTTON_LOW(1);
then not only does that button not work, but it also kills the matrix. All the other free pins still worked as regular buttons, even if they didn't work as part of the key matrix.