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

Esp8266 и mqtt

YDen

Member
Добрый всем.
Подскажите пожалуйста. Есп 8266 в исполнении NodeMcu, с подключенным дисплеем на MAX7219 и датчиком освещенности. Есп разговаривает по mqtt с другими девайсами, в частности сервером УД majordomo. Подписок на топики - 7. Шлет сообщения на 4 топика - настроены таймеры отправки. Так же настроена удаленная прошивка по веб.
С неясной периодичностью есп теряет связь с mqtt - перестает слать\получать сообщения. Но пинг идет, прошивка "залетает". После перезагрузки модуль начинает работать нормально.
Ниже прикладываю код (строки управляющие дисплеем выпилил), может что не так закодил:
Код:
#include <WiFiUdp.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Adafruit_GFX.h>
#include <ESP8266mDNS.h>

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

const char *mqtt_server = "192.168.1.70"; // Имя сервера MQTT
const int mqtt_port = 1883; // Порт для подключения к серверу MQTT
const char *mqtt_user = "****"; // Логи от сервер
const char *mqtt_pass = "****"; // Пароль от сервера

WiFiClient wclient;
PubSubClient client(wclient);

int clouds;
float windSpeed;
float temp = 0;
String date;
String line;
String currencyRates;
String scroll_String;
String text1;

//датчик света
const int inRaw = A0; //вход датчик света
int raw = 0; //сила света
int raw_mean = 0; //сила света среднее
int raw_old = 0; //сила света

String t_out;
String t_out_delta;
String t_out_delta_sym;
String t_banya;
String t_banya_delta;
String t_banya_delta_sym;
String p_atm;
String p_atm_delta;
String p_atm_delta_sym;

boolean mqtt_light_banya = false; //флаг включения света баня

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

//raw
long previousMillis_raw = 0;  // храним время последнего подключения
long interval_raw = 300000;     //интервал

//mqtt
long previousMillis_mqtt = 0;  // храним время последнего подключения
long interval_mqtt = 10000;     //интервал

//mqtt raw
long previousMillis_mqtt_raw = 0;  // храним время последнего подключения
long interval_mqtt_raw = 300000;     //интервал

//wifi
long previousMillis_wifi = 0;  // храним время последнего подключения
long interval_wifi = 10000;     //интервал
unsigned long currentMillis_wifi = 0;

// =======================================================================
// Функция получения данных от сервера
void callback(char* topic, byte* payload, unsigned int length)
{
  //--------------------------------------------------------------------------------------
  //температура баня
  if (String(topic) == "ihouse/climat/banya/temp")
  {
    t_banya = "";
    for (int i = 0; i < length; i++) 
    {
      t_banya = t_banya +(char)payload[i];
    }
  }
  if (String(topic) == "ihouse/climat/banya/tempDelta")
  {
    t_banya_delta = "";
    for (int i = 0; i < length; i++) 
    {
      t_banya_delta = t_banya_delta +(char)payload[i];
    }
  }
 
  //--------------------------------------------------------------------------------------
  //температура улица
  if (String(topic) == "ihouse/climat/out/temp")
  {
    t_out = "";
    for (int i = 0; i < length; i++) 
    {
      t_out = t_out +(char)payload[i];
    }
  }
  if (String(topic) == "ihouse/climat/out/tempDelta")
  {
    t_out_delta = "";
    for (int i = 0; i < length; i++) 
    {
      t_out_delta = t_out_delta +(char)payload[i];
    }
  }

  //--------------------------------------------------------------------------------------
  //давление
  if (String(topic) == "ihouse/climat/out/pressAtm")
  {
    p_atm = "";
    for (int i = 0; i < length; i++) 
    {
      p_atm = p_atm +(char)payload[i];
    }
  }
  if (String(topic) == "ihouse/climat/out/pressAtmDelta")
  {
    p_atm_delta = "";
    for (int i = 0; i < length; i++) 
    {
      p_atm_delta = p_atm_delta +(char)payload[i];
    }
  }

  //--------------------------------------------------------------------------------------
  //свет баня
  if (String(topic) == "ihouse/svet/banya/in")
  {
    if ((char)payload[0] == '1') mqtt_light_banya = true;
    if ((char)payload[0] == '0') mqtt_light_banya = false; 
  }
}

