Help storing a variable properly from IR transmitter

Disclaimer: I'm kind of new.

Attached is my code. My goal is to get numerical input from an IR remote and store a 10 digit code as latstr and another as longstr. This is part of a larger project. My IR works great and stores latstr perfectly if I do a serial.print(latstr) right after the first while statement. However, when it moves to the next part of the program and stores longstr, if I view the latstr variable, it contains the longstr as well and I can't figure out why. Also longstr seems to be adding a few random characters at the end and I don't know why.

Exanple:
Start program.
Press 1234567890 for LAT input on ir keypad
Press 5554443332 for LONG input on ir keypad

Output of serial.println(latstr) = 1234567890 after first while statement
Output of longstr = null after first while statement (obviously)

Output of latstr = 12345678905554443332 after second statement
Output of longstr = 5554443332 and some weird characters after 2nd while statement (obviously)

2 issues. Why is it adding on to latstr when I didn't even mention it in the second while statement? And why is it tacking on weird characters at the end of longstr?

Code:

#include <IRremote.h>

//setup variables
const int irPin = 11; //IR in pin
IRrecv irrecv (irPin); //Create IR receiving
decode_results results; //object on irPin 
char irnum[12] = {'.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'f'};
char latstr[10]; //latitude string location - format ##.######f
char longstr[10]; //longitude string location - format ##.######f
char lcdlat[6] = "Lati:";
char lcdlong[6] = "Long:";
char lcdmsg[16];
int oldVal = 0; //These two variables store
int val = 0; //numbers decoded from the remote
int irnumCodes[12] = {
  16728765,
  16730805, //Values for certain
  16738455, //keys that are assigned
  16750695, //to certain letters.
  16756815, //Replace these with
  16724175, //values from your remote.
  16718055,
  16743045,
  16716015,
  16726215,
  16734885,
  16732845,
};




void setup () {
  Serial.begin (9600); // debugger
  irrecv.enableIRIn (); //enable decoding
}





void loop () {
Serial.println("loopstart");
int y = 0; //lat increment
int x = 0; //long increment
Serial.println("intxy set");
while (y <= 9)//input Lat
  {
  if (irrecv.decode (&results)) { //check if IR data is received
    val = results.value; //If so, set val to decoded data
	irrecv.resume (); //keep receiving
  if (val != oldVal) { //make sure a single key is not being held down
    
    for (int i = 0; i <= 12; i++) {
      
      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character
        Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
        latstr[y] = irnum[i];
        y++;
      }
      
    }
  }
  oldVal = val;
  }
  }Serial.println("endwhile");
while (x <= 9) // input Long
  {
  if (irrecv.decode (&results)) { //check if IR data is received
    val = results.value; //If so, set val to decoded data
	irrecv.resume (); //keep receiving
  if (val != oldVal) { //make sure a single key is not being held down
    
    for (int i = 0; i <= 12; i++) {
      
      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character
        Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
        longstr[x] = irnum[i];
        x++;
      }Serial.println(irnum);
      
    }
  }
  oldVal = val;
  }
  }
  Serial.println("endwhile2");
//outputs 16 characters to lcd
//lcd.clear(); //clears lcd
Serial.println("."); //debug only
Serial.println("."); //debug only
Serial.println("6char lcdlat"); 
Serial.println(lcdlat); //prints 6chars
Serial.println("."); //debug only
Serial.println("10char latstr"); 
Serial.println(latstr); //prints 10chars
Serial.println("."); //debug only
Serial.println("6char lcdlong"); 
Serial.println(lcdlong); //prints 6chars
Serial.println("."); //debug only
Serial.println("10char longstr"); 
Serial.println(longstr); //prints 10chars
Serial.println("."); //debug only
Serial.println("."); //debug only
Serial.println("The above should be 16 characters"); //debug only
}

Serial Output:

loopstart
intxy set
loopstart
intxy set
1234567890endwhile
5554443332endwhile2
.
.
6char lcdlat
Lati:
.
10char latstr
12345678905554443332g˜g˜
.
6char lcdlong
Long:
.
10char longstr
5554443332g˜g˜
.
.
The above should be 16 characters

Comment out the "oldVal = val;" lines. Seemed to get rid of the weird characters at the end. Not sure why.

latstr (when printed to serial at the end of the program) still contains both sets of numbers, while longstr does not. Thoughts?

10char latstr
12345678905554443332
.
10char longstr
5554443332

