tzapu / WiFiManager

ESP8266 WiFi Connection manager with web captive portal
http://tzapu.com/esp8266-wifi-connection-manager-library-arduino-ide/
MIT License
6.64k stars 1.98k forks source link

ESP32 loses WiFi connection after 24hours #1250

Closed warnerthuis closed 3 years ago

warnerthuis commented 3 years ago

Basic Infos

I build an alarmclock with a 6-digit leddisplay with a TM1637 connected to my home system via MQTT. I set the times and en/dis-able the alarms in NodeRed on my phone and send that via MQTT. I am already sending every minute the current time from the ESP to NodeRed as a kind of keep-alive but that doesn't help. I have used this library on other projects with ESP8266's and then I had no problems. I don't know if the problem is related to this library or not. I'm using latest version of Arduino IDE

Hardware

WiFimanager Branch/Release: 2.0.3-alpha

Esp8266/Esp32: ESP32

Hardware: LILYGO TT7 v1.5 with ESP32-WROVER-B

Core Version:

Description

Connection is lost after 24 hours

Settings in IDE

Module: ESP32 Wrover Module

Additional libraries: multiple

Sketch

#BEGIN
/*
 * Alarmclock display with a 6-digit display and running on a LILYGO TTGO T7 V1.5 and adjusting time through NTP 
 * created 28-03-2021
 * by Warner Krelekamp
 * Sets time when started and then every 1801 seconds (=30'01").
 * Uses a modified TM1637TinyDisplay library to display a blank digit
 * 
 */

#include <Arduino.h>
#include <TM1637TinyDisplay6wk.h>
#include <PubSubClient.h>

#define DISPLAY_DEBUG
#define DISPLAY_DEBUG_1
#define DISPLAY_DEBUG_2

#define wait_time 50

const char* mqtt_server = "192.168.17.70";
#define mqtt_port 1883
#define MQTT_USER "xxxxxx"
#define MQTT_PASSWORD "yyyyyy"
#define MQTT_SERIAL_PUBLISH_CH "AlarmClock"
#define MQTT_SERIAL_RECEIVER_CH "wekker/#"

#include <ezTime.h>
#include <WiFi.h>
#include <EEPROM.h>

//needed for library
#include <DNSServer.h>
#include <WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

//pins definitions for TM1637 and can be changed to other ports
#define DIO 22                 // LILYGO TTGO T7 V1.5 pin D5
#define CLK 21                 // LILYGO TTGO T7 V1.5 pin D4

//#define Time_OK 19             // LILYGO TTGO T7 V1.5 pin D19 is on-board green led

#define buzzPin 25       // the number of the buzzer pin
#define keyAO 27         // key to switch off alarm (23)

#define POINT_OFF 0x00  
#define POINT_ON  0x80

#define numberOfAlarms 7    // number of numberOfAlarms
#define EEPROM_SIZE ((2*numberOfAlarms)+1)

TM1637TinyDisplay6 display(CLK, DIO);

int8_t listDispPoint[6] = {POINT_OFF,POINT_OFF,POINT_OFF,POINT_OFF,POINT_OFF,POINT_OFF};
byte alarmMinute[numberOfAlarms];
byte alarmHour[numberOfAlarms];
int8_t timeDisp[6]; 
byte alarmActive = 0;     // is 1 if alarm is sounding
byte alarmEnabled = 0;    // 0= no alarm enabled, otherwise is the nuber of the enabled alarm
byte displayBrightness;
byte eeAddress = 0;
byte showDisplay = 1;
char buf[10];
char buf2[14] = "ClockAlarms/0";      // is 13 kar's en dan nog de \0
String regel  = "";

Timezone myTZ;

WiFiClient wifiClient;

PubSubClient client(wifiClient);
//-----------------------------------------------------------------------------

void toondata(int8_t DispData[], int8_t DispPointData[]) {
  int k;
  uint8_t data[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };    // Test Pattern - All
    for (k = 0; k < 6; k++)
    data[k] = (display.encodeDigit(DispData[k]))|(DispPointData[k]);
  display.setSegments(data);
}

//-----------------------------------------------------------------------------

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Create a random client ID
    String clientId = "AlarmClock-";
    clientId += String(random(0xffff), HEX);
    // Attempt to connect
    if (client.connect(clientId.c_str(),MQTT_USER,MQTT_PASSWORD)) {
      Serial.println("connected");
      //Once connected, publish an announcement...
      //client.publish("/icircuit/presence/ESP32/", "hello world");
      client.publish(MQTT_SERIAL_PUBLISH_CH, "connected");
      // ... and resubscribe
      client.subscribe(MQTT_SERIAL_RECEIVER_CH);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

//------------------------------------------------------------------------------------

void callback(char* topic, byte *payload, unsigned int length) {
  int teller;
#ifdef DISPLAY_DEBUG
  Serial.println(topic);
#endif
//-------------------------------------------------
  if(strcmp(topic, "wekker/enable") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("hulp = " + str);  
#endif
    int hulp = str.toInt();
    int welkAlarm = hulp / 10;
    int stand = hulp % 10;
#ifdef DISPLAY_DEBUG
    Serial.println(welkAlarm);
    Serial.println(stand);
#endif
    if ( stand == 1) alarmEnabled = welkAlarm;
    else alarmEnabled = 0;
    EEPROM.write(eeAddress+(2*numberOfAlarms), alarmEnabled);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/1") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 0;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/2") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 1;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/3") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 2;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/4") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 3;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/5") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 4;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/6") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 5;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/7") == 0) {
    String str = String();    
    for (int i = 0; i < length; i++) {
      if ( (char)payload[i] != ':') 
        str += (char)payload[i];
    }
#ifdef DISPLAY_DEBUG
    Serial.println("sp = " + str);  
#endif
    //
    int tijd = str.toInt();
    Serial.println(tijd);
    teller = 6;
    alarmHour[teller]   = tijd /100;
    alarmMinute[teller] = tijd %100;
    EEPROM.write(eeAddress+(teller*2), alarmHour[teller]);
    EEPROM.write(eeAddress+1+(teller*2), alarmMinute[teller]);
    EEPROM.commit();
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/print") == 0) {
    //
    for (teller = 0; teller < numberOfAlarms; teller++) {
      Serial.print("Alarmtijd[");
      Serial.print(teller+1);
      Serial.print("]: ");
      if ( alarmHour[teller] < 10 ) Serial.print("0");
      Serial.print(alarmHour[teller]);
      Serial.print(':');
      if ( alarmMinute[teller] < 10 ) Serial.print("0");
      Serial.print(alarmMinute[teller]);
      if(alarmEnabled == (teller+1)) {
        Serial.println(", alarm enabled.");
      }
      else {
        Serial.println(", alarm disabled.");
      }
    }
  }

//-------------------------------------------------

  if(strcmp(topic, "wekker/opvragen") == 0) {
    //
#ifdef DEBUG
    Serial.println("opvragen");    
#endif
    for (teller = 0; teller < numberOfAlarms; teller++) {
      if ( alarmHour[teller] < 10 ) regel ='0';
      regel = regel + String(alarmHour[teller]);
      regel = regel + ':';
      if ( alarmMinute[teller] < 10 ) regel = regel + '0';
      regel = regel + String(alarmMinute[teller]);
#ifdef DEBUG
      Serial.println(regel);    
#endif
      String(regel).toCharArray(buf, 10);
      //String hulpje = "ClockAlarms/"+String(teller);
      buf2[12]= '0'+teller;
      client.publish( buf2 , buf );
    }

    //
  }

}

//------------------------------------------------------------------------------------

void publishTime() {
  if (minute()<10){
    regel = String(myTZ.hour()) + ":0" + String(minute());
  } else{
    regel = String(myTZ.hour()) + ":" + String(minute());
  }
  String(regel).toCharArray(buf, 10);
  client.publish("ClockTime", buf);  
}

//------------------------------------------------------------------------------------

void setup()
{
  byte teller;
  int8_t bla[] = {0, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a};  //0x0a is a blank display position
//  display.setBrightness(BRIGHT_HIGH);
  display.setBrightness(BRIGHT_LOW);
  display.clear();
  toondata(bla, listDispPoint);
/*
  // first we put 0 on display
*/

  pinMode(keyAO, INPUT_PULLUP);

  // set the buzzpin pin as output:
  pinMode(buzzPin, OUTPUT);

//  pinMode(Time_OK, OUTPUT);
//  digitalWrite(Time_OK, HIGH);    // Time_OK indicator off

  bla[1] = 1;
  toondata(bla, listDispPoint);

#ifdef DISPLAY_DEBUG
  Serial.begin(115200);
  delay(1000); // give me time to bring up serial monitor
  Serial.println();
  Serial.println("NTP-MQTT-wekker-1.5-WM");
#endif

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //reset saved settings
  //wifiManager.resetSettings();

  //set custom ip for portal
  //wifiManager.setAPStaticIPConfig(IPAddress(10,0,1,1), IPAddress(10,0,1,1), IPAddress(255,255,255,0));

  //fetches ssid and pass from eeprom and tries to connect
  //if it does not connect it starts an access point with the specified name
  //here  "AutoConnectAP"
  //and goes into a blocking loop awaiting configuration
  //wifiManager.autoConnect("AutoConnectAP");
  wifiManager.autoConnect("AlarmClockAP");
  //or use this for auto generated name ESP + ChipID
  //wifiManager.autoConnect();

  bla[2] = 2;
  toondata(bla, listDispPoint);

  //if you get here you have connected to the WiFi

  // Uncomment the line below to see what it does behind the scenes
  //setDebug(INFO);

  waitForSync();

#ifdef DISPLAY_DEBUG
  Serial.println();
  Serial.println("UTC:             " + UTC.dateTime());
#endif

  //Timezone myTZ;

  myTZ.setLocation(F("nl"));

#ifdef DISPLAY_DEBUG
  Serial.print(F("Nederland:         "));
  Serial.println(myTZ.dateTime());
#endif
  setInterval(1801);
  setDebug(DEBUG);

  bla[3] = 3;
  toondata(bla, listDispPoint);

  if (!EEPROM.begin(EEPROM_SIZE))
  {
#ifdef DISPLAY_DEBUG
    Serial.println("failed to initialise EEPROM"); 
#endif
    delay(1000000);
  }

  // get alarmtime from EEPROM
  alarmEnabled = EEPROM.read(eeAddress+(2*numberOfAlarms));
#ifdef DISPLAY_DEBUG
  Serial.print("alarmEnabled:");
  Serial.println(alarmEnabled);
#endif
  if ( (alarmEnabled < 0) || (alarmEnabled > (numberOfAlarms)) ) alarmEnabled = 0;
#ifdef DISPLAY_DEBUG
  Serial.print("alarmEnabled:");
  Serial.println(alarmEnabled);
#endif
  for (teller = 0; teller < numberOfAlarms; teller++) {
    alarmHour[teller] = EEPROM.read(eeAddress+(teller*2));
    alarmMinute[teller] = EEPROM.read(eeAddress+1+(teller*2));
    //check if eeprom contains valid values
    if(alarmHour[teller] > 23) {
      alarmHour[teller] = 7;
    }
    if(alarmMinute[teller] > 59) {
      alarmMinute[teller] = 30;
    }
#ifdef DISPLAY_DEBUG
    Serial.print("Alarmtijd[");
    Serial.print(teller+1);
    Serial.print("]: ");
    if ( alarmHour[teller] < 10 ) Serial.print("0");
    Serial.print(alarmHour[teller]);
    Serial.print(':');
    if ( alarmMinute[teller] < 10 ) Serial.print("0");
    Serial.print(alarmMinute[teller]);
    if(alarmEnabled == (teller+1)) {
      Serial.println(", alarm enabled.");
      listDispPoint[3] = POINT_ON;
      listDispPoint[1] = POINT_ON;
    }
    else {
      Serial.println(", alarm disabled.");
    }
#endif
  }

  bla[4] = 4;
  toondata(bla, listDispPoint);

#ifdef DISPLAY_DEBUG
  Serial.println("Connect MQTT server");
#endif
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
  reconnect();
  publishTime();
}

//------------------------------------------------------------------------------------

void ToonTijd(){

  if ( showDisplay == 0 ){
    // display off
    timeDisp[0] = 10;
    timeDisp[1] = 10;
    timeDisp[2] = 10;
    timeDisp[3] = 10;
    timeDisp[4] = 10;
    timeDisp[5] = 10;
  }
  else {
    // display on:
    // format the time
    timeDisp[0] = myTZ.hour() / 10;
    timeDisp[1] = myTZ.hour() % 10;
    timeDisp[2] = minute() / 10;
    timeDisp[3] = minute() % 10;
    timeDisp[4] = second() / 10;
    timeDisp[5] = second() % 10;
    if (alarmEnabled == 0){
      //
      listDispPoint[3] = POINT_OFF;
      listDispPoint[1] = POINT_OFF;
    }
    else {
      //
      listDispPoint[3] = POINT_ON;
      listDispPoint[1] = POINT_ON;
    }
  }
  // show it

#ifdef DISPLAY_DEBUG_1
  Serial.print(myTZ.hour() / 10);
  Serial.print(myTZ.hour() % 10);
  Serial.print(":");
  Serial.print(minute() / 10);
  Serial.print(minute() % 10);
  Serial.print(":");
  Serial.print(second() / 10);
  Serial.println(second() % 10);
#endif

  // show it
  toondata(timeDisp, listDispPoint);
}

//------------------------------------------------------------------------------------

void loop()
{
  client.loop();  // do MQTT stuff
  events();       // do ezTime stuff
  if (secondChanged()){
    if (second() == 0) {
      for (byte teller = 0; teller < numberOfAlarms; teller++) {
        if ((myTZ.hour() == alarmHour[teller]) && (minute() == alarmMinute[teller]) && (alarmEnabled == teller+1)) {
          // Alarm!
          Serial.println("Alarm active.");
          alarmActive = 1;
          digitalWrite(buzzPin, HIGH);
          Serial.println("Alarm on.");
          showDisplay = 1;
          listDispPoint[3] = POINT_ON;
          listDispPoint[1] = POINT_ON;
        }
      }
    publishTime();
    }
    ToonTijd();
  }
  if (!digitalRead(keyAO)) {
    if ( alarmActive == 1 ) {
      alarmActive = 0;
      Serial.println("Alarm off.");
      digitalWrite(buzzPin, LOW);
      while (!digitalRead(keyAO)) delay(wait_time);
      delay(wait_time);
    }
    else {
      // turn display on or off
      if ( showDisplay == 1 ) {
        // switch display off
        Serial.println("Display off.");
        showDisplay = 0;
        listDispPoint[3] = POINT_OFF;
        listDispPoint[1] = POINT_OFF;
        while (!digitalRead(keyAO)) delay(wait_time);
        delay(wait_time);
      }
      else {
        // switch display on
        Serial.println("Display on.");
        showDisplay = 1;
        if ( alarmEnabled > 0) {
          listDispPoint[3] = POINT_ON;
          listDispPoint[1] = POINT_ON;
        } 
        while (!digitalRead(keyAO)) delay(wait_time);
        delay(wait_time);
      }
    }
  }
}

#END

Debug Messages

messages here
warnerthuis commented 3 years ago

I think the ESP loses contact with the WiFi and does not reconnect.

warnerthuis commented 3 years ago

Sorry, error is on the MQTT side. I did not check in the main loop if the connection is still available.