Skip to content

Instantly share code, notes, and snippets.

@sudoalx
Last active August 18, 2023 01:06
Show Gist options
  • Save sudoalx/09a0611361149d748f744a2eafc807b4 to your computer and use it in GitHub Desktop.
Save sudoalx/09a0611361149d748f744a2eafc807b4 to your computer and use it in GitHub Desktop.
This Gist features ESP32 code for an IoT plant monitoring system using Ubidots. It reads soil humidity, water level, and controls a pump for automated watering. Real-time data is sent to Ubidots for monitoring and control, enhancing plant care.
/****************************************
* Include Libraries
****************************************/
#include "UbidotsEsp32Mqtt.h"
/****************************************
* Define Constants
****************************************/
const char *UBIDOTS_TOKEN = <UBIDOTS-TOKEN>; // Insert your Ubidots TOKEN here
const char *WIFI_SSID = <WIFI SSID>; // Insert your Wi-Fi SSID here
const char *WIFI_PASS = <WIFI PASSWORD>; // Insert your Wi-Fi password here
const char *DEVICE_LABEL = <DEVICE LABEL>; // Insert your device label where data will be published
const char *HUMIDITY_LABEL = <DEVICE LABEL>; // Insert your humidity variable label
const char *PUMP_LABEL = <DEVICE LABEL>; // Insert your pump variable label
const char *WATER_LEVEL_LABEL = <DEVICE LABEL>; // Insert your water level variable label
const int HUMIDITY_PUBLISH_INTERVAL = 2000; // Humidity publishing interval in milliseconds (30 minutes)
const int PUMP_RUNTIME = 180000; // Pump operating duration in milliseconds (3 minutes)
const int HUMIDITY_THRESHOLD = 300; // Humidity threshold value, adjust as needed
const int WATER_LEVEL_SENSOR_PIN = 35; // Pin connected to the water level sensor
unsigned long humidityTimer;
unsigned long pumpTimer;
unsigned long waterLevelTimer; // Timer for water level readings
uint8_t analogPin = 34; // Pin used to read data from GPIO34 ADC_CH6.
uint8_t pumpPin = 32; // Pin used to control the water pump
Ubidots ubidots(UBIDOTS_TOKEN);
/****************************************
* Auxiliar Functions
****************************************/
void callback(char *topic, byte *payload, unsigned int length)
{
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
Serial.println();
}
bool isWaterLevelLow()
{
int waterLevelValue = analogRead(WATER_LEVEL_SENSOR_PIN);
// Assuming the sensor output is lower when water level is low (adjust this condition if it's the opposite)
return (waterLevelValue < 500); // Adjust the threshold value as needed
}
/****************************************
* Main Functions
****************************************/
void setup()
{
Serial.begin(115200);
pinMode(pumpPin, OUTPUT); // Configure the pump pin as output
digitalWrite(pumpPin, LOW); // Turn off the pump initially
// ubidots.setDebug(true); // Uncomment this line to enable debug messages
ubidots.connectToWifi(WIFI_SSID, WIFI_PASS);
ubidots.setCallback(callback);
ubidots.setup();
ubidots.reconnect();
humidityTimer = millis();
pumpTimer = 0; // Initialize the pump timer to 0 to ensure it doesn't trigger initially
waterLevelTimer = millis(); // Initialize the water level timer to current millis
}
void loop()
{
if (!ubidots.connected())
{
ubidots.reconnect();
}
unsigned long currentMillis = millis();
float humidity = analogRead(analogPin) / 10;
// Publish humidity every 30 minutes
if (currentMillis - humidityTimer >= HUMIDITY_PUBLISH_INTERVAL)
{
ubidots.add(HUMIDITY_LABEL, humidity); // Insert your humidity variable label and the value to send
ubidots.publish(DEVICE_LABEL);
humidityTimer = currentMillis;
}
// Print humidity every 15 seconds on the serial monitor
if (currentMillis % 15000 == 0)
{
Serial.print("Soil Humidity: ");
Serial.println(humidity);
}
// Water pump control based on soil humidity
if (currentMillis - pumpTimer >= PUMP_RUNTIME)
{
digitalWrite(pumpPin, LOW); // Turn off the pump once the operating duration is reached
// If soil humidity is low (analog value >= 300 after scaling)
if (humidity >= HUMIDITY_THRESHOLD)
{
digitalWrite(pumpPin, HIGH); // Turn on the pump
pumpTimer = currentMillis; // Restart the pump timer
Serial.println("Pump turned on");
Serial.println(humidity);
}
else
{
digitalWrite(pumpPin, LOW); // Turn off the pump
Serial.println("Pump turned off");
}
}
// Water level control - publish and print every 5 seconds
if (currentMillis - waterLevelTimer >= 15000)
{
if (isWaterLevelLow())
{
// Water level is low, take appropriate action (e.g., send notification)
Serial.println("Water level is low");
ubidots.add(WATER_LEVEL_LABEL, 0); // Water level is low, send value 0
}
else
{
// Water level is high, take appropriate action (e.g., send notification)
Serial.println("Water level is high");
ubidots.add(WATER_LEVEL_LABEL, 1); // Water level is high, send value 1
}
// Send water level data to Ubidots
ubidots.publish(DEVICE_LABEL);
waterLevelTimer = currentMillis; // Reset the water level timer
}
ubidots.loop();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment