Dumb Question - Global variable not holding value on change

Sorry, I'll have to drop out of this. My first dumb answer was the best I could do for your dumb question. :wink:

that is ok I found that I am getting corruption in that value, if i try to print after the if it prints 5 and a garbage character,the second print statement does not print at all. so I have a bigger issue, I need to review my variable declarations may be I have too many for an UNO.

"Dumb question #2"

If eXtime is ONLY used here, WHY is it global?

Use it here, and return a value which the outside code can see and act on that rather than the actual value.

Just a thought.

This is not correct function as I understand it a global variable should maintain it's value until the loop restarts

It would be more accurate to say that it retains its value until something changes it. loop() restarting has nothing to do with it.

To get more help you must post all of your code or attach it to a post.

rgallant:
that is ok I found that I am getting corruption in that value, if i try to print after the if it prints 5 and a garbage character,the second print statement does not print at all. so I have a bigger issue, I need to review my variable declarations may be I have too many for an UNO.

Oops... so much for me keeping out of this. If you find you are running out of variable space, why not look at all your "int"s. Decide which ones both never get a negative value and never contain a value over 255, and change them to "byte". That should save 1 byte for each one you convert... (int is 2 bytes on the UNO.)

Might be a red herring though....

ukHelibob,

That is why I am confused, your explanation is exactly my understanding of how things should be working, but they are not. I was hoping I had simply done something unusually dumb and missed it. I will post or attach the whole section of code later.

rgallant:
portion that is failing

Unless you can post a complete sketch that demonstrates the problem, you're pretty much wasting your time trying to figure it out from code snippets. If you're able to produce a simpler sketch that demonstrates the problem, so much the better. But the code you post needs to compile, run and demonstrate the problem.

Everything as requested, this code compile and runs the problem as noted above is in the armed 2 if statement.

Output from serial :

the garbage characters are from the print right after the arm 2 check.

#include <I2C.h>

// FOR RFID Reader

#include <SoftwareSerial.h>
#define RFID_READ 0x01
#define txPin 6
#define rxPin 10

// define Devantech LCD address

#define DLCD 0x63

int int_sys = 1;
int y = 0;
int z = 0;
int err_c = 0;
int i;

int second=00; 
int minut; 
int hour=0; // declare time variables
int armed = 0;

int go_boom = 0;
int big_boom = 0;
int Arm_card[4];
int Test_val[4] = {1,248,124,0};

// canned messages

char message[10] = "Hello Hal";
char message2[15] ="Arm the System";
char message3[15] ="Verfiying Code";
char boom[2] ="b";
char message4[14] ="Arming Failed";

// For data from RFID tags

SoftwareSerial mySerial(rxPin, txPin);

int val;
int runs = 0;
char Set1[5];
char Set2[5];
char Set3[5];
char Set4[5];
char sec[3];
char minu[3];
char hou[3];
char zer[2] = "0";

void setup()
{
  I2c.begin();
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(txPin, OUTPUT);    
  pinMode(rxPin, INPUT);
  minut = 5;  
}

void loop()
{
  int eXtime = 0;  
  while (big_boom == 0)
    {
     while (int_sys == 1)
       { 
        clr_scr();
        backlight_on();
        LCD_Message(message,10,1);
        LCD_Message(message2,15,2);
        delay(3000); //make em wait
        // debug only
        // I2c.scan();
        int_sys = 2;
       }

       Get_card();
       check_arm();

       if (armed ==2)
         {
          clr_scr();
          LCD_Message(message4,14,1);
          eXtime = eXtime + 6;
          Serial.print(eXtime);
          Serial.println(" in loop xtime val"); 
          delay (5000);
          } 
        Serial.print(eXtime);
        Serial.println(" after armed 2 if xtime val"); 
       if (armed==1)
         {
           clr_scr();
           minut=minut + eXtime;
           Serial.print(eXtime);
           Serial.println(" xtime val");
           Serial.print(minut);
           Serial.println(" minut val");
           itoa(minut,minu,10);
           LCD_Message(minu,3,1);
           itoa(second,sec,10);
           LCD_Message(sec,3,1);

           while (go_boom==0)
             {
              countdown();
              if (minut == 0)
                {
                 if (second == 0)
                   {
                    go_boom = 1;
                    clr_scr();
                    LCD_Message(boom,16,1);
                    delay(2000); 
                    big_boom = 1;
                   }     
                 }     
               }   
         }  
     }
 }

