• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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 девайсах везде на ура....
 
Сверху Снизу