Hello everyone, I’m working on an automated greenhouse project using a DOIT ESP32 DEVKIT V1 connected to the Blynk server. My setup involves reporting sensor data and actuator statuses, with the system set to automatically adjust environmental conditions based on sensor input. However, I’m encountering recurring disconnections from the Blynk server, which compromise the system’s reliability.
Here are the details:
- Hardware: DOIT ESP32 DEVKIT V1 + ESP32 DEVKIT development board
- Communication type: WiFi, via university’s IoT network
- Datastreams: 10 total (5 for sensor data, 5 for actuator status)
- Power for ESP32: Type-C cable with USB adapter plugged into a power socket
Problem:
The system initially operates as expected, transmitting data to the Blynk server without issues for a few hours. Disconnection periods vary, lasting from 30 seconds to 17 minutes. However, after roughly 6-7 hours, it fails to reconnect, resulting in complete operational failure. I’ve attempted to maintain a clean void loop()
and adjusted timer intervals to 2000L and 5000L for data transmission. Notably, reducing the datastreams to 5 (sensor data only) allowed for longer operation times (over 10 hours) but did not eliminate disconnection issues.
Attempts to Resolve:
- Ensured
void loop()
remains clean - Adjusted data-sending intervals (2000L and 5000L)
- Tested with reduced number of datastreams
Could anyone provide insights or suggestions on how to maintain a stable connection to the Blynk server? Any advice or similar experiences shared would be immensely appreciated. Thank you in advance for your help!
#define BLYNK_TEMPLATE_ID "TMPL5QnD7wJfZ"
#define BLYNK_TEMPLATE_NAME "IoT Smart Agriculture System"
#define BLYNK_AUTH_TOKEN "xxx"
// WiFi credentials
char ssid[] = "XXXXX-IoT"; // WiFi Name
char pass[] = "Oio602npoEKo"; // WiFi Password
char auth[] = "xxxxx";
#include <Ticker.h>
#include <WiFi.h>
#include <DallasTemperature.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>
#include <BH1750.h>
#include <DHT.h> //For air moisture and temperature sensor
#include <OneWire.h> //For Soil moisture sensor
// GPIO pins for ESP32
#define DHTPIN 15 // For DHT11
#define DHTTYPE DHT11 // DHT 11 Air temperature and moisture sensor
#define SOUND_SPEED 0.034 // SR04 Ultrasonic sensor
#define CM_TO_INCH 0.393701 // SR04 Ultrasonic sensor
#define MOIST_PIN 34
#define ONE_WIRE_BUS 4
#define WATER_PUMP_PIN 25
#define HEAT_MAT_PIN 26
#define LED_PIN 27
// Virtual pins for blynk
#define VPIN_AIR_HUMIDITY V0
#define VPIN_AIR_TEMPERATURE V1
#define VPIN_SOIL_MOISTURE V2
#define VPIN_SOIL_TEMPERATURE V3
#define VPIN_WATER_TANK_LEVEL V4
#define VPIN_LIGHT_SENSOR V5
#define VPIN_CONNECTION V6
#define VPIN_WATER_PUMP_STATUS V7
#define VPIN_HEAT_MAT_STATUS V8
#define VPIN_LED_GROW_LIGHT_STATUS V9
unsigned long lastWaterPumpActivation = 0;
const unsigned long waterPumpCooldown = 1800000; // 30 minutes in milliseconds
//For SR04 Ultrasonic sensor
const int trigPin = 5;
const int echoPin = 18;
long duration;
float distanceCm;
float distanceInch;
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
BH1750 lightMeter;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1 = { 0x28, 0x38, 0x7D, 0x81, 0xE3, 0xE1, 0x3C, 0xA };
DeviceAddress sensor2 = { 0x28, 0x57, 0xFC, 0x81, 0xE3, 0xE1, 0x3C, 0xEB };
float measureDistance(){
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
return distanceCm;
}
float measureSoilTemp(){
sensors.requestTemperatures();
float tempC1 = sensors.getTempC(sensor1);
float tempC2 = sensors.getTempC(sensor2);
float avgTempC = (tempC1 + tempC2) / 2;
return avgTempC;
}
float measureMoist(){
int moist = analogRead(MOIST_PIN);
// Invert the calculation logic: (4000 - moist) represents the inverse reading
float moistPercent = ((float)(4000 - moist) / (4000 - 2000)) * 100;
moistPercent = constrain(moistPercent, 0, 100); // Ensure the percentage is between 0 and 100
Serial.print("Soil Moisture Reading: ");
Serial.print(moist);
Serial.print(" - Moisture %: ");
Serial.println(moistPercent);
return moistPercent;
//return moist;
}
float measureWaterTankLevel() {
float distance = measureDistance(); // Use the existing measureDistance function to get the current distance.
float fullTankDistance = 2.5; // Distance when the tank is full.
float emptyTankDistance = 17.0; // Distance when the tank is empty.
// Calculate the percentage full. This will invert the measurement since a smaller distance means more water.
float tankLevelPercent = (1.0 - ((distance - fullTankDistance) / (emptyTankDistance - fullTankDistance))) * 100;
// Ensure the percentage is between 0 and 100
tankLevelPercent = constrain(tankLevelPercent, 0, 100);
Serial.print("Water Tank Level Reading: ");
Serial.print(distance);
Serial.print(" cm - Level %: ");
Serial.println(tankLevelPercent);
return tankLevelPercent;
}
void sendSensorData() {
float h = dht.readHumidity(); //Measure air moisture value in %
float t = dht.readTemperature(); //Measure temperature valur in degrees Celsius
float lux = lightMeter.readLightLevel();
float waterTankLevel = measureWaterTankLevel();
float moistPercent = measureMoist();
float temp = measureSoilTemp();
Blynk.virtualWrite(VPIN_AIR_TEMPERATURE, t);
Blynk.virtualWrite(VPIN_AIR_HUMIDITY, h);
Blynk.virtualWrite(VPIN_SOIL_MOISTURE, moistPercent);
Blynk.virtualWrite(VPIN_WATER_TANK_LEVEL, waterTankLevel);
Blynk.virtualWrite(VPIN_LIGHT_SENSOR, lux);
Blynk.virtualWrite(VPIN_SOIL_TEMPERATURE, temp);
Blynk.virtualWrite(VPIN_CONNECTION, Blynk.connected() ? 1 : 0);
}
void controlActuators() {
unsigned long currentMillis = millis();
float waterTankLevel = measureWaterTankLevel();
float soilMoisturePercent = measureMoist();
float soilTemperature = measureSoilTemp();
float lightLevel = lightMeter.readLightLevel();
if (waterTankLevel < 10 && soilMoisturePercent < 40 && millis() - lastWaterPumpActivation > waterPumpCooldown) {
digitalWrite(WATER_PUMP_PIN, LOW); // Turn on the pump
Blynk.virtualWrite(VPIN_WATER_PUMP_STATUS, 1);
Serial.println("Pump activated.");
delay(2000); // Keep the pump on for 2 seconds
digitalWrite(WATER_PUMP_PIN, HIGH); // Turn off the pump
Serial.println("Pump deactivated.");
Blynk.virtualWrite(VPIN_WATER_PUMP_STATUS, 0);
lastWaterPumpActivation = millis(); // Update the last activation time
}
// Heat mat logic
if (soilTemperature < 18) {
digitalWrite(HEAT_MAT_PIN, LOW);
Blynk.virtualWrite(VPIN_HEAT_MAT_STATUS, 1);
} else if (soilTemperature > 16) {
digitalWrite(HEAT_MAT_PIN, HIGH);
Blynk.virtualWrite(VPIN_HEAT_MAT_STATUS, 0);
}
// LED grow light logic
if (lightLevel < 150) {
digitalWrite(LED_PIN, LOW);
Blynk.virtualWrite(VPIN_LED_GROW_LIGHT_STATUS, 1);
} else if (lightLevel > 100) {
digitalWrite(LED_PIN, HIGH);
Blynk.virtualWrite(VPIN_LED_GROW_LIGHT_STATUS, 0);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
Wire.begin();
lightMeter.begin();
sensors.begin();
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
// Set up the actuator pin
pinMode(WATER_PUMP_PIN, OUTPUT);
pinMode(HEAT_MAT_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
// Ensure actuators are off initially
digitalWrite(WATER_PUMP_PIN, HIGH);
digitalWrite(HEAT_MAT_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
Blynk.config(auth);
Serial.println("WiFi connected");
Blynk.begin(BLYNK_AUTH_TOKEN , ssid, pass);
timer.setInterval(2000L, sendSensorData);
timer.setInterval(5000L, controlActuators);
}
void loop() {
Blynk.run();
timer.run();
}