Blynk not reconeccted in Esp32 GPRS sim7600G after 12 hours

I am having trouble reconnecting, my program sends the data smoothly between 8 and 10 hours but unexpectedly disconnects, I thought using the HEARTBEAT would work but it won’t reconnect, my oled display keeps showing and reading the sensor data normally. I have read in other forums that it should connect normally or try to since the Blynk.run() function takes care of it. I will now try to set the Blynk.connected == false and then Blynk.connect() to check if it works.Do you have any suggestions for reconnections on cards over GPRS or 2G,3G,4G connection?

#define BLYNK_TEMPLATE_ID "sssssssssssssss"
#define BLYNK_TEMPLATE_NAME "xxxxxxxxxxxxxxxxxxx"
#define BLYNK_AUTH_TOKEN "xxxxxxxxxxxxxxxxxxxxx"

// Select your modem:
#define TINY_GSM_MODEM_SIM7600

// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial

// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1

// See all AT commands, if wanted
#define DUMP_AT_COMMANDS

// Default heartbeat interval for GSM is 60
// If you want override this value, uncomment and set this option:
#define BLYNK_HEARTBEAT 70

#include <TinyGsmClient.h>
#include <BlynkSimpleTinyGSM.h>

#include <Arduino.h>
#include <Wire.h>

#include <SPI.h>
#include <SD.h>

BlynkTimer timer;

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = BLYNK_AUTH_TOKEN;

// Your GPRS credentials
// Leave empty, if missing user or pass
char apn[]  = "";
char user[] = "";
char pass[] = "";

#define SerialAT Serial1
#define UART_BAUD           115200

#define MODEM_TX            27
#define MODEM_RX            26
#define MODEM_PWRKEY        4
#define MODEM_DTR           32
#define MODEM_RI            33
#define MODEM_FLIGHT        25
#define MODEM_STATUS        34


#define SD_MISO             2
#define SD_MOSI             15
#define SD_SCLK             14
#define SD_CS               13

#define LED_PIN             12
bool reply = false;
//////////////////////////////////////////////////////////////////////////

#include <BMx280I2C.h>
#define I2C_ADDRESS 0x76  //sensor de temperatura y humedad para el refri
BMx280I2C bmx280(I2C_ADDRESS);

//////////////////////////////////////////////////////////////////////////////
#include <Adafruit_GFX.h> //pantalla
#include <Adafruit_SH110X.h>

#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1   //   QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//////////////////////////////////////
#include<ADS1115_WE.h> 
#include<Wire.h>
#define I2C_ADDRESS_1  0x48// para los voltajes 
#define I2C_ADDRESS_2  0x49// para otros

ADS1115_WE adc_1 = ADS1115_WE(I2C_ADDRESS_1);
ADS1115_WE adc_2 = ADS1115_WE(I2C_ADDRESS_2);
//AHT10 0x38 el azul
//bmp280 0x76 el morado
//HTU12D 0x40 el rojo el otro azul tambien es 0x40
///////////////////////////////////////////////////////
#include <Wire.h>
#include "Adafruit_HTU21DF.h"
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
////////////////////////////////////////////////////////

const int buzzerPin = 33; // Pin del buzzer
//////////////////////////////////////////////////