// LCD functions
// All tested and working as expected

 void backlight_on()
{
  err_c = I2c.write(DLCD,0);  // set the register pointer 
  if (err_c != 0)
    {
     Serial.print(err_c);
     Serial.println("  Error setting pointer");
    }  

  err_c = I2c.write(DLCD,0,19);
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting backlight on");
    }  
} 

void backlight_off()
{
   err_c = I2c.write(DLCD,0);  // set the register pointer 
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting pointer");
    } 
 err_c = I2c.write(DLCD,0,20);
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting backlight off");
    }  
  
}  

void LCD_Message(char mess[],int C_len, int M_line)
{
  if (M_line == 2)
   {
    Line_2();
   }
  err_c = I2c.write(DLCD,0);  // set the register pointer 
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting pointer");
    } 
for (i=0;i<C_len;i++)
 {
 err_c = I2c.write(DLCD,0,mess[i]);
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error writing message");
    }
 } 
}
  
void Line_2()
{
  err_c = I2c.write(DLCD,0);  // set the register pointer 
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting pointer");
    } 

  err_c = I2c.write(DLCD,0,13);
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error writing message 2");
    }
}

void clr_scr()
{
   err_c = I2c.write(DLCD,0);  // set the register pointer 
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error setting pointer");
    } 
  err_c = I2c.write(DLCD,0,12);
  if (err_c != 0)
    {
      Serial.print(err_c);
      Serial.println("  Error clearing screen");
    }     
}

void check_arm ()
{
  int arm_good = 0;
  for(i=0;i<4;i++)
   {
    if (Arm_card[i+1] == Test_val[i])
      {
       arm_good = arm_good + 1;          
      }
   }
   if (arm_good == 4)
    {
     armed = 1;
    }  
   else
    {
     armed = 2; 
    }  
}  

// RFID read section note for new cards

void Get_card ()
{
  int val;
  int got_data = 0;
  while (got_data == 0)
  {
    mySerial.write("!RW");
    mySerial.write(byte(RFID_READ));
    mySerial.write(byte(32));
    mySerial.available();
 
    if(mySerial.available() > 0)
    {      
      val = mySerial.read();                        //The mySerial.read() procedure is called, but the result is not printed because I don't want the "error message: 1" cluttering up the serial monitor
      if (val != 1)                                   //If the error code is anything other than 1, then the RFID tag was not read correctly and any data collected is meaningless. In this case since we don't care about the resultant values they can be suppressed
       {suppressAll();}                              
   }      
 
   if(mySerial.available() > 0) 
   {      
    clr_scr();
    LCD_Message(message3,15,1);
    delay(2000); // more waiting :)
    val = mySerial.read();
    itoa(val,Set1,10);
    LCD_Message(Set1,4,2);
    delay(2000);
    Arm_card[1] = val;
    Serial.print("1st:");
    Serial.println(val);
    }

   if(mySerial.available() > 0) {        
    val = mySerial.read();
    itoa(val,Set2,10);
    LCD_Message(Set2,4,1);
    delay(2000);
    Arm_card[2] = val;
    Serial.print("2nd:");
    Serial.println(val);
    }

   if(mySerial.available() > 0) {      
    val = mySerial.read();
    itoa(val,Set3,10);
    LCD_Message(Set3,4,1);
    delay(2000);
    Arm_card[3] = val;    
    Serial.print("3rd:");
    Serial.println(val);
    }

   if(mySerial.available() > 0) {          
    val = mySerial.read();
    itoa(val,Set4,10);
    LCD_Message(Set4,4,1);
    delay(2000);
    Arm_card[4] = val;
    Serial.print("4th:");
    Serial.println(val);
    Serial.println("-----------------");
    got_data = 1;
   }  
   delay(750);
  }
}

void suppressAll()                                //suppresses the "null result" from being printed if no RFID tag is present
{
    if(mySerial.available() > 0)
    { mySerial.read();
      suppressAll();
    }
}


