Johan van Vugt
Published © GPL3+

ESP8266 - Solar Moisture Sensor with Supercapacitors

This moisture sensor sends hourly updates to Ubidots and Pushover, and runs for years on solar power.

IntermediateFull instructions provided4 hours4,483
ESP8266 - Solar Moisture Sensor with Supercapacitors

Things used in this project

Hardware components

ESP8266 ESP-12E
Espressif ESP8266 ESP-12E
×1
solar panel 5V
×1
1N5817 Schottky diode
×1
Super capacitor 22F 2,5V
×2
LMS33460 Voltage detector/supervisor 3V
×1
HT7833 -voltage regulator 3.3v
×1
Capacitor 1 µF
Capacitor 1 µF
×1
Capacitor 2.2 uF
×1
Resistor 470K Ohm
×2
Resistor 220K Ohm
optional
×1
SparkFun Soil Moisture Sensor (with Screw Terminals)
SparkFun Soil Moisture Sensor (with Screw Terminals)
or similar
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Moisture Garden.jpg

Code

ESP-12E Moisture Garden Solar Supercaps Ubidots Pushover

C/C++
#include "Pushover.h"
#include <UbidotsMicroESP8266.h>
#include <ESP8266WiFi.h>


// YL-69 humidity sensor
byte humidity_sensor_pin = A0;
byte humidity_sensor_vcc = 14;

//variables
int categoryRead;
int categoryNew;
int value;
int valuePercent;
String messageSend;
int sleepTimeS = 4260; // sleep in seconds . max ongeveer 71 minuten (4260 sec).

//UBIDOTS//
#define ubidotsDevice  "********"
#define ubidotsVariableLabel  "********"
#define ubidotsVariable "********" // Put your variable ID here
#define ubidotsToken  "********"  // Put here your Ubidots TOKEN
Ubidots client(ubidotsToken);


//PUSHOVER//
const char pushoverToken [] = "********"; //Application: Garden Moisture
const char pushoverUser [] = "********";


//WIFI//
#define ssid  "********"  //  your network SSID (name)
#define pass  "********"   // your network password




void setup() {
  Serial.begin(115200);
  WiFi.persistent(false); //only write credentials to flash when empty. saves time and flash
  WiFi.begin(ssid, pass); 

  int tries = 0;
  while (WiFi.status() != WL_CONNECTED) { //wait short time for connection
    delay(500);
    tries++;
    Serial.println (tries);
    if (tries > 16) {
      break;
      Serial.println ("not connected!");
    }
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println ("Wifi connected!");
    
   //get latest ubidots value
    int latestUbidotsValue = client.getValueWithDevice(ubidotsDevice, ubidotsVariableLabel); 
    Serial.print("Latest value obtained: ");
    Serial.println(latestUbidotsValue);

    //categorize latest ubidots value
    if (latestUbidotsValue > 80) {
      categoryRead = 5;
    }
    if (latestUbidotsValue > 60 && latestUbidotsValue <= 80) {
      categoryRead = 4;
    }
    if (latestUbidotsValue > 40 && latestUbidotsValue <= 60) {
      categoryRead = 3;
    }
    if (latestUbidotsValue > 20 && latestUbidotsValue <= 40) {
      categoryRead = 2;
    }
    if (latestUbidotsValue <= 20) {
      categoryRead = 1;
    }

    //Measure moisture value
    Serial.println ("Measuring...");
    pinMode(humidity_sensor_vcc, OUTPUT);
    pinMode(humidity_sensor_pin, INPUT);
    digitalWrite(humidity_sensor_vcc, HIGH);
    delay(100); //100ms seems to work 
    value = analogRead(humidity_sensor_pin);
    digitalWrite(humidity_sensor_vcc, LOW);
    pinMode(humidity_sensor_vcc, INPUT);
    pinMode(humidity_sensor_pin, OUTPUT);
    Serial.print ("value: ");
    Serial.println (value);
    if (value < 250) { //to prevent outliers above 100%
      value = 250;
    }
    if (value > 935) { //to prevent outliers under 0%
      value = 935;
    }
    Serial.print ("valuecorrected: ");
    Serial.println (value);
    valuePercent = map(value, 250, 935, 100, 0); //min stable: 265 (in water) max: 935 (air) is maximum stable reading.

    // upload latest measurement to ubidots
    client.add(ubidotsVariable, valuePercent);
    client.sendAll(false);

    //categorize new measurement
    if (valuePercent > 80) {
      categoryNew = 5;
    }
    if (valuePercent > 60 && valuePercent <= 80) {
      categoryNew = 4;
    }
    if (valuePercent > 40 && valuePercent <= 60) {
      categoryNew = 3;
    }
    if (valuePercent > 20 && valuePercent <= 40) {
      categoryNew = 2;
    }
    if (valuePercent <= 20) {
      categoryNew = 1;
    }

    // Push notification if category old reading is different from category new reading. In other words: only send a push notification when categeory changes. To prevent getting swamped with notifications.
    if (categoryNew != categoryRead) {
      PushoverNotifications();
    }
  }
  //sleep
  ESP.deepSleep(sleepTimeS * 1000000);
}