//////////////////////////////////////////////////
BLYNK_CONNECTED()
{
    Blynk.syncVirtual(V0);  // will cause BLYNK_WRITE(V3) to be executed
    delay(200);
    Blynk.syncVirtual(V1);
    delay(200);
    Blynk.syncVirtual(V2);
    delay(200);
    Blynk.syncVirtual(V3);
    delay(200);
    Blynk.syncVirtual(V4);
    delay(200);
    Blynk.syncVirtual(V5);
    delay(200);
    Blynk.syncVirtual(V6);
    delay(200);
    Blynk.syncVirtual(V7);
    delay(200);
    Blynk.syncVirtual(V8);
    delay(200);
    Blynk.syncVirtual(V9);
    delay(200);
    Blynk.syncVirtual(V10);
    delay(200);
}

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.
float data_1_adc;
float data_2_adc;
float data_3_adc;
float data_4_adc;
float data_5_adc;
float data_6_adc;
float temp_ext;
float hum_ext;
float temp_int;
float hum_int;
float VPanel;
float VBatt;
float cototalSubAC;
float corrienBatteria;
float CoPanel;
float VoltAC;
float temp1;
float temp2;
float hum1;
float hum2;
float vibracion1;
float vibracion;
float vibracionD;
//#define Voltaje_bateria    32 // pin del sensor de corriente bateria
//#define Voltaje_Panel    34
#define FILTER_LEN  15
uint32_t AN_Pot1_Buffer[FILTER_LEN] = {0};
int AN_Pot1_i = 0;
int AN_Pot1_Raw = 0;
int AN_Pot1_Filtered = 0;
uint32_t AN_Pot2_Buffer[FILTER_LEN] = {0};
int AN_Pot2_i = 0;
int AN_Pot2_Raw = 0;
int AN_Pot2_Filtered = 0;
void sendSensor()
{ 
   if(measure_environment_ADC1()){
    Serial.print("ADC_1 Comp 0-1: ");
    Serial.println(data_1_adc);
    VPanel=data_1_adc;
    delay(100);
  }
  if(measure_environment_ADC2()){
    Serial.print("ADC_1 Comp 2-3: ");
    Serial.println(data_2_adc);
    VBatt=data_2_adc;
    delay(100);
  }

 
  if(measure_environment_ADC3()){
    Serial.print("ADC_2 Comp 0-GND: ");
    Serial.println(data_3_adc);
    cototalSubAC= data_3_adc;
    delay(100);
  }
  if(measure_environment_ADC4()){
    Serial.print("ADC_2 Comp 1-GND: ");
    Serial.println(data_4_adc);
    corrienBatteria=data_4_adc;
    delay(100);
  }

  if(measure_environment_ADC5()){
    Serial.print("ADC_2 Comp 2-GND: ");
    Serial.println(data_5_adc);
    CoPanel=data_5_adc;
    delay(100);
  }

  if(measure_environment_ADC6()){
    Serial.print("ADC_2 Comp 3-GND: ");
    Serial.println(data_6_adc);
    VoltAC=data_6_adc;
    delay(100);
  }
  
  
  
  float temRefrigerador;
  float humRefrigerador;
  float temAmbiente;
  float humAmbiente;
  if (measure_environment2()) {
    Serial.print("T2 = ");
    Serial.print(temp_ext, 2);
    temp1=temp_ext;
    Serial.print(" deg. C, H2 = ");
    Serial.print(hum_ext, 2);
    hum1= hum_ext;
    Serial.println("%");
    delay(100);
  }
  if (measure_environment1()) {
    Serial.print("T1 = ");
    Serial.print(temp_int, 2);
    temp2= temp_int;
    Serial.print(" deg. C, H1 = ");
    Serial.print(hum_int, 2);
    hum2= hum_int;
    Serial.println("%");
    
    delay(100);
  }
    delay(100);
    display.clearDisplay();
  
    drawdata();
    display.display();
    delay(2000);
    display.clearDisplay();
    delay(100);
    if (temp1 > 40){
      alarma();
    }

    if (temp2 > 10){
      alarma();
    }
    Blynk.virtualWrite(V0, temp1);
    delay(200);
    Blynk.virtualWrite(V1, hum1);
    delay(200);
    Blynk.virtualWrite(V2, temp2);
    delay(200);
    Blynk.virtualWrite(V3, hum2);
    delay(200);
    Blynk.virtualWrite(V4,VBatt);
    delay(200);
    Blynk.virtualWrite(V5,CoPanel);
    delay(200);
    Blynk.virtualWrite(V6,VPanel);
    delay(200);  
    Blynk.virtualWrite(V7,VoltAC);
    delay(200);       
    Blynk.virtualWrite(V8,cototalSubAC);
    delay(200);     
    Blynk.virtualWrite(V9,corrienBatteria); 
    delay(200);     
    Blynk.virtualWrite(V10,12);  

   
}

