Go Down

Topic: Keypad Input Function (Read 1 time) previous topic - next topic

Blade2021

Hi all,

Got a little problem that i'm sure is just a simple mistake but I can't find any real clear answers on the web.

I have a simple keypad function thats taking input from a user and then I want to parse it through into an integer.  However i'm not getting the function to trigger on the "*" key.  Am I over-looking something?

Code: [Select]

void changetime(int x){
  char key;
  int j = 0;
  char arraya [] = {0};
  key = keypad.getKey();
  if(key){
    lcd.print(key);
    pos++;
    lcd.setCursor(pos,3);
    arraya[j]=key;
    j++;
    if (pos > 20){
      pos = 13;
    }
    if(key=="*"){
      int tempa = atoi(arraya);
      y[x]=tempa;
      Serial.println("Ran array process");
      return;
    }
  }
}

el_supremo

Code: [Select]
char arraya [] = {0};
An array with one character (a zero - null). I doubt that your code works with that. The array has to be able to hold all the characters you're going to store in it, plus one for the NULL at the end (which is required for atoi to work).

Pete
Don't send me technical questions via Private Message.

el_supremo

P.S. the array should be global because otherwise it will disappear when the changetime function terminates.

Pete
Don't send me technical questions via Private Message.

PaulS

The atoi() function expects a string (a NULL terminated array of chars), not just an array of chars. The NULL IS important.

septillion

#4
Jan 31, 2017, 08:39 pm Last Edit: Jan 31, 2017, 08:39 pm by septillion
Yes, you overlook the fact your array is only size 1....

And instead of storing it as chars first and then try to do atoi() it's easier to calculate while you do it.

Code: [Select]
unsigned int output = 0;
key = keypad.getKey();
if(key){
  if(key != '*'){
    output *= 10;
    output += (key - '0');
  }
  else{
    //you have the value in output ;) save it to where you want
  }
}


But please don't post snippets. Because it leaves even more questions. Like, why do you use a terrible name like y for a global....
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Blade2021

Alright..

I'm taking everything in as much as I can but i'm not out of the water yet.  The atoi() function needs a null-character at the end.  Lets say I want to enter a 4 digit number, I would use the 5th character as my null?

@Septillion
Heh, its kinda funny.  I only posted a snippet cause if I posted everything it would be a huge eye sore to sort through it all. 

@el_supremo
I planned it this way on purpose.  I want the array to initialize only when called and "reset".  Therefore I put it directly into my slave function.

