Esp8266 12E + MQTT проблема с подпиской на топики

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Ответить
ZyaK
Сообщения: 407
Зарегистрирован: Вт окт 24, 2017 2:01 pm
Откуда: Ижевск
Благодарил (а): 45 раз
Поблагодарили: 69 раз

Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение ZyaK » Пт ноя 24, 2017 1:19 pm

Встала задача рулить через esp 8-ю релюхами, остальные gpio будут задействованы под кнопки и пару термодатчиков, потому надо экономить ноги, решил делать на сдвиговом регистре 74hc 595
нашел скетч по MQTT, начал допиливать под себя.
и вроде все ничего, но как только количество топиков подписки переваливает за 5 штук - к MQTT мы не можем законектиться
железо нажатие на кнопку отрабатывает, в монитор порта пишет попытка подключения к MQTT
стоит закоментировать client.subscribe(relays_topic6);
и все работает как часы
Ткните пожалуйста носом что не так я делаю?

Код: Выделить всё

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
const char* ssid = "MikroTik"; //Название сети
const char* password = "csn941601";           //пароль
const char* mqtt_server = "192.168.1.216";    //ip брокера mqtt
#define RELAY_1 2                            //Выход на реле или светодиод
#define BUTTON_1 5                           //Кнопка
#define relays_topic1 "ESP01/r_1"
#define relays_topic2 "ESP01/r_2"
#define relays_topic3 "ESP01/r_3"
#define relays_topic4 "ESP01/r_4"
#define relays_topic5 "ESP01/r_5"
#define relays_topic6 "ESP01/r_6"
 
WiFiClient espClient;                        //инициализация WiFi клиента
PubSubClient client(espClient);              //инициализация MQTT клиента
 
long last_mls = millis();                    //функция времени в милисекундах
long last_mls2 = millis();
 
boolean Status1 = true;                       //объявляем статус реле в 0
boolean btnPress1 = false;                    //объявляем что кнопка не нажата 0
boolean lastbtnStat1 = false;                 //временная переменная для хранения статуса
boolean Status2 = true;
boolean Status3 = true;
boolean Status4 = true;
boolean Status5 = true;
boolean Status6 = true;
 
int regim1 = 0;                               //режим по умолчанию при включении
int regim2 = 0;
int regim3 = 0;
int regim4 = 0;
int regim5 = 0;
int regim6 = 0;
 
void setup(){
  pinMode(RELAY_1, OUTPUT);                  //Выход на реле или светодиод
  pinMode(BUTTON_1, INPUT);                  //Кнопка
  digitalWrite(RELAY_1, Status1);             //устанавливаем на выходе статус реле
 
  Serial.begin(115200);
  WiFi.begin(ssid, password);                //подключаемся к WiFi
  delay(5000);
  client.setServer(mqtt_server, 1883);       //подключаемся к MQTT
  client.setCallback(callback);              //функция получения топиков с брокера
  delay(100);
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
 
  client.connect("ESP01Client");             //конектимся с брокером как клиент
  delay(100);
  client.subscribe(relays_topic1);            //подписываемся на топик
  client.subscribe(relays_topic2);            //подписываемся на топик
  client.subscribe(relays_topic3);            //подписываемся на топик
  client.subscribe(relays_topic4);            //подписываемся на топик
  client.subscribe(relays_topic5);            //подписываемся на топик
  client.subscribe(relays_topic6);
 
}
 
