Использование millis вместо задержки перезагрузки реле
Я хочу перезагрузить реле (выключить, подождать 4 секунды и включить) он отлично работает, если я использую задержку (4000), но код блокируется во время задержки (4 секунды), и я не могу запустить реле 2. Как я могу использовать Millis вместо задержки, чтобы перезагрузить реле 1 и запустить реле 2 одновременно?
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <EthernetUdp.h> //Загружаем UDP-библиотеку
// Ethernet
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Назначаем mac адрес
IPAddress ip(192, 168, 1, 178); // Назначаем IP-адрес
unsigned int localPort = 80; // Назначаем порт для разговора
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; // размер массива символов для хранения нашего пакета данных
String datReq; //Строка для наших данных
int packetSize; //Размер пакета
EthernetUDP Udp; // Создаем объект UDP // порт сервера
String readString;
bool relayState = false;
// определяем контакты реле
int relay_1 = 22;
int relay_2 = 24;
void setup() {
Serial.begin(9600);
Ethernet.begin(mac, ip);
Udp.begin(localPort); //Инициализировать UDP
delay(2000);
//Исходное состояние реле
pinMode(relay_1, OUTPUT); digitalWrite(relay_1, LOW); // реле 1 включено
pinMode(relay_2, OUTPUT); digitalWrite(relay_2, HIGH);//реле 2 выключено
}
void loop() {
packetSize = Udp.parsePacket(); //Чтение размера пакета
if (packetSize > 0) { //если packageSize >0, значит кто-то отправил запрос
Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE); //Чтение запроса данных
String datReq(packetBuffer); // Преобразование массива символов packetBuffer в строку с именем datReq
//Serial.println(datReq);
if (datReq == "relay1reboot") { //перезагрузить реле
digitalWrite(relay_1, HIGH);//реле выключено
delay(4000);
digitalWrite(relay_1, LOW);//реле включено
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Инициализируем отправку пакета
Udp.print("relay 1 reboot");
Udp.endPacket(); //Конец пакета
}
if (datReq == "relay2on") {
digitalWrite(relay_2, LOW);//реле 2 включено
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Инициализируем отправку пакета
Udp.print("relay 2 on");
Udp.endPacket(); //Конец пакета
}
if (datReq == "relay1on") {
digitalWrite(relay_1, LOW);//реле 2 включено
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //Инициализируем отправку пакета
Udp.print("relay 1 on");
Udp.endPacket(); //Конец пакета
}
// Используйте снимок, чтобы установить время отслеживания до следующего события
//предыдущий Миллис = текущий Миллис;
}
}
//}
memset(packetBuffer, 0, UDP_TX_PACKET_MAX_SIZE); //очищаем массив packetBuffer
}
@vito, 👍0
Обсуждение1 ответ
Общий подход к удалению delay()
заключается в замене его некоторым кодом.
что:
обратите внимание, что некоторые действия (независимо от того, что следует за
delay()
) будут иметь будет выполнено в будущемпринимает к сведению текущее время.
Затем где-то еще в loop()
вы проверяете, не произошло ли это «какое-то действие».
нужно сделать прямо сейчас и, если это так, делает это.
В этом конкретном случае я бы добавил глобальную логическую переменную с именем
relay1isRebooting
. Когда это правда, это означает, что реле было
выключено и должно быть включено в ближайшем будущем.
bool relay1isRebooting = false;
unsigned long relay1rebootStarted;
void loop() {
packetSize = Udp.parsePacket();
if (packetSize > 0) { //мы получили пакет
// ...
if (datReq == "relay1reboot") {
digitalWrite(relay_1, HIGH); // реле выключено
relay1isRebooting = true;
relay1rebootStarted = millis();
}
// ...
}
// Включите обратно реле 1, если необходимо.
if (relay1isRebooting && millis() - relay1rebootStarted >= 4000) {
digitalWrite(relay_1, LOW); //реле на
relay1isRebooting = false;
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.print("relay 1 reboot");
Udp.endPacket();
}
}
Обратите внимание, что тест на предмет того, следует ли включить реле 1 в обратном направлении
on выполняется вне блока if (packetSize > 0)
. Также обратите внимание, что
relay1rebootStarted
имеет допустимое значение, только если relay1isRebooting
истина
.
для продвинутых кодеров: я обычно использую только переменную для миллисекунд. если он равен 0, таймер не работает. if (relay1rebootStarted && millis() - relay1rebootStarted >= RELAY_DELAY)
, @Juraj
@Juraj: мне не нравится такой подход. Ноль является законным возвращаемым значением для millis()
, которое возвращается каждые 49,7 дней., @Edgar Bonet
- управление 2 датчиками и 3 насосами с помощью millis
- Как инициализировать цифровой выходной контакт как LOW
- Несколько кнопок для управления реле
- Функции Delay() и millis() не работают во внешних файлах cpp
- Выходное напряжение цифрового вывода падает при управлении реле
- Ищу ссылку на двухполюсное однопозиционное реле (DPST) для Arduino.
- Вопрос новичка - Biltong Box Project
- Использование задержки 1 мс () в цикле for для проверки входных данных.. Плохо?
"перезагрузка" - это термин, относящийся к программируемым устройствам, таким как компьютеры... он не применяется к простому реле... имело бы смысл сказать "я хочу включить реле", @jsotola