I'm currently trying to retrofit an existing program to use a keypad instead of buttons. I know the keypad works, thanks to everyone who assisted me in a previous thread.
Right now, this function is being called just about everywhere:
void readButtons()
{
 buttons[buttonUp] = digitalRead(A3);
 buttons[buttonDown] = digitalRead(A0);
 buttons[buttonSelect] = digitalRead(A2);
 buttons[buttonBack] = digitalRead(A1);
}
With it being called a few times like this:
  readButtons();
 Â
  // back button
  if (buttons[buttonBack] == HIGH) return;
 Â
  // up buttonÂ
  if (buttons[buttonUp] == HIGH) CursorPrevious(DiagMenu, 5);
 Â
  // down button
  if (buttons[buttonDown] == HIGH) CursorNext(DiagMenu, 5);
}
Please note there was more code, but it wasn't applicable to this scenario.
I think I need to use a keypad.getState() and maybe changes the buttons[] to 'true' instead of 'HIGH', but I'm not sure.
FTPMonster:
I'm currently trying to retrofit an existing program to use a keypad instead of buttons. I know the keypad works, thanks to everyone who assisted me in a previous thread.
Right now, this function is being called just about everywhere:
You might be able to make all the rest of the code work correctly if you just change readButtons() to:
void readButtons()
{
// Clear the button states before checking for a new keypress.
buttons[buttonUp] = LOW;
buttons[buttonDown] = LOW;
buttons[buttonSelect] = LOW;
buttons[buttonBack] = LOW;
switch (key) {
case 'U': // <-- Change all these to match your keypad characters.
buttons[buttonUp] = HIGH;
break;
case 'D':
buttons[buttonDown] = HIGH;
break;
case 'S':
buttons[buttonSelect] = HIGH;
break;
case 'B':
buttons[buttonBack] = HIGH;
break;
}
void readButtons()
{
  // Clear the button states before checking for a new keypress.
  buttons[buttonUp] = LOW;
  buttons[buttonDown] = LOW;
  buttons[buttonSelect] = LOW;
  buttons[buttonBack] = LOW;
  switch (key) {
    case '2':   // <-- Change all these to match your keypad characters.
      buttons[buttonUp] = HIGH;
      break;
    case '8':
      buttons[buttonDown] = HIGH;
      break;
    case '6':
      buttons[buttonSelect] = HIGH;
      break;
    case '4':
      buttons[buttonBack] = HIGH;
      break;
  }
}
and it threw an error: " 'key' was not declared in this scope". I've called the keypad 'kpd', changing 'key' to that gives "switch quantity not an integer". Then, I went to the top of the program, and threw an "int key=0" just to get it initialized. While it passes the compiler test, it doesn't actually move the prompt up and down.
FTPMonster:
and it threw an error: " 'key' was not declared in this scope".
key is expected to be a char. Since I didn't have the rest of your code I was only guessing that you might have something like the following:
#include "keypad.h"
// kpd = keypad setup, blah...
char key; // Temporarily stores the active key.
void setup () {
Serial.begin(9600);
}
void loop () {
key = kpd.getKey();
readButtons(); // Uses 'key' internally. It might be better to pass a parameter.
// back button
if (buttons[buttonBack] == HIGH) return;
// up button
if (buttons[buttonUp] == HIGH) CursorPrevious(DiagMenu, 5);
// down button
if (buttons[buttonDown] == HIGH) CursorNext(DiagMenu, 5);
}
void readButtons() {
// Clear the button states before checking for a new keypress.
buttons[buttonUp] = LOW;
buttons[buttonDown] = LOW;
buttons[buttonSelect] = LOW;
buttons[buttonBack] = LOW;
switch (key) {
case '2': // <-- Change all these to match your keypad characters.
buttons[buttonUp] = HIGH;
break;
case '8':
buttons[buttonDown] = HIGH;
break;
case '6':
buttons[buttonSelect] = HIGH;
break;
case '4':
buttons[buttonBack] = HIGH;
break;
}
}
mstanley:
Since I didn't have the rest of your code...
The code's like 1K+ lines long, which is why I didn't upload it. It's also a reverse-engineer of an existing program, so it makes it tough to just focus on the parts I need.
Instead of doing posts with a fraction of the program, attach the whole file. At the bottom when you write your post, "Additional options" ...
Then we can see the problem.
That's OK. It still only took 5 minutes to find a problem. When you first wrote you said that readButtons() was peppered all through the code. That isn't really much of a problem. The real problem is that it is stuck inside a while(true) loop:
while (1) // Do forever loop.
{
readButtons();
// Do more stuff.
}
This means that getKey() isn't going to be called at all and you won't get any keypresses. To fix it (I think) you will need to change this:
#include "keypad.h"
// kpd = keypad setup, blah...
// char key; <------- Remove this.
void setup () {
Serial.begin(9600);
}
void loop () {
// key = kpd.getKey(); <----- Remove this.
// readButtons(); <----- Remove this.
mainMenu(); <----- This is already in your loop and should stay.
}
void readButtons() {
// Clear the button states before checking for a new keypress.
buttons[buttonUp] = LOW;
buttons[buttonDown] = LOW;
buttons[buttonSelect] = LOW;
buttons[buttonBack] = LOW;
char key = kpd.getKey(); // <---------- Add this.
switch (key) {
case 'U': // <-- Change all these to match your keypad characters.
buttons[buttonUp] = HIGH;
break;
case 'D':
buttons[buttonDown] = HIGH;
break;
case 'S':
buttons[buttonSelect] = HIGH;
break;
case 'B':
buttons[buttonBack] = HIGH;
break;
}
}
OK, I've been going through the code as I write and it needs to be said that it's not a very good idea to include screen updates (lcdPrint), button testing, and menu selection all in the same function. The problem is that the keypad library expects to be called quite frequently, at least a few hundred times per second, but that will cause the LCD to flicker or more likely to fade out. Looking through the code you'll notice delay()'s of 150 and 250 milliseconds are sprinkled everywhere. This will make the keypad buttons very sluggish. But if you remove the delay()'s it will mess with the LCD. The trick is to move the LCD display code to its own function and only update the LCD when the information to be displayed changes.
I truly hope I am not discouraging you as this looks like a really cool project and I would hate to see you give up on it. I just need to warn you against using all those delay()'s. But if you following my warning then it is going to mess up your display. :~ You might be able to reach a happy balance for testing by adjusting the length of the delay()'s but rewriting how the information is displayed would make it a lot easier to change the code in the future without breaking it.
mark7w:
Instead of doing posts with a fraction of the program, attach the whole file. At the bottom when you write your post, "Additional options" ...
Then we can see the problem.
You'd think I'd be better at this by now. Time to restock on my personal clue stash.
The one I've attached is the ones with mstanley's updates. I'm still in process of testing.
Quick update:
The fixes mstanley gave me worked. The code I put up a little while ago works. There are still some pretty huge issues with the codebase, but the integration of the keypad was successful.
One of the drawbacks to this setup is you need to run a Mega, or some other board that has at least 19 digital I/O ports (6 for ethernet, 7 for my keypad, 6 for the LCD).
Next up is to do a full test on what does and does not work, and then report back.
FTPMonster:
One of the drawbacks to this setup is you need to run a Mega, or some other board that has at least 19 digital I/O ports (6 for ethernet, 7 for my keypad, 6 for the LCD).
Well, since you are using the Adafruit lcd library you can share the data pins of the LCD with the ROW pins of the keypad. That will let you recover four more pins.