ESP32 after 1h disconnects from ubidots and never reconnescts


#1

Hi,

I have the problem described on the tittle.
Reading some similar problems and comparing my code to theirs i cannot see what can i be doing wrong.
It´s weird beacuse if i manually restart the esp32 it will connect again normally.

Thanks in advance from anyone who reads this.

HERES THE CODE:

/****************************************
 * Include Libraries
 ****************************************/
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

#include <EmonLib.h>
#include "chewing.h"


EnergyMonitor emon1;        
EnergyMonitor emon2; 
EnergyMonitor emon3;    

filter chew;

/****************************************
 * Include WIFI Networks
 ****************************************/
I DELETED MY WIFI INFORMATION

#define TOKEN "XXXX" // Put your Ubidots' TOKEN
#define MQTT_CLIENT_NAME "Random" // MQTT client Name, please enter your own 8-12 alphanumeric character ASCII string; 
                                           //it should be a random and unique ascii string and different from all other devices
/****************************************
 * Offsets
 ****************************************/

 #define sensor1_offset 0.35
 #define sensor2_offset 0.35
 #define sensor3_offset 0.25
 
/****************************************
 * Define Constants
 ****************************************/
 //IN
#define PHASE1_LABEL "current1" // Assing the variable label
#define PHASE2_LABEL "current2" //Assing the variable label
#define PHASE3_LABEL "current3" // Assing the variable label
#define TEMP_LABEL "temperature" // Assing the variable label
#define HUMID_LABEL "humidity" // Assing the variabl3e label
//OUT
#define VARIABLE_LABEL_SUB_0 "relay_big" // Assing the variable label
#define VARIABLE_LABEL_SUB_1 "relay_small" // Assing the variable 
#define VARIABLE_LABEL_SUB_2 "relay_fan" // Assing the variable 
  //Temperature Sensor
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321


#define DEVICE_LABEL "esp32" // Assig the device label
/****************************************
 * Define Pins
 ****************************************/
#define SENSOR0 34 // Set the GPIO12 as SENSOR
#define SENSOR1 32 // Set the GPIO12 as SENSOR
#define SENSOR2 35 // Set the GPIO12 as SENSOR
#define R1 33 // Set the GPIO as RELAY
#define R2 25
#define R3 26

uint8_t DHTPin = 4; 


char mqttBroker[]  = "things.ubidots.com";
char payload[100];
char topic[150];
// Space to store values to send
char str_sensor1[10];
char str_sensor2[10];
char str_sensor3[10];
char str_temp[10];
char str_humid[10];

const uint8_t NUMBER_OF_VARIABLES = 16; // Number of variable to subscribe to
char * variable_labels[NUMBER_OF_VARIABLES] = {"relay_big", "relay_small", "relay_fan"}; // labels of the variable to subscribe to

float CONTROL1; // Name of the variable to be used within the code.
float CONTROL2; // Name of the variable to be used within the code.
float CONTROL3; // Name of the variable to be used within the code.

float value; // To store incoming value.
uint8_t variable; // To keep track of the state machine and be able to use the switch case.
const int ERROR_VALUE = 65535; // Set here an error value

// Force EmonLib to use 10bit ADC resolution
#define ADC_BITS    10
#define ADC_COUNTS  (1<<ADC_BITS)

/****************************************
 * Interrupts
 ****************************************/
//--------------- initialize timer1 16bits ( 2Hz )--------------- 
 
/****************************************
 * Auxiliar Functions
 ****************************************/
WiFiClient ubidots;
PubSubClient client(ubidots);
DHT dht(DHTPin, DHTTYPE);          


float Temperature;
float Humidity;

// Set your Static IP address
IPAddress local_IP(192, 168, 1, 184);
// Set your Gateway IP address
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);   //optional
IPAddress secondaryDNS(8, 8, 4, 4); //optional


void get_variable_label_topic(char * topic, char * variable_label) {
  Serial.print("topic:");
  Serial.println(topic);
  sprintf(variable_label, "");
  for (int i = 0; i < NUMBER_OF_VARIABLES; i++) {
    char * result_lv = strstr(topic, variable_labels[i]);
    if (result_lv != NULL) {
      uint8_t len = strlen(result_lv);
      char result[100];
      uint8_t i = 0;
      for (i = 0; i < len - 3; i++) {
        result[i] = result_lv[i];
      }
      result[i] = '\0';
      Serial.print("Label is: ");
      Serial.println(result);
      sprintf(variable_label, "%s", result);
      break;
    }
  }
}

