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!
2 Answers 2
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.
-
2He has also an overflow in
(5 *60000)
, which should be5 * 60000UL
Edgar Bonet– Edgar Bonet2018年05月22日 19:53:42 +00:00Commented May 22, 2018 at 19:53 -
@EdgarBonet you’re right! Nicely spotted.Gerben– Gerben2018年05月22日 20:04:00 +00:00Commented May 22, 2018 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.2018年05月23日 08:25:54 +00:00Commented May 23, 2018 at 8:25
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.
-
1No clock is perfect.
millis()
long term accuracy is typically around 0.1%. An RTC should be significantly better. Whether or notmillis()
is suitable for the application has little to do with the length of the delays: it only depends on the required accuracy.Edgar Bonet– Edgar Bonet2018年05月23日 07:50:20 +00:00Commented May 23, 2018 at 7:50