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

Не работает подписка на топики

Deonis

New member
Экспериментирую с MQTT
На одной ESP программа которая публикует топики, судя по Spy-MQTT у нее это отлично получается
На вторую ESP загрузил программу которая должна выводить значения в Консоль, но судя по Spy-MQTT подключение к серверу проходит, а вот в консоль ничего не выводится, такое чувство что callback не срабатывает... Какую то "мелочь" похоже упустил...

Код:
/*
Подписка к MQTT
  подписываемся к серверу
 
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// =======================================================================
// Конфигурация устройства:
// =======================================================================

const char* ssid = "SSID";   //SSID
const char* password = "Пароль";  //Пароль

#define REPORT_INTERVAL 10 // интервал обмена WIFI

// Топики для подписи
char* hellotopic = "ESP_0"; //Топик для приветственной инициализации
char* temperature_topic = "garden/hotbed_1/temperature";  //Топик для температуры в теплице1
char* humidity_topic = "garden/hotbed_1/humidity";        //Топик для влажности в теплице1

IPAddress server(*, *, *, *); // mosquitto адрес

String clientName;  // Сбор строки информации о клиенте

WiFiClient wclient;
PubSubClient client(wclient, server, 1883); //Создание колиента MQTT


// Список возвращаемых данных
String t_hotbed_1;
String h_hotbed_1;

//подсчет времени
long previousMillis_time = 0;  // храним время последнего подключения
long interval_time = 10;     //интервал 1 час 3600000

// =======================================================================
// Функция получения данных от сервера
void callback(char* topic, byte* payload, unsigned int length)
{
  Serial.println("callback");
  //--------------------------------------------------------------------------------------
  //температура 1 теплица
  if (String(topic) == "temperature_topic")
  {
    t_hotbed_1 = "";
    for (int i = 0; i < length; i++)
    {
      t_hotbed_1 = t_hotbed_1 +(char)payload[i];
    }

    Serial.print("Температура: ");
    Serial.println(t_hotbed_1);
  } 
  //--------------------------------------------------------------------------------------
  //Влажность 1 теплица
  if (String(topic) == "humidity_topic")
  {
    h_hotbed_1 = "";
    for (int i = 0; i < length; i++)
    {
      h_hotbed_1 = h_hotbed_1 +(char)payload[i];
    }
     Serial.print("Влажность: ");
    Serial.println(h_hotbed_1);
  }
 
}//void callback

String macToStr(const uint8_t* mac)
{
  String result;
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    if (i < 5)
      result += ':';
  }
  return result;
}//String macToStr

// =======================================================================
void setup_wifi()
{
  while (WiFi.status() != WL_CONNECTED) { //Если нет подключения к WIFI
    delay(500); //Задержка 50 сек
    Serial.print(".");
  }
  Serial.println("+");
  Serial.println("WiFi connected"); // Вывод в СОМ информации о подключении к WIFI
  Serial.println("IP address: "); // Вывод в СОМ информации о полученом IP адресе
  Serial.println(WiFi.localIP());  
}// void setup_wifi

// =======================================================================
void reconnect()
{
  // подключаемся к MQTT серверу
  if (WiFi.status() == WL_CONNECTED)
  {
    if (!client.connected())
    {
    Serial.print("Connecting to ");
    Serial.print(server);   
    Serial.print(" as ");
    Serial.println(clientName); //Вывод в СОМ собранной информации о клиенте

    if (client.connect((char*) clientName.c_str())) //конектимся с брокером как клиент
  { 
    Serial.println("Connected to MQTT broker");
    
    if (client.publish(hellotopic, "hello from ESP8266"))
  {
    Serial.println("Publish ok");
    }
    else {
    Serial.println("Publish failed");
    }
 
        //подписываемся по топики
        client.subscribe(temperature_topic);
        client.loop();
        client.subscribe(humidity_topic);
        client.loop(); 
  }
  else {
    Serial.println("MQTT connect failed");
    Serial.println("Will reset and try again...");
    abort();
  }   
  }
  }
}//void reconnect

///////////////////////////////////////////////////////

void setup() {
  // Setup console
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
  WiFi.mode(WIFI_STA);        // режим клиента
  WiFi.begin(ssid, password);
  delay(10); 
  clientName += "esp8266-"; // Сбор строки информации оклиенте
  uint8_t mac[6];
  WiFi.macAddress(mac);  // Получение МАС адреса
  clientName += macToStr(mac); // Добовление МАС адреса клиента в строку о клиенте
  clientName += "-";
  clientName += String(micros() & 0xff, 16);
}//void setup

void loop() {

  if (WiFi.status() != WL_CONNECTED) //если нет подключения к вифи
  {
    setup_wifi();
  }
 
   if (!client.connected())
  {
    reconnect();                                         
  }
    client.loop();
   
//////////////////////////////////////////
  int cnt = REPORT_INTERVAL;

  while (cnt--)
    delay(1000);
Serial.println("loop");
}// void loop
 

Deonis

New member
Программа которая публикует сообщения:
Код:
/*
    esp8266 + dht22 + mqtt
    отправка на MQTT сервер информации с датчика DHT22
*/

#include "DHT.h"
#include <PubSubClient.h>
#include <ESP8266WiFi.h>

// =======================================================================
// Конфигурация устройства:
// =======================================================================
const char* ssid = "SSID";   //SSID для WiFi
const char* password = "Пароль";  //Пароль для WiFi

// описание датчика DHT
#define DHTPIN 2     // Пин для подключения датчика DHT (D4 на ESP)
#define DHTTYPE DHT22   // DHT 22

#define REPORT_INTERVAL 10 // интервал обмена WIFI

