Go Down

Topic: Problem with 3*4 Keypad Again (Read 1 time) previous topic - next topic

guitarboy667

#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
 {'1','2','3'},
 {'4','5','6'},
 {'7','8','9'},
 {'*','0','#'}
};

byte rowPins[ROWS] = { 25, 35, 33, 29 };
byte colPins[COLS] = { 27, 23, 31 };

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
 Serial.begin(9600);
}

char charGain[4];
int charindex =0;
int i;

void loop(){

for(charindex == 0;charindex < 3; charindex++){

 char key = kpd.getKey();
 if (key != NO_KEY){  
  if (key = '#'){  
       for(charindex;charindex < 3;charindex++){  //if the user didn't enter 4 digits float from the keypad, then other char in the array is set to be 0
       charGain[charindex]=0;
       }
         charindex=0;
         }
  else if (key = '*'){
           int charindex =0;
           }
  else{      //if the user enter 0-9, then store it into array and display it
      charGain[charindex]=key;
      charindex++;
      Serial.print(charGain[charindex]);
       }
 }
}
charGain[4] = '\0';
i = atoi (charGain);
Serial.print(i);
}

Can anyone tell me what's wrong here?

PaulS

#1
Jul 13, 2010, 06:08 pm Last Edit: Jul 13, 2010, 06:10 pm by PaulS Reason: 1
Well, the code was not posted using the # button.

Other than that, our crystal ball is broken, I'm afraid. You have to give us at least a tiny hint. Does the code not compile? Does it compile, but not produce the correct results?

If it compiles, but does not produce correct results, what results are you expecting, and what results are you getting?

There are some errors, like this:
Code: [Select]
if (key = '#')

That should be a == in there, I'm pretty sure.

Senso

Code: [Select]
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};

byte rowPins[ROWS] = { 25, 35, 33, 29 };
byte colPins[COLS] = { 27, 23, 31 };

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
Serial.begin(9600);
}

char charGain[4];
int charindex =0;
int i;

void loop(){

for(charindex = 0;charindex < 3; charindex++){    //to compare use == to assign use =

char key = kpd.getKey();
if (key != NO_KEY){  
 if (key == '#'){     //to compare use == to assign use =
      for(charindex= ??;charindex < 3;charindex++){  //if the user didn't enter 4 digits float from the keypad, then other char in the array is set to be 0
//you need to say where charindex start
      charGain[charindex]=0;
      }
        charindex=0;
        }
 else if (key == '*'){   //to compare use == to assign use =
          int charindex =0;
          }
 else{      //if the user enter 0-9, then store it into array and display it
     charGain[charindex]=key;
     charindex++;
     Serial.print(charGain[charindex]);
      }
}
}
charGain[4] = '\0';
i = atoi (charGain);
Serial.print(i);
}


Does this even compile?

guitarboy667

It compiles correctly. The problem was I'd get whatever the input key was repeated an infinite amount of times.

Unfortunately I currently don't have a keypad to test it again, but all I'm trying to do is store a number that the user inputs that is 3 digits or less. I may have to change it to 4 digits though.

guitarboy667

I'd also like to be able to break the code up into sections as I've seen done before for example:

void loop(){

calibrate();
...
}

void calibrate(){
...
}

but if I reference a variable from calibrate in a different part of void loop then it says that the variable is not in scope.

Grumpy_Mike

If you declare the variable outside of any function it is available in all functions.

guitarboy667

I tried that, but this is what happens.

int x;
int y;

void loop(){

calibrate();
y = x *4;
Serial.print(x);
Serial.print(y);
}

void calibrate(){
x = 5;
}

and I'd get that both x and y equal zero.

davekw7x

#7
Jul 16, 2010, 06:20 pm Last Edit: Jul 16, 2010, 07:23 pm by davekw7x Reason: 1
Here's my version (the complete sketch made from the incomplete code in your last post):

Code: [Select]

int x;
int y;

void setup()
{
   Serial.begin(9600);
}
void loop()
{
   calibrate();
   y = x * 4;
   Serial.print("x = ");
   Serial.print(x);
   Serial.print(", y = ");
   Serial.println(y);
   Serial.println();
   delay(5000);
}

void calibrate(){
   x = 5;
}


Here's the output:


x = 5, y = 20




Now what do you get?


Regards,

Dave


Footnotes:

1:  For small test cases like this, when you post code and report results, it might be more useful to people reading the thread if you would post the entire sketch, so that we know exactly what you are running.

2:  Notice that I make the print statements verbose enough to tell me exactly what it is that I am seeing on the serial monitor.  I mean, when you just print some digits with no separation and no identification, how can you tell what the heck the program is really doing?

guitarboy667


PaulS

#9
Jul 16, 2010, 06:49 pm Last Edit: Jul 16, 2010, 06:50 pm by PaulS Reason: 1
Code: [Select]
       int ca = ca2 * 1;
       int upper = ca + 2;
       int lower = ca - 2;

In calibrate(), you are creating and manipulating local variables named ca and upper. Then, in loop(), you are printing the global (unchanged) variables. No wonder they are always 0.

guitarboy667

Nevermind I solved the problem. I shouldn't have repeated the int. Nevertheless I still may need help with the keypad.

AWOL

Quote
It's an accelerometer


What is?
A 3x4 keypad?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

CowJam

#12
Jul 19, 2010, 11:36 am Last Edit: Jul 19, 2010, 11:38 am by cowjam Reason: 1
Firstly, you seem to want four digits inputted but your FOR loops go from 0 to less than three.  Less than three is 2, so it goes 0,1,2.  

Secondly, you define a string as: charGain[4]
That means it has four chars in it.  Arrays start counting from 0 though, so the available characters in charGain are charGain[0], charGain[1], charGain[2] and charGain[3].
You add a character to charGain[4] which doesn't exist.

Thirdly, you have nested FOR loops using the same counter variable.  I think it'll work, but it's a bad idea.  It's really easy to get wrong and mess up your first loop, so you'd be better using a different variable then when complete terminate the loop.

You get the same character infinite times because you have no condition on it printing i.

Look through your LOOP: you've got a FOR loop, within which is an if (key != NO_KEY){ loop.
So, your FOR loop executes three times, if there's a keypress then it does something. If there is no keypress it doesn't executre that IF loop.  It doesn't wait for there to be a keypress, it just doesn't execute that for loop.

So it keeps looping, and it loops quickly.  Once you've pressed a key then it processes it, and afterwards it has a keypress in its variables so every time a key isn't pressed it doesn't do the IF A KEY HAS BEEN PRESSED bit and shoots straight to the end, where it prints the key it has.

Change that IF (key !=.. to something like (and this is a guesstimate, not guaranteed to work):
Code: [Select]
char key = kpd.getKey();
while (key == NO_KEY){
  key = kpd.getKey();
 }
if (key = '#'){  

Then the rest of your code.

That while loop will hold the programme there until it gets a keypress and should solve your problem.

guitarboy667

AWOL another guy asked a different question I had about an accelerometer, but I deleted most of those messages.

guitarboy667

Code: [Select]
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 3;

char keys[ROWS][COLS] = {
 {'1','2','3'},
 {'4','5','6'},
 {'7','8','9'},
 {'*','0','#'}
};

byte rowPins[ROWS] = {25, 35, 33, 29};
byte colPins[COLS] = {27, 23, 31};

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup()
{
 Serial.begin(9600);
}

char charGain[4];
int charindex =0;
int i;

void loop(){

char key = kpd.getKey();
if (key != NO_KEY){
while (charindex < 4){
  if (key == '#'){
       while (charindex < 4){  //if the user didn't enter 4 digits float from the keypad, then other char in the array is set to be 0
         charGain[charindex]=0;
         ++charindex;
       }
      //   charindex=0;
         }
  else if (key == '*'){
           charindex =0;
           }
  else if (key != NO_KEY || '#' || '*'){      //if the user enter 0-9, then store it into array and display it
      charGain[charindex]=key;
      ++charindex;
       }
}
}
charGain[4] = '\0';
i = atoi (charGain);
Serial.println(i);
/* for (charindex == 0;charindex < 4;charindex++){
   //lcd.print("array [" ++ charindex ++ "]"++ charGain[charindex]);
   Serial.print("array [");
   Serial.print(charindex);
   Serial.print("] ");
   Serial.print(charGain[charindex]);
} */
}


Well I tried it again using this code and I'll either get the same number 4 times in a row, for example, if a 1 was pressed: 1111 or just a 0.

The # seems to clear it, so idk what the problem is there with either the * key or the # key or both.

I would appreciate any help though.

Go Up