Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By frjariello
#73504 Hi,
I have a nodemcu that I manage via an android app but, I do not understand why my code after two / three days of operation freezes, and I can not understand why (not having a display that tells me the error).
Even if I do not use the app, after a couple of days it freezes...

Some idea?

Code: Select all#include <ESP8266WiFi.h>
#include <WiFiUDP.h>
#include <NTPClient.h>
#include <Time.h>
#include <TimeLib.h>
#include <Timezone.h>
#include "DHT.h"
#include "EEPROM.h"

// Define NTP properties
#define NTP_OFFSET   60 * 60      // In seconds
#define NTP_INTERVAL 60 * 1000    // In miliseconds
#define NTP_ADDRESS  "ca.pool.ntp.org"  // change this to whatever pool is closest (see ntp.org)
// Set up the NTP UDP client
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);

#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#define ComCaldaia 2

const char* ssid = "XXXXXXXX";
const char* password = "XXXXXXXX";


String date;
String istante;
const char * days[] = {"Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato"} ;
const char * months[] = {"Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"} ;
const char * ampm[] = {"AM", "PM"} ;
unsigned long millisOrario=999999;
unsigned long millisSonde=999999;
unsigned long millisthings=999999;
unsigned long MinutiOnTotali=0;
unsigned long MinutiOnAvvio=0;
int IndirizzoMem;
int MinutiOn =0;
int Comando = 0;
int ComandoPrec = 2;
String ComandoTXT = "";

// ThingSpeak Settings
const int channelID = 999999999;
String apiKey = "XXXXXXXX"; // write API key for your ThingSpeak Channel
const char* serverTS = "api.thingspeak.com";
String postStr = apiKey;

// variabili di funzionamento
boolean Abilitazione = false;
boolean ManualeCom = false;
boolean CheckOrario1 = false;
boolean CheckOrario2 = false;
boolean CheckOrario3 = false;
int Orario1Avvio = 0;
int Orario2Avvio = 0;
int Orario3Avvio = 0;
int Orario1Durata = 0;
int Orario2Durata = 0;
int Orario3Durata = 0;
int OrarioAttuale = 9999;
int VirtOraAttuale = 0;
boolean CambioOra = false;
int ManualeAvvio = 0;
int ManualeFine = 0;

WiFiServer server(80);

void setup() {
  delay(500);
  Serial.begin(115200);
  delay(500);
  timeClient.begin();

  // Prepara Uscita
  pinMode(ComCaldaia, OUTPUT);
  digitalWrite(ComCaldaia, 0);
  //pinMode(2, INPUT_PULLUP);
  //pinMode(0, INPUT_PULLUP);
 
  Connessione();
 
  EEPROM.begin(512);
  EEPROM.get(1, Abilitazione);
  EEPROM.get(2, ManualeCom);
  EEPROM.get(3, CheckOrario1);
  EEPROM.get(4, CheckOrario2);
  EEPROM.get(5, CheckOrario3);
  EEPROM.get(11, Orario1Avvio);
  EEPROM.get(15, Orario2Avvio);
  EEPROM.get(19, Orario3Avvio);
  EEPROM.get(23, Orario1Durata);
  EEPROM.get(27, Orario2Durata);
  EEPROM.get(31, Orario3Durata);
  EEPROM.get(35, ManualeAvvio);
  EEPROM.get(39, ManualeFine);

  ESP.wdtDisable();
  ESP.wdtEnable(WDTO_8S);
}

String OkInvio = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
String InviaLettura = "";
int pStart = -1;
int pEnd = -1;
String dato = "";
String risultato = "-";
float TempAmb;
float TempAmbPrec;
float UmidAmb;
float TempPerc;