#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif


void setup()
{

    // Set console baud rate
    SerialMon.begin(115200);
    //begin() checks the Interface, reads the sensor ID (to differentiate between BMP280 and BME280)
	while (!Serial);
  pinMode(buzzerPin,OUTPUT);
	Wire.begin();
  ///////////////////////////////////////////////////////
  delay(400); // wait for the OLED to power up
  display.begin(i2c_Address, true); // Address 0x3C default
 //display.setContrast (0); // dim display
  display.display();
  delay(2000);
  // Clear the buffer.
  ////////////////////////////////////////////////////
  if (!bmx280.begin())
	{
		Serial.println("begin() failed. check your BMx280 Interface and I2C Address.");
		while (1);
	}

	if (bmx280.isBME280())
		Serial.println("sensor is a BME280");
	else
		Serial.println("sensor is a BMP280");

	//reset sensor to default parameters.
	bmx280.resetToDefaults();

	//by default sensing is disabled and must be enabled by setting a non-zero
	//oversampling setting.
	//set an oversampling setting for pressure and temperature measurements. 
	bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
	bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);

	//if sensor is a BME280, set an oversampling setting for humidity measurements.
	if (bmx280.isBME280())
		bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);

  //set the sensor to "normal" mode with 4 measurement per second:
  bmx280.writeStandbyTime(BMx280MI::T_SB_3);
  bmx280.writePowerMode(BMx280MI::BMx280_MODE_NORMAL);
  //////////////////////////////////////////////
  if(!adc_1.init()){
    Serial.print("ADS1115 No 1 not connected!");
  }
  adc_1.setVoltageRange_mV(ADS1115_RANGE_6144);
  adc_1.setMeasureMode(ADS1115_CONTINUOUS); 
  adc_1.setCompareChannels(ADS1115_COMP_0_GND);
  adc_1.setCompareChannels(ADS1115_COMP_2_GND);
  if(!adc_2.init()){
    Serial.print("ADS1115 No 2 not connected!");
  }
  delay(10);
  adc_2.setVoltageRange_mV(ADS1115_RANGE_6144);
  adc_2.setMeasureMode(ADS1115_CONTINUOUS); 
  adc_2.setCompareChannels(ADS1115_COMP_0_GND);
  adc_2.setCompareChannels(ADS1115_COMP_1_GND);
  adc_2.setCompareChannels(ADS1115_COMP_2_GND);
  adc_2.setCompareChannels(ADS1115_COMP_3_GND);


    delay(10);
    //voltageSensor.setSensitivity(SENSITIVITY);
    // Set GSM module baud rate
    SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);

    /*
      The indicator light of the board can be controlled
    */
    pinMode(LED_PIN, OUTPUT);
    digitalWrite(LED_PIN, HIGH);

    /*
      MODEM_PWRKEY IO:4 The power-on signal of the modulator must be given to it,
      otherwise the modulator will not reply when the command is sent
    */
    pinMode(MODEM_PWRKEY, OUTPUT);
    digitalWrite(MODEM_PWRKEY, HIGH);
    delay(300); //Need delay
    digitalWrite(MODEM_PWRKEY, LOW);

    /*
      MODEM_FLIGHT IO:25 Modulator flight mode control,
      need to enable modulator, this pin must be set to high
    */
    pinMode(MODEM_FLIGHT, OUTPUT);
    digitalWrite(MODEM_FLIGHT, HIGH);

    //Initialize SDCard
    SPI.begin(SD_SCLK, SD_MISO, SD_MOSI, SD_CS);
    if (!SD.begin(SD_CS)) {
        Serial.println("SDCard MOUNT FAIL");
    } else {
        uint32_t cardSize = SD.cardSize() / (1024 * 1024);
        String str = "SDCard Size: " + String(cardSize) + "MB";
        Serial.println(str);
    }



    // Restart takes quite some time
    // To skip it, call init() instead of restart()
    Serial.println("Initializing modem...");
    if (!modem.restart()) {
        Serial.println("Failed to restart modem, attempting to continue without restarting");
    }

    String name = modem.getModemName();
    delay(500);
    Serial.println("Modem Name: " + name);

    Blynk.begin(auth, modem, apn, user, pass);
    // Setup a function to be called every second
    delay(5000);
    timer.setInterval(2000L, sendSensor);

	  

	
  
    // Setup pin for intterrupt
}

