After some hours, the device disconnect automatically

I’m using the NodeMCU ESP8266, and after some hour in constant communication, the device simply disconnect and a reset is necessary to connect again.
I really don’t know how solve this issue.
The objective of the project is to make an IoT garden, composed of three soil moisture sensors, a temperature and humidity sensor and an LDR sensor.
Every time whem i loop the void loop(), besides calling thing.handle (), I check if a physical button or a virtual button was pressed to activate the irrigation manually.
This is my code:

#define USERNAME "xxxx"
#define DEVICE_ID "xxxx"
#define DEVICE_CREDENTIAL "xxxx"

#define WIFI_SSID "xxxx"
#define WIFI_PASSWORD "xxxx"

#define ON 1
#define OFF 0
#define SEC_1 1
#define SEC_2 2
#define SEC_3 3
#define ALL 4 

#define MUT_A D0
#define MUT_B D1
#define SOL_1 D2
#define SOL_2 D3
#define SOL_3 D4
#define PUMP D5
#define BTN_SEC_1 D8
#define BTN_SEC_2 3
#define BTN_SEC_3 10
#define DHT_PIN D6
#define MANL_ACT D7
#define ANALOG_IN A0

#define DHTTYPE DHT22

int16_t utc = -3; //UTC -3:00 Brazil
uint32_t currentMillis = 0;
uint32_t previousMillis = 0;
uint32_t previousMillis2 = 0;


int LDR_VALUE = 0;
int HYG1_VALUE = 0;
int HYG2_VALUE = 0;
int HYG3_VALUE = 0;
int MIN_HOUR = 0;

int btnLastSatatus = 0;

bool sol_1 = false;
bool sol_2 = false;
bool sol_3 = false;
bool pump = false;
bool man_act = false;

WiFiUDP ntpUDP;
DHT dht(DHT_PIN, DHTTYPE);
NTPClient timeClient(ntpUDP, "a.st1.ntp.br", utc*3600, 60000);
ThingerESP8266 thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL);

void(* resetFunc) (void) = 0; 

void setupPins(){
  pinMode(MUT_A, OUTPUT);
  pinMode(MUT_B, OUTPUT);
  pinMode(SOL_1, OUTPUT);
  pinMode(SOL_2, OUTPUT);
  pinMode(SOL_3, OUTPUT);
  pinMode(PUMP, OUTPUT);
  pinMode(BTN_SEC_1, INPUT_PULLUP);
  pinMode(BTN_SEC_2, INPUT_PULLUP);
  pinMode(BTN_SEC_3, INPUT_PULLUP);
  pinMode(MANL_ACT, INPUT_PULLUP);  
  pinMode(ANALOG_IN, INPUT);
  pinMode(DHT_PIN, DHTTYPE);
  
  digitalWrite(MUT_A, 0);
  digitalWrite(MUT_B, 0);
  digitalWrite(SOL_1, HIGH);
  digitalWrite(SOL_2, HIGH);
  digitalWrite(SOL_3, HIGH);
  digitalWrite(PUMP, HIGH);
}

void setupWifi(){
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("connecting");
  while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
  }
  Serial.println();
  Serial.print("connected: ");
  Serial.println(WiFi.localIP());
}

void setupClock(){
  timeClient.begin();
  timeClient.update();
}

void setUpReferences (){  

  LDR_VALUE = 49;
  HYG1_VALUE = 68;
  HYG2_VALUE = 68;
  HYG3_VALUE = 68;
  MIN_HOUR = 18;
  
  thing["LDR_VALUE"] << [](pson& ref){
if(ref.is_empty()){
  ref = LDR_VALUE;
}
   else {
 LDR_VALUE = ref;
}
  };
  thing["HYG1_VALUE"] << [](pson& ref){
if(ref.is_empty()){
  ref = HYG1_VALUE;
}
   else {
 HYG1_VALUE = ref;
}
  };
  thing["HYG2_VALUE"] << [](pson& ref){
if(ref.is_empty()){
  ref = HYG2_VALUE;
}
   else {
 HYG2_VALUE = ref;
}
  };
  thing["HYG3_VALUE"] << [](pson& ref){
if(ref.is_empty()){
  ref = HYG3_VALUE;
}
   else {
 HYG3_VALUE = ref;
}
  };
  thing["MIN_HOUR"] << [](pson& ref){
if(ref.is_empty()){
  ref = MIN_HOUR;
}
   else {
 MIN_HOUR = ref;
}
  };
}

