Помогите плиз модифицировать код
- Войдите на сайт для отправки комментариев
Пт, 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 мин. Поэтому хочется логику изменить так. Пришли данные с брокера на включение реле.
088 else if (String(pub.topic()) == "Apex/Led/Kir") 089 { 090 int data = payload.toInt(); // преобразуем полученные данные в тип integer 091 Serial.println("Принят Led");И сразу же за включением реле нужно отправить подтверждающие данные на брокер.
206 client.publish("Apex/Led/Kir", String(upravlenie)); // отправляем в топик статус релеКод, естественно не срабатывает, так как функция вне видимости.
На чем застрял. Я никак не разберусь с callback. Полез в библиотеку и совсем запутался. Какую именно функцию и где мне нужно объявить, чтобы функция
была видна код отработал? Пока выкрутился так. В переменную period заношу с брокера данные, с какой частотой выполнять отправку. Типа включение телеметрии. Тогда вместо минуты данные отправляются каждые полсекунды и я вижу сразу статус отработки реле.
Буду очень рад советам
Следующим шагом хочу попытаться функцию пингования сделать через прерывания, так как во время ее выполнения контроллер больше ничего не делает и не отправляет и не принимает данные. Это правильная мысль?