void loop() {
  delay(1000);
  if (WiFi.status() == WL_CONNECTED) //Check connessione WiFi
  {
    ESP.wdtFeed();
    if ((millis()>(millisOrario+60000)) || (millis()<(millisOrario))) {
      millisOrario=millis();
      CheckOrario();}

    if ((millis()>(millisSonde+30000)) || (millis()<(millisSonde))) {
      millisSonde=millis();
      CheckSonde();}

    if ((millis()>(millisthings+900000)) || (millis()<(millisthings))) {
      millisthings = millis();
      postStr = apiKey;
      postStr += "&field1=";
      postStr += String(TempAmb);
      postStr += "&field2=";
      postStr += String(UmidAmb);
      postStr += "&field3=";
      postStr += String(TempPerc);
      //postStr += "&field4=";
      //postStr += String((Comando*100));
      things(postStr);
      }
   
//----- Inizio codice logiche funzionamento

    if (OrarioAttuale >= (ManualeAvvio-5) && OrarioAttuale < ManualeFine) {
      ManualeCom = true;} else {
      ManualeCom = false;}
    if ((Orario3Avvio+Orario3Durata) > 1440 && OrarioAttuale < (Orario3Avvio+Orario3Durata-1440)) {
      CambioOra=true;
      } else { CambioOra=false; }
    if (Abilitazione && (ManualeCom || (CheckOrario3 && CambioOra) ||
    (CheckOrario1 && (OrarioAttuale >= Orario1Avvio) && (OrarioAttuale < (Orario1Avvio+Orario1Durata))) ||
    (CheckOrario2 && (OrarioAttuale >= Orario2Avvio) && (OrarioAttuale < (Orario2Avvio+Orario2Durata))) ||
    (CheckOrario3 && (OrarioAttuale >= Orario3Avvio) && (OrarioAttuale < (Orario3Avvio+Orario3Durata)))))
    {
      if (Comando != 0) {
        ComandoTXT = "ON";
        Comando = 0;
        MinutiOnAvvio = OrarioAttuale;
        postStr = apiKey;
        postStr += "&field4=";
        postStr += String(0);
        things(postStr);
      }
    } else {
      if (Comando != 1) {
        ComandoTXT = "OFF";
        Comando = 1;
        MinutiOn = int(OrarioAttuale - MinutiOnAvvio);
        postStr = apiKey;
        postStr += "&field4=";
        postStr += String(100);
        postStr += "&field5=";
        postStr += String(MinutiOn);
        things(postStr);
        MinutiOnAvvio=0;
        }
    }
    if (Comando != ComandoPrec) {
      ComandoPrec = Comando;
      digitalWrite(ComCaldaia, Comando);
      Serial.print("Comando: "); Serial.println(ComandoTXT);
    }

//----- Inizio codice webserver

  WiFiClient client = server.available();
  if (!client) { return; }

  while (!client.available()) { delay(500); }
 
  Serial.println("- - - - - - - Nuova connessione - - - - - - -");

  String req = client.readStringUntil('\r');
  client.flush();

 // Ricezione aggiornamento dati
  scrittura(req, "Abilitazione");
  if (risultato != "NO") { if (risultato=="true") {
    Abilitazione=true;} else {Abilitazione=false;}
    client.print(OkInvio);
    IndirizzoMem = 1;
    EEPROM.put(IndirizzoMem, Abilitazione);EEPROM.commit();
    return; }

  scrittura(req, "CheckOrario1");
  if (risultato != "NO") { if (risultato=="true") {
    CheckOrario1=true;} else {CheckOrario1=false;}
    client.print(OkInvio);
    IndirizzoMem = 3;
    EEPROM.put(IndirizzoMem, CheckOrario1);EEPROM.commit();
    return; }

  scrittura(req, "CheckOrario2");
  if (risultato != "NO") {
    if (risultato=="true") { CheckOrario2=true;} else {CheckOrario2=false;}
    client.print(OkInvio);
    IndirizzoMem = 4;
    EEPROM.put(IndirizzoMem, CheckOrario2);EEPROM.commit();
    return; }

  scrittura(req, "CheckOrario3");
  if (risultato != "NO") {
    if (risultato=="true") { CheckOrario3=true;} else {CheckOrario3=false;}
    client.print(OkInvio);
    IndirizzoMem = 5;
    EEPROM.put(IndirizzoMem, CheckOrario3);EEPROM.commit();
    return; }

  scrittura(req, "Orario1Avvio");
  if (risultato != "NO") {
    Orario1Avvio = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 11;
    EEPROM.put(IndirizzoMem, Orario1Avvio);EEPROM.commit();
    return; }

  scrittura(req, "Orario2Avvio");
  if (risultato != "NO") {
    Orario2Avvio = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 15;
    EEPROM.put(IndirizzoMem, Orario2Avvio);EEPROM.commit();
    return; }

  scrittura(req, "Orario3Avvio");
  if (risultato != "NO") {
    Orario3Avvio = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 19;
    EEPROM.put(IndirizzoMem, Orario3Avvio);EEPROM.commit();
    return; }

  scrittura(req, "Orario1Durata");
  if (risultato != "NO") {
    Orario1Durata = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 23;
    EEPROM.put(IndirizzoMem, Orario1Durata);EEPROM.commit();
    return; }

  scrittura(req, "Orario2Durata");
  if (risultato != "NO") {
    Orario2Durata = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 27;
    EEPROM.put(IndirizzoMem, Orario2Durata);EEPROM.commit();
    return; }
 
  scrittura(req, "Orario3Durata");
  if (risultato != "NO") {
    Orario3Durata = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 31;
    EEPROM.put(IndirizzoMem, Orario3Durata);EEPROM.commit();
    return; }

  scrittura(req, "ManualeAvvio");
  if (risultato != "NO") {
    ManualeAvvio = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 35;
    EEPROM.put(IndirizzoMem, ManualeAvvio);EEPROM.commit();
    return; }

  scrittura(req, "ManualeFine");
  if (risultato != "NO") {
    ManualeFine = risultato.toInt();
    client.print(OkInvio);
    IndirizzoMem = 39;
    EEPROM.put(IndirizzoMem, ManualeFine);EEPROM.commit();
    return; }

  lettura(req);
  if (pStart != -1) {
    client.print(risultato);
    Serial.println(risultato);
    return; }
  }
  else // Disconnessione
  {
    Serial.println("--> WiFi disconnesso... Ritento la connessione <--");
    server.stop();
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    Serial.println("--> TRA 3 MINUTI <--");
    delay(170000);
    Serial.println("--> MANCANO 10 SECONDI <--");
    delay(10000);
    Connessione();
  }
  delay(1000); // Ritardo di fine loop
}

