0

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 == &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

}

vito
  • 101
  • 3

1 Answers1

2

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.

Edgar Bonet
  • 45,094
  • 4
  • 42
  • 81