• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Проблема с работой Serial

Собственно сабж: Решил воспользоваться решением от компании RobotDyn с Arduino 2560 + ESP8266 на борту. Получать команду по mqtt для esp, пересылать по Serial Arduino Mega, затем возвращать ESP и отправлять результ по mqtt.

Для асинхронного приема данных по Serial использовал библиотеку AsyncStream.h от Gyver
Ну и собственно что происходит - все проходит до Arduino (сделал мигание светодиодом) а вот ответа по Serial в ESP не приходит.

#ifndef AsyncStream_h
#define AsyncStream_h

template < uint16_t SIZE >
class AsyncStream {
public:
AsyncStream(Stream* port, char ter = ';', uint16_t tout = 50) {
_port = port;
_tout = tout;
_ter = ter;
}
bool available() {
if (_port -> available()) {
if (!_parseF) {
_parseF = true;
_count = 0;
_tmr = millis();
}
char ch = _port -> read();
if (ch == _ter) {
buf[_count] = '\0';
_parseF = false;
return true;
} else if (_count < SIZE - 1) buf[_count++] = ch;
_tmr = millis();
}
if (_parseF && millis() - _tmr >= _tout) {
_parseF = false;
return true;
}
return false;
}

char buf[SIZE];

private:
Stream* _port;
char _ter;
uint16_t _tout, _count = 0;
uint32_t _tmr = 0;
bool _parseF = false;
};

#endif

#include "AsyncStream.h"


char inst[45]="";

// указываем обработчик, терминатор (символ конца приёма) и таймаут в мс
// в <> указан размер буфера!
AsyncStream<100> serial(&Serial, '\n');



// =====================================================
void setup()
{
Serial.begin(115200);

pinMode(LED_BUILTIN, OUTPUT);
}


// =====================================================
void loop()
{ strcpy(inst,""); // Очищаем
if (serial.available()) { // если данные получены
digitalWrite(LED_BUILTIN, HIGH); // данные получены - включаем светодиод
strcat(inst,serial.buf); // копируем буфер в строку
strcat(inst,"-ack"); // добавляем признак ответа
delay(500); // для демонстрации
Serial.println(inst); // выводим их (как char*)
digitalWrite(LED_BUILTIN, LOW); // данные отправлены - гасим светодиод
}
}

#include <ESP8266WiFi.h>
#include <PubSubClient.h> // установить
#define debug_print 0

#include "AsyncStream.h"

// указываем обработчик, терминатор (символ конца приёма) и таймаут в мс
// в <> указан размер буфера!
AsyncStream<100> serial(&Serial, '\n');

char inst[45]="";

#define MQTT_client "MegaESP" // произвольное название MQTT клиента, иногда требуется уникальное.
// настройки домашней сети
const char *ssid = "LinetIOT"; // название точки достпа
const char *pass = ""; // Пароль от точки доступа

// настройки для MQTT брокера
const char *mqtt_server = "192.168.1.20"; // адрес сервера MQTT broker.hivemq.com
const int mqtt_port = 1883; // Порт для подключения к серверу MQTT
const char *mqtt_user = ""; // Логин от сервера MQTT
const char *mqtt_pass = ""; // Пароль от сервера MQTT
// далее топики

const char *data_topic = "/md/test/megaesp/uptime"; // топик для uptime
const char *ctrl_topic = "/md/test/megaesp/status"; // топик для Управления

int pause = 300; // переменная для паузы между отправками данных
long int times = 0; // для времени

int tme,tmr;
// char ctrltp[6];

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

// получение данных с сервера и отработка
void callback(const MQTT::publish& pub)
{
String topic = pub.topic();
#if debug_print != 0
Serial.print(topic); // выводим в сериал порт название топика
Serial.print(" => ");
#endif

String payload = pub.payload_string(); // чтение данных из топика
#if debug_print != 0
Serial.print(payload); // выводим в сериал порт значение полученных данных
Serial.println();
#endif
// действия над пином в зависимости от данных из топика
if (topic == ctrl_topic)
{
Serial.print(payload); // отправляем Mege
tmr=millis(); // "запускаем таймер"
/*
if (payload[0] == '0') digitalWrite(CtrlPin, !active);
else if (payload[0] == '1') digitalWrite(CtrlPin, active);
else if (payload[0] == '2') digitalWrite(CtrlPin, !digitalRead(CtrlPin));
if (digitalRead(CtrlPin)==active) {Status='1';} else {Status='0';}
if (payload[0] == '3') {digitalWrite(CtrlPin, !active);delay(100);digitalWrite(CtrlPin, active);} // Restart device
*/
}
// ----------------------------------------------------------------
// }
}

//-------------------------------

// Функция отправки показаний
void refreshData() {
if (pause == 0) {
times = millis(); // формируем данные для отправки
client.publish(data_topic, String(times));
if (inst=="") {client.publish(ctrl_topic, String(inst));}
// client.publish(ctrl_topic, String(inst)+String(tme));
pause = 3000; // пауза меду отправками 3 секунды
}
pause--;

delay(1);
}

// =====================================================
void setup()
{
Serial.begin(115200);
#if debug_print != 0
Serial.println();
#endif

// pinMode(CtrlPin, OUTPUT); pinMode(BtnPin, INPUT);

}


// =====================================================
void loop()
{

if (WiFi.status() != WL_CONNECTED) { // если соединения нет
#if debug_print != 0
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.println("...");
#endif
WiFi.hostname("MegaESP");
WiFi.begin(ssid, pass);// подключаемся к wi-fi

if (WiFi.waitForConnectResult() != WL_CONNECTED) // ждем окончания подключения
return;
#if debug_print != 0
Serial.println("WiFi connected");
#endif
}

// подключаемся к MQTT серверу
if (WiFi.status() == WL_CONNECTED) { // если есть подключение к wi-fi
if (!client.connected()) { // если нет подключения к серверу MQTT
#if debug_print != 0
// Serial.println("MQTT - none");
#endif
if (client.connect(MQTT::Connect(MQTT_client) // если соединились то делаем всякое
.set_auth(mqtt_user, mqtt_pass))) {
#if debug_print != 0
// Serial.println("MQTT - ok");
#endif
client.set_callback(callback);
client.subscribe(ctrl_topic); // подписка на топик led1
// client.subscribe(data_topic); // подписка на топик data

} else {
#if debug_print != 0
Serial.println("MQTT - error"); // если не удалось подключиться сообщаем в порт
#endif
}
}

if (client.connected()) { // если есть соединение с MQTT
client.loop();
refreshData();
strcpy(inst,""); // Очищаем
if (serial.available()) { // если данные получены
tme=millis()-tmr; // получаем пройденное время
strcat(inst,serial.buf); // копируем буфер в строку
strcat(inst,"-0077"); // добавляем признак ответа
}
}
}


}
p.s. Библиотека от Гайвера работает, по крайней мере на Arduino девайсах везде на ура....
 
Сверху Снизу