keeping track of time through out entire program

edit* so I just need a way of keeping time consistent through the entire process, like I want to keep track of time continuously, and be able to print it out when I call the method timeData but every time I enter an if statement or loop, millis() stops and time stays the same. Here I tried to fix it but I'm not incrementing it correctly and after about 3 times I push the button, my elapsed time turns negative for some reason.

void setup() {

  Serial.begin(9600);//start serial monitor
  pinMode(buttonPin, INPUT); 
  pinMode(ledPinr, OUTPUT);
  pinMode(ledPing, OUTPUT);
  myservo.attach(10);//servo attached to pin 10
 pinMode(buzzer, OUTPUT); // Set buzzer - pin 52 as an output
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {

firstTime = millis();
  buttonState = digitalRead(buttonPin);  // read the button
  photoValue = analogRead(photoPin);
  myservo.write(0); // set servo to pos 0
  digitalWrite(ledPing, LOW);
  digitalWrite(ledPinr, LOW);
 
  if (buttonState == HIGH) { // if button is pressed it asks user for code
    currentTime = millis();
    buttonValue = 100;
    Serial.println("Welcome..");
    Serial.println("Please enter the secret code");
    delay(30);
    check++; // adds to the check to make sure it stays in the loop
    trialCounter++;
   // zTime = bTime+ zTime;
   elapsedTime = elapsedTime + currentTime;
    timeData(elapsedTime,photoValue,buttonValue);
  }else{
 buttonValue = 0;

  }
  if(xcounter ==0){
    Serial.println("empty...");
      for(int i = 1;i<2;i++){
    buttonState = digitalRead(buttonPin);
     timeData(firstTime,photoValue,buttonValue);
      }
      xcounter++;
  }

 



 
  while ( check == 1 || check == 2) { // while the check is 1 or 2 it remains in the loop asking for input
 ///
 buttonValue = 0;
    customKey = customKeypad.getKey();   //check keypad for input
    if (customKey != NO_KEY) {
      if ((customKey >= '0') && (customKey <= '9')) { //Only valid for number keys
        value = value * 10; //First time through is zero then multiply by ten for each input
        value = value + customKey - '0';  //CustomKey input is ASCII - zero is 48, one is 49, etc. Subtract ASCII zero to get to decimal zero
      }
      if (customKey == '#') {
        Serial.print(value);
        if ( value == spy) { // if the code is the spy code it will welcome the spy
          currentTime = millis();
          digitalWrite(ledPing, HIGH);
          digitalWrite(ledPinr, LOW);
          Serial.println(" Welcome Spy");
          myservo.write(180);
          tone(buzzer, 660); // Send 1KHz sound signal...
            delay(1000);
          noTone(buzzer);     // Stop sound...
          delay(1000);///this holds the door open for only one second so that the agent may pass, this can change
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // read the value from the sensor:
   //zTime =millis();
  photoValue = analogRead(photoPin);
  if(photoValue < 100){
    
  spyCounter++;
 
    Serial.print("[enetered]");//if the sensor value is high, then it means the agent has passed through the door
    myservo.write(0);
    photoCounter = photoCounter + 1;

    if (photoCounter > 0){
    photoCounter = photoCounter/10;
    Serial.print("                                                       PhotoCellValue: ");//this doesnt work yet but its for componet 4
  Serial.println(photoValue);//
  elapsedTime = elapsedTime + currentTime;
     timeData(elapsedTime,photoValue,buttonValue);
  //////////////////////////////////////////////ifs for photo Value data


 
////////////////////////////////////////////////////////////
  }
   photoCounter = 0;
  } else{
     //zTime =millis();
// intruderCounter++;
  myservo.write(0);//if they dont pass the door within the 1 second (can change) then the system will go into lockdown mode
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
          digitalWrite(ledPing, LOW);
          Serial.println("Intruder! Lockdown initiated");//lockdown mode if no one passes, its suspicious
          boolean lockdownOff = false;//lockdown mode makes LED blink and shutsdown any further access to entrance (keypad, secret button)
 while(lockdownOff != true){//
            buttonState = digitalRead(buttonPin);//just in case you want to deactivate lockdown mode, hold button down until both lights go off
            //this is the code to make the LED blink
            tone(buzzer, 220); // Send 1KHz sound signal...
            digitalWrite(ledPinr, HIGH);//turn it
            delay(500);//leave on for a short time
            noTone(buzzer);     // Stop sound...
            digitalWrite(ledPinr,LOW);//then off
            delay(500);//hold, then repeat until loop is broken
            //end of blink LED code
            if (buttonState == HIGH){
   if (lastButtonState == HIGH){
     startTime = millis();//begins counting how long you've held the button for
     Serial.println("Admin override button pressed");//
   }
}
lastButtonState = buttonState;
if(ledOn(startTime) == false){//call method to determin if button was held down for 5 seconds
  digitalWrite(ledPinr,HIGH);
  digitalWrite(ledPing,HIGH);
  Serial.println("Reset intiated");
  
 
  lockdownOff = true;
  delay(5000);//hold 5 seconds
  break;
}
          }
          if (lockdownOff == true){
              Serial.println("Lockdown mode deactivated");//
            check = 0;//once check is back to 0, we can press button again to start process of agent entering 
          }else{
            check++;
          }
 /////////////////////////////////////////////////////////////
       
 }
          check = 0;//break loop to enter again once button is pressed
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
//timeData(time,photoValue,buttonValue);

}//end of main loop
//////////////////////////////////////////////////////////////////////////
void agentData(int a, int b, int c, int d){
  Serial.println("Data over 10 trails:  ");
  delay(2000);
  Serial.print("# of spies entered =      ");
Serial.println(a);
Serial.print("# of analysts entered =   ");
Serial.println(b);
Serial.print("# of Directors entered =  ");
Serial.println(c);
Serial.print("# of incorrect attempts = ");
Serial.println(d);




 Serial.print("Copy&paste: ");Serial.print(a);Serial.print(b);Serial.print(c);Serial.print(d);
 
}


//////////////////////////////////////////////////////////////////////////
//this is one of my attempts at componet 5 where this method makes sure the
//button is held down for as long as duration time 
boolean ledOn(unsigned long myStart){
  if (millis() - myStart < duration){
    return false;
  } else{
    return true;
  }
}//end of ledOn()
///////////////////////////////////////////////////////////////////////
void timeData(int a, int b, int c){
  //a is time in seconds
  //b is photocell value
  //c is buttonValue (0=LOW and 100=HIGH)

  Serial.println("_______________________________________");
Serial.print("time"); Serial.print("  "); Serial.print("photocellValue");Serial.print("  "); Serial.print("button data"); Serial.println(" ");

Serial.print(a/1000); Serial.print("          "); Serial.print(b);Serial.print("          "); Serial.print(c); Serial.println(" ");
Serial.println("_______________________________________");


}


////////////////////////////////////////////////
//this clears the monitor
void clearS(){
  for(int a=0;a<20;a++) {
    Serial.println("");
  }
}

More useless code snippets! Are you thinking that millis() returns an integer? Wrong! Try a long integer, 4 bytes.

Paul

This is interesting. Your time runs faster and faster as the real time since boot up increases.

    zTime =zTime + millis();

(even if you fix the other problem by making zTime a long or unsigned long int)

Always use unsigned long variables with millis() and micros().

For sensor timestamps, I recommend to use the Arduino Time library (TimeLib.h) and unix time. That automatically keeps track of date and timed, provided it is initialized properly.

1 Like

jremington:
Always use unsigned long variables with millis() and micros().

For sensor timestamps, I recommend to use the Arduino Time library (TimeLib.h) and unix time. That automatically keeps track of date and timed, provided it is initialized properly.

i did use unassaigned long variables for my zTime

But you used zTime incorrectly. Post ALL the code, using code tags, if you want to learn what else is wrong with it.

Yep, lots of us are waiting for these lines to get executed...

          if (lockdownOff == true){
              Serial.println("Lockdown mode deactivated");//

In New Zealand, when lockdown was lifted somewhat, there was a big rush to buy McDonald's hamburgers and Kentucky Fried Chicken.

jremington:
But you used zTime incorrectly. Post ALL the code, using code tags, if you want to learn what else is wrong with it.

I updated my code, I didnt realzie I left a huge chunk out. You can assume I included all the right libraries and everything has a set pin. And yes I used unsigned long for all my millis() variables

the value returned by millis() is an unsigned long.
Do not try to store in in an int:

void timeData(int a, int b, int c){

int can hold values -32768 through 32767.
How long, exactly, do you think 32767 is in milliseconds?
What do you think happens to a signed int when you add one to 32767?

As pointed out earlier, this line is fairly much gobbledygook to all intense and purposes:

elapsedTime = elapsedTime + currentTime;

Plus:

  1. Please do NOT update posts to include your latest code. Post a new post with the new code. When you update and retrospectively "fix" posts the entire train of the conversation is lost.
  2. It's still not a complete program. We cannot see how you have defined currentTime, elapsedTime, etc. Are these "unsigned long", or have you mistakenly used "int" for these as well?

so I just need a way of keeping time consistent through the entire process, like I want to keep track of time continuously, and be able to print it out when I call the method timeData but every time I enter an if statement or loop, millis() stops and time stays the same. Here I tried to fix it but I'm not incrementing it correctly and after about 3 times I push the button, my elapsed time turns negative for some reason. any help? Also, please assume that I included all the correct libraries and all pins are set. My code is just too long so I had to cut a large portion out, but I included the important parts.

unsigned long int firstTime;
unsigned long int currentTime; 
unsigned long int elapsedTime;
void setup() {

  Serial.begin(9600);//start serial monitor
  pinMode(buttonPin, INPUT);
  pinMode(ledPinr, OUTPUT);
  pinMode(ledPing, OUTPUT);
  myservo.attach(10);//servo attached to pin 10
 pinMode(buzzer, OUTPUT); // Set buzzer - pin 52 as an output
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {

firstTime = millis();
  buttonState = digitalRead(buttonPin);  // read the button
  photoValue = analogRead(photoPin);
  myservo.write(0); // set servo to pos 0
  digitalWrite(ledPing, LOW);
  digitalWrite(ledPinr, LOW);
 
  if (buttonState == HIGH) { // if button is pressed it asks user for code
    currentTime = millis();
    buttonValue = 100;
    Serial.println("Welcome..");
    Serial.println("Please enter the secret code");
    delay(30);
    check++; // adds to the check to make sure it stays in the loop
    trialCounter++;
   // zTime = bTime+ zTime;
   elapsedTime = elapsedTime + currentTime;
    timeData(elapsedTime,photoValue,buttonValue);
  }else{
 buttonValue = 0;

  }
  if(xcounter ==0){
    Serial.println("empty...");
      for(int i = 1;i<2;i++){
    buttonState = digitalRead(buttonPin);
     timeData(firstTime,photoValue,buttonValue);
      }
      xcounter++;
  }

 



 
  while ( check == 1 || check == 2) { // while the check is 1 or 2 it remains in the loop asking for input
 ///
 buttonValue = 0;
    customKey = customKeypad.getKey();   //check keypad for input
    if (customKey != NO_KEY) {
      if ((customKey >= '0') && (customKey <= '9')) { //Only valid for number keys
        value = value * 10; //First time through is zero then multiply by ten for each input
        value = value + customKey - '0';  //CustomKey input is ASCII - zero is 48, one is 49, etc. Subtract ASCII zero to get to decimal zero
      }
      if (customKey == '#') {
        Serial.print(value);
        if ( value == spy) { // if the code is the spy code it will welcome the spy
          currentTime = millis();
          digitalWrite(ledPing, HIGH);
          digitalWrite(ledPinr, LOW);
          Serial.println(" Welcome Spy");
          myservo.write(180);
          tone(buzzer, 660); // Send 1KHz sound signal...
            delay(1000);
          noTone(buzzer);     // Stop sound...
          delay(1000);///this holds the door open for only one second so that the agent may pass, this can change
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  // read the value from the sensor:
   //zTime =millis();
  photoValue = analogRead(photoPin);
  if(photoValue < 100){
   
  spyCounter++;
 
    Serial.print("[enetered]");//if the sensor value is high, then it means the agent has passed through the door
    myservo.write(0);
    photoCounter = photoCounter + 1;

    if (photoCounter > 0){
    photoCounter = photoCounter/10;
    Serial.print("                                                       PhotoCellValue: ");//this doesnt work yet but its for componet 4
  Serial.println(photoValue);//
  elapsedTime = elapsedTime + currentTime;
     timeData(elapsedTime,photoValue,buttonValue);
  //////////////////////////////////////////////ifs for photo Value data


 
////////////////////////////////////////////////////////////
  }
   photoCounter = 0;
  } else{
     //zTime =millis();
// intruderCounter++;
  myservo.write(0);//if they dont pass the door within the 1 second (can change) then the system will go into lockdown mode
          ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
          digitalWrite(ledPing, LOW);
          Serial.println("Intruder! Lockdown initiated");//lockdown mode if no one passes, its suspicious
          boolean lockdownOff = false;//lockdown mode makes LED blink and shutsdown any further access to entrance (keypad, secret button)
 while(lockdownOff != true){//
            buttonState = digitalRead(buttonPin);//just in case you want to deactivate lockdown mode, hold button down until both lights go off
            //this is the code to make the LED blink
            tone(buzzer, 220); // Send 1KHz sound signal...
            digitalWrite(ledPinr, HIGH);//turn it
            delay(500);//leave on for a short time
            noTone(buzzer);     // Stop sound...
            digitalWrite(ledPinr,LOW);//then off
            delay(500);//hold, then repeat until loop is broken
            //end of blink LED code
            if (buttonState == HIGH){
   if (lastButtonState == HIGH){
     startTime = millis();//begins counting how long you've held the button for
     Serial.println("Admin override button pressed");//
   }
}
lastButtonState = buttonState;
if(ledOn(startTime) == false){//call method to determin if button was held down for 5 seconds
  digitalWrite(ledPinr,HIGH);
  digitalWrite(ledPing,HIGH);
  Serial.println("Reset intiated");
 
 
  lockdownOff = true;
  delay(5000);//hold 5 seconds
  break;
}
          }
          if (lockdownOff == true){
              Serial.println("Lockdown mode deactivated");//
            check = 0;//once check is back to 0, we can press button again to start process of agent entering
          }else{
            check++;
          }
 /////////////////////////////////////////////////////////////
       
 }
          check = 0;//break loop to enter again once button is pressed
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
//timeData(time,photoValue,buttonValue);

}//end of main loop
//////////////////////////////////////////////////////////////////////////
void agentData(int a, int b, int c, int d){
  Serial.println("Data over 10 trails:  ");
  delay(2000);
  Serial.print("# of spies entered =      ");
Serial.println(a);
Serial.print("# of analysts entered =   ");
Serial.println(b);
Serial.print("# of Directors entered =  ");
Serial.println(c);
Serial.print("# of incorrect attempts = ");
Serial.println(d);




 Serial.print("Copy&paste: ");Serial.print(a);Serial.print(b);Serial.print(c);Serial.print(d);
 
}


//////////////////////////////////////////////////////////////////////////
//this is one of my attempts at componet 5 where this method makes sure the
//button is held down for as long as duration time
boolean ledOn(unsigned long myStart){
  if (millis() - myStart < duration){
    return false;
  } else{
    return true;
  }
}//end of ledOn()
///////////////////////////////////////////////////////////////////////
void timeData(int a, int b, int c){
  //a is time in seconds
  //b is photocell value
  //c is buttonValue (0=LOW and 100=HIGH)

  Serial.println("_______________________________________");
Serial.print("time"); Serial.print("  "); Serial.print("photocellValue");Serial.print("  "); Serial.print("button data"); Serial.println(" ");

Serial.print(a/1000); Serial.print("          "); Serial.print(b);Serial.print("          "); Serial.print(c); Serial.println(" ");
Serial.println("_______________________________________");


}


////////////////////////////////////////////////
//this clears the monitor
void clearS(){
  for(int a=0;a<20;a++) {
    Serial.println("");
  }
}

Why have you started a new thread?
Duplicate post: keeping track of time through out entire program - #5 by wolfgrayy - Programming Questions - Arduino Forum

Duplicate topics merged

Cross-posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes (or more) writing a detailed answer on this topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting will result in a suspension from the forum.

In the future, please take some time to pick the forum board that best suits the topic of your question and then only post once to that forum board. This is basic forum etiquette, as explained in the sticky "How to use this forum - please read." post you will find at the top of every forum board. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

You still haven't fixed....

void timeData(int a, int b, int c){

int ≠ unsigned long

Yes because I dont know how, when I call the method, what type do I refer to it as?

pcbbc:
You still haven't fixed....

void timeData(int a, int b, int c){

int ≠ unsigned long

okay so I just casted it into an int byt using '(int) x' so now the only problem I have is incrementing it correctly

wolfgrayy:
Yes because I dont know how, when I call the method, what type do I refer to it as?

Ok so I just casted it into an int using the cast '(int) x' method. Now I just need help incrementing it correclty.
I used elapsedTime = elapsedTime+currentTime; but it jumps way too much.

wolfgrayy:
Yes because I dont know how, when I call the method, what type do I refer to it as?

The same type as the variable you are passing in.
millis() returns an unsigned long.
At least variable "a", which is receiving a value passed in obtained from millis(), should be unsigned long as well.

When receiving values from functions, and when passing values into functions, ALWAYS use the same type. You are just asking for trouble if you do not, unless you know what you are doing.

Edit: Fixed typos - thanks gfvalvo

pcbbc:
The same type as the variable you are passing in.
millis() returns an unsigned int long.
At least variable "a", which is receiving a value passed in obtained from millis(), should be unsigned long as well.

When receiving values from functions, and when passing values into functions, ALWAYS use the same type. You are just asking for trouble if you do not, unless you knwo know what you are doing.

wolfgrayy:
Ok so I just casted it into an int using the cast '(int) x' method. Now I just need help incrementing it correclty.
I used elapsedTime = elapsedTime+currentTime; but it jumps way too much.

Don't you see how that line of code is nonsense? If you don't see, step through the code with pen and paper writing down the values at each step...

Let's say current time is 12000, and elapsedTime is 0.
First time through that code elapsedTime = 0 + 12000 = 12000.
1 second later, currentTime (which is read from millis()) is 1000 larger, so 13000.
So then elapsedTime = 12000 + 13000 = 25000.
1 second later, currentTime is 14000.
So then elapsedTime = 25000 + 14000 = 39000.

Does that look right to you?

elapsedTime = currentTime - lastTime;
lastTime = currentTime;