First, the range of values for an int is roughly plus or minus 32,767 so a number as big as you're trying to place in an int won't work. Second, we need to know the way in which the latitude and longitude are sent to the Arduino. In its string format, is it all sent as one long string, or two strings, or some form of delimited string?

The ints are only being used to decode the ir keypresses and that part seems to work fine. Either way, I updated the code with your advice. No changes, but I don't think we expected any.

It stores each keypress (single numerical digit) in the while statement (into a spot in longstr or latstr) and that actually seems to work well too. It's just that latstr seems to be getting the data from longstr for some reason after the second while statement runs, yet I can't find any connection between the two statements. If I do a println for latstr after the first while statement, the value is exactly what i want. To answer your question, it is sent via keypress from an IR remote. The first while statement waits for a keypress, then stores it as a digit of latstr. Once it fills up all 10 digits, the while statement ends and moves on to to the next while statement. It waits for 10 more keypresses and fills up longstr.

At that point, output of both look like:
10char latstr
12345678905554443332
10char longstr
5554443332

I typed in 1234567890 for long and 5554443332 for lat on my remote.

Weird thing is if I print the latstr variable directly after the first while statement, it is correct. Something in the second while statement is adding longstr to latstr but I can't figure out what.

edit: Greetings from Ohio!

Take a look at irnumCodes[]. The first value is 16728765, which is considerably bigger than 32767, so that array should be an unsigned long to work.

Next, consider the statement:

  if (val != oldVal) { //make sure a single key is not being held down

where you are checking for a duplicate value (debouncing??). Is there anything that prevents a value coordinate like 1122334455?? If so, you'll never catch both inputs.

Also, I would add a print statement to check what I actually have, using:

  }
  Serial.print("endwhile 1:  latstr =");
  Serial.println(latstr);

and do the same for longstr. If you see garbage after the numbers, chances are it's not a null-terminated string. If that's the case, before the serial prints above, add:

latstr[y] = '\0';   // Make it into a C string

I have a bit of free time now, so let me read through your post to make sure I understand it.

In the mean time, I narrowed down the problem to the line longstr[x] = irnum[i];
I outputted the value of latstr before and after it by inserting the following code:
I pressed the "3" button

              delay (1000);
              Serial.println("debug1 values right before longstr assignment:");
              Serial.println(latstr);
              Serial.println(val);
              Serial.println(irnumCodes[i]);
              Serial.println(longstr);
              Serial.println("end debug block1");
              delay (1000);
        longstr[x] = irnum[i];
              delay (1000);
              Serial.println("debug2 value right after longstr assignment:");
              Serial.println(latstr);
              Serial.println(val);
              Serial.println(irnumCodes[i]);
              Serial.println(longstr);
              Serial.println("end debug block2");
              delay (1000);

The results (comments by me):

debug1 value right before longstr assignment:
1234567890 //latstr
16756815    // val
16756815    //irnumcodes[i]
                  //longstr
end debug block1

debug2 value right after longstr assignment:
12345678903 //latstr **NOTE THAT THERE IS NOW A 3 AT THE END. Why?**
16756815      //val
16756815      //irnumcodes
3                  //longstr
end debug block2

So how on earth can setting a char in longstr affect the variable latstr? The only thing in between them is: longstr[x] = irnum[i];

Replying to your earlier post, all of the ints are fixed. I no longer get garbage on my strings. But longstr[x] = irnum[i]; seems to be adding it's contents on to the latstr string and I can't figure out why.

Figured it out. I don't know WHY this broke it, but I increased it from 10 to 11 spaces and everything started working. Weird because I was only assigning 10 characters.

char latstr[10]; //latitude string location - format ##.######f
char longstr[10]; //longitude string location - format ##.######f

I've only had a quick glance at your code but, Are you perhaps going beyond the bounds of your char arrays?

char latstr[10]; //latitude string location - format ##.######f
...
...

      for (int i = 0; i <= 12; i++) {
  
      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character
        Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
        latstr[y] = irnum[i];//<<--y could hold 11 here yes? OR EVEN 12 that's 13 chars!
        y++;
      }

Don't forget to treat a char array as a string, you need to add the null termination character ('\0') to the end. So, if there are 10 digit characters, you need 11 elements in the char array to provide space for the null.

econjack:
Don't forget to treat a char array as a string, you need to add the null termination character ('\0') to the end. So, if there are 10 digit characters, you need 11 elements in the char array to provide space for the null.

Well in the small snippet I highlighted it's potentially going up to 13 characters (then the terminator) so it really wants to be 14 characters minimum.

Hello everyone,

I am noob. Sorry if I cannot clearly express myself.

Below code works great for me if I want to enter 3-digit number.

How about 1 or 2 digit numbers?

Assume I want to enter "21" and hit "#" in remote, it will not give me 2 digit array since this code always requires 3-digit array. Can we find a way through?

Thank you

#include <IRremote.h>

//setup variables
const int irPin = 6; //IR in pin
IRrecv irrecv (irPin); //Create IR receiving
decode_results results; //object on irPin 
char irnum[12] = {'.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#'};
char game[3]; 
int oldVal = 0; //These two variables store
int val = 0; //numbers decoded from the remote
int irnumCodes[12] = {
  16728765,
  16730805, //Values for certain
  16738455, //keys that are assigned
  16750695, //to certain letters.
  16756815, //Replace these with
  16724175, //values from your remote.
  16718055,
  16743045,
  16716015,
  16726215,
  16734885,
  16732845,
};


void setup () {
  Serial.begin (9600); // debugger
  irrecv.enableIRIn (); //enable decoding
}

void loop () {
 getGameId();
}

void getGameId()
{
Serial.println("loopstart");
int x = 0; //long increment
while (x <= 2)
  {
  if (irrecv.decode (&results)) { //check if IR data is received
    val = results.value; //If so, set val to decoded data
  irrecv.resume (); //keep receiving
  if (val != oldVal) { //make sure a single key is not being held down
    for (int i = 0; i <= 12; i++) {
      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character
        Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
        game[x] = irnum[i];
        x++;
      }
    }
  }
  oldVal = val;
  }
  }
  game[x] = '\0';
Serial.print("game no: ");
Serial.println(game);
}
int irnumCodes[12] = {
  16728765,
  16730805, //Values for certain
  16738455, //keys that are assigned
  16750695, //to certain letters.
  16756815, //Replace these with
  16724175, //values from your remote.
  16718055,
  16743045,
  16716015,
  16726215,
  16734885,
  16732845,
};

NONE of those values are ints.

void getGameId()
{
Serial.println("loopstart");

That print statement is NOT at the start of loop.

int x = 0; //long increment

There is NOTHING long about the variable or the value.

      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character
        Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
        game[x] = irnum[i];
        x++;
      }

Why would you store the "I be done entering the value" code in the array?

PaulS:

int irnumCodes[12] = {

16728765,
 16730805, //Values for certain
 16738455, //keys that are assigned
 16750695, //to certain letters.
 16756815, //Replace these with
 16724175, //values from your remote.
 16718055,
 16743045,
 16716015,
 16726215,
 16734885,
 16732845,
};



NONE of those values are ints.

I can convert these into HEX, np. I just modified the code in the first post, since it works, I did not care :slight_smile:

void getGameId()

{
Serial.println("loopstart");



That print statement is NOT at the start of loop.

In serial monitor, it still works. I did not understand what you mean.

int x = 0; //long increment

There is NOTHING long about the variable or the value.

Yes. I copied comments as well :slight_smile:

      if (val == irnumCodes[i]) { //check if val is equal to the code for a certain character

Serial.print (irnum[i]); //If so, print out the appropriate character to the Serial Monitor
       game[x] = irnum[i];
       x++;
     }



Why would you store the "I be done entering the value" code in the array?

Still could not figure out how to do it with 1-digit, 2-digit and 3-digit at the same time.

In serial monitor, it still works. I did not understand what you mean.

Doesn't this code:

void setup()
{
   Serial.begin(115200);

   Serial.println("This is the loop function");
}

void loop()
{
   Serial.println("This is the snowball function");

   snowball();
}

void snowball()
{
   Serial.println("This is the loop function");
}

look pretty stupid? None of the Serial.print() statements print useful information about the function that the statement is in (where useful == correct).

That is what YOUR code looks like, when one function prints that it is something else.

Yes. I copied comments as well

Why? Comments should be useful. They should explain WHY the code is doing something.

float pi = 3.14159; // Set banana to three

That is what YOUR comment looks like. Get rid of useless comments - especially those that are wrong.

Still could not figure out how to do it with 1-digit, 2-digit and 3-digit at the same time.

You have some key that means "use the stored data". That key should NOT be added to the array. When that key is pressed, you KNOW how many valid characters there are in the array.