/***********************************************************
* Main countdown timer                                     *
*                 countdown()                              *
************************************************************/
void countdown()
{

  static unsigned long lastTick = 0; // set up a local variable to hold the last time we decremented one second
// (static variables are initialized once and keep their values between function calls)
 
// decrement one second every 1000 milliseconds
  if (second > 0) {
      if (millis() - lastTick >= 1000) {
          lastTick = millis();
          second--;
          clr_scr();
          itoa(minut,minu,10);
          LCD_Message(minu,3,1);
          itoa(second,sec,10);
          if (second < 10)
           {
           LCD_Message(zer,1,1);
           }  
          LCD_Message(sec,3,1);

      }
  }
 
 // decrement one minute every 60 seconds
  if (minut > 0) {
      if (second <= 0) {
          minut--;
          second = 60; // reset seconds to 60
      }
  }
 
// decrement one hour every 60 minutes
  if (hour > 0) {
      if (minut <= 0) {
          hour--;
          minut = 60; // reset minutes to 60
      }//closes if
  }//closes if
 
}

3-28-2013 2-25-36 PM.png

char message3[15] ="Verfiying Code"; the compiler can't do much about your spelling, but it is quite capable of counting the number of characters in a string char message3[] ="Verifying Code";

void loop()
{
  int eXtime = 0;

Global?

(Hey AWOL).

Ok, question - not to you AWOL.

Line 65 is where you set exTime

That is inside the loop and so every time the loop loops, it will be wiped.

You do understand that don't you? :smiley:

rgallant:
eXtime is declared Global

void loop()
{
	int eXtime = 0;

Not in your example, it isn't. Since it's declared as a local variable in loop(), it will be reinitialised to zero at the start of each call to loop().

UKHeliBob:

This is not correct function as I understand it a global variable should maintain it's value until the loop restarts

It would be more accurate to say that it retains its value until something changes it. loop() restarting has nothing to do with it.

So, eXtime is not declared global after all and is behaving as one would expect considering that it is declared and initialised as the first thing in loop()

Yes I am aware that the variable is inside the loop function now, it is however outside the nested while statements. So once the loop is restarted it will, be reset to zero that is fine.

I made that change when I realized that the data is getting corrupted. However it changes nothing significant in the behavior of the code, please see the output from the serial monitor attached to the full code post.

Inside the if statement the variable is set to 6 immediately upon exit is corrupted.

rgallant:
please see the output from the serial monitor attached to the full code post.

Inside the if statement the variable is set to 6 immediately upon exit is corrupted.

This is the output you're referring to?

1st: 2
2nd: 58
3rd: 203
4th: 61
------------------
6 in loop xtime val
¶Þ

So is your whole question actually about the two garbage characters printed at the end, and not about what's happening to eXtime?

What happens after this point - is the Arduino still working? Does it print anything else after this? If so, what?

The code in Get_card() looks horrible, and suppressAll() is a disaster waiting to happen. I wouldn't be at all surprised if you have simply run out of memory due to recursive calls to suppressAll blowing your stack space.

This is an extremely bad idea:

void suppressAll()                                //suppresses the "null result" from being printed if no RFID tag is present
{
  if(mySerial.available() > 0)
  { 
    mySerial.read();
    suppressAll();
  }
}

Get rid of the recursion and then we can talk.

In any case just reading and discarding serial data is rarely a good idea.

I don't understand what Get_card is doing but perhaps you should read this:

Thanks for your reply Nick,

I used the RFID reader code as I found it, with very little change.

I will clean it up in the am and get rid of the recursive call.

I generally try to clean up my code once it is working, but had done so yet with this, I had not considered the impact of the recursive call.

Just wanted to say thanks to all and particularly Nick, the recursive call, and another bad section of code were generating the problem. I removed that call as well as another similar piece of code and works as expected. The card reading code needs some clean up to read the card correctly but that is pretty minor.

Thanks again for your help.

Thanks, and glad it's working. I must give credit to PeterH who initially spotted the problem with the recursion. I just made it more obvious what the problem was. :slight_smile: