ESP8266 MQTT

kingoff
Offline
Зарегистрирован: 06.01.2021

Принимаю данные по MQTT всегда фиксированной длинный 8 значений и передаю по UART в формате байта. 

можно код как-то упростить , а то через какое то время перезагружается ESP

void callback(const MQTT::Publish& pub)//Прерывание после приема по MQTT
{
  char tp[4] = {0}; //Байтовый буффер
  char charBufVar1[50];
  String payload;
  unsigned char leng_pay = 0;
  String string_convert = "";
  unsigned int top = 0;
  char ind = 0;
  String topic;

   topic = pub.topic(); //Принимаем тему сообщения из MQTT и пишем в строку
  top = topic.toInt();//Преобразуем топик в число

    payload = pub.payload_string();//Пишем сообщение в переменную
    payload = payload + " ";//Добавляем в конце пробел
    leng_pay = payload.length() + 1; //Подсчитываем кол-во символов в строке
    payload.toCharArray(charBufVar1, leng_pay);//Преобразуем строку в массив

    for (char i = 0; i < leng_pay; i++)//Парсируем массив
    {
      if (charBufVar1[i] != 0x20) // если это не пробел
      {
        string_convert += charBufVar1[i];       // складываем в строку
      }
      else                                   // если это пробел
      {
        intData[ind] = string_convert.toInt();  // преобразуем строку в int и кладём в массив
        string_convert = "";                  // очищаем строку
        ind++;                              // переходим к парсингу следующего элемента массива
      }

    }   
    
    if(ind==8) 
   {
    Serial.write(top);//Передаем байт топика
      for (char i = 0; i < ind; i++)
      {
      Serial.write(intData[i]);//Передаем байты сообщения
      }  
delay(30);
  }
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А код привести нормально - никак?

Например, где, когда и как описана переменная "intData"?

Без нормального кода здесь будет только глум и Ваши обиды на форум и мир.

kingoff
Offline
Зарегистрирован: 06.01.2021
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define DEBUG
const char *ssid = "ASUS_F8";   // cannot be longer than 32 characters!
const char *pass = "12345678";  //
const char *mqtt_user = "tyiygfr";
const char *mqtt_pass = "123456";
const char *mqtt_server =  "mqtt.dealgate.ru";  // Имя сервера MQTT
const int mqtt_port = 1883; // Порт для подключения к серверу MQTT

WiFiClient wclient;
PubSubClient client(wclient, mqtt_server, mqtt_port);

char data[20];
unsigned char i = 0;
String top_save = "255"; //Топик в котором содержатся топики на которые подписываться


int intData[5];     // массив численных значений после парсинга
boolean recievedFlag;
boolean getStarted;
unsigned int top = 0;
char ind = 0;
String topic;

void subs(String s)//Функция подписывания на топики
{
  char a[100];//Байтовый буффер
  s.toCharArray(a, s.length());//Переводим из строки в байты
  String b;
  char *str;
  char *p = a;
  while ((str = strtok_r(p, ",", &p)) != NULL) //Переводим байт в строку до символа запятая
  {
    client.subscribe(str);//Подписываемся на топики
  }
}
void callback(const MQTT::Publish& pub)//Прерывание после приема по MQTT
{
  char tp[4] = {0}; //Байтовый буффер
  char charBufVar1[50];
  String payload;
  unsigned char leng_pay = 0;
  String string_convert = "";


  topic = pub.topic(); //Принимаем тему сообщения из MQTT и пишем в строку

  if (top_save.equals(topic)) //Если топик равен 255
  {
#ifdef DEBUG
    Serial.print(topic);
    Serial.print(":");
#endif
    subs(pub.payload_string() + " "); //Передаем список топиков на подписывание

  }
  else//Если принято обычное сообщение
  {
    top = topic.toInt();//Преобразуем топик в число

    payload = pub.payload_string();//Пишем сообщение в переменную
    payload = payload + " ";//Добавляем в конце пробел
    leng_pay = payload.length() + 1; //Подсчитываем кол-во символов в строке
#ifdef DEBUG
    Serial.print("leng_pay-");
    Serial.println(leng_pay);
#endif
    payload.toCharArray(charBufVar1, leng_pay);//Преобразуем строку в массив
    for (char i = 0; i < leng_pay; i++)
    {
      if (charBufVar1[i] != 0x20) // если это не пробел
      {
        string_convert += charBufVar1[i];       // складываем в строку
      }
      else                                   // если это пробел
      {
#ifdef DEBUG
        Serial.println(string_convert);
#endif
        intData[ind] = string_convert.toInt();  // преобразуем строку в int и кладём в массив
        string_convert = "";                  // очищаем строку
        ind++;                              // переходим к парсингу следующего элемента массива
      }

    }

    recievedFlag = true;
#ifdef DEBUG
    Serial.print(topic);
#endif
  }

}
void setup() {
  pinMode(2, OUTPUT); //Передача данных
  pinMode(4, INPUT); //Разрешение передачи
  pinMode(5, INPUT); //Прием данных
  pinMode(14, INPUT);

  Serial.begin(9600);
  delay(10);
  client.set_callback(callback);
}
void loop()
{
  if (WiFi.status() != WL_CONNECTED)
  {
#ifdef DEBUG
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
#endif
    WiFi.begin(ssid, pass);
    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
#ifdef DEBUG
    Serial.println("WiFi connected");
#endif
  }
  if (WiFi.status() == WL_CONNECTED)
  {
    if (!client.connected())
    {
#ifdef DEBUG
      Serial.println("MQTT_Connected");
#endif
      if ( client.connect(MQTT::Connect("ESP_Witty").set_auth(mqtt_user, mqtt_pass)) )
      {
        client.subscribe("255");//Подписываемся по умолчанию
        client.publish("Gateway", "Start"); //Передаем запрос на получение списка топиков
      }
    }
    if (client.connected())
      client.loop();
  }

  if (Serial.available() > 0)//Если в UART есть принятые символы
  {
    data[i++] = Serial.read(); //Переносим принятые символы в буффер
  }
  else
  {
    if (i == 9) //Если приняли 9 байт
    {
      char MQ_ID[5];
      char MQ_DAT[20];
      sprintf(MQ_ID, "%d", data[0]);
      sprintf(MQ_DAT, "%d,%d,%d,%d,%d,%d,%d,%d", data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]);
      client.publish(MQ_ID, MQ_DAT); //Публикуем в MQTT
      i = 0;
    }
  }
  if (recievedFlag)
  {
    digitalWrite(2, HIGH);
    recievedFlag = false;
    Serial.write(top);//Передаем байт топика
    for (char i = 0; i < ind; i++)
    {
      Serial.write(intData[i]);//Передаем байты сообщения
    }
#ifdef DEBUG
    Serial.print(topic);
#endif
    delay(30);
    digitalWrite(2, LOW);
  }
  delay(1);
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Что то мне подсказывает , в случае приема более 20 байт непрерывно то МК легко перезагрузиться может. Пройдитесь по всем строкам своего кода и попытайтесь понять каждый ход процессора, тогда и придёт понимание.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В строке №80 поставьте заодно и печать ind - узнаете много интересного. Обратите внимание, чему она равна перед перезагрузкой и какое отношение её размер имеет в размеру массива intData.

kingoff
Offline
Зарегистрирован: 06.01.2021

ну да что-то с размером массива промахнулся занизил его мне постоянно приходят 8 байт. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

дело не только и не столько в этом. Поставите 8 или 10 - не поможет. Сделайте то, что я сказал - вставьте печать и понаблюдайте.