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
}
1 Answer 1
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 futuretakes 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
.
-
for advanced coders: I usually use only the variable for millis. if it is 0 the timer is not running.
if (relay1rebootStarted && millis() - relay1rebootStarted >= RELAY_DELAY)
2022年08月21日 06:33:58 +00:00Commented Aug 21, 2022 at 6:33 -
1@Juraj: I dislike this approach. Zero is a legitimate return value for
millis()
, returned every 49.7 days.Edgar Bonet– Edgar Bonet2022年08月21日 20:12:45 +00:00Commented Aug 21, 2022 at 20:12
reboot
is a term that is specific to programmable devices, such as computers ... it does not apply to a simple relay ... it would make sense to sayI want to cycle a relay