void Connessione() {
  Serial.println();
  Serial.print("Connessione a ");
  Serial.println(ssid);

  WiFi.hostname("ESP_Caldaia");
  WiFi.begin(ssid, password);
  IPAddress ip(192,168,1,77);   
  IPAddress gateway(192,168,1,254);   
  IPAddress subnet(255,255,255,0);   
  WiFi.config(ip, gateway, subnet);
  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if(i>40) ESP.restart();
    i++;
  }
  Serial.println("");
  Serial.println("WiFi connesso");
  server.begin();
  Serial.println("Server avviato");
  Serial.println(WiFi.localIP());
}

void CheckOrario() {
      timeClient.update();
      unsigned long epochTime =  timeClient.getEpochTime();
      time_t local, utc;
      utc = epochTime;
      TimeChangeRule usEDT = {"EDT", Last, Sun, Mar, 2, 60};
      TimeChangeRule usEST = {"EST", Last, Sun, Oct, 3, 0};
      Timezone usEastern(usEDT, usEST);
      local = usEastern.toLocal(utc);
      date = days[weekday(local)-1];
      date += ", ";
      date += day(local);
      date += " ";
      date += months[month(local)-1];
      date += " ";
      date += year(local);
      istante = year(local);
      istante += "-";
      istante += month(local);
      istante += "-";
      istante += day(local);
      istante += " ";
      istante += hour(local);
      istante += ":";
      istante += (minute(local)<10) ? "0" : "";
      istante += minute(local);
      OrarioAttuale = (hour(local)*60)+minute(local); // Orario di riferimento
      Serial.println("");
      Serial.print(istante);Serial.print(" ");Serial.println(date);
}

void CheckSonde() {
      TempAmb = dht.readTemperature();
      if ((TempAmb>(TempAmbPrec+2) || TempAmb<(TempAmbPrec-2)) && TempAmbPrec>5) {
        Serial.print("Lettura scartata: ");Serial.print(TempAmb); Serial.println("°C");
        TempAmb=TempAmbPrec;
      } else {
        TempAmbPrec = TempAmb;
        UmidAmb = dht.readHumidity();
        TempPerc = dht.computeHeatIndex(TempAmb, UmidAmb, false);
      }
      /*
      Serial.print("Abilitazione: ");Serial.println(Abilitazione);
      Serial.print("Manuale: ");Serial.println(ManualeCom);
      Serial.print("Manuale Fine: ");Serial.println(ManualeFine);
      Serial.print("CheckOrario1: ");Serial.println(CheckOrario1);
      Serial.print("CheckOrario2: ");Serial.println(CheckOrario2);
      Serial.print("CheckOrario3: ");Serial.println(CheckOrario3);
      Serial.print("Orario1Avvio: ");Serial.println(Orario1Avvio);
      Serial.print("Orario2Avvio: ");Serial.println(Orario2Avvio);
      Serial.print("Orario3Avvio: ");Serial.println(Orario3Avvio);
      Serial.print("Orario1Durata: ");Serial.println(Orario1Durata);
      Serial.print("Orario2Durata: ");Serial.println(Orario2Durata);
      Serial.print("Orario3Durata: ");Serial.println(Orario3Durata);
      Serial.print("Orario Attuale: ");Serial.println(OrarioAttuale);
      Serial.print("Comando: "); Serial.println(ComandoTXT);
      */
      Serial.print("Temperatura: "); Serial.print(TempAmb); Serial.print("°C  |");
      Serial.print("  Umidità: "); Serial.print(UmidAmb); Serial.print("%  |");
      Serial.print("  Percepita: "); Serial.print(TempPerc); Serial.println("°C");
}