void loop()
{
  if (Blynk.connected()){
    Blynk.connect();
  }
  
  Blynk.run();
  timer.run();
  BLYNK_CONNECTED();
  
}


static bool measure_environment2() {
    static unsigned long measurement_timestamp = millis();

    // Measure once every four seconds. 
    if (millis() - measurement_timestamp > 2000ul) {
      if(htu.begin()){
        temp_int =  htu.readTemperature();
        hum_int = htu.readHumidity();
        measurement_timestamp = millis();
        return (true);
      }else{
        alarma();
        temp_int = 250.0; 
        hum_int = 250.0;
        return(true);
      }  
    }

    return (false);
}
static bool measure_environment1() {
    static unsigned long measurement_timestamp = millis();
    delay(1000);
    // Measure once every four seconds. 
    if (millis() - measurement_timestamp > 1000ul) {
      if(bmx280.begin()){
        if(!bmx280.measure()){
          Serial.println("could not start measurement, is a measurement already running?");
		      return(true);
        }
        do{
          delay(100);     
        }while(!bmx280.hasValue());
        long da1= bmx280.getPressure();
	      long da2= bmx280.getPressure64();
	      long da3= bmx280.getPressureI64();
        temp_ext=bmx280.getTemperature();
	      if (bmx280.isBME280()){
          hum_ext=bmx280.getHumidity();
	      }
        if(isnan(temp_ext) && isnan(hum_ext)){
          alarma();
          bmx280.resetToDefaults();
          bmx280.writeOversamplingPressure(BMx280MI::OSRS_P_x16);
	        bmx280.writeOversamplingTemperature(BMx280MI::OSRS_T_x16);

	//if sensor is a BME280, set an oversampling setting for humidity measurements.
	        if (bmx280.isBME280())
		        bmx280.writeOversamplingHumidity(BMx280MI::OSRS_H_x16);

          //set the sensor to "normal" mode with 4 measurement per second:
          bmx280.writeStandbyTime(BMx280MI::T_SB_3);
          bmx280.writePowerMode(BMx280MI::BMx280_MODE_NORMAL);
        }
        measurement_timestamp = millis();
        delay(1000);
        return (true);
      }else{
        temp_ext = 250.0; 
        hum_ext = 250.0;
        alarma();
        return(true);
      }  
    }

    return (false);
}
float readChannel1(ADS1115_MUX channel) {
  float voltage = 0.0;
  adc_1.setCompareChannels(channel);
  voltage = adc_1.getResult_mV(); // alternative: getResult_mV for Millivolt
  return voltage;
}
float readChannel2(ADS1115_MUX channel) {
  float voltage = 0.0;
  adc_2.setCompareChannels(channel);
  voltage = adc_2.getResult_mV(); // alternative: getResult_mV for Millivolt
  return voltage;
}
static bool measure_environment_vibracion() {
    static unsigned long measurement_timestamp = millis();

    
    if (millis() - measurement_timestamp > 2000ul) {
        //vibracion1=analogRead(32); 
        //vibracionD=digitalRead(34);
        measurement_timestamp = millis();
        return (true);
        
    }

    return (false);
}

static bool measure_environment_ADC1() {
    static unsigned long measurement_timestamp = millis();

    
    if (millis() - measurement_timestamp > 2000ul) {
      
        data_1_adc=readChannel1(ADS1115_COMP_0_GND); 
        measurement_timestamp = millis();
    
        return (true);
        
    }

    return (false);
}

