Помогите плиз модифицировать код
- Войдите на сайт для отправки комментариев
Пт, 24/04/2020 - 13:06
Собственно сам код, текст следующим постом
// Встроенный D0 //Прошивочный D4 //D8 Реле //Питание компа D2 Включаются LOW #include <ESP8266WiFi.h> #include <PubSubClient.h> #include <ESP8266Ping.h> int pingS = 0; // отправляем результат пинга int pingR = 0; // принимаем запрос на пинг unsigned long timing1; // Переменная для хранения точки отсчета int period1 = 10000; // Переменная для хранения периода отправки показаний на сервер const IPAddress remote_ip(192, 168, 1, 21); const char *ssid = "Murr"; // Имя вайфай точки доступа const char *pass = "Diana2006"; // Пароль от точки доступа const char *mqtt_server = "m11.cloudmqtt.com"; // Имя сервера MQTT const int mqtt_port = 13966; // Порт для подключения к серверу MQTT const char *mqtt_user = "11111"; // Логи от сервер const char *mqtt_pass = "11111"; // Пароль от сервера void setup() { Serial.begin(115200); delay(10); Serial.println(); Serial.println(); pinMode(D0, OUTPUT); pinMode(D4, OUTPUT); pinMode(D8, OUTPUT); digitalWrite(D0, LOW); digitalWrite(D4, LOW); } #define BUFFER_SIZE 100 bool LedState = false; // Функция получения данных от сервера void callback(const MQTT::Publish& pub) { String payload = pub.payload_string(); // вспышка диода Vspishkarecive (); if (String(pub.topic()) == "Apex/Relay/Kir") // проверяем из нужного ли нам топика пришли данные { int data = payload.toInt(); // преобразуем полученные данные в тип integer digitalWrite(D8, data); // Включаем реле Serial.println("Принят Relay"); pingS = 0; // выключаем на виджете результат пинга delay (100); } else if (String(pub.topic()) == "Apex/Powerstatus/Kir") { int data = payload.toInt(); // преобразуем полученные данные в тип integer Serial.println("Принят Powerstatus"); } else if (String(pub.topic()) == "Apex/Led/Kir") { int data = payload.toInt(); // преобразуем полученные данные в тип integer Serial.println("Принят Led"); } else if (String(pub.topic()) == "Apex/Time/Kir") { int data = payload.toInt(); // преобразуем полученные данные в тип integer period1 = data; Serial.println(period1); } else if (String(pub.topic()) == "Apex/pingR/Kir") { int data = payload.toInt(); // преобразуем полученные данные в тип integer Serial.println(data); Serial.println("Пингуем"); if (Ping.ping(remote_ip)) { Serial.println("Success!!"); pingS = 1; } else { Serial.println("Error :("); pingS = 0; } Serial.println("Принят Ping"); } } WiFiClient wclient; PubSubClient client(wclient, mqtt_server, mqtt_port); void loop() { // подключаемся к wi-fi if (WiFi.status() != WL_CONNECTED) { digitalWrite(D0, LOW); //пока выйфай нет Serial.print("Connecting to "); Serial.print(ssid); Serial.println("..."); WiFi.begin(ssid, pass); if (WiFi.waitForConnectResult() != WL_CONNECTED) return; Serial.println("WiFi connected"); digitalWrite(D0, HIGH); // Есть файфай } // подключаемся к MQTT серверу if (WiFi.status() == WL_CONNECTED) { if (!client.connected()) { Serial.println("Connecting to MQTT server"); if (client.connect(MQTT::Connect("ApexKir_146254") .set_auth(mqtt_user, mqtt_pass))) { Serial.println("Connected to MQTT server"); client.set_callback(callback); digitalWrite(D4, HIGH); // MQTT подключен // Подписываемся на топики client.subscribe("Apex/Relay/Kir"); client.subscribe("Apex/Led/Kir"); client.subscribe("Apex/Time/Kir"); client.subscribe("Apex/Powerstatus/Kir"); client.subscribe("Apex/Period/Kir"); client.subscribe("Apex/pingS/Kir"); client.subscribe("Apex/pingR/Kir"); } else { Serial.println("Could not connect to MQTT server"); delay (500); digitalWrite(D4, LOW); } } if (client.connected()) { client.loop(); // Считываем статус реле и статус питания int upravlenie = digitalRead(D8); // Считываем управляющее напряжение с реле int pitanie = digitalRead(D2); if (millis() - timing1 > period1) { timing1 = millis(); // Отправляем на сервер с интервалом Vspishkasent (); client.publish("Apex/Led/Kir", String(upravlenie)); // отправляем в топик статус реле client.publish("Apex/Period/Kir", String(period1)); // отправляем в топик частоту опроса client.publish("Apex/Powerstatus/Kir", String(pitanie)); // отправляем в топик статус питания client.publish("Apex/pingS/Kir", String(pingS)); // отправляем в топик результат пинга Serial.println(period1); Serial.println(pingS); } // Продолжение кода } } } // конец основного цикла void Vspishkasent () { int temp = digitalRead (D0); //сохраняем состояние светодиода digitalWrite(D0, HIGH); delay(100); digitalWrite(D0, LOW); delay(10); digitalWrite(D0, HIGH); delay(10); digitalWrite(D0, temp); //восстанавливаем состояние состояние светодиода } void Vspishkarecive () { int temp = digitalRead (D4); //сохраняем состояние светодиода digitalWrite(D4, HIGH); delay(100); digitalWrite(D4, LOW); delay(10); digitalWrite(D4, HIGH); delay(10); digitalWrite(D4, temp); //восстанавливаем состояние состояние светодиода } void Test () { }
Привет, друзья!
За основу был взят известный код с форума по управлению реле. Добавил в него совсем немножечко. Плата ESP8266. Это удаленное отключение и включение удаленного компьютера.
- Один светодиод дает вспышку при отправке на брокер, второй при приеме.
- В топик отправляются данные о наличии питания на компе (берется через делитель с разъема харда), чтобы знать запущен комп или нет.
- Добавил пингование компа.
Очень прошу помочь немного изменить код. В данном устройстве нет необходимости часто отсылать данные. Достаточно 1 раз в 10 мин. Поэтому хочется логику изменить так. Пришли данные с брокера на включение реле.
И сразу же за включением реле нужно отправить подтверждающие данные на брокер.
Код, естественно не срабатывает, так как функция вне видимости.
На чем застрял. Я никак не разберусь с callback. Полез в библиотеку и совсем запутался. Какую именно функцию и где мне нужно объявить, чтобы функция
была видна код отработал? Пока выкрутился так. В переменную period заношу с брокера данные, с какой частотой выполнять отправку. Типа включение телеметрии. Тогда вместо минуты данные отправляются каждые полсекунды и я вижу сразу статус отработки реле.
Буду очень рад советам
Следующим шагом хочу попытаться функцию пингования сделать через прерывания, так как во время ее выполнения контроллер больше ничего не делает и не отправляет и не принимает данные. Это правильная мысль?