void PushoverNotifications() { //this part needs cleaning up. possible to make much shorter
  if (valuePercent > 80) {
    // You can use strings. special symbols like % do not work. for percentage sign use code %25. See:https://en.wikipedia.org/wiki/Percent-encoding
    String valueString = String (valuePercent); 
    String messageSend = String ("Your plants are drowning! (" + valueString + "%25)");
    Pushover po = Pushover (pushoverToken, pushoverUser);
    po.setHTML(1);
    po.setUrl("https://app.ubidots.com/ubi/public/getdashboard/page/MCGcKLgLdrN-pQyJoCeuv2I2lgQ");
    po.setUrlTitle("Ubidots");
    po.setMessage(messageSend);
    po.setTitle("Garden");
    po.setSound("bike");
    po.send(); //should return 1 on success

  }
  if (valuePercent > 60 && valuePercent <= 80) {
    String valueString = String (valuePercent);
    String messageSend = String ("Moisture level is HIGH (" + valueString + "%25)");
    Pushover po = Pushover (pushoverToken, pushoverUser);
    po.setHTML(1);
    po.setUrl("https://app.ubidots.com/ubi/public/getdashboard/page/MCGcKLgLdrN-pQyJoCeuv2I2lgQ");
    po.setUrlTitle("Ubidots");
    po.setMessage(messageSend);
    po.setTitle("Garden");
    po.setSound("bike");
    po.send(); //should return 1 on success
  }
  if (valuePercent > 40 && valuePercent <= 60) {
    String valueString = String (valuePercent);
    String messageSend = String ("Moisture level is MEDIUM (" + valueString + "%25)");
    Pushover po = Pushover (pushoverToken, pushoverUser);
    po.setHTML(1);
    po.setUrl("https://app.ubidots.com/ubi/public/getdashboard/page/MCGcKLgLdrN-pQyJoCeuv2I2lgQ");
    po.setUrlTitle("Ubidots");
    po.setMessage(messageSend);
    po.setTitle("Garden");
    po.setSound("bike");
    po.send(); //should return 1 on success
  }
  if (valuePercent > 20 && valuePercent <= 40) {
    String valueString = String (valuePercent);
    String messageSend = String ("Moisture level is LOW (" + valueString + "%25)");
    Pushover po = Pushover (pushoverToken, pushoverUser);
    po.setHTML(1);
    po.setUrl("https://app.ubidots.com/ubi/public/getdashboard/page/MCGcKLgLdrN-pQyJoCeuv2I2lgQ");
    po.setUrlTitle("Ubidots");
    po.setMessage(messageSend);
    po.setTitle("Garden");
    po.setSound("bike");
    po.send(); //should return 1 on success

  }
  if (valuePercent <= 20) {
    String valueString = String (valuePercent);
    String messageSend = String ("YOUR PLANTS ARE THIRSTY! (" + valueString + "%25)");
    Pushover po = Pushover (pushoverToken, pushoverUser);
    po.setHTML(1);
    po.setUrl("https://app.ubidots.com/ubi/public/getdashboard/page/MCGcKLgLdrN-pQyJoCeuv2I2lgQ");
    po.setUrlTitle("Ubidots");
    po.setMessage(messageSend);
    po.setTitle("Garden");
    po.setSound("bike");
    po.send(); //should return 1 on success

  }
}

void loop() {
}

Credits

Johan van Vugt

Johan van Vugt

3 projects • 5 followers

Comments