ESP8266 MQTT
- Войдите на сайт для отправки комментариев
Ср, 06/01/2021 - 00:46
Принимаю данные по 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);
}
}
А код привести нормально - никак?
Например, где, когда и как описана переменная "intData"?
Без нормального кода здесь будет только глум и Ваши обиды на форум и мир.
#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); }Что то мне подсказывает , в случае приема более 20 байт непрерывно то МК легко перезагрузиться может. Пройдитесь по всем строкам своего кода и попытайтесь понять каждый ход процессора, тогда и придёт понимание.
В строке №80 поставьте заодно и печать ind - узнаете много интересного. Обратите внимание, чему она равна перед перезагрузкой и какое отношение её размер имеет в размеру массива intData.
ну да что-то с размером массива промахнулся занизил его мне постоянно приходят 8 байт.
дело не только и не столько в этом. Поставите 8 или 10 - не поможет. Сделайте то, что я сказал - вставьте печать и понаблюдайте.