void callback(char* topic, uint8_t* payload, unsigned int length){
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("  ");
  String strTopic = String(topic);
  String strPayload = String((char*)payload);
  for (unsigned int i = 0; i < length; i++) {
  Serial.print((char)payload[i]);
  }
  Serial.println();
  if (strTopic == "ESP01/r_1") {
    if ((char)payload[0] == '0') {
      Status1 = true;
      regim1 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status1 = false;
      regim1 = 1;
    }
 
  if (strTopic == "ESP01/r_2") {
    if ((char)payload[0] == '0') {
      Status2 = false;
      regim2 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status2 = true;
      regim2 = 1;
    }
  }
  if (strTopic == "ESP01/r_3") {
    if ((char)payload[0] == '0') {
      Status3 = false;
      regim1 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status3 = true;
      regim1 = 1;
    }
  }
  if (strTopic == "ESP01/r_4") {
    if ((char)payload[0] == '0') {
      Status4 = false;
      regim1 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status4 = true;
      regim1 = 1;
    }
  }
  if (strTopic == "ESP01/r_5") {
    if ((char)payload[0] == '0') {
      Status5 = false;
      regim1 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status5 = true;
      regim1 = 1;
    }
  }
  if (strTopic == "ESP01/r_6") {
    if ((char)payload[0] == '0') {
      Status6 = false;
      regim1 = 0;
    }
    else if ((char)payload[0] == '1') {
      Status6 = true;
      regim1 = 1;
    }
  }
}
}
 
void button1()
{
  btnPress1 = digitalRead(BUTTON_1);
  Status1 = digitalRead(RELAY_1);
  if (btnPress1 == LOW && lastbtnStat1 == false)
  {
    delay(5); // защита от дребезга
    regim1++;
    lastbtnStat1 = true;
    if (regim1 > 1)
    {
      regim1 = 0;
    }
  }
  if (btnPress1 == HIGH && lastbtnStat1 == true)
  {
    lastbtnStat1 = false;
  }
 
  if (regim1 == 0)
  {
    Status1 = true;
    digitalWrite(RELAY_1, Status1);
  }
  if (regim1 == 1)
  {
    Status1 = false;
    digitalWrite(RELAY_1, Status1);
  }
}
 
