Hi, I have a question about sending data through the serial port without releasing the jey press.
The current setup allows me to transfer data into the serial port by pressing down the key and then releasing the key. However, it doesn't seem to work if I keep the key pressed, or, if I continuously closing the circuit.
I built my own keypad by doing something like this:
When I complete the circuit of one of the switch module, the sending worked. However, without releasing (reopening the circuit of that switch), I noticed that I couldn't send another piece of data.
Is this a behaviour I can configure for the keypad library or the serial.write function?
How many keys do you want to be able to press simultaneously?
Have a look at the MultiKey example for the Keypad library, it demonstrates how to check for multiple keys being pressed/held/released.
I am thinking of building an electronic go board. It's dimension is 19 by 19. They keys will remain on the board so the number of on-ed switches will increase over time. Is that possible with the multi key library? Alternatively if there is a library function that allows me to know what switches are in the on state at any given time that works too.
The Keypad library keeps track of up to 10 key presses at one time, that can be expanded to 361 but will take up a considerable amount of the ram of a mega. You can then search the list for each key code (the two-letter combination in your case), or query the library to see if a particular keycode is pressed (basically let the library do the search for you).
Sounds like the way to go. If I can modify the library so it supports 361 keys, I should be able to know which keypress is the new key.
Do you where in the code the 10 key memorizing is?
Look in the Keypad.h file, it is defined as a constant, something like MAX_ITEM, not where I can look at it at the moment.
< edit >
Looking at johnwasser's code, looks like the constant is LIST_MAX
I see. The maxList should be updated and I can make use of updateList probably to check the key states.
However, I didn't find how to use the keypad to register a new key being pressed when there are already other keys being held down.
For example, in the sketch, inside the loop, we use getKey to determine when something should be executed during the loop. But this function doesn't support multi key press. I guess this is when I need the multi keypress library right? So inside the loop I can tell Arduino that when there are some keys being pressed, there is another new key that just got pressed and we should do something about it.
I hate to point this out but a MATRIX keypad does not work with multiple, simultaneous keys down. Rather it is designed to spot a SINGLE key in the field with the expectation that it will be released before the next key is pressed. On a Go table the stones are placed, and remain in place, for the duration (mostly). In order to do this right each switch needs to be in parallel and sensed individually (probably thru a mux). The keypad example, even expanded to 19x19, is NOT going to work as required/expected. Sorry.
Thanks for pointing it out. I appreciate the straightforwardness.
I read the musical keyboards also use the matrix and it can support multiple key press at the same time. Also, doesn't conventional keyboard supports holding as well?
The only keys a conventional keyboard uses are crtl/alt/shift. The shift key for instance, was directly wired to bit #6 to toggle case. All of the other keys are scanned, Try holding multiple character keys down and nothing good happens.
I didn't know that's how keyboards work. Kind of unfortunate.
Assuming that a keyboard matrix scan through all combination of rows and columns to find the key that got pressed down, isn't it possible to have it complete the scan and store the label of all the "on" switches in some kind of variable and when a key is pressed we compare if the key is inside that variable?
No. Multiple row and column lines active at once prevent identifying the key.
You can try this code, the keypad library appears to be set up to handle multiple key presses at once, but a diode is needed on every key.
/* @file CustomKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact alexanderbrevig@gmail.com
||
|| @description
|| | Demonstrates changing the keypad size and key values.
|| #
*/
#include "BigKeypad.h"
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
uint16_t hexaKeys[ROWS][COLS] = {
{'1a', '2a', '3a', 'a3'},
{'4b', '5b', '6b', '3a'}, // There may be a warning mesage for each
{'7c', '8c', '9c', '3a'}, // of the multi-char constants. Ignore them.
{'ef', 'cd', 'ab', '3a'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
BigKeypad customKeypad = BigKeypad( makeIntKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup() {
Serial.begin(9600);
}
void loop() {
if (customKeypad.getKeys()) {
for (uint16_t i = 0; i < LIST_MAX; i++) {
if (customKeypad.key[i].stateChanged) {
if (customKeypad.key[i].kstate == PRESSED) {
Serial.write(char(customKeypad.key[i].kchar >> 8));
Serial.write(char(customKeypad.key[i].kchar));
Serial.write('\n'); //newline added for readability in serial monitor
}
}
}
}
}
Thanks for the suggestion. I have a question about using getKeys define when to execute a block of code inside a loop. During the game, stones will be placed on the board and they will stay there as long as they are not taken out. In that situation, the switches corresponding to those locations will always be in the pressed state and getKeys will always return some value in every loop iteration. Won't that cause the micro controller chip to consume too much computational resources and .... maybe damage the chip? It would be nice if the first if statement can know the previous board state and only start executing the block of code if new getKeys value is observed. But ..... is that possible? If there is an array storing all the pressed keys and inside the if statement, check if the value of customKeypad.getKeys() is not already in that array. If that's the case, execute the block of code.
getKeys() returns true if any key has changed state, otherwise it returns false, so there is already detection in the library for when nothing has changed from the previous scan. Not sure how long it will take to scan a 19x19 key matrix, but you are not going to damage the chip by performing too many computations.
That's cool! I misunderstood getKeys(). I just tested the setup again and with the new sketch, it was successful to add new switches while keeping some of the existing switches in the pressed state!!! The only thing left is to increase the max list value to 361 to account for the total number of positions on a go board.
Thank you so much!!