1

I have 3 components: a relay and two LEDs...I want two timers using Arduino... In timer one, relay should be off on; one LED is off; and other is on...In second timer, relay is off; one led is on; other is off... This is my Code:

//const unsigned long onTime = (2 *3600000); // 2 Hours in miliseconds;
const unsigned long onTime = (3 *1000); // 3 seconds;
//const unsigned long onTime = (5 *60000); // 15 minutes;

//const unsigned long offTime = (0.5 *3600000); // 1/2 Hours in miliseconds;
const unsigned long offTime = (2 *1000); // 1 seconds;
//const unsigned long offTime = (5 *60000); // 5 minutes;

const unsigned long start_delay = (5 *60000);  // 5 minute in miliseconds

// Tracks the last time event fired
unsigned long previousMillis=0;

// Interval is how long we wait
int interval = onTime;

// Used to track if relay should be on or off
boolean relayState = true;

void setup() 
{
  pinMode(13, OUTPUT); //Relay
  pinMode(3, OUTPUT); //LED Green for ON
  pinMode(4, OUTPUT); //LED Red for OFF

  digitalWrite(13, LOW);   // Relay Off
  digitalWrite(3, LOW);    // Green LED off 
  digitalWrite(4, LOW);    // Red LED OFF

  //delay (start_delay);  // wait for 5 minute
}
void loop() 
{
  if (relayState == true)
  {
    // Relay ON
    digitalWrite(13, HIGH);   // Relay ON
    digitalWrite(3, HIGH);    // Green LED ON 
    digitalWrite(4, LOW);    // Red LED OFF
  }
  if (relayState == false)
  {
    // Relay OFF
    digitalWrite(13, LOW);   // Relay Off
    digitalWrite(3, LOW);    // Green LED Off 
    digitalWrite(4, HIGH);    // Red LED On
  }

  // Grab snapshot of current time, this keeps all timing
  long currentMillis = millis();

  // Compare to previous capture to see if enough time has passed
  if ((unsigned long)(currentMillis - previousMillis) >= interval)
  {
    // Change wait interval, based on current relay state
    if (relayState) 
    {
      // Relay is currently on, set time to stay off
      interval = offTime;
    } 
    else 
    {
      // Relay is currently off, set time to stay on
      interval = onTime;
    }
    // Toggle the relay's state
    relayState = !(relayState);
    // Save the current time to compare "later"
    previousMillis = currentMillis;
  }
}

Now issue is; when I make timer for seconds like OnTime is 3 second and offTime is 1 second... It works perfect... But timer for hours or minutes does not simply works... it does not switch state from on to off... It constantly remains on... What could be the problem... Thanks!

4

You declare interval as an integer, while onTime and offTime are unsigned long.

Change int interval = onTime; to unsigned long interval = onTime;

The maximum value of int is only 32767 (215-1), which is only 33 seconds.

An unsigned long can be as high as 4294967296 (232-1). Which is around 49.7 days worth of milliseconds.

  • 2
    He has also an overflow in (5 *60000), which should be 5 * 60000UL – Edgar Bonet May 22 '18 at 19:53
  • @EdgarBonet you’re right! Nicely spotted. – Gerben May 22 '18 at 20:04
  • Just to point out: On PCs and Macs it is very likely that an int is 32 if not 64 bits. You have been surprised by the fact that it is only 16 bits on this platform. – Nick Gammon May 23 '18 at 8:25
0

You should not depend on millis() function for long time delays, use an extra rtc chip(DS3231/DS1307) instead.

Theoretically millis() function should produce 1 millisecond time frame, but it is not exactly that. There will always be a difference; and if you multiply that small time difference with a big number, then there will be a significant delay.

  • 1
    No clock is perfect. millis() long term accuracy is typically around 0.1%. An RTC should be significantly better. Whether or not millis() is suitable for the application has little to do with the length of the delays: it only depends on the required accuracy. – Edgar Bonet May 23 '18 at 7:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.