void setupPublishSensors(){
  thing["sec_1"] >> [](pson& out){ out = map(readHyg1(), 0, 1023, 0, 100);};  //ATENÇÃO POIS PARECE ESTAR AO CONTRARIO 
  thing["sec_2"] >> [](pson& out){ out = map(readHyg2(), 0, 1023, 0, 100);};
  thing["sec_3"] >> [](pson& out){ out = map(readHyg3(), 0, 1023, 0, 100);};
  thing["ldr"] >> [](pson& out){ out = map(readLDR(), 0, 1023, 0, 100);};
  thing["temp"] >> [](pson& out){ out = readTemp();};
  thing["humd"] >> [](pson& out){ out = readHum();};
}

void setupOutputsSatatus(){
  thing["SOL_1"] >> [](pson& stat){ stat = sol_1;};
  thing["SOL_2"] >> [](pson& stat){ stat = sol_2;};
  thing["SOL_3"] >> [](pson& stat){ stat = sol_3;};
  thing["PUMP"] >> [](pson& stat){ stat = pump;};

  thing["MANL_ACT"] << [](pson& ref){
if(ref.is_empty()){
  ref = man_act;
}
   else {
 man_act = (bool)ref;
}
  };
}


void forceUpdate(void) {
  timeClient.forceUpdate();
}

void checkTime(void) {
  currentMillis = millis();//Tempo atual em ms
  //Lógica de verificação do tempo
  if (currentMillis - previousMillis > 1800000) {
previousMillis = currentMillis;    // Salva o tempo atual
Serial.println("TEMPO");
makeAction();
  }
}

int readHyg1(){
  digitalWrite(MUT_A, LOW);
  digitalWrite(MUT_B, LOW);
  return analogRead(ANALOG_IN);
}

int readHyg2(){
  digitalWrite(MUT_A, HIGH);
  digitalWrite(MUT_B, LOW);
  return analogRead(ANALOG_IN);
}

int readHyg3(){
  digitalWrite(MUT_A, LOW);
  digitalWrite(MUT_B, HIGH);
  return analogRead(ANALOG_IN);
}

int readLDR(){
  digitalWrite(MUT_A, HIGH);
  digitalWrite(MUT_B, HIGH);
  return analogRead(ANALOG_IN);
}

String readTemp (){
  char celsiusTemp[7];
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  // Check if any reads failed and exit early (to try again).
  if (isnan(t)) {
return "0.0";
  }else{
// Computes temperature values in Celsius + Fahrenheit and Humidity
float hic = dht.computeHeatIndex(t, h, false);       
dtostrf(hic, 6, 2, celsiusTemp);                
return String(celsiusTemp);
}
}

String readHum (){
  float h = dht.readHumidity();
  return String(h);
}

void pump_control (boolean sec1, boolean sec2, boolean sec3){
  if(sec1 == true || sec2 == true || sec3 == true){
digitalWrite(PUMP, LOW);
pump = true;
  }else{
digitalWrite(PUMP, HIGH);
pump = false;
  }
}

void actWater(int section){
  switch (section) {
case SEC_1:
  digitalWrite(SOL_1, LOW);
  delay(300);
  sol_1 = true;
  break;
case SEC_2:
  digitalWrite(SOL_2, LOW);
  delay(300);
  sol_2 = true;
  break;
case SEC_3:
  digitalWrite(SOL_3, LOW);
  delay(300);
  sol_3 = true;
  break;
case ALL:
  digitalWrite(SOL_1, LOW);
  digitalWrite(SOL_2, LOW);
  digitalWrite(SOL_3, LOW);
  digitalWrite(PUMP, LOW);
  delay(300);
  sol_1 = true;
  sol_2 = true;
  sol_3 = true;
  pump = true;
  break;
default:
  // statements
  break;
  }
}