I have changed the array to hold more characters and I have changed the "" to '' around the *.  (It didn't like the "")

Code: [Select]

void changetime(int x){
  char key;
  int j = 0;
  char arraya [] = {0, 1, 2, 3, 4};
  key = keypad.getKey();
  if(key){
    lcd.print(key);
    pos++;
    lcd.setCursor(pos,3);
    arraya[j]=key;
    j++;
    if (pos > 20){
      pos = 13;
    }
    if(key=='*'){
      int tempa = atoi(arraya);
      Serial.println(tempa);
      y[x]=tempa;
      Serial.println("Ran array process");
      return;
    }
  }
}


So its still not giving me the outcome I expected.  Does it have to store the variables in a string then convert the string to a char array using the "StringToCharArray" function?  Or am I just that oblivious where i'm not seeing the answer.

septillion

Heh, its kinda funny.  I only posted a snippet cause if I posted everything it would be a huge eye sore to sort through it all. 
For good answers it's best to make a small "demo" program with the same problem. Learning in a complex program is hard anyway.

It didn't like the "")
That's because a "" indicates a NULL terminated array. ;)

I have changed the array to hold more characters
But you still don't null terminate it.

Does it have to store the variables in a string then convert the string to a char array using the "StringToCharArray" function?  Or am I just that oblivious where i'm not seeing the answer.
Nonononono. Stay away from String here. And why convert a char to sting and then to another string to turn into a int :o

But really, why not do it as you go? Wayyyyyyyyyyy easier.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

PaulS

Quote
The atoi() function needs a null-character at the end.  Lets say I want to enter a 4 digit number, I would use the 5th character as my null?
That's not really the way to think about it. Yes, you need a 5 element array. The NULL starts in position 0. When you overwrite that position with a key press value, you move the NULL to the next position.

Code: [Select]
   arraya[j++] = key;
   arraya[j] = '\0'; // Keep the array NULL terminated.

Delta_G

Heh, its kinda funny.  I only posted a snippet cause if I posted everything it would be a huge eye sore to sort through it all. 
We are coders.  We are good at reading through code.  And we would really greatly prefer the "eyesore" of a long code to the total time waste of trying to guess what the rest of your code says.  It is always better to reduce the program to a simple test program that illustrates the problem.  But we always need a complete program.  Otherwise we have to add the other parts to make it compile if we want to test and we might not write those parts the same way you do. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

Delta_G

Code: [Select]
void changetime(int x){
  char key;
  int j = 0;
  char arraya [] = {0, 1, 2, 3, 4};
  key = keypad.getKey();
  if(key){
    lcd.print(key);
    pos++;
    lcd.setCursor(pos,3);
    arraya[j]=key;
    j++;
    if (pos > 20){
      pos = 13;
    }
    if(key=='*'){
      int tempa = atoi(arraya);
      Serial.println(tempa);
      y[x]=tempa;
      Serial.println("Ran array process");
      return;
    }
  }
}



Lets look at this function for a second and think about what it does.  First you create an array to hold four characters in a string.  You populate it with '1','2','3','4'.  Then you read ONE character from the keypad and put it in the first position of the array.  Then this function exits.  You've read exactly one character, not 4.

Now when we go into this function again, we first reset that array to '1','2','3','4'.  We lose that key that you just put in there last time.  And now we again read ONE value and put it in the first slot of the array, do some printing and exit. 

Next time in we throw away that value just read, reset the array to '1','2','3','4' and read ONE key again. 

So you see that you will never get any 4 digit passcode.  You only read 1 character from the keypad and then when you get ready to read another you throw away the old one.  You only want to reset that array when you've read a full passcode from it. 
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

el_supremo

Quote
I planned it this way on purpose.  I want the array to initialize only when called and "reset".  Therefore I put it directly into my slave function.
Your "plan" is wrong. The array, whether you declared it to have one character or one hundred, will be created each time you enter the changetime function. It will then, probably, read ONE character from the keypad and then it will exit the function, at which time your planning falls apart because arraya will be destroyed.
You need to learn the concept of scope of variables.

Pete
Don't send me technical questions via Private Message.

Blade2021

That's not really the way to think about it. Yes, you need a 5 element array. The NULL starts in position 0. When you overwrite that position with a key press value, you move the NULL to the next position.

Code: [Select]
   arraya[j++] = key;
   arraya[j] = '\0'; // Keep the array NULL terminated.

Honestly it took me a while to get the concept of arrays so I do appreciate you explaining it further.  One last question the \0 moves the "Forced End" to the end of the array no matter how many keys are entered.  Do I understand this correct?

Lets look at this function for a second and think about what it does.  First you create an array to hold four characters in a string.  You populate it with '1','2','3','4'.  Then you read ONE character from the keypad and put it in the first position of the array.  Then this function exits.  You've read exactly one character, not 4.

Now when we go into this function again, we first reset that array to '1','2','3','4'.  We lose that key that you just put in there last time.  And now we again read ONE value and put it in the first slot of the array, do some printing and exit. 

Next time in we throw away that value just read, reset the array to '1','2','3','4' and read ONE key again. 

So you see that you will never get any 4 digit passcode.  You only read 1 character from the keypad and then when you get ready to read another you throw away the old one.  You only want to reset that array when you've read a full passcode from it. 
I see.  In my thought pattern (which was obviously wrong), I was taking it as it wouldn't exit the function until the ending key was pressed.  In this case the *.

Your "plan" is wrong. The array, whether you declared it to have one character or one hundred, will be created each time you enter the changetime function. It will then, probably, read ONE character from the keypad and then it will exit the function, at which time your planning falls apart because arraya will be destroyed.
You need to learn the concept of scope of variables.

Pete
I agree but thats why i'm here ;)  practice, learn, advance.  Don't get me wrong, I don't post here to get the answers handed to me but to see what I have misunderstood which in this case was actually a good bit so I do appreciate all of you.  (Yes you too @septillion).  I will correct my mistakes and continue. 

Thanks all,
- B

PaulS

Quote
One last question the \0 moves the "Forced End" to the end of the array no matter how many keys are entered.  Do I understand this correct?
I think of the NULL as a stop sign, not a "Forced End". It tells functions that expect strings to stop processing the array when they encounter the NULL/stop sign/Forced End.

You can keep the array declaration in the function, by adding static to the declaration. That means that the array will continue to exist, and to hold the values entered. Just be sure to make the index variable static, too.

Go Up