1

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.

2
  • You don't show us how timeElapsed is updated. But according to your functional description, why shouldn't it work to pull Relay1 low, wait for interval milliseconds, then pull it high again? Code is like digitalWrite(Relay1, LOW); delay(interval); digitalWrite(Relay1, HIGH);. Jan 27, 2018 at 21:31
  • 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, then delay() is fine, and it's the simplest solution. Jan 28, 2018 at 11:30

1 Answer 1

2

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;
        }
    }
}
9
  • 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)�ώ Jan 27, 2018 at 21:56
  • I would be interested if it's not difficult to to show me a state machine example. 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 a delay() call (even with 0 as argument). The result is that your Arduino resets after a watchdog reset. 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? 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 timer
    – chrisl
    Jan 27, 2018 at 23:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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