float btof(byte * payload, unsigned int length) {
  char * demo_ = (char *) malloc(sizeof(char) * 10);
  for (int i = 0; i < length; i++) {
    demo_[i] = payload[i];
  }
  return atof(demo_);
}


void set_state(char* variable_label) {
  variable = 0;
  for (uint8_t i = 0; i < NUMBER_OF_VARIABLES; i++) {
    if (strcmp(variable_label, variable_labels[i]) == 0) {
      break;
    }
    variable++;
  }
  if (variable >= NUMBER_OF_VARIABLES) variable = ERROR_VALUE; // Not valid
}



void callback(char* topic, byte* payload, unsigned int length) {
  char p[length + 1];
  memcpy(p, payload, length);
  p[length] = NULL;
  String message(p);
  Serial.write(payload, length);
  //Serial.println(topic);                                      //print relays payload
  
  execute_cases(topic,p[0]);
  
}

void execute_cases();
void reconnect();
/****************************************
 * Main Functions
 ****************************************/
void setup() {
  Serial.begin(115200);
  //adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
  analogReadResolution(ADC_BITS);                               //Enable 10 bits in emonlib
  
    if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("STA Failed to configure");
  }
  
  WiFi.begin(WIFISSID, PASSWORD);
  // Assign the pin as INPUT 
  pinMode(SENSOR0, INPUT);
  pinMode(SENSOR1, INPUT);
  pinMode(SENSOR2, INPUT);
  pinMode(DHTPin, INPUT);

  pinMode(R1, OUTPUT);
  pinMode(R2, OUTPUT);
  pinMode(R3, OUTPUT);

   //Lemon Setup
  emon1.current(SENSOR0,30);
  emon2.current(SENSOR1,30); 
  emon3.current(SENSOR2,30);  
  
  dht.begin();  //Starting DHTT
   
  Serial.println();
  Serial.print("Wait for WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  
  Serial.println("");
  Serial.println("WiFi Connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  client.setServer(mqttBroker, 1883);
  client.setCallback(callback);  
}

void loop() {
  if (!client.connected()) {  //Runs once!
    reconnect();
    
       // Subscribes for getting the value of the control variable in the temperature-box device
    char topicToSubscribe_variable_1[200];
    sprintf(topicToSubscribe_variable_1, "%s", ""); // Cleans the content of the char
    sprintf(topicToSubscribe_variable_1, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
    sprintf(topicToSubscribe_variable_1, "%s/%s/lv", topicToSubscribe_variable_1, VARIABLE_LABEL_SUB_0);
    Serial.println("subscribing to topic:");
    Serial.println(topicToSubscribe_variable_1);
    client.subscribe(topicToSubscribe_variable_1);

    char topicToSubscribe_variable_2[200];
    sprintf(topicToSubscribe_variable_2, "%s", ""); // Cleans the content of the char
    sprintf(topicToSubscribe_variable_2, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
    sprintf(topicToSubscribe_variable_2, "%s/%s/lv", topicToSubscribe_variable_2, VARIABLE_LABEL_SUB_1);
    Serial.println("subscribing to topic:");
    Serial.println(topicToSubscribe_variable_2);
    client.subscribe(topicToSubscribe_variable_2);

    char topicToSubscribe_variable_3[200];
    sprintf(topicToSubscribe_variable_3, "%s", ""); // Cleans the content of the char
    sprintf(topicToSubscribe_variable_3, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
    sprintf(topicToSubscribe_variable_3, "%s/%s/lv", topicToSubscribe_variable_3, VARIABLE_LABEL_SUB_2);
    Serial.println("subscribing to topic:");
    Serial.println(topicToSubscribe_variable_3);
    client.subscribe(topicToSubscribe_variable_3);

    
    }
    
  //------Current Sensor value--------
    double sensor1 = emon1.calcIrms(1480);
    double sensor2 = emon2.calcIrms(1480);
    double sensor3 = emon3.calcIrms(1480);

  // -------Offset setting------------- 
    sensor1 = sensor1 - sensor1_offset;
    sensor2 = sensor2 - sensor2_offset;
    sensor3 = sensor3 - sensor3_offset;
  //---------FILTERTING----------------
    sensor1 = chew.chewing_it(sensor1);                   //FILTERTING
    sensor2 = chew.chewing_it(sensor2);
    sensor3 = chew.chewing_it(sensor3);
    
  //--------------DHT Sensor------------------
  Temperature = dht.readTemperature();                    // Gets the values of the temperature
  Humidity = dht.readHumidity();                          // Gets the values of the humidity   
  //--------------Uploading Values-------------
  
  sprintf(topic, "%s%s", "/v1.6/devices/", DEVICE_LABEL);
  sprintf(payload, "%s", ""); // Cleans the payload
  sprintf(payload, "{\"%s\":", PHASE1_LABEL); // Adds the variable label
  
  /* 4 is mininum width, 2 is precision; float value is copied onto str_sensor*/
  dtostrf(sensor1, 4, 2, str_sensor1);
  dtostrf(sensor2, 4, 2, str_sensor2);
  dtostrf(sensor3, 4, 2, str_sensor3);
  dtostrf(Temperature, 4, 2, str_temp);
  dtostrf(Humidity, 4, 2, str_humid);
  
  sprintf(payload, "{\"");
  sprintf(payload, "%s%s\":%s", payload, PHASE1_LABEL, str_sensor1);
  sprintf(payload, "%s,\"%s\":%s", payload, PHASE2_LABEL, str_sensor2);
  sprintf(payload, "%s,\"%s\":%s", payload, PHASE3_LABEL, str_sensor3);
  sprintf(payload, "%s,\"%s\":%s", payload, TEMP_LABEL, str_temp);
  sprintf(payload, "%s,\"%s\":%s", payload, HUMID_LABEL, str_humid);
  
  sprintf(payload, "%s}", payload);
  
  Serial.println(payload);    //Print payload
  client.publish(topic, payload);

  client.loop();
  delay(500);
}

void execute_cases(String message, int bi) {

    //Serial.print(message[26]);   //Show first Letter of topic
    if (message[26] == 's'){
      variable=0;
    }
    if  (message[26] == 'b'){
      variable=1;
    }
    if  (message[26] == 'f'){
      variable=2;
    }
  
  switch (variable) {
    case 0:     //Small rig  1 relay
      if(bi==48){     //48 == 0 in string 49 == 1
        digitalWrite(R1,HIGH);
      }
      else{
        digitalWrite(R1,LOW);
      }

      break;
    case 1:   //Big Rig 2 relays
      if(bi==48){
        digitalWrite(R2,HIGH);  //Non switching PSU
        digitalWrite(R3,HIGH);  //MOBO PSU
      }
      else{
        digitalWrite(R2,LOW);
        digitalWrite(R3,LOW);
      }

      break;
//    case 2:   //Fan 1 Relay
//     if(bi==48){
//        digitalWrite(R3,HIGH);
//      }
//      else{
//        digitalWrite(R3,LOW);
//      }
////      Serial.print("CONTROL3: ");
////      Serial.println(bi);
////      Serial.println();
//      break;
    case ERROR_VALUE:
      Serial.println("error");
      Serial.println();
      break;
    default:
      Serial.println("default");
      Serial.println();
      digitalWrite(R1,LOW);
      digitalWrite(R2,LOW);
      digitalWrite(R3,LOW);
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    
    // Attemp to connect
    if (client.connect(MQTT_CLIENT_NAME, TOKEN, "")) {
      Serial.println("Connected");
    } else {
      Serial.print("Failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 2 seconds");
      // Wait 2 seconds before retrying
      delay(2000);
    }
  }
}

Publishing and subscribing using ESP32
#2

Hi there, try just calling your reconnect() routine always in your infinite loop, if the device is connected it should not do nothing but if not it will maintain the broker connection.

All the best


#3

Thank you for your response!
Just to clarify this:

if (!client.connected()) { //Runs once!
reconnect();}

is in my loop.

So i must put the reconnect(); outside the if(!client.connected)?
I know my code is messy…i will attend to that later. I´m really just experimenting with this MQTT thing


#4

I tried to put the reconnect() appearing always on the loop.
after 1h30 hours it gets stuck on the "“Attempting MQTT connection…” Failed rc=2…
the only way out is by restarting the esp…wich is not the best in my case.

Any new idea?
I´ve been trying everything.