I am using a relay on my Arduino Uno and i want it to be on LOW for a calculated interval of time, let's say ftime=7 seconds, and after that i need it to be set as HIGH (no power through relay). My code below makes no changes to the relay state. How would that be possible? I tried to use "delay()" too (which i know that is generally a bad idea), but had no success.
unsigned int interval = ftime*1000; //ftime in ms
do
{
digitalWrite(Relay1, LOW);
}
while(timeElapsed < interval);
digitalWrite(Relay1, HIGH);
Also, if i try without:
digitalWrite(Relay1, HIGH);
relay is LOW (motor running) but it never returns to HIGH obviously.
1 Answer 1
you need to update the timeElapsed variable inside the while loop:
unsigned int interval = ftime*1000; //ftime in ms
unsigned long startTime = millis();
do
{
digitalWrite(Relay1, LOW);
timeElapsed = millis() - startTime;
}
while(timeElapsed < interval);
digitalWrite(Relay1, HIGH);
Another way is to create a state machine make startTime
a global and update the logical state (and the pin) when the time is elapsed.
unsigned long startTime;
bool relayLOW = false;
void loop(){
if(relayLOW && millis() - startTime > interval){
digitalWrite(Relay1, HIGH);
relayLOW = false;
}
if(!relayLOW){
bool closeRelay= //decide if relay needs to be triggered
if(closeRelay){
startTime = millis();
digitalWrite(Relay1, LOW);
relayLOW = true;
}
}
}
-
Made the changes but i get an error after the do/while: Soft WDT reset ctx: cont sp: 3fff0850 end: 3fff0a50 offset: 01b0 >>>stack>>> 3fff0a00: 3ffef964 3ffef458 3ffef964 40203807 3fff0a10: 0000078c 0000001c 3ffef6c0 40106bad 3fff0a20: 00000000 00000000 00000001 3ffefa24 3fff0a30: 3fffdad0 00000000 3ffefa1c 40205894 3fff0a40: feefeffe feefeffe 3ffefa30 40100a28 <<<stack<<< ΖεΦΤΖU)�ώGalinho Salonica– Galinho Salonica2018年01月27日 21:56:06 +00:00Commented Jan 27, 2018 at 21:56
-
I would be interested if it's not difficult to to show me a state machine example.Galinho Salonica– Galinho Salonica2018年01月27日 21:57:29 +00:00Commented Jan 27, 2018 at 21:57
-
The problem with this code is that it does busy waiting without reseting the watchdog. It loops the entire time until the time has elapsed, but the Arduino watchdogs bites after 5 seconds without exiting the
loop
function or executing adelay()
call (even with0
as argument). The result is that your Arduino resets after a watchdog reset.Maximilian Gerhardt– Maximilian Gerhardt2018年01月27日 22:09:12 +00:00Commented Jan 27, 2018 at 22:09 -
I believe i understand the situation. If i understand correctly, if the time was below 5 seconds, the error/reset would not occur. However, i cannot figure out how i will solve that? Any ideas?Galinho Salonica– Galinho Salonica2018年01月27日 23:24:37 +00:00Commented Jan 27, 2018 at 23:24
-
As Maximillian Gerhardt suggested you could insert a
delay(0);
into your while loop, which will reset the watchdog timerchrisl– chrisl2018年01月27日 23:39:00 +00:00Commented Jan 27, 2018 at 23:39
timeElapsed
is updated. But according to your functional description, why shouldn't it work to pullRelay1
low, wait forinterval
milliseconds, then pull it high again? Code is likedigitalWrite(Relay1, LOW); delay(interval); digitalWrite(Relay1, HIGH);
.delay()
is to be avoided because, while it is delaying, the Arduino cannot do any useful work (other than interrupts). In particular, if it has any kind of user interface, it will not respond to user input while delaying. However, if your Arduino really has nothing else to do, thendelay()
is fine, and it's the simplest solution.