Приём данных с MQTT сервера внутри цикла
- Войдите на сайт для отправки комментариев
Всем привет! Я занимаюсь ардуино и сделал много самых разных проектов. Недавно я начал делать "умный увлажнитель" на плате ESP8266, управляемый со смартфона по MQTT серверу. Я написал скетч который принимает данные MQTT сервера и когда плате ESP8266 приходит сообщение, то на 10 секунд включается светодиод. PS: я оставил только ту часть кода которая принимает сообщения с MQTT сервера. Если вам нужен полный код, то вот ссылка: https://drive.google.com/open?id=1iL7dp8FgjUuLZasjQ9RBiqLuJKXOTGrF
void callback(const MQTT::Publish& pub) {
String payload = pub.payload_string();
if (String(pub.topic()) == "wetting") {
Serial.print("Название Топика: ");
Serial.print(String(pub.topic()));
Serial.print(" >>> ");
Serial.println(payload.toInt());
if (payload.toInt() == 1) {
digitalWrite(D2, HIGH);
int i = 0;
while (i <= 10000 && payload.toInt() == 1) {
i ++;
callback(MQTT::Publish);
payload = pub.payload_string();
Serial.print("wetting: ");
Serial.print(payload.toInt());
Serial.print(" ");
Serial.println(i);
delay(1);
}
digitalWrite(D2, LOW);
}
if (payload.toInt() == 0) {
digitalWrite(D2, LOW);
}
}
}
У меня возникла одна проблема: когда я отправляю плате ESP8266 сообщение на MQTT сервер, то светодиод включается на 10 секунд. Но мне нужно сделать так, чтобы я мог прервать эту задержку отправив плате ESP8266 другое сообщение. Подскажите как вызвать функцию приёма сообщений внутри цикла while, с помощью которого осуществляется задержка.
что-то вы несусветное наворотили в коде. Во-первых. у вас цико while будет работать не 10 секунд, а 10 тыс раз, что совсем не одно и тоже. Во-вторых, все эти разы вы будете выводить в терминал слово "wetting" и прочие сообщения - зачем это делать 10 тыс раз?
ну и главное, все это у вас код функции callback() - и вы внутри этой функции снова вызываете ее же (14 строка) ? - это верный способ завесить программу. тем более если это сделать 10 тыс раз
Отсчитывание временных интервалов делается на функции миллис. а не на многократном верчении циклов
Самый умный увлажнитель описан вот здесь. Увлажняет именно то, что надо за милую душу. Всё остальное - так, поделки.
Спасибо, что подсказали! Я не заметил у себя в коде ошибку. Но вопрос остаётся, даже если осуществлять задержку с помощью "millis", то как тогда в это время проверять не пришли ли плате ESP8266 новые сообщения.
даже если осуществлять задержку с помощью "millis", то как тогда в это время проверять не пришли ли плате ESP8266 новые сообщения.
Неверно. С помощью millis задержку осуществлять не нужно. Этим millis и отличается от delay.
unsigned long wetting_timer = 0 ; void callback(const MQTT::Publish& pub) { String payload = pub.payload_string(); if (String(pub.topic()) == "wetting") { Serial.print("Название Топика: "); Serial.print(String(pub.topic())); Serial.print(" >>> "); Serial.println(payload.toInt()); if (payload.toInt() == 1) { digitalWrite(D2, HIGH); wetting_timer = millis() ; } else { digitalWrite(D2, LOW); } } } } void wetting_timer_chk(){ if (payload.toInt() == 1) if ( (millis() - wettind_timer) > 10000){ digitalWrite(D2, LOW); } }Типа такого можно попробовать и гденибудь в loop() ... wetting_timer_chk()
От. копипасте до чего доводит )) ошибочка
void wetting_timer_chk(){ if (payload.toInt() == 1) // заменить на void wetting_timer_chk(){ if (Digitalread(D2) == 1)void callback(const MQTT::Publish& pub) { String payload = pub.payload_string(); if (String(pub.topic()) == "wetting") { Serial.print("Название Топика: "); Serial.print(String(pub.topic())); Serial.print(" >>> "); Serial.println(payload.toInt()); if (payload.toInt() == 1) { digitalWrite(D2, HIGH); wetting_timer = millis() ; } else { digitalWrite(D2, LOW); } } } } void wetting_timer_chk(){ if (digitalRead(D2) == 1) { if ( (millis() - wettind_timer) > 10000){ digitalWrite(D2, LOW); } } }Типа такого можно попробовать и где нибудь в loop() ... wetting_timer_chk()
Спасибо! Сейчас проверю.