// Привязка топиков
char* hellotopic = "ESP_1"; //Топик инициализации позволяет контролировать количество подключений устройства
char* temperature_topic = "garden/hotbed_1/temperature";  //Топик для температуры в теплице1
char* humidity_topic = "garden/hotbed_1/humidity";        //Топик для влажности в теплице1

IPAddress server(*, *, *, *); // адрес сервера mosquitto

String clientName;  // Сбор строки информации о клиенте

DHT dht(DHTPIN, DHTTYPE, 15); // Инициализация датчика
WiFiClient wclient; // Создание WIFI клиента
PubSubClient client(wclient, server, 1883); //Создание колиента MQTT

float oldH ;  //Старое значение Влажности
float oldT ;  //Старое значение температуры

void setup() {
  Serial.begin(115200);
  delay(20); //Задержка

  Serial.println();
  Serial.println();
  Serial.print("Connecting to "); // вывод в СОМ к какому
  Serial.println(ssid);          // WIFI подключаемся

  WiFi.mode(WIFI_STA);        // режим клиента
  WiFi.begin(ssid, password);
  delay(10);

  while (WiFi.status() != WL_CONNECTED) { //Если нет подключения к WIFI
    delay(500); //Задержка 50 сек
    Serial.print(".");
  }
  Serial.println("+");
  Serial.println("WiFi connected"); // Вывод в СОМ информации о подключении к WIFI
  Serial.println("IP address: "); // Вывод в СОМ информации о полученом IP адресе
  Serial.println(WiFi.localIP());

  clientName += "esp8266-"; // Сбор строки информации оклиенте
  uint8_t mac[6];
  WiFi.macAddress(mac);  // Получение МАС адреса
  clientName += macToStr(mac); // Добовление МАС адреса клиента в строку о клиенте
  clientName += "-";
  clientName += String(micros() & 0xff, 16);

  Serial.print("Connecting to ");
  Serial.print(server);   
  Serial.print(" as ");
  Serial.println(clientName); //Вывод в СОМ собранной информации о клиенте

  if (client.connect((char*) clientName.c_str())) //конектимся с брокером как клиент
  { 
    Serial.println("Connected to MQTT broker");
    
    if (client.publish(hellotopic, "hello from ESP8266")) {
      Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }
    client.setCallback(callback);   
  }
  else {
    Serial.println("MQTT connect failed");
    Serial.println("Will reset and try again...");
    abort();
  }

  dht.begin(); //Инициализация датчика
  oldH = -100;
  oldT = -100;
}

void loop() {

  if (client.connected() != 1 || WiFi.status() != WL_CONNECTED)
  {
    Serial.println("Нет подключения");
    Serial.println(WiFi.status());
    reconnect_server();
  }
  else
  {
     sendToMQTT();
  }
  //////////////////////////////////////////
  int cnt = REPORT_INTERVAL;

  while (cnt--)
    delay(1000);
}// void loop


//-------------------
void sendToMQTT() {

    float h = dht.readHumidity();
    float t = dht.readTemperature();

    if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
    }
 
    Serial.print("Sending payload: "); // Вывод в ком отправляемой на MQTT информации
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C ");

    if (client.publish(humidity_topic, String(h).c_str())) {
      Serial.println("Publish Humidity ok");
    }
    else {
      Serial.println("Publish Humidity failed");
    }   
    if (client.publish(temperature_topic, String(t).c_str())) {
      Serial.println("Publish Temperature ok");
    }
    else {
      Serial.println("Publish Temperature failed");
    }
}//void sendToMQTT()

// =======================================================================
// Функция получения данных от сервера
void callback(char* topic, byte* payload, unsigned int length) {
  // handle message arrived
}



String macToStr(const uint8_t* mac)
{
  String result;
  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);
    if (i < 5)
      result += ':';
  }
  return result;
}//String macToStr

void reconnect_server()                      //функция проверки подключения
{
  Serial.println("функция проверки подключения");
  if (WiFi.status() != WL_CONNECTED)         //если нет подключения с сети
  {
    WiFi.begin(ssid, password);
    Serial.println("");
    Serial.println("WiFi connect...");       //выводим в монитор порта что пытаемся подключиться
  } else {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
    if (!client.connected() && WiFi.status() == WL_CONNECTED) //если к сети подключились но к MQTT нет
    {     
    if (client.connect((char*) clientName.c_str())) //конектимся с брокером как клиент
    {
    Serial.println("Connected to MQTT broker");
    }
    if (client.publish(hellotopic, "hello from ESP8266")) {
    Serial.println("Publish ok");
    }
    else {
      Serial.println("Publish failed");
    }

  }
}//void reconnect_server
 

Deonis

New member
Сам же и нашел ответ... нужно добавить - client.set_callback(callback); в функцию reconnect(), я добавил перед 122 строчкой.
Помимо этого видимо библиотека PubSubClient.h изменилась либо во взятом мною источнике была другая нужно изменить функцию callback :
Код:
void callback(const MQTT::Publish& pub)
{

  Serial.print(pub.topic());
  Serial.print(" => ");
  Serial.println(pub.payload_string());

 
  //--------------------------------------------------------------------------------------
  //температура 1 теплица
  if (String(pub.topic()) == "temperature_topic")
  {
    t_hotbed_1 = pub.payload_string();
  
    Serial.print("Температура: ");
    Serial.println(t_hotbed_1);
  }
  //--------------------------------------------------------------------------------------
  //Влажность 1 теплица
  if (String(pub.topic()) == "humidity_topic")
  {
    h_hotbed_1 = pub.payload_string();
 
     Serial.print("Влажность: ");
    Serial.println(h_hotbed_1);
  }
 
}//void callback
 

Deonis

New member
Не заметил сразу, кавычки убрать нужно у: "temperature_topic" и "humidity_topic" иначе фигня получается... :(
 
Сверху Снизу