static bool measure_environment_ADC2() {
    static unsigned long measurement_timestamp = millis();

    
    if (millis() - measurement_timestamp > 2000ul) {
     
      data_2_adc=readChannel1(ADS1115_COMP_2_GND); 
      measurement_timestamp = millis();
      
      
       return (true);   
        
    }

    return (false);
}
static bool measure_environment_ADC3() {
    static unsigned long measurement_timestamp = millis();

   
    if (millis() - measurement_timestamp > 2000ul) {
        data_3_adc=readChannel2(ADS1115_COMP_0_GND); 
        measurement_timestamp = millis();
        return (true);
        
    }

    return (false);
}
static bool measure_environment_ADC4() {
    static unsigned long measurement_timestamp = millis();

    
    if (millis() - measurement_timestamp > 2000ul) {
        data_4_adc=readChannel2(ADS1115_COMP_1_GND); 
        measurement_timestamp = millis();
        return (true);
        
    }

    return (false);
}
static bool measure_environment_ADC5() {
    static unsigned long measurement_timestamp = millis();

  
    if (millis() - measurement_timestamp > 2000ul) {
        data_5_adc=readChannel2(ADS1115_COMP_2_GND); 
        measurement_timestamp = millis();
        return (true);
        
    }

    return (false);
}
static bool measure_environment_ADC6() {
    static unsigned long measurement_timestamp = millis();

   
    if (millis() - measurement_timestamp > 2000ul) {
        data_6_adc=readChannel2(ADS1115_COMP_3_GND); 
        measurement_timestamp = millis();
        return (true);
        
    }

    return (false);
}

void drawdata(){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SH110X_WHITE);
  display.setCursor(0, 0);
  
  display.print("TAm:");display.print(temp1); display.println("C");
  display.print("TRe");display.print(temp2);display.println("C");
  display.print("HAm:");display.print(hum1); display.println("%");
  display.print("HRe");display.print(hum2);display.println("%");
  display.display();
  delay(1);
}

void alarma(){
  tone(buzzerPin,660,250);

  // Esperar 0.5 segundos
  delay(500);

  // Apagar el buzzer
  //digitalWrite(buzzerPin, LOW);
}

why my code looks weird?

I have no idea what you’re trying to achieve here, but this code is all wrong.

Your void loop should look like this…

void loop()
{
  Blynk.run();
  timer.run();
}

You should never manually call BLYNK_CONNECTED this is a callback function that is called automatically by the Blynk library when the device connects or re-connects to the Blynk server.

Also, this…

Is forcing is checking if the device is connected to Blynk, and if it is then it’s forcing it to re-connect. This makes no sense, why force a reconnection when it’s already connected!

My advice would be to remove all of the blocking delay commands from your code.

Pete.

Thank you very much for your response.

Thanks friend Pete, I’ll delete it and maybe it will work as it should.

void loop()
{
  if (Blynk.connected()==false){
    Blynk.connect();
  }
  
  Blynk.run();
  timer.run();
  BLYNK_CONNECTED();
  
}

this had to be like this, the idea was that if I had no connection with the server it would force it to reconnect me, regarding the BLYNK_CONNECTED() before it did not let me update the data if I did not call this function but I will see if it changes when eliminating it or where should I call it?

But the code you’ve included in your latest post is different from the code in your initial post.

There is no point in using Blynk.connected() and Blynk.connect() if you are using Blynk.begin() in your void setup.

I’ve already answered this, but I’ll say it again, YOU SHOULD NEVER MANUALLY CALL BLYNK_CONNECTED()

BLYNK_CONNECTED() is a callback which is called automatically by the Blynk library when the device connects or re-connects to the Blynk server. Do not call this function manually.

Please re-read my last two paragraphs until you 100% understand that you should not be calling BLYNK_CONNECTED() manually anywhere in your code.

Pete.

oki doky Pete, thanks for clarifying my doubts I will remove that part of the code and I hope it will reconnect to my server regularly.