// =======================================================================
void reconnect() 
{
  // подключаемся к MQTT серверу
  if (WiFi.status() == WL_CONNECTED)
  {
    if (!client.connected())
    {
      Serial.print("Attempting MQTT connection...");
      if (client.connect("informer_in",mqtt_user, mqtt_pass))
      {
        //подписываемся по топики
        client.subscribe("ihouse/climat/out/temp");
        client.loop();
        client.subscribe("ihouse/climat/out/tempDelta");
        client.loop();
        client.subscribe("ihouse/climat/banya/temp");
        client.loop();
        client.subscribe("ihouse/climat/banya/tempDelta");
        client.loop();
        client.subscribe("ihouse/svet/banya/in");
        client.loop();
        client.subscribe("ihouse/climat/out/pressAtm");
        client.loop();
        client.subscribe("ihouse/climat/out/pressAtmDelta");
        client.loop();
      }
    }     
  }
}

// =======================================================================
void setup_wifi() 
{
    if (currentMillis_wifi - previousMillis_wifi > interval_wifi)
    {
      WiFi.begin(ssid, password); //конектимся
      previousMillis_wifi = currentMillis_wifi;
    }
}

// =======================================================================
void setup()
{
  // Удаляем предыдущие конфигурации WIFI сети
  WiFi.disconnect(); // обрываем WIFI соединения
  WiFi.softAPdisconnect(); // отключаем отчку доступа(если она была
  WiFi.mode(WIFI_OFF); // отключаем WIFI
  delay(500);

  // присваиваем статичесий IP адрес
  WiFi.mode(WIFI_STA); // режим клиента
  WiFi.config(IPAddress(192, 168, 1, 71), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1));

  WiFi.begin(ssid, password);
  delay(10);

  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  pinMode(inRaw,  INPUT);

  Serial.begin(115200);                           // Дебаг

}

// =======================================================================
// Функция отправки в mqtt
void TempSend()
{
  unsigned long currentMillis_mqtt = millis();
  unsigned long currentMillis_mqtt_raw = millis();

  if (currentMillis_mqtt - previousMillis_mqtt >= interval_mqtt)
  {
    previousMillis_mqtt = currentMillis_mqtt;
    client.publish("ihouse/work/informerIn", String(random(1000)).c_str());
  }

  if (h != h_old)
  {
    client.publish("ihouse/clock/h", String(h).c_str());
    h_old = h;
  }
 
  if (m != m_old)
  {
    client.publish("ihouse/clock/m", String(m).c_str()); 
    m_old = m;
  }

  if (currentMillis_mqtt_raw - previousMillis_mqtt_raw >= interval_mqtt_raw)
  {
    previousMillis_mqtt_raw = currentMillis_mqtt_raw;
    client.publish("ihouse/raw", String(raw).c_str()); // отправляем в топик значение освещенности
  }
  delay(10);
}

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

  unsigned long currentMillis_time = millis();
  unsigned long currentMillis_raw = millis();
  unsigned long currentMillis_wifi = millis();
 
  //--------------------------------------------------------------------------------------
  if (WiFi.status() != WL_CONNECTED) //если нет подключения к вифи
  {
    setup_wifi();
  }

  //--------------------------------------------------------------------------------------
  if (!client.connected()) 
  { 
    reconnect();                                           
  }

  //--------------------------------------------------------------------------------------
  raw = analogRead(inRaw);

  //запуск синхронизации времени
  if (currentMillis_time - previousMillis_time >= interval_time)
  {
    previousMillis_time = currentMillis_time;
    getTime();
  }
   
  client.loop();
  TempSend();

}
благодарю
 
Сверху Снизу