Помогите плиз модифицировать код

Wrongbee13
Offline
Зарегистрирован: 05.11.2014

Собственно сам код, текст следующим постом

// Встроенный 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 () {

}

 

Wrongbee13
Offline
Зарегистрирован: 05.11.2014

Привет, друзья!

За основу был взят известный код с форума по управлению реле. Добавил в него совсем немножечко. Плата 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. Полез в библиотеку и совсем запутался. Какую именно функцию и где мне нужно объявить, чтобы функция 

client.publish()

была видна код отработал? Пока выкрутился так. В переменную period заношу с брокера данные, с какой частотой выполнять отправку. Типа включение телеметрии. Тогда вместо минуты данные отправляются каждые полсекунды и я вижу сразу статус отработки реле.

Буду очень рад советам

Следующим шагом хочу попытаться функцию пингования сделать через прерывания, так как во время ее выполнения контроллер больше ничего не делает и не отправляет и не принимает данные. Это правильная мысль?