I am new using arduino, having troubles uploading code on lesson 11 keypad. any suggestion appreciated. thanks
lischiluarduino1:
any suggestion appreciated. thanks
Here's a suggestion- start your own thread, don't try to hijack this one.
OK I have done a bit more testing and here are all the specifics now and what is happening that i am trying to figure out:
Here is the code of the best working 1x7 matrix:
/* Base File
// Included Libraries
#include <Keypad.h>
// Variable Declaration
String msg;
#define PSWROWS 7
#define PSWCOLS 1
//Define Button Numbers and Pin Map
byte PSWbuttons[PSWROWS][PSWCOLS] = {
{ 1},
{ 2},
{ 3},
{ 4},
{ 5},
{ 6},
{ 7},
};
byte PSWrowPins[PSWROWS] = { 10, 9, 8, 7, 6, 5, 4}; //row pinouts
byte PSWcolPins[PSWCOLS] = { 3}; //column pinouts
//initialize Keypad Physical Matrix
Keypad PSWstandard = Keypad( makeKeymap(PSWbuttons), PSWrowPins, PSWcolPins, PSWROWS, PSWCOLS);
// Program
void setup() {
Serial.begin(38400);
PSWstandard.setDebounceTime(20); // Default is 50mS
}
void loop() {
CheckAllButtons();
}
void CheckAllButtons(void) {
if (PSWstandard.getKeys()) {
for (int i=0; i<LIST_MAX; i++) { // Scan the whole key list.
if ( PSWstandard.key[i].stateChanged ) { // Only find keys that have changed state.
switch (PSWstandard.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " PRESSED.";
break;
case HOLD:
Joystick.button(PSWstandard.key[i].kchar, 1);
msg = " HOLD.";
break;
case RELEASED:
msg = " RELEASED.";
break;
case IDLE:
Joystick.button(PSWstandard.key[i].kchar, 0);
msg = " IDLE.";
break;
}
int iB = PSWstandard.key[i].kchar;
Serial.print("Button ");
Serial.print (iB);
Serial.print(PSWstandard.key[i].kchar);
Serial.println(msg);
}
}
}
}
This code works perfectly off the pins on the Tensy LC I am using:
I have a Ethernet Socket on a Breakout board soldered to the Teensy LC with the 8 outputs from the socket going to pins 3 - 10 attached through a header for the shortest most direct connection.
I have tried multiple hardware and everything does the same thing so it is not a hardware or connection issue directly..
Anyway Results (with the code above)...
#1. Buttons directly connected to the Teensy - Everything works Correctly
#2. Buttons connected through a .5M Ethernet cable with an ethernet socket on the other end for button connection - Everything Works Correctly
#3. Buttons connected through a 1.8M Ethernet cable all buttons work as intended EXCEPT button "2" at Column 1, Row 2 witch also triggers "1" at Column 1 Row 1
#4. Buttons connected through a 3M Ethernet cable all buttons "2, 3, 4, 5, 6, and 7" trigger the correct button + "1" at Column 1 Row 1
Now, if I alter the program to have 7 columns and 1 row (instead of the above 7 row 1 column) I get more random triggering than the above and actually get constant triggering on buttons "4, 5, and 7" when just connecting the 3M ethernet cable without even pressing a button.. same sort of results otherwise in that the .5M works, 1.8M sort of works.
When I run the full matrix program with 16, buttons with rows on pins 3, 4, 5, and 6 with columns on 7, 8, 9, and 10. I again get perfect with .5M or shorter, oddity with 1.8, and dual triggers with 3M.. rows 1 and two pins 3 and 4 will trigger with each other in this case..
Anyway I am not sure any of this has to do with the program itself but if there is any thought on a workaround programming wise to still allow for multiple button presses along with error rejecting or any added information about the possibility of using external pull-up resistors on the KeyPad array and what can and cannot be done there as in all honesty I do think it is a low voltage ghost in that the pins are on the verge of going low and with the wire connected in the extended length, 3M especially because that is where I need to get to, it is pulling the voltage just barely to the low state making the buttons flicker on their own or turn on without being pressed.
Anyway I am at a loss and I really don't want to screw things up by putting a resistor where I shouldn't and frying something.
SOLVED! ---
In order to stabilize the circuit I needed a Single external pull up resistor (not sure why it only took one) on Pin 3, which is Row 1 for both the 1x7 and 4x4 matrixes. Is given how I read the keypad code I should not have an issue with instate changes as if I am reading correctly the columns are the pins that will switch states..
Anyway It works, I'm Happy, if I am missing something here that can cause damage to my circuit or a thought of a better manner in which to do it please let me know.
OK NEW Question, Might be simple Might be impossible..
Anyway I am now working on a program to run different Arrays based on Different triggers on the TeensyLC so what I am wondering is if it is possible to Convert made Keypad into a Keypad of a different Name.
So Say use :
Keypad PSbutton28 = Keypad( makeKeymap(button28), B28rPins, B28rPins, PSROW4, PSCOLS);
to make a 4x7 matrix of 28 buttons is it possible to then later in the program change it's name to be PSbuttons..
i.e. but doesn't work apparently.
PSbuttons = PSbutton28;
I can do what I want the long way by having a completely separate if loop for each combination but that can get really long on the program so I am hoping to be able to consolidate the detection functions by changing the Matricies that are presented to that detection program by doing an if statement to change the wanted matrix to a common name that would then be what is used to detect the button presses and everything.
If I understand you correctly take a look at the DynamicKeypad example.
File --> Examples --> Keypad --> DynamicKeypad:
|| @description
|| | This is a demonstration of keypadEvents. It's used to switch between keymaps
|| | while using only one keypad.
It's like your phone switching between one keypad with numbers, another with letters, and yet another with symbols.
mstanley:
If I understand you correctly take a look at the DynamicKeypad example.File --> Examples --> Keypad --> DynamicKeypad:
|| @description
|| | This is a demonstration of keypadEvents. It's used to switch between keymaps
|| | while using only one keypad.It's like your phone switching between one keypad with numbers, another with letters, and yet another with symbols.
I have had a look at it and I am not sure that will work because I am actually creating different sizes matrixes an in many cases dual matrix sets instead of one.. I don't actually have a lot of code written for this so Im not sure it can be tested yet..
Anyway what I am trying to do is to that I will have four options for Matrixes using the same input pins. The Main Matrix is a 4r x 7c
Option #1 is a Button Matrix of 4r x 7r
Option #2 is a Dual Button Matrix of 3r x 7r + a 2nd Button Matrix on the last row of the original matrix (1r x 7r)
Option #3 is a Dual Button Matrix of 2r x 7r + a 2nd Button Matrix on the last 2 rows of the original matrix (2r x 7r)
Option #4 is a Dual Button Matrix of 1r x 7r + a 2nd Button Matrix on the last 3 rows of the original matrix (3r x 7r)
This is where I think the Dynamic Keypad example won't work as I am not really changing characters only but I am actually changing the Matrix sizing as well as the reference to the input pins.
So what I am hoping is that there is a way that I can define all 7 different Matrix options, and then depending on certain physical parameters applied to the Teensy changing the keypads that are run through the system. This only will need to be done at startup so the actual determination of the KeyPads to be used would be in Set-up.
So in Practice if I had the modifier set to -
Option 1, then only the 28 button 4x7 matrix would be used and sent through the Keypress system.
so if I could say :
Keypad A = KeypadA Matrix 28 (4r x 7c)
Then
if I have the modifiers set to one of the other options (2-4) then the dual matrixes would be sent to their corresponding Keypress systems.
opt 1
Keypad A = KeypadA 21 (3r x 7c)
Keypad B = KeypadB 7 (1r x 7c)
or
opt 2
Keypad A = KeypadA 14 (2r x 7c)
Keypad B = KeypadB 14 (2r x 7c)
or
opt 3
Keypad A = KeypadA 7 (1r x 7c)
Keypad B = KeypadB 21 (3r x 7c)
Then Keypad A and Keypad B would be sent through the Button Press Decoding loops for the correct Matrix either A or B.
As I mentioned I could do this the long way with a BUNCH of if statements and a New Decoding loop for Each of the 4 combinations but I am hoping there is a more concise way by actually determining the correct Keypads to be used in Set-up and then actually only use those..
Now after I wrote this out One thing that I though of that I haven't just done trial and error on is CAN the actual initialization of the Keypad take place inside the Set-up.
i.e
void setup() {
Serial.begin(38400);
Keypad buttonmatrix = Keypad( makeKeymap(buttons), buttonrowPins, buttoncolPins, BUTTONROWS, BUTTONCOLS);
buttonmatrix.setDebounceTime(20); // Default is 50mS
}
If this can be done then I could use if statements to set-up the correct KeypadA and KeypadB's within the setup and it solves all the issues (I haven't tried that yet - but something is telling me it would fail compiling)
OK I tried the above with the Keypad Creation in Setup and it compiles for that section but fails ultimately because the Variable for the KeyPad is in Setup it is not Global in scope and therefor gets lost.. and it complains that it is not used and not defined..
How could I make it so that the keypad in set-up is global instead of local to set-up
Im back to my OLD Original issue and now have another question..
is it possible to use get.state to find the state of a certain Key without having to run the switch loop?
My old code for this process failed miserably when it got to actually reading as an HID Device.. It worked fine in serial but it was probably due to delays that aren't present normally.
So now it is back to the drawing board
OK, as I see things so far we've been working on the problem that you are having within your code and not your entire project. By working this way we've (I've) pretty much been ignoring the entirety of your program (sketch). The answers that I provided have ultimately led you to a dead-end solution where you will never get to your goal from here.
Using 7 different keypads with changing characters and matrices is that dead-end.
So let's do something different. Let's talk about your project. What are you trying to build? Just describe what a user is going to do when they walk up to your machine and what they expect to happen. And if you are OK with it then maybe I can help with code and explanations that are more in line with your expectations? We can talk about what hardware you are using and any other libraries that you may need and how they all can work together.
Best regards,
Mark
mstanley:
OK, as I see things so far we've been working on the problem that you are having within your code and not your entire project. By working this way we've (I've) pretty much been ignoring the entirety of your program (sketch). The answers that I provided have ultimately led you to a dead-end solution where you will never get to your goal from here.Using 7 different keypads with changing characters and matrices is that dead-end.
So let's do something different. Let's talk about your project. What are you trying to build? Just describe what a user is going to do when they walk up to your machine and what they expect to happen. And if you are OK with it then maybe I can help with code and explanations that are more in line with your expectations? We can talk about what hardware you are using and any other libraries that you may need and how they all can work together.
Best regards,
Mark
You definitely didn't steer me down a dead-end path.. My ambitions just got bigger as originally I was only having two Matricies one for buttons and the other for encoder and trying to get reads from certain pairs of buttons in order to allow a (greycode output) rotary encoder to be read correctly through the Keypad inputs.
For what I described in the last couple of posts I have actually got it working by just doing it the long way and setting up 7 Matricies, where different combinations of Matricies are triggered by an outside switch pair these run properly using a while statement that I setup so it only runs the correct functions for each matrix combination I need at one time based on the constant switch state.
So by example
By example I have two switches:
#1 - Switch #1 (OFF) & Switch #2 (OFF) a 4x7 matrix is active
#2 - Switch #1 (ON) & Switch #2 (OFF) a 3x7 matrix and a 1x7 matrix is active
#3 - Switch #1 (OFF) & Switch #2 (ON) a 2x7 matrix and a 2x7 matrix is active
#4 - Switch #1 (ON) & Switch #2 (ON) a 1x7 matrix and a 3x7 matrix is active
These different settings are being used to reallocate the Button Numbers for an HID Gaming device and to allow for a separate Matrix for the Encoders (Once I figure out how to deal with those). So basically doing this the long way is using up more space and probably memory but it is not really an issue as I still have plenty and I don't see this program expanding any further in scope.
Originally with the Multiple Matricies I was hoping that I could just reallocate the Matrix array that needs to be used to a common Matrix array so that I would only have to have one instance of the Button State loop. instead of different ones. This may still be able to be done which will make the program MUCH smaller but at the same time I have it running without this.
i.e.
if I have buttonKeypad and encoderKeypad as the two main matrix and that the matrixes from say #2, #3, or #4 above could be transferred into. Such as Option #2 is Created Key Array 3x7 (keypad21) + Created Key Array 1x7 (keypad7) could be reinitialized to keypad21 = buttonKeypad and keypad7 = encoderKeypad and so on so that the same function code can be used.
BUT as I mentioned technically I have everything regarding the Matrix allocation worked out the long way with a different function for each.
So now I am back at the encoders and getting correct reads from them which I thought I had working but it turns out when I actually hooked it all up to the computer as the HID Device to test the encoder set-up didn't work properly at all. So I got what I thought was right as it worked with Serial Output checks but there was other stuff going on between the prints that I didn't know was going on ..
So in the end what I am trying to do is to figure out how to track two specific Keypad buttons in a loop to determine when each button is pressed and released in relation to each other, This would be the two outputs of the Greycode encoder and then would allow me to determine which direction the encoder is turning (via the comparison) and at what point I need to send a Button (ON and OFF).
So let me run by my current thinking and what I asked if there was a way to use get.state of a specific Key. From what I understand from our prior conversation getkeys with get a list of ALL active keys at a specific time regardless of what key is pressed. For each loop that getkeys runs it puts the first active key into position 0 and then any subsequent keys after that.
So I am currently thinking that during a single loop I can use the find key command to find if the keys that I need are active or not i.e I can findinlist #9 and then findinlist #10 which would be the encoder pair and it should return 1 or -1 for each depending on whether to not they are in the list?
So if say I cal GetKeys and then call encA = kpd.findInList('9') and encB = kpd.findInList('10')
The it should return:
encA = -1, encB = -1 if neither are in the list
encA = 1, encB = -1 if A is in the list
encA = -1, encB = 1 if B is in the list
encA = 1, encB = 1 if both are in the list
If I am correct on this I may be able to get this to work the way I want I will just have to continuously poll the matrix with the geyKeys.
Right now I had it set up to run an Event so tha it only polled upon that event which of course would only take a snapshot of the GetKeys for that particular loop.. Which of course would send things out of scope on the next activation of the event, which I think is where I was having things work in serial but not in reality and I could determine a direction by just the initial button press (though the other button was also pressed but not registered by the event directly).
I hope this explains a bit about my questions and intensions and what I actually have working.. But basically I am stuck at the point of being able to compare the activation and state of two pairs buttons.. ie 9/10, 11/12, 21/22, 25/26 ect...
OK I have done more playing in the meantime and right now I have the following CODE for separating out 3 buttons from the normal loop and then letting the remaining go into an another switch to allow for decoding for the encoders.
void CheckEncoders9(void){
// Check for Single Button usage or Run Encoder Coding
if (PSE9matrix.getKeys()) {
for (int i=0; i<LIST_MAX; i++) { // Scan the whole key list.
if (PSE9matrix.key[i].stateChanged ) { // Only find keys that have changed state.
if (PSE9matrix.key[i].kchar == 8 ||PSE9matrix.key[i].kchar == 21 || PSE9matrix.key[i].kchar == 22) {
switch (PSE9matrix.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " pressed";
Joystick.button(PSE9matrix.key[i].kchar, 1);
break;
case HOLD:
msg = " held";
break;
case RELEASED:
msg = " released";
Joystick.button(PSE9matrix.key[i].kchar, 0);
break;
case IDLE:
msg = " idle";
break;
}
byte s = PSE9matrix.key[i].kchar;
Serial.print("Button ");
Serial.print(s);
Serial.print(" is");
Serial.println(msg);
} else {
switch (PSE9matrix.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " pressed";
Joystick.button(PSE9matrix.key[i].kchar, 1);
break;
case HOLD:
msg = " held";
break;
case RELEASED:
msg = " released";
Joystick.button(PSE9matrix.key[i].kchar, 0);
break;
case IDLE:
msg = " idle";
break;
}
byte s = PSE9matrix.key[i].kchar;
Serial.print("Encoder Button ");
Serial.print(s);
Serial.print(" is");
Serial.println(msg);
}
}
}
}
}
By this code I get the following presses on an encoder on inputs for button 27 and 28
Clockwise Turn
Encoder Button 28 is pressed
Encoder Button 27 is pressed
Encoder Button 28 is released
Encoder Button 28 is idle
Encoder Button 27 is released
Encoder Button 27 is idle
Counter-Clockwise Turn
Encoder Button 27 is pressed
Encoder Button 28 is pressed
Encoder Button 27 is released
Encoder Button 27 is idle
Encoder Button 28 is released
Encoder Button 28 is idle
Which of course is the exact opposite sequence..
So now I have to pair up the buttons into ODD and EVEN sets so they are dedicated to an encoder and then be able to read which ordering is triggered through the state to determine whether the encoder is turning Clockwise or Counter-Clockwise.. I need to somehow pair them up because the active keylist does not always have buttons next to each other such as if two encoders were turned at the same time I could end up with an active key list of [ 14, 28, 15, 27] even though the ones that have to be paired to read the sequence correctly would be 14 / 15 and 27 / 28, so I can't just read the next Active list rotation as is or I might be reading wrong patterns.
So I will have to think about this a bit.. Right now I am thinking I am going to have to separate out the odd and even kchar into separate state loops like I did for the single button and then do a variable for that can be passed out of the loop to be able to pair up the correct odd/odd and even buttons and then make sure that their activation follows one of the two sequences above to verify the Button to actually be pressed through the HID interface for the game controller to indicate Clockwise or Counter-Clockwise..
Earlier I determined the ODD and Even off to the First of the pair to trigger ie if 27 was trigged because it was an odd number I would +1 to get 28 and if 28 (even determination) I would -1 to get 27 which easily paired the numbers and I think I can still use this method and possibly the findInList to pair up the state on each loop and if I can read the state over four loops I can determine the sequence.. But then just running through my head if a second encoder started turning mid sequence I could run into issues unless i separate the sequences which I guess I can do if I can build a state array for the Active encoder list and then compare that array with the Known Sequence and then trigger the HID Button wanted if the Arrays match...
OK now I am just thinking aloud so I will stop.. But I think there are several ways that I can accomplish this.. just trying to figure out the best and most efficient.
I think I can do it.. If you have any suggestions for doing this please feel free to suggest...
OK, Well after a Bunch more playing I feel like I am going in circles a bit and have ended up at the same place several times..
The One thing that seems to not be working right is the findInList as it seems to not be allowing me to actually find the Key in the active Key list:
Anyway the code I have for the what I am doing is this right now..
I have edited out everything that is not being worked on:
// Included Libraries
#include <Keypad.h>
// Variable Declaration
String msg;
int enc;
int encA;
int encB;
int Afound;
int Bfound;
#define PSE9r 3
#define PSE9c 7
//Define Button Matrix Options and Pin Map
byte PSE9[PSE9r][PSE9c] = {
{ 8, 9, 10, 11, 12, 13, 14},
{ 21, 15, 16, 17, 18, 19, 20},
{ 22, 23, 24, 25, 26, 27, 28}
};
byte PSE9rPins[PSE9r] = { 22, 21, 20}; //row pinouts
byte PSE9cPins[PSE9c] = { 19, 18, 17, 16, 15, 14, 13}; //column pinouts
//initialize Keypad Physical Matrix
Keypad PSE9matrix = Keypad( makeKeymap(PSE9), PSE9rPins, PSE9cPins, PSE9r, PSE9c);
// Program
void setup() {
Serial.begin(500000);
PSE9matrix.setDebounceTime(0); // Default is 50mS
PSE9matrix.setHoldTime(10000); // Default is 500mS
}
void loop() {
CheckEncoders9();
}
// Encoder Program
void CheckEncoders9(void){
// Check for Single Button usage or Run Encoder Coding
if (PSE9matrix.getKeys()) {
for (int i=0; i<LIST_MAX; i++) { // Scan the whole key list.
if (PSE9matrix.key[i].stateChanged ) { // Only find keys that have changed state.
if (PSE9matrix.key[i].kchar == 8 ||PSE9matrix.key[i].kchar == 21 || PSE9matrix.key[i].kchar == 22) {
switch (PSE9matrix.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " pressed";
Joystick.button(PSE9matrix.key[i].kchar, 1);
break;
case RELEASED:
msg = " released";
Joystick.button(PSE9matrix.key[i].kchar, 0);
break;
}
byte s = PSE9matrix.key[i].kchar;
Serial.print("Button ");
Serial.print(s);
Serial.print(" is");
Serial.println(msg);
} else {
// Determine Active Encoder A or B
enc = PSE9matrix.key[i].kchar;
if ( PSE9matrix.key[i].kchar % 2 == 0 ){
encA = enc - 1;
encB = enc;
Afound = PSE9matrix.findInList(encA);
Bfound = PSE9matrix.findInList(encB);
}else{
encA = enc;
encB = enc + 1;
Afound = PSE9matrix.findInList(encA);
Bfound = PSE9matrix.findInList(encB);
}
byte n = PSE9matrix.key[i].kstate;
Serial.print("Encoder ");
Serial.print(encA);
Serial.print(" ");
Serial.println(encB);
Serial.print("Encoder State ");
Serial.println(n);
switch (PSE9matrix.key[i].kstate) { // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
case PRESSED:
msg = " pressed";
Joystick.button(PSE9matrix.key[i].kchar, 1);
break;
case HOLD:
msg = " held";
break;
case RELEASED:
msg = " released";
Joystick.button(PSE9matrix.key[i].kchar, 0);
break;
case IDLE:
msg = " idle";
break;
}
Serial.print("A Encoder Found = ");
Serial.println(Afound);
Serial.print("B Encoder Found = ");
Serial.println(Bfound);
byte s1 = PSE9matrix.key[i].kchar;
Serial.print("Encoder Button ");
Serial.print(s1);
Serial.print(" is");
Serial.println(msg);
}
}
}
}
}
I have an encoder connected with Ground on Pin 20 and Output A on Pin 14 - Matrix [3] [6] for button 27 and Output B on Pin 13 -Matrix [3] [7] for button 28.
continued next post...
So here is what I get as an output which takes 6 loops for one encoder detent in the Clockwise Rotation.
LOOP 1
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 1 -- This is the correct Pressed State for button 28 (encoder output B)
A Encoder Found = -1 -- This seems right, however,further output issues indicate otherwise
B Encoder Found = -1 -- I would expect this to be "0" or "28" as Button 28 is pressed
Encoder Button 28 is pressed -- This is the correctly determined Button State for this loop
LOOP 2
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 1 -- This is the correct Pressed State for button 27 (encoder output A)
A Encoder Found = -1 -- I would expect this to be "1" or "27" as Button 27 is pressed
B Encoder Found = -1 -- I would expect this to be "0" or "28" as Button 28 is still pressed
Encoder Button 27 is pressed -- This is the correctly determined Button State for this loop
LOOP 3
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 3 -- This is the correct Released State for button 28 (encoder output B)
A Encoder Found = -1 -- I would expect this to be "1" or "27" as Button 27 is still pressed
B Encoder Found = -1 -- I would expect this to be "0" or "28" as Button 28 is being released
Encoder Button 28 is released -- This is the correctly determined Button State for this loop
LOOP 4
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 0 -- This is the correct Idle State for button 28 (encoder output B)
A Encoder Found = -1 -- I would expect this to be "1" or "27" as Button 27 is still pressed
B Encoder Found = -1 -- I would expect this to be "-1" as Button 28 is Idle
Encoder Button 28 is idle -- This is the correctly determined Button State for this loop
LOOP 5
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 3 -- This is the correct Released State for button 27 (encoder output A)
A Encoder Found = -1 -- I would expect this to be "1" or "27" as Button 27 is being released
B Encoder Found = -1 -- I would expect this to be "-1" as Button 28 is Not Active
Encoder Button 27 is released -- This is the correctly determined Button State for this loop
LOOP 6
Encoder 27 28 -- This is the correct encoder Pair as defined in // Determine Active Encoder A or B
Encoder State 0 -- This is the correct Idle State for button 27 (encoder output A)
A Encoder Found = -1 -- I would expect this to be "-1" as Button 27 is Idle
B Encoder Found = -1 -- I would expect this to be "-1" as Button 28 is Not Active
Encoder Button 27 is idle -- This is the correctly determined Button State for this loop
I am probably off in what I think the findInList() outputs are for Idle but I know they should probably change from being returned as -1 (or not in list for every loop). I have done another test program which uses basically the same code but is carried in an Event handler (without the switch) where it actually does give me correct findInList() outputs so I am really quite confused..
I have tried changing the Variable type = Byte constantly outputs 255, Int constantly outputs -1, and char constantly outputs a Diamond with a ? in it.
I belive that if I can track the state of the paired buttons through the loops with the findInList() I should be able to determine the point at which to trigger a single actual HID Joystick button output. This should also allow me to not get the encoder positions in list confused if another input is detected such as a button press placing itself between the Encoder A and Encoder B in the active encoder list.
Any help would be greatly appreciated.. I have this feeling I am just missing something REALLY small such as the placement of things in the loops or a variable type or something that I should have been able to figure out but have just NOT yet.
The first thing I'll make note of is the Serial.begin setting you are using.
Serial.begin(500000); // not a normal value. Is this really what you want?
From the Arduino code reference page:
Serial.begin()
DescriptionSets the data rate in bits per second (baud) for serial data transmission. For communicating with the computer, use one of these rates: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200.
The default is generally; Serial.begin(57600);
The second problem is your use of findInList(encA) is incorrect. I see that you are assigning integers to the keymap which might work if you would assign something other than the ASCII control codes. Using the numbers you provided in your keymap and comparing them to the ASCII chart you get the following:
8 backspace
9 horizontal tab
10 line feed
11 vertical tab
12 form feed
13 carriage return
14 shift out
15 shift in
16 data link escape
17 device contro 1
18 device contro 2
19 device contro 3
20 device contro 4
21 negative acknowledge
22 synchronous idle
23 end of trans. block
24 cancel
25 end of medium
26 substitute
27 escape
28 file separatorYour keymap "number" is on the left which defines the ASCII char on the right.
None of those characters are searchable using the version of findInList(char keyChar). So it seems you are then trying to search the list using the other version of findInList(int keyCode). But the numbers you are entering are NOT the keyCode's. The keyCode's are automatically assigned behind the scenes like thus:
//Define Button Matrix Options and Pin Map
byte PSE9[PSE9r][PSE9c] = {
{ 8, 9, 10, 11, 12, 13, 14}, // assigned keyCodes are { 0, 1, 2, 3, 4, 5, 6}
{ 21, 15, 16, 17, 18, 19, 20}, // assigned keyCodes are { 7, 8, 9, 10, 11, 12, 13}
{ 22, 23, 24, 25, 26, 27, 28} // assigned keyCodes are {14, 15, 16, 17, 18, 19, 20}
};
byte PSE9rPins[PSE9r] = { 22, 21, 20}; //row pinouts
byte PSE9cPins[PSE9c] = { 19, 18, 17, 16, 15, 14, 13}; //column pinouts
Hope that helps.
mstanley:
The first thing I'll make note of is the Serial.begin setting you are using.Serial.begin(500000); // not a normal value. Is this really what you want?
From the Arduino code reference page:
The default is generally; Serial.begin(57600);The second problem is your use of findInList(encA) is incorrect. I see that you are assigning integers to the keymap which might work if you would assign something other than the ASCII control codes. Using the numbers you provided in your keymap and comparing them to the ASCII chart you get the following:
None of those characters are searchable using the version of findInList(char keyChar). So it seems you are then trying to search the list using the other version of findInList(int keyCode). But the numbers you are entering are NOT the keyCode's. The keyCode's are automatically assigned behind the scenes like thus:
//Define Button Matrix Options and Pin Map
byte PSE9[PSE9r][PSE9c] = {
{ 8, 9, 10, 11, 12, 13, 14}, // assigned keyCodes are { 0, 1, 2, 3, 4, 5, 6}
{ 21, 15, 16, 17, 18, 19, 20}, // assigned keyCodes are { 7, 8, 9, 10, 11, 12, 13}
{ 22, 23, 24, 25, 26, 27, 28} // assigned keyCodes are {14, 15, 16, 17, 18, 19, 20}
};
byte PSE9rPins[PSE9r] = { 22, 21, 20}; //row pinouts
byte PSE9cPins[PSE9c] = { 19, 18, 17, 16, 15, 14, 13}; //column pinouts
Hope that helps.
Yes that helps a TON.
The Serial thing is that I just assigned a baud rate that was listed in the Arduino Serial Monitor.. The Serial outputs are really just for testing and will not be used in the final program.. I raised it thinking the serial output was missing some information output at times in regard to the loop and/or slowing it down and therefore I was missing something. that was causing outputs through the serial to be unexpected.
I DID NOT know how the keyCodes were assigned and therefore was missing that crucial information so now it makes complete sense as to why findInList would always return -1 since 27 and 28 are not in the KeyCodes.. I should now be able to actually find the correct buttons in the Matrix via the keyCode.
I really had no IDEA which version of the findInList was being called but I figured that it was the KeyCode version when changing the variable to a char was outputting the odd symbol. I just didn't know HOW the keyCodes were actually determined and that was going to be my next question but you answered it in your response..
I really do appreciate the time you have put into in helping me understand how this works.
Brion Sohn
Thank you again.. I just tested some new code and now I am getting correct reading for the KeyState of each of the Paired Buttons as well as the Position (or existence) of the button in the Active button list..
This should allow me now to determine the combination of states to cause other stuff to occur in both a clockwise or counterclockwise direction as I can check to see whether a button is Pressed, Released and before or after the other in the keyList giving me state and direction which is what I was trying to get to.
Thank you..
Its all those little things that make the difference.
EDIT: All is working perfectly, just now have to figure out the optimal delay before button release after button press for my purposes.. But things are being read, paired, decoded, and output correctly.
Thank you for all your help...
NOW that I have everything working.. I want to break it again.. lol just kidding..
But I am revisiting something to reduce code and of course it is a question that I cannot figure out..
Anyway the Question is if there is a way to create a pointer to a keypad array. such as in simplied terms.
#1 - I create a keypad array
Keypad original = Keypad( makeKeymap(orgkey), OrgrPins, OrgcPins, Orgr, Orgc);
#2 - I have the basic button switch code form the multi key example
However instead of that basic code running with keypad.original as the basis I would like to run it with
keypad.runtime with runtime being a pointer to original..
I have found examples in C that state that you can just do int runtime = original; and that will create a pointer to the original array, however, I don't think that works in this case or I am missing something.
The reason for this is if I can do this I can define the runtime arrays through pointers and eliminate about 200 lines of essentially the same code for differing arrays.
If I understand you then what you are saying is that you would like to create several key maps and allow each one to call the same copy of code underlying the mechanism for scanning pressed buttons/keys?
I need to think about this for a bit but the first thing that comes to mind is <> NO WAY!!! YOU CAN'T DO THAT!!! ![]()
First off let me know if my assumption is right. I don't want to head down a rabbit hole just for the fun of it. But I'm already starting to get some ideas.
mstanley:
If I understand you then what you are saying is that you would like to create several key maps and allow each one to call the same copy of code underlying the mechanism for scanning pressed buttons/keys?I need to think about this for a bit but the first thing that comes to mind is <> NO WAY!!! YOU CAN'T DO THAT!!!
First off let me know if my assumption is right. I don't want to head down a rabbit hole just for the fun of it. But I'm already starting to get some ideas.
Yes, But not at the same time..
I right now I basically call an encoder Matrix and a corresponding Button Matrix under certain conditions. No matrixes overlap in process but if they were to all run together they of course would.
This is why I was asking if I can set-up essentially a common loop where under each of these situations I can point the appropriate matrix to the appropriate state code. however if the condition changes it would change the Keypad arrays that are presented to the loop .
ie
Say I have Keypad A, Keypad B, KeyPad C, and Keypad D
Keypad A is a 2x7 matrix and keypad B is a 2x7 matrix and go together over the same 4x7 space and
Keypad C is a 1x7 matrix and keypad D is a 3x7 matrix and go together over the same 4x7 space and
Both sets use the same pins..
So
If Condition A exists then I would like to know if I can do
KeypadAruntime = Keypad A
KeypadBruntime = Keypad B
and if the Condition changed from A To Condition B then
KeypadAruntime = Keypad C
KeypadBruntime = Keypad D
This way KeypadAruntime and KeypadBruntime are the pointers to the keypads that I want to use and then there is only one set of state loops for the KeypadAruntime and KeypadBruntime instead of 4 separate state loops one for each Keypad A, Keypad B, KeyPad C, and Keypad D
If it cannot be done then I guess I have things as streamlined as I can get.. though I am hoping it can be done..