Hi,
I’m currently working on a weather station project using Blynk Edgent with an ESP32, and have successfully implemented deep sleep. However, I’m encountering an issue during the deployment of new hardware with Blynk.Inject. The ESP32 enters deep sleep before the completion of the WiFi provisioning process. Is there a method to verify that the new WiFi credentials have been fully provisioned before the device goes into deep sleep, or should I simply incorporate a timed delay?
Best regards,
Here is the relevant code
#define BLYNK_TEMPLATE_ID "XXXXXXXXX"
#define BLYNK_TEMPLATE_NAME "XXXXXXXXXXX"
#define BLYNK_FIRMWARE_VERSION "0.1.32"
#define BLYNK_PRINT Serial
#define APP_DEBUG
// Uncomment your board, or configure a custom board in Settings.h
#define USE_ESP32S2_DEV_KIT
#include "DHT.h"
#include <numeric>
#include <HTTPClient.h>
#include "BlynkEdgent.h"
#include <Adafruit_BMP280.h>
#include <Adafruit_MLX90614.h>
#include "riodejaneiro_openweather.h"
#include <HardwareSerial.h>
#include "SPIFFS.h"
#include <deque>
#include <TinyGPSPlus.h>
#include <ArduinoJson.h>
#define DHTPIN 15 // GPIO 15
#define DHTTYPE DHT22 // DHT 22 (AM2302)
#define SCL_PIN 22 // GPIO 22
#define SDA_PIN 21 // GPIO 21
#define RXD2 16
#define TXD2 17
#define BMP280_ADDRESS 0x76
// Struct to hold intervals and their corresponding max entries for historical data
struct TimeIntervals {
const long intervals[5] = {60000L, 300000L, 900000L, 1800000L, 3600000L}; // Intervals in milliseconds
int maxEntriesForIntervals[5] = {60, 12, 4, 2, 1}; // Based on 1-hour history: 60min / interval in minutes
size_t maxEntries; // Calculated based on time intervals
} timeData;
// Struct to manage global flags and thresholds
struct GlobalSettings {
bool readyForSleep = false;
const long datasetinterval = 1 * 60; // dataset interval in minutes
long measureinterval = 1; // measure interval in minutes
long sleepinterval;
float threshold = 0.41;
//float minTempDifference = -11; // Minimum temperature difference for 0% cloud cover (in Celsius)
//float maxTempDifference = -1; // Maximum temperature difference for 100% cloud cover (in Celsius)
float minTempDifference = -4.45; // Minimum temperature difference for 0% cloud cover (in Celsius)
float maxTempDifference = -2.16; // Maximum temperature difference for 100% cloud cover (in Celsius)
} settings;
int timerId1;
// Create sensor instances
Adafruit_BMP280 bmp; // For the BMP280 sensor
DHT dht(DHTPIN, DHTTYPE); // For the DHT sensor
Adafruit_MLX90614 mlx = Adafruit_MLX90614(); // For the MLX90614 sensor
TinyGPSPlus gps; // For the GPS module
BlynkTimer timer; // For Blynk timer
// This function is called every time the device is connected to the Blynk.Cloud
BLYNK_CONNECTED()
{
Blynk.syncVirtual(V0);
}
BLYNK_WRITE(V0) {
int value = param.asInt();
// You now need to reference `timeData.intervals` instead of `timeIntervals`
if (value >= 0 && value < sizeof(timeData.intervals) / sizeof(timeData.intervals[0])) {
Serial.print("Setting interval to ");
Serial.print(timeData.intervals[value] / 60000L);
Serial.println(" minutes");
// Use `timeData` struct to access intervals and max entries
settings.measureinterval = timeData.intervals[value] / 60000L; // Convert back to minutes
settings.sleepinterval = timeData.intervals[value]; // Already in milliseconds
timeData.maxEntries = timeData.maxEntriesForIntervals[value];
} else {
Serial.println("Invalid value");
}
}
void takeMeasurements() {
Blynk.sendInternal("rtc", "sync"); // Request current local time for device
updateSensorReadings();
printSensorValues();
readGPS();
makeRainPredictionAndSendMessage();
measureBattery();
// Update Blynk with sensor readings from the 'sensorData' struct
Blynk.virtualWrite(V1, sensorData.temperature);
Blynk.virtualWrite(V2, sensorData.pressure);
Blynk.virtualWrite(V3, sensorData.humidity);
Blynk.virtualWrite(V4, sensorData.cloudcover);
Blynk.virtualWrite(V5, sensorData.skytemperature);
Blynk.virtualWrite(V6, sensorData.ambienttemperature);
Blynk.virtualWrite(V7, batteryData.bat_percentage);
Blynk.virtualWrite(V8, predictionData.probabilities[0] * 100.0);
Blynk.virtualWrite(V9, predictionData.probabilities[1] * 100.0);
Blynk.virtualWrite(V14, globalStrings.message);
// Set the flag to indicate readiness for sleep
settings.readyForSleep = true;
}
void setup() {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
// Connect to Blynk, set up timers, etc.
BlynkEdgent.begin();
timerId1 = timer.setInterval(30 * 1000L, takeMeasurements);
// Initialize sensors and buffers
initializeSensors();
// Initialize maxEntries based on the smallest interval
// Use the timeData instance to access intervals
timeData.maxEntries = 3600000 / timeData.intervals[0]; // Max entries for 1 hour based on the smallest interval
// Load previous measurements into the buffers
loadMeasurementsAndInitializeBuffers();
}
void loop() {
BlynkEdgent.run();
timer.run();
Blynk.run();
// Check if ready to sleep and if so, go to sleep
if (settings.readyForSleep) {
goToSleep();
}
}
void goToSleep() {
// Save buffers and any other state necessary before sleeping
Serial.println("Saving measurements");
saveMeasurements();
// Calculate the time to sleep in microseconds using the sleep interval from settings struct
uint64_t sleep_time_us = settings.sleepinterval * 1000ULL;
// Convert microseconds to minutes for logging
double sleep_time_min = sleep_time_us / 60000000.0;
// Print the sleep interval in microseconds and minutes
Serial.print("Going to sleep for ");
Serial.print(sleep_time_us);
Serial.print(" microseconds (");
Serial.print(sleep_time_min, 2); // Printing with 2 decimal places
Serial.println(" minutes)");
// Enter deep sleep
Serial.println("Going to sleep now");
Blynk.disconnect();
Serial.flush(); // Wait for transmission of outgoing serial data to complete
Serial.end(); // Disable serial
// Use ESP-IDF functions to enable timer wakeup and start deep sleep
esp_sleep_enable_timer_wakeup(sleep_time_us);
esp_deep_sleep_start();
}