void MQTT()                                   //публикуем топик с состоянием режима
{
  if (millis() - last_mls2 > 3000)            //периодичность публикации топика
  { last_mls2 = millis();
    client.publish(relays_topic1, String(regim1).c_str());
    client.publish(relays_topic2, String(regim2).c_str());
    client.publish(relays_topic3, String(regim1).c_str());
    client.publish(relays_topic4, String(regim1).c_str());
    client.publish(relays_topic5, String(regim1).c_str());
    client.publish(relays_topic6, String(regim1).c_str());
    Serial.println("Отправка данных MQTT");
   }
}
void reconnect_server()                      //функция проверки подключения
{
  if (WiFi.status() != WL_CONNECTED)         //если нет подключения с сети
  {
    WiFi.begin(ssid, password);
    Serial.println("");
    Serial.println("WiFi попытка подключения reconnect");       //выводим в монитор порта что пытаемся подключиться
  } else {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
  if (!client.connected() &&  WiFi.status() == WL_CONNECTED  ) { //если к сети подключились но к MQTT нет
     client.connect("ESP01Client");             //конектимся с брокером как клиент
     delay(100);
     client.subscribe(relays_topic1);            //подписываемся на топик
     client.subscribe(relays_topic2);            //подписываемся на топик
     client.subscribe(relays_topic3);            //подписываемся на топик
     client.subscribe(relays_topic4);
     client.subscribe(relays_topic5);
     client.subscribe(relays_topic6);
     Serial.println("Mosquitto попытка подключения"); //выводим в монитор порта что пытаемся подключиться
  }
}
void loop()
{
  client.loop();
  MQTT();
  button1();
  //button2();
  //button3();
  //delay(200);
  if (millis() - last_mls > 15000)     //проверка подключений раз в 60 сек
  {
   last_mls = millis();
   reconnect_server();
   
  }
 
} 
PI2 + MQTT + 5 ESP8266 + Atmega16
Аватара пользователя
nick7zmail
Сообщения: 7573
Зарегистрирован: Пн окт 28, 2013 8:14 am
Откуда: Екатеринбург
Благодарил (а): 121 раз
Поблагодарили: 2010 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение nick7zmail » Пт ноя 24, 2017 1:25 pm

А нельзя подписать на 1 топик, типа relays_control, и туда высылать сообщения типа номер_реле:статус_реле например?
Raspberry Pi3+Broadlink+esp8266 (blynk)+AMS
Если вам помогло какое-либо сообщение - не забывайте пользоваться кнопкой "СПАСИБО".
:arrow: Услуги в профиле коннект
>>>>>Мой новый канал на ютутбе, подписывайтесь!<<<<<
ZyaK
Сообщения: 407
Зарегистрирован: Вт окт 24, 2017 2:01 pm
Откуда: Ижевск
Благодарил (а): 45 раз
Поблагодарили: 69 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение ZyaK » Сб ноя 25, 2017 10:37 am

nick7zmail писал(а):А нельзя подписать на 1 топик, типа relays_control, и туда высылать сообщения типа номер_реле:статус_реле например?
интересно, надо попробовать будет, на базе ESP то я это сделаю, а вот в мажордоме что и где прописать с этим как то у меня тяжеловато, пока мучаю распберри на столе
PI2 + MQTT + 5 ESP8266 + Atmega16
ZyaK
Сообщения: 407
Зарегистрирован: Вт окт 24, 2017 2:01 pm
Откуда: Ижевск
Благодарил (а): 45 раз
Поблагодарили: 69 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение ZyaK » Пн ноя 27, 2017 11:46 am

Создал массив, хранящий в себе 8 данных о состоянии реле(вкл или выкл) преобразовал его в строку из 8 символов 0 или 1
мажордом понимает данные, если меняю их с железных кнопок и управляет тоже если прописываю значение. теперь надо как то научить мажордом побитово менять значения
что бы при включении одного выключателя он не затрагивал остальные,
как это сделать на php не знаю, подскажите пожалуйста

если ESP не подписывать на топики, а просто отправлять их то все работает без проблем, естественно из мжордома она не управляется
то есть проблема именно в подписке на топики, а не в их отправке, сейчас отправляю 25 штук и нормально
PI2 + MQTT + 5 ESP8266 + Atmega16
ZyaK
Сообщения: 407
Зарегистрирован: Вт окт 24, 2017 2:01 pm
Откуда: Ижевск
Благодарил (а): 45 раз
Поблагодарили: 69 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение ZyaK » Чт дек 21, 2017 7:56 am

разобрался, можно тему удалять.
после каждой подписки на топики надо делать client loop
ну и данные по mqtt отправлять не пачками раз в 2 секунды или в 5 секунд, а только при изменении состояния и не все, а только необходимые.
PI2 + MQTT + 5 ESP8266 + Atmega16
avp8853
Сообщения: 52
Зарегистрирован: Пт июн 09, 2017 8:39 pm
Благодарил (а): 4 раза
Поблагодарили: 1 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение avp8853 » Пн янв 15, 2018 10:37 am

Можно так

Код: Выделить всё

client.subscribe("ESP01/#");            //подписываемся на топик

int odin=0;
int dva=0;


int sto =0;

void last_mls2_time()
{
  if (millis() - last_mls2 > 3000)            //периодичность публикации топика
  { last_mls2 = millis();  
    odin=1;
    dva=1;
   //здесь пишем остальные топики

    sto =1;
  }
}

void MQTT_odin()                                   //публикуем топик с состоянием режима
{
  if (odin)            //периодичность публикации топика
  { 
    client.publish(relays_topic1, String(regim1).c_str());
    odin=0;
    Serial.println("Отправка данных MQTT");
   }
}

void MQTT_dva()                                   //публикуем топик с состоянием режима
{
  if (dva)            //периодичность публикации топика
  { 
    client.publish(relays_topic2, String(regim2).c_str());
    
    Serial.println("Отправка данных MQTT");
   }
}
// И так далее
// Все функции записываем в loop  
ZyaK
Сообщения: 407
Зарегистрирован: Вт окт 24, 2017 2:01 pm
Откуда: Ижевск
Благодарил (а): 45 раз
Поблагодарили: 69 раз

Re: Esp8266 12E + MQTT проблема с подпиской на топики

Сообщение ZyaK » Вс янв 28, 2018 4:56 pm

я убрал публикацию топиков по времени, шлю только при изменении состояния, чтоб не спамить и только тот топик, который поменялся, а подписываюсь так же через клиент луп, на второй еспишке вообще около 30 топиков получилось(управление IR устройствами)
PI2 + MQTT + 5 ESP8266 + Atmega16
Ответить