ESP32-C3 disconnects after 12-16 hours everytime

• Hardware model + communication type. ESP32C3-Xiao
• Smartphone OS (iOS or Android) + OS version Android S22 Ultra
• Blynk server region US
• Blynk Library version Latest 1.3.2

// Smart Garden Monitoring System using XIAO ESP32 and Blynk
// Author: jhigg
// Created: 1/17/2024

// Blynk Configuration
#define BLYNK_TEMPLATE_ID "XXX"
#define BLYNK_TEMPLATE_NAME "Smart Garden"
#define BLYNK_AUTH_TOKEN "XXX"

#include <Wire.h>
#include <BlynkSimpleEsp32.h>
#include <AHTxx.h>

// WiFi credentials
const char ssid[] = "XXX";
const char pass[] = "XXX";

// AHT20 Sensor Initialization
AHTxx aht20(AHTXX_ADDRESS_X38, AHT2x_SENSOR);

void setup() {
    Serial.begin(115200); // Start the serial communication
    Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass); // Connect to Blynk
    Wire.setClock(400000); // Set I2C speed to 400KHz (experimental)

    // Initialize AHT20 sensor
    while (!aht20.begin()) {
        Serial.println(F("AHT2x not connected or calibration failed"));
        delay(5000);
    }
    Serial.println(F("AHT20 Initialized"));
}

void sendSensorData() {
    float temperatureCelsius = aht20.readTemperature();
    float humidity = aht20.readHumidity();
    int soilMoistureValue = analogRead(A0);  //Read soil moisture
    float soilMoisturePercent = map(soilMoistureValue, 4095, 2300, 0, 100); // Example conversion

    // Check for sensor errors
    if (temperatureCelsius != AHTXX_ERROR && humidity != AHTXX_ERROR) {
        float temperatureFahrenheit = celsiusToFahrenheit(temperatureCelsius);

        // Print sensor data
        Serial.printf("Temperature: %.2f F\n", temperatureFahrenheit);
        Serial.printf("Humidity: %.2f%%\n", humidity);
        Serial.printf("Soil: %.2f%%\n", soilMoisturePercent);

        // Send data to Blynk
        Blynk.virtualWrite(V5, temperatureFahrenheit);
        Blynk.virtualWrite(V6, humidity);
        Blynk.virtualWrite(V7, soilMoisturePercent);
    }
    else {
        printStatus(); // Print error status
        if (!aht20.softReset()) Serial.println(F("Sensor reset failed"));
    }
}

void loop() {
    Blynk.run(); // Handle Blynk connection
    sendSensorData();
    delay(15000); // Data sending interval of 15 seconds
}

// Function to convert Celsius to Fahrenheit
float celsiusToFahrenheit(float celsius) {
    return (celsius * 9.0 / 5.0) + 32;
}

// Function to print the status of the AHT20 sensor
void printStatus() {
    switch (aht20.getStatus()) {
    case AHTXX_NO_ERROR:
        Serial.println(F("no error"));
        break;
        // Add cases for other error types with appropriate messages
    default:
        Serial.println(F("unknown status"));
        break;
    }
}

The above code works fine- for about 12-16 hours and then ends up in some sort of cycle where it connects and disconnects constantly. From the portal I can see the device come online and offline about 5 times a min. No data is transferred while the device is online. If I power cycle the device it works for another 12-16 hours. The sensor code worked for weeks at a time without the blynk code- so I don’t think it’s that.

Any ideas here? Thank you for the assistance.

You should read this…

Pete.

Thank you for responding Pete. I appreciate it.

I’m 100% going to change my code for this change- but what causes it to work for 12 hours straight…then stop working? (This isn’t doubting- I just need to learn why so I don’t make this mistake with other systems)

Also- will this completely limit my ability to put this device into sleep mode? Eventually I need to move this system to a battery- this seems like I won’t actually be able to put my device into deep sleep. This will be a problem because I need the battery to last months…not days. (I’m aiming for 1 sensor reading a minute > month of battery life)

It’s difficult to say, but when your code breaks all the rules the first step is to fix that, then re-test.

I’m not sure what element of this you think is going to limit deep sleep.

If you want to use deep sleep then your code will need to be structured very differently anyway. No amount of testing with conventionally structured code will tell you anything about deep sleep operation, and with deep sleep you wnat your device to be connected for as little time as possible.

There are a few topics about deep sleep in the forum, but it really depends what your aim is when you explore the various options about code structure. If you simply want to wake-up, take a reading, upload it to Blynk then go to sleep then it’s pretty straightforward.

One thing you need to avoid with deep sleep is the use of Blynk.begin(), as this is a blocking function and if the device can’t connect to either WiFi or the Blynk server then all code execution will stop at Blynk.begin() so the device will never go to sleep - and you’ll have a flat battery.

Managing your own WiFi connection and using Blynk.config() and Blynk.connect() are the way to go with deep sleep.

Pete.

Again- thank you for taking the time to respond to my silliness :wink:

RE: deep sleep - I mistakenly assumed that the Blynk code had to run all the time to keep the connection alive, which is true if the connection needs to stay alive. IE updates every 1 sec or 15 secs. But I believe what you are saying is that there is a way to reconnect each time the device wakes up that won’t break the service? IE instead of keeping a connection alive, the connection is disconnected, the device is slept, and on wake it is reconnected and data sent?

100% understand my code needs to completely change for this- was just making sure there was a way to make it behave like I want.

Thank you again!

When you put a device into deep sleep everything stops, except the clock that keeps running to know when to wake itself up, and (in the case of your board) a circuit which monitors the GPIO pins to allow manual wake-up by pressing a button connected to a GPIO pin.

The device can’t remain connected to Blynk, as the WiFi modem is shut down. This means that the device will disconnect, and appear offline in Blynk.
When it wakes-up it will re-connect to Blynk and briefly appear online. You should be aiming to keep this wake time in the region of 5-10 seconds.

It’s generally quicker to use the Blynk HTTP API to upload data to Blynk, so you can shave a few seconds off the wake time using that approach, but people generally find it harder to make API calls in code than they do to use the regular Blynk library and re-0negotiate the connection on each wake-up.

Pete.

1 Like