[SOLVED] 'What will happen' question... variable basics

EDIT:
Got everything working!

For anyone interested in the final project, I posted about it here:
http://ranchhousereno.com/making-an-arduino-controlled-litter-box-fan-how-to/

I appreciate your help! Thank you!


Hi All,

I’m new to this and have a question. I wrote the below code today and I don’t know how it will behave when it reaches a certain point. I was hoping to avoid using delay() because I may want to have it doing something like printing to a display during that time.

At the start, with millis() at 0, I know everything will work. I have a concern though. My code relies on millis() to tell it when a photocell detects a light is no longer on. If the millis() is at the edge of rolling back to 0, what will happen to my variables and calculations?

My delays are assuming something like millis() + 1800000. If it is right at the edge of rolling over the overflow, what does my method of adding delays do?

I would hate to get in a situation where the computer has to wait 49 days to turn off a fan and stop a loop.

/* 
 Litter_Box_Fan
 
 This program is designed to operate a fan based on the status of a light. 
 The litterbox has an LED on it which flashes when it is going to start a cleaning cycle.
 This will recognize the flashing and do the following:
 Wait [waitTime] until it starts the fan. Run fan until [stopTime] has been reached.
 
 A photocell resistor has been attached to analogue pin 0, 5v, and ground. 
 An LED (on board) will be manipulated using pin 13.
 
 The actual milli value of the time the fan runs is determined by changeDetected().
 
 The circuit:
 * photocell attached to analog input 0
 * OUT pin of photocell attached to the analogue pin
 * VCC of photocell to 5v
 * GND of photocell to ground
 * On board LED attached to digital output 13
 * Relay +in attached to 3.3v
 * Relay -in attached to analog input A1
 * Relay Ground attached to ground
 
 Created by Charles Hettinger
 modified 10/25/14 
*/

unsigned long timeOfChange;//milli time that change in photocell is detected
unsigned long timeOfStart;//milli time that fan starts
unsigned long timeOfStop; //milli time that fan stops
unsigned long delayTime; //flashing status LED delay time milli (this changes based on millis()) (milliseconds)
int blinkDelay = 1000; //time between status LED blinks (milliseconds)
long int waitTime = 900000; //time to wait before fan start (milliseconds)
long int stopTime = 1800000; //time fan will stop (milliseconds)
boolean lightIsOn = false; //boolean that stores previous status LED value
boolean fanStarted = false; //boolean to store fan state
int ledPin = 13; //pin of LED
int lightPin = A0; //pin of photo sensor
const int powerPin = A1; //control pin for power switch relay
boolean powerOn = false; //boolean describing if power is on to fan

void setup () {
  pinMode(ledPin, OUTPUT); //sets the LED as an output
  pinMode(powerPin, OUTPUT); //sets the powerPin as an output
  digitalWrite(powerPin, HIGH); //sets power to OFF
  Serial.begin(9600); //allows println debug communication
  
  Serial.println("milli start: ");
  Serial.println(millis());
  Serial.println("Wait time set to: ");
  Serial.println(waitTime);
  Serial.println("Stop time set to: ");
  Serial.println(stopTime);
}

void loop()
{
    digitalWrite(ledPin,LOW); //turn LED off
    
    //Serial.println(analogRead(lightPin)); //Write the value of the photoresistor to the serial monitor.
    if (analogRead(lightPin) >=500) //check for high light level NOW
    {
      //Serial.println("Light is on");
      switch (lightIsOn) //based on the boolean of the light having been on previously
      {
        case true: //light is on now, and was on last time it checked
          //Serial.println("Same state, do nothing.");
          break;
        case false: //light is on now, and was not on last time it checked
          Serial.println("Different state!");
          lightIsOn = true; //set boolean to true showing light was on when it checked
          break;
        default:
          Serial.println("Boolean error: not defined");
          break;  
      }    
    }
    else if (analogRead(lightPin)<500) //check for low light level NOW
    {
      //Serial.println("Light is off");
      switch (lightIsOn) //based on the boolean of the light having been on previously
      {
        case true: //light is off now, and was on last time it checked
          Serial.println("Different state!");
          lightIsOn = false; //set boolean to false showing light was off when it checked
          changeDetected();
          break;
        case false: //light is off now, and was not on last time it checked
          //Serial.println("Same state, do nothing.");
          break;
        default:
          Serial.println("Boolean error: not defined"); 
          break; 
      }    
    }    
}

void changeDetected () //this function will be called when a change from ON to OFF is detected
{
  timeOfChange = millis(); //set time of change to current milli from program start
  timeOfStart = timeOfChange + waitTime; //set the fan start time to [waitTime] after the current time
  timeOfStop = timeOfChange + stopTime; //set the fan stop time to [stopTime] after the current time
  Serial.println("Time of change is: ");
  Serial.println(timeOfChange);
  Serial.println("Time of start is: ");
  Serial.println(timeOfStart);
  Serial.println("Time of stop is: ");
  Serial.println(timeOfStop);
  
  Serial.println("Fan is waiting.");
  while (millis() < timeOfStart) //if current time is less than the time of fan start
  {
    delayTime = millis() + blinkDelay;
    //make the LED flash while in this state
    if (lightIsOn) //if LED is on
    {
      while (millis() < delayTime) //allows LED to blink with delay
      {//do nothing
      }
      digitalWrite(ledPin,LOW); //turn LED off
      lightIsOn = false; //set boolean to false
    }
    else //if LED is on
    {
      while (millis() < delayTime) //allows LED to blink with delay
      {//do nothing
      }
      digitalWrite(ledPin, HIGH); //turn LED on
      lightIsOn = true; //set boolean to true
    }
  }
  
  digitalWrite(ledPin, HIGH); //after wait period, set LED to high
  lightIsOn = true; //set LED boolean to true
  
  powerOn =true;//set power boolean to true
  digitalWrite(powerPin, LOW);//send ON signal to relay
  
  Serial.println("Fan is on.");
  while (millis() < timeOfStop) //during fan on cycle
  { 
  }
  digitalWrite(powerPin, HIGH);//send off signal to relay
  powerOn = false; //set power boolean to false
  Serial.println("Fan is off.");
  digitalWrite(ledPin,LOW); //turn LED off
  lightIsOn = false; //set boolean to false
}

The way to deal with millis is to use subtraction. This causes the roll over to procede with no effect on your code.

Example, if you have

if( (currentTime-startTime) > allowedDuration)

In the event that time has rolled over since the start time, then the subtraction of the (now higher) start time, will lead to a negative value. But since you’re using unsigned variables. it will reflect the true time difference. So everything behaves.

My delays are assuming something like millis() + 1800000. If it is right at the edge of rolling over the overflow, what does my method of adding delays do?

I have done some testing with overflow on specific code here. http://forum.arduino.cc/index.php?topic=270831.msg1909586#msg1909586

In your implementation, if you're still not feeling confident on what will happen to your variables, etc., then try a test that presets your time values to a short time before overflow so you can test the before and after results.

Thank you both for your replies. I am reading the topic you linked, dlloyd, now.

I like your solution KenF! Never would have thought of that. It being unsigned really works well.

millis ( ) overflow ... a bad thing?

[quote author=Nick Gammon link=msg=1935665 date=1414287793] millis ( ) overflow ... a bad thing? [/quote]

I found this link in the thread that dlloyd posted. Very very helpful.

Thanks!

Got everything working!

For anyone interested in the final project, I posted about it here: http://ranchhousereno.com/making-an-arduino-controlled-litter-box-fan-how-to/

I appreciate your help! Thank you!