void scrittura(String req, String dato) {
  pStart = req.indexOf("/XXXXXXXX/"+dato);
  pEnd = req.indexOf("HTTP/");
  if (pStart != -1) {
    risultato = req.substring((pStart + 4 + dato.length()), (pEnd - 1));
    Serial.print(dato);
    Serial.println(": |" + risultato + "|");
  } else {
    risultato = "NO";
  }
}

void lettura(String req) {
  pStart = req.indexOf("/XXXXXXXX/Leggi");
  if (pStart != -1) {
    InviaLettura = OkInvio;
    InviaLettura += istante;
    InviaLettura += " |Abil:";InviaLettura += Abilitazione;
    InviaLettura += "|Manu:";InviaLettura += ManualeCom;
    InviaLettura += "|Comando:"; InviaLettura += ComandoTXT;
    InviaLettura += "|Check1:";InviaLettura += CheckOrario1;
    InviaLettura += "|Check2:";InviaLettura += CheckOrario2;
    InviaLettura += "|Check3:";InviaLettura += CheckOrario3;
    InviaLettura += "|Orario1:";InviaLettura += Orario1Avvio;
    InviaLettura += "|Orario2:";InviaLettura += Orario2Avvio;
    InviaLettura += "|Orario3:";InviaLettura += Orario3Avvio;
    InviaLettura += "|Durata1:";InviaLettura += Orario1Durata;
    InviaLettura += "|Durata2:";InviaLettura += Orario2Durata;
    InviaLettura += "|Durata3:";InviaLettura += Orario3Durata;
    InviaLettura += "|OraAttuale:";InviaLettura += OrarioAttuale;
    InviaLettura += "|Temp:"; InviaLettura += String(TempAmb); InviaLettura += " °C";
    InviaLettura += "|Umid:"; InviaLettura += String(int(UmidAmb)); InviaLettura += " %";
    InviaLettura += "|Perc:"; InviaLettura += String(TempPerc); InviaLettura += "° C|";
    risultato = InviaLettura;
  }
}

void things(String postStr) {
   WiFiClient client;
   if (client.connect(serverTS, 80)) { // use ip 184.106.153.149 or api.thingspeak.com
     Serial.println("Connesso con api.thingspeak.com");
     postStr += "\r\n\r\n";
     client.print("POST /update HTTP/1.1\n");
     client.print("Host: api.thingspeak.com\n");
     client.print("Connection: close\n");
     client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
     client.print("Content-Type: application/x-www-form-urlencoded\n");
     client.print("Content-Length: ");
     client.print(postStr.length());
     client.print("\n\n");
     client.print(postStr);
   }
   client.stop();
}


Thanks
User avatar
By mrburnette
#73514 Mod your sketch to output free memory once a minute.. you can send the number out serial of tack it on a webpage.

See: viewtopic.php?f=43&t=12502#p58041

Essentially that number should not change after it stabilizes ... if there is a memory leak, the number will become smaller over time.

You may also have a "clean power" issue. This issue is very difficult to find.

But, I have run ESP8266-12 for 9 months straight without issues in an attic with extreme temperature shifts. I used an old PC power brick for stable power.

Good luck.
User avatar
By lucasromeiro
#73717
mrburnette wrote:Mod your sketch to output free memory once a minute.. you can send the number out serial of tack it on a webpage.

See: viewtopic.php?f=43&t=12502#p58041

Essentially that number should not change after it stabilizes ... if there is a memory leak, the number will become smaller over time.

You may also have a "clean power" issue. This issue is very difficult to find.

But, I have run ESP8266-12 for 9 months straight without issues in an attic with extreme temperature shifts. I used an old PC power brick for stable power.

Good luck.

hi...
Do you can explain more?
I found it interesting and I have not read anything about it ... How could memory leak? I did not understand ... In case if this happens the WDT would not be activated? I am now beginning to develop an important project. I think this information will be welcome. Do you have other tips for keeping a program running smoothly?
Thank you!