user61755: I want to reboot relay (turn off , waiting 4 seconds and turn ON)
it works perfectly if I use delay(4000), but code is blocked while delay (4 seconds) and I cant start relay 2.
How can I use Millis instead of delay to reboot relay 1 and start relay 2 same time?
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <EthernetUdp.h> //Load the Udp Library

//Ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Assign mac address
IPAddress ip(192, 168, 1, 178); //Assign the IP Adress
unsigned int localPort = 80; // Assign a port to talk over
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //dimensian a char array to hold our data packet
String datReq; //String for our data
int packetSize; //Size of the packet
EthernetUDP Udp; // Create a UDP Object                            //server port
String readString;

bool relayState = false;
//define relay pins
int relay_1 = 22;
int relay_2 = 24;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  Udp.begin(localPort); //Initialize Udp
  delay(2000);

  //Initial state of the relay
  pinMode(relay_1, OUTPUT); digitalWrite(relay_1, LOW); //relay 1 is On
  pinMode(relay_2, OUTPUT); digitalWrite(relay_2, HIGH);//relay 2 is Off


}

void loop() {

  packetSize = Udp.parsePacket(); //Reads the packet size
  if (packetSize > 0) { //if packetSize is >0, that means someone has sent a request
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer); //Convert char array packetBuffer into a string called datReq
    //Serial.println(datReq);

    if (datReq == "relay1reboot") { //reboot relay
      digitalWrite(relay_1, HIGH);//relay off
      delay(4000); 
      digitalWrite(relay_1, LOW);//relay on

      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print("relay 1 reboot");
      Udp.endPacket(); //End the packet

    }
    if (datReq == "relay2on") {
      digitalWrite(relay_2, LOW);//relay 2 on
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print("relay 2 on");
      Udp.endPacket(); //End the packet
    }
    if (datReq == "relay1on") {
      digitalWrite(relay_1, LOW);//relay 2 on
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print("relay 1 on");
      Udp.endPacket(); //End the packet
    }
    // Use the snapshot to set track time until next event
    //previousMillis = currentMillis;
  }
}

//}
memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE); //clear out the packetBuffer array

}


user7508: A general approach to remove a delay() is to replace it by some code
that:

takes note that some action (whatever follows the delay()) will have
to be performed in the future

takes note of the current time.


Then, somewhere else in loop(), you check whether that “some action”
has to be done right now and, if this is the case, does it.
In this particular case, I would add a global boolean variable named
relay1isRebooting. When it is true, that means that the relay has been
turned off and will have to be turned on in the near future.
bool relay1isRebooting = false;
unsigned long relay1rebootStarted;

void loop() {
  packetSize = Udp.parsePacket();
  if (packetSize > 0) { //we have received a packet
    // ...
    if (datReq == "relay1reboot") {
      digitalWrite(relay_1, HIGH); //relay off
      relay1isRebooting = true;
      relay1rebootStarted = millis();
    }
    // ...
  }

  // Switch back the relay 1 on if needed.
  if (relay1isRebooting && millis() - relay1rebootStarted >= 4000) {
      digitalWrite(relay_1, LOW); //relay on
      relay1isRebooting = false;
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.print("relay 1 reboot");
      Udp.endPacket();
  }
}

Please note that the test for whether the relay 1 should be turned back
on is performed outside the if (packetSize > 0) block. Also note that
relay1rebootStarted has a valid value only when relay1isRebooting is
true.

61755: <p>I want to reboot relay (turn off , waiting 4 seconds and turn ON)
it works perfectly if I use delay(4000), but code is blocked while delay (4 seconds) and I cant start relay 2.
How can I use Millis instead of delay to reboot relay 1 and start relay 2 same time?</p>
<pre><code>#include &lt;SPI.h&gt;
#include &lt;Ethernet.h&gt;
#include &lt;Wire.h&gt;
#include &lt;EthernetUdp.h&gt; //Load the Udp Library

//Ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Assign mac address
IPAddress ip(192, 168, 1, 178); //Assign the IP Adress
unsigned int localPort = 80; // Assign a port to talk over
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //dimensian a char array to hold our data packet
String datReq; //String for our data
int packetSize; //Size of the packet
EthernetUDP Udp; // Create a UDP Object                            //server port
String readString;

bool relayState = false;
//define relay pins
int relay_1 = 22;
int relay_2 = 24;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  Udp.begin(localPort); //Initialize Udp
  delay(2000);

  //Initial state of the relay
  pinMode(relay_1, OUTPUT); digitalWrite(relay_1, LOW); //relay 1 is On
  pinMode(relay_2, OUTPUT); digitalWrite(relay_2, HIGH);//relay 2 is Off


}

void loop() {

  packetSize = Udp.parsePacket(); //Reads the packet size
  if (packetSize &gt; 0) { //if packetSize is &gt;0, that means someone has sent a request
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Read the data request
    String datReq(packetBuffer); //Convert char array packetBuffer into a string called datReq
    //Serial.println(datReq);

    if (datReq == &quot;relay1reboot&quot;) { //reboot relay
      digitalWrite(relay_1, HIGH);//relay off
      delay(4000); 
      digitalWrite(relay_1, LOW);//relay on

      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print(&quot;relay 1 reboot&quot;);
      Udp.endPacket(); //End the packet

    }
    if (datReq == &quot;relay2on&quot;) {
      digitalWrite(relay_2, LOW);//relay 2 on
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print(&quot;relay 2 on&quot;);
      Udp.endPacket(); //End the packet
    }
    if (datReq == &quot;relay1on&quot;) {
      digitalWrite(relay_1, LOW);//relay 2 on
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Initialize packet send
      Udp.print(&quot;relay 1 on&quot;);
      Udp.endPacket(); //End the packet
    }
    // Use the snapshot to set track time until next event
    //previousMillis = currentMillis;
  }
}

//}
memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE); //clear out the packetBuffer array

}
</code></pre>
 7508: <p>A general approach to remove a <code>delay()</code> is to replace it by some code
that:</p>
<ul>
<li><p>takes note that some action (whatever follows the <code>delay()</code>) will have
to be performed in the future</p>
</li>
<li><p>takes note of the current time.</p>
</li>
</ul>
<p>Then, somewhere else in <code>loop()</code>, you check whether that “some action”
has to be done right now and, if this is the case, does it.</p>
<p>In this particular case, I would add a global boolean variable named
<code>relay1isRebooting</code>. When it is true, that means that the relay has been
turned off and will have to be turned on in the near future.</p>
<pre class="lang-cpp prettyprint-override"><code>bool relay1isRebooting = false;
unsigned long relay1rebootStarted;

void loop() {
  packetSize = Udp.parsePacket();
  if (packetSize &gt; 0) { //we have received a packet
    // ...
    if (datReq == &quot;relay1reboot&quot;) {
      digitalWrite(relay_1, HIGH); //relay off
      relay1isRebooting = true;
      relay1rebootStarted = millis();
    }
    // ...
  }

  // Switch back the relay 1 on if needed.
  if (relay1isRebooting &amp;&amp; millis() - relay1rebootStarted &gt;= 4000) {
      digitalWrite(relay_1, LOW); //relay on
      relay1isRebooting = false;
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.print(&quot;relay 1 reboot&quot;);
      Udp.endPacket();
  }
}
</code></pre>
<p>Please note that the test for whether the relay 1 should be turned back
on is performed outside the <code>if (packetSize &gt; 0)</code> block. Also note that
<code>relay1rebootStarted</code> has a valid value only when <code>relay1isRebooting</code> is
<code>true</code>.</p>
