ESP8266 MQTT для умного дома не работает автоконект
- Войдите на сайт для отправки комментариев
Сб, 01/09/2018 - 12:27
Есть модуль ESP8266 он подключен по wifi к распери пи зеро на котором установлен MajorDoMo есть проблема работы модуля. После отключеня питания на роуторе и его подключения обратно модуль автоматически подключается к роутеру, распери получает данные от модуля, а вот управлять модулем не получается. Но если выключить и включить модуль то все отлично работает.
Сам код собран со всего интернета :) как заставить получать данные и их выполнять?
#include <MQTT.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <OneWire.h>
OneWire ds(12);
// Connect to the WiFi
const char* ssid = "**********";
const char* password = "**************";
const char* mqtt_server = "MajorDoMo MQTT";
char* pubTopic = "/ESP8266/DATA";
char* controlTopic = "/ESP8266/CONTROL/#";
int knopka=0;
int knopka1=0;
int temperature = 0;
int counter = 0;
int ms = 0;
int seconds = 0;
int heap = 0;
String mqtt_user = "test";
String mqtt_pass = "test";
String mqtt_client = "ESP8266";
int qwe=0;
long lastUpdateTime = 0;
const int TEMP_UPDATE_TIME = 1000;
WiFiClient espClient;
IPAddress MQTTserver(192, 168, 1, 238);
PubSubClient client(espClient, MQTTserver);
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback (const MQTT::Publish& sub){
Serial.print("Get data from subscribed topic ");
Serial.print(sub.topic()); // Название топика
Serial.print(" => ");
Serial.println(sub.payload_string()); // Данные из топика
if (sub.topic() == "/ESP8266/CONTROL/GPIO/2") {
if (sub.payload_string() == "0") {
digitalWrite(2, LOW);
}
if (sub.payload_string() == "1") {
digitalWrite(2, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/0") {
if (sub.payload_string() == "0") {
digitalWrite(0, LOW);
}
if (sub.payload_string() == "1") {
digitalWrite(0, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/4") {
if (sub.payload_string() == "0") {
digitalWrite(4, LOW);
}
if (sub.payload_string() == "1") {
digitalWrite(4, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/5") {
if (sub.payload_string() == "0") {
digitalWrite(5, LOW);
}
if (sub.payload_string() == "1") {
digitalWrite(5, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/14") {
// int intVar;
// String stringVar = sub.payload_string();
// intVar=stringVar.toInt();
// qwe = intVar;
// analogWrite(14, intVar);
// }
if (sub.payload_string() == "1") {
digitalWrite(14, LOW);
}
if (sub.payload_string() == "0") {
digitalWrite(14, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/16") {
if (sub.payload_string() == "1") {
digitalWrite(16, LOW);
}
if (sub.payload_string() == "0") {
digitalWrite(16, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/15") {
if (sub.payload_string() == "1") {
digitalWrite(15, LOW);
}
if (sub.payload_string() == "0") {
digitalWrite(15, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/12") {
if (sub.payload_string() == "1") {
digitalWrite(12, LOW);
}
if (sub.payload_string() == "0") {
digitalWrite(12, HIGH);
}
}
if (sub.topic() == "/ESP8266/CONTROL/GPIO/13") {
if (sub.payload_string() == "1") {
digitalWrite(13, LOW);
}
if (sub.payload_string() == "0") {
digitalWrite(13, HIGH);
}
}
MQTT::Publish newpub(pubTopic, sub.payload(), sub.payload_len());
client.publish(newpub);
}
void restart() {
Serial.println("Will reset and try again...");
abort();
}
void setup()
{
Serial.begin(115200);
// Задаем режим работы GPIO и их начальное состояние
pinMode(2, OUTPUT);
digitalWrite(2, 0);
pinMode(0, OUTPUT);
digitalWrite(0, 0);
pinMode(4, OUTPUT);
digitalWrite(4, 0);
pinMode(5, OUTPUT);
digitalWrite(5, 0);
pinMode(14, INPUT);
digitalWrite(14, 0);
pinMode(16, OUTPUT);
digitalWrite(16, 0);
pinMode(15, OUTPUT);
digitalWrite(15, 0);
pinMode(12, INPUT);
digitalWrite(12, 0);
pinMode(13, OUTPUT);
digitalWrite(13, 0);
setup_wifi();
// client.setServer(mqtt_server, 1883);
client.set_callback(callback);
Serial.println("Connecting to MQTT broker ");
if (client.connect(MQTT::Connect(mqtt_client).set_auth(mqtt_user, mqtt_pass))) {
Serial.println("Connected to MQTT broker");
client.subscribe(controlTopic);
} else {
restart();
}
heap = ESP.getFreeHeap();
}
void reconnect() {
setup_wifi();
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266 Client")) {
Serial.println("connected");
// ... and subscribe to topic
client.subscribe("ledStatus");
} else {
Serial.print("failed, rc=");
//Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop()
{
//if (WiFi.getAutoConnect() != true) WiFi.setAutoConnect(true); //on power-on automatically connects to last used hwAP
//WiFi.setAutoReconnect(true); //automatically reconnects to hwAP in case it is disconnected
if (!client.connected()) {
reconnect();
//setup_wifi();
}
client.loop();
detectTemperature();
if ( micros() / 1000 - ms > 1000 || ms > micros() / 1000 ) {
if ( heap > ESP.getFreeHeap() ) {
Serial.println("Detect mem leak!");
heap = ESP.getFreeHeap();
}
ms = micros() / 1000;
++seconds;
}
if(digitalRead(14)==HIGH&&knopka==0)//если кнопка нажата
// и перемення "knopka" равна 0 , то ...
{
//delay(50);//защита от дребезга
knopka++;//пишем 1 в переменную кнопка
//это нужно для того что бы с каждым нажатием кнопки
//происходило только одно действие
digitalWrite(14, !digitalRead(14));//меняем значение порта на противоположное
//Считываем данные из ADC
// int knopka = digitalRead(12);
String ADCString = String(knopka);
Serial.print("ADC = ");
Serial.print(knopka);
//Публикуем ADC в топике
if (client.publish("/ESP8266/DATA/KNOPKA", ADCString)) {
Serial.println(" Publish ok");
}
else {
Serial.println(" Publish failed");
}
}
if(digitalRead(14)==LOW&&knopka==1)//если кнопка НЕ нажата
//и переменная knopka равна - 1 ,то ...
{
knopka=0;//обнуляем переменную "knopka"
//}
//Считываем данные из ADC
//int knopka = digitalRead(12);
String ADCString = String(knopka);
Serial.print("ADC = ");
Serial.print(knopka);
//Публикуем ADC в топике
if (client.publish("/ESP8266/DATA/KNOPKA", ADCString)) {
Serial.println(" Publish ok");
}
else {
Serial.println(" Publish failed");
}
}
if ( seconds >= 10 ) {
seconds = 0;
++counter;
String ADCString = String(temperature);
//Публикуем ADC в топике
if (client.publish("/ESP8266/DATA/TEMPERAT", ADCString))
// printTemperature(Thermometer1);
{
Serial.println(" Publish ok");
}
else {
Serial.println(" Publish failed");
}
}
if ( !client.loop() ) {
restart();
}
yield();
}
int detectTemperature(){
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
if (millis() - lastUpdateTime > TEMP_UPDATE_TIME)
{
lastUpdateTime = millis();
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
temperature = (data[1] << 8) + data[0]; temperature = temperature >> 4;
}
}
Вы в setup() подписываетесь на топик '/ESP8266/CONTROL/#'
строка 189 client.subscribe(controlTopic)
а в reconnect() той самой которую вызываете в случае потери соединения с брокером, уже подписываетесь совершенно на другой топик 'ledStatus'
не понятно зачем на другой, если обработчик callback (const MQTT::Publish& sub) его совсем не обрабатывает.
Спасибо за подскаску, я поправил код, но нашел причину в неработоспособности реконекта
оно связано с самой библиотекой для ESP8266 нужно было поставить версию пониже и тогда реконект
полностью работает. Оказывается это глобальная и известная проблема, и все знают кроме меня :)
укжите какие версии? или дайте ссылку на рабочую библиотеку 8266.
Нужно установить esp8266 by ESP8266 Community версия 2.2.0 реконект стабильно работает
А вот если поставить 2.3.0 работает не стабильно, в версии 2.4.0 писали что сломалась данная функия для платок ESP8266