void deactWater(int section){
  switch (section) {
case SEC_1:
  delay(300);
  digitalWrite(SOL_1, HIGH);
  sol_1 = false;
  break;
case SEC_2:
  delay(300);
  digitalWrite(SOL_2, HIGH);
  sol_2 = false;
  break;
case SEC_3:
  delay(300);
  digitalWrite(SOL_3, HIGH);
  sol_3 = false;
  break;
case ALL:
  delay(300);
  digitalWrite(SOL_1, HIGH);
  digitalWrite(SOL_2, HIGH);
  digitalWrite(SOL_3, HIGH);
  digitalWrite(PUMP, HIGH);
  sol_1 = false;
  sol_2 = false;
  sol_3 = false;
  pump = false;
  break;
default:
  // statements
  break;
  }
}

void makeAction(){

  boolean sec1 = false;
  boolean sec2 = false;
  boolean sec3 = false;
  
  int humSec1 = readHyg1();
  delay(500);
  int humSec2 = readHyg2();
  delay(500);
  int humSec3 = readHyg3();
  delay(500);
  int lumLDR = readLDR();
  delay(500);
  int hour = timeClient.getHours();                            
  String temp = readTemp();
  String humd = readHum();
  
  Serial.print("Sec 1: ");
  Serial.println(humSec1);
  Serial.print("Sec 2: ");
  Serial.println(humSec2);
  Serial.print("Sec 3: ");
  Serial.println(humSec3);
  Serial.print("LDR: ");
  Serial.println(lumLDR);
  Serial.print("Temp: ");
  Serial.println(temp);
  Serial.print("Hum: ");
  Serial.println(humd);
  Serial.print("Hour: ");
  Serial.println(hour);

  if(humSec1 < 100 || humSec1 < 100 || humSec1 < 100 ){
resetFunc();
  }

  if(digitalRead(BTN_SEC_1) == LOW && hour >= MIN_HOUR && humSec1 <= map(HYG1_VALUE, 0, 100, 0, 1023) && lumLDR <= map(LDR_VALUE, 0, 100, 0, 1023)){
Serial.println("SEC 1");
actWater(SEC_1);
sec1 = true;
  }else{
deactWater(SEC_1);
sec1 = false;
  }
  if(digitalRead(BTN_SEC_2) == LOW && hour >= MIN_HOUR && humSec2 <= map(HYG2_VALUE, 0, 100, 0, 1023) && lumLDR <= map(LDR_VALUE, 0, 100, 0, 1023)){
Serial.println("SEC 2");
actWater(SEC_2);
sec2 = true;
  }else{
deactWater(SEC_2);
sec2 = false;
  }
  if(digitalRead(BTN_SEC_3) == LOW && hour >= MIN_HOUR && humSec3 <= map(HYG3_VALUE, 0, 100, 0, 1023) && lumLDR <= map(LDR_VALUE, 0, 100, 0, 1023)){
Serial.println("SEC 3");
actWater(SEC_3);
sec3 = true;
  }else{
deactWater(SEC_3);
sec3 = false;
  }
}

void streaming(){
  thing.stream(thing["MANL_ACT"]);
  thing.stream(thing["SOL_1"]);
  thing.stream(thing["SOL_2"]);
  thing.stream(thing["SOL_3"]);
  thing.stream(thing["PUMP"]);
}

void setup() {
  Serial.begin(9600);

  dht.begin();

  setupPins();
  setupWifi();    
  //setupFirebase();
  setupClock();
  setUpReferences();
  setupPublishSensors();
  setupOutputsSatatus();
}

void loop() {
  if(WiFi.status() != WL_CONNECTED) {
Serial.print("DISCONECTED");
setupWifi();
  }
  
  //Manual Activation
  int btnPressed = OFF;
  if(digitalRead(MANL_ACT) == LOW || man_act == true){
actWater(ALL);
btnPressed = ON;
btnLastSatatus = btnPressed;
  }else btnPressed = OFF;

  if(btnLastSatatus != btnPressed){
deactWater(ALL);
btnLastSatatus = btnPressed;
  }

  thing.handle();
  streaming();
  checkTime();
}

Hi, do not add your custom setup Wifi, as Thinger.io libraries handles all this logic by default, and it may be causing some problems.

So, please, remove you setupWifi calls and code, and just add the “add_wifi” in the setup, as in the examples. Then, the thing.handle call will control all the wifi connection and reconnection.

Hope it helps.

1 Like

That makes a lot of sense!
I’ll try, thank you!