Get Alerted When Your Plant’s Dying🌱

Tweeting and notifying the plant’s health with an ESP moisture monitoring system 💦

Ariel Liu
10 min readJun 7, 2020

Allow me to pose a question… How much do you need to mess up to kill a cactus? 🌵

I mean that thing’s literally designed for desert conditions. What idiot would manage to dry out a cactus?

Well, the answer is me…I’m that idiot 😶

https://cdn.dribbble.com/users/203287/screenshots/4389638/cacti2.gif

Operation Plant Revitalization🧠

Phew, so I can’t say I have the greenest thumb, just looking at my track record of plant murders…But I do enjoy propagating succulents (not so much cacti thou 😭) and yes, I want them to stay alive a little longer.

So here’s how I went about making sure my plants don’t die

I collected data from the moisture sensor using an ESP and sent it using Wifi to the Blynk App on my phone. This way I can monitor the water levels in the soil from my phone! The plan here is when the soil is too dry, I’ll receive a notification on my phone to water it. The ESP will consistently check the moisture, display real-time moisture data on my phone, and tweet it using my twitter account.

A flow diagram of my master plan

Preparations 🔧

Before we head straight into the coding and software there are a few hardware components we need to setup.

Read a more thorough guide on how I set up the Wifi and Arduino IDE here in my previous article!

ESP 🧰

The ESP is a chip microcontroller, similar to Arduino but better built for IoT applications. I’m using the ESP32 Dev Module which luckily has onboard WiFi and Bluetooth support, along with built-in sensors like touch, hall, and an internal temperature sensor!

ESP32: https://images-na.ssl-images-amazon.com/images/I/61RixSStGBL._AC_SX466_.jpg

ESP can be programmed with the Arduino IDE. Go to File → Preferences . Then, add this link to the Additional Board Manager URLs box.

Then go to Tools → Board → Board manager, use the search bar to find ESP32, and install the package. Make sure that under tools the correct board and port are selected and you’re all set!

Make sure it’s on the correct board

Moisture Sensor 🔑

For this project, I used the Flying Fish Soil Moisture sensor. These sensors were designed for applications such as smart agriculture projects in mind. The moisture sensor I received is composed of a probe for data collection and an electronic board equipped with a potentiometer and LEDs.

https://www.circuitstoday.com/wp-content/uploads/2017/03/Pin-out.jpg

The probes are able to measure the amount of water in the soil, and the amount of voltage that the sensor returns to the ESP depends on the moisture level. Between the probes, an electric current runs through the soil. Since the more water content in the soil, the more electricity can be conducted. When the soil is dry, there is more resistance and less electricity is conducted.

My Moisture Sensor Probe

Hooking it up to the ESP 🔌

If your moisture sensor is just a probe with a total of three pins you can connect it to the microcontroller directly. Like so…

https://hackster.imgix.net/uploads/attachments/849609/soil-moisture-tutorial-fritzing_aQgyXkStfJ.jpg?auto=compress%2Cformat&w=680&h=510&fit=max
Diagram I created at https://www.circuito.io/

Since my moisture sensor had two separate parts, the two pins from the probe connect to the two pins on the electronic board. Afterward, I connected the pins GND, A0, Vcc to their corresponding GND, 35 (any analog pin), 5V on my ESP.

My sensor model also has a DO pin which returns “1” when the moisture is below a certain amount and will otherwise return “0”. (The certain amount is adjusted by the potentiometer.)

Here’s my ESP hardware setup

The Blynk App 🤳

For this project, I chose to use the Blynk IoT platform to record the data, tweet, and send notifications! Using Blynk is really simple and it provides a convenient way to connect your electronics to the cloud, monitor data analytics, and respond to the data using pre-designed widgets.

The first thing you gotta do is download Blynk the mobile app. Luckily it’s available for both iOS and Andriod.

The Blynk App

Create a new project, and start adding widgets! Use the plus icon on the top left to add a widget. I started with a Value Display and named it “Moisture”. Then I set the input to virtual pin 5, and the reading rate to “Push”. I also added another Value Display (set to pin V4), along with twitter and notification widgets.

My Blynk widgets

After, you’ve set up the app head over to the Arduino IDE and install the Blynk library. The Blynk library will handle the complexities of connection and data exchange. Go to Sketch → Library → Manage Libraries(Ctrl+Shift+I), search for the Blynk library, and install it. Check that it’s listed under Sketch → Include Library.

You can also install Blynk as a ZIP file, download the file here. Then go to Sketch → Include Library → Add.ZIP Library and upload the Zip file.

Step by Step Guide on Installing the Blynk Library — by Blynk

Plant 🌱

Step 1: Grab a potted plant!

And…. you're done! 🎉

Null in all his undying glory

Here’s my plant Null! (Don’t mind the antennas, they were leftover from Christmas haha…🦌)

Coding the Project 💻

This time around, I’m gonna explain this project’s code broken down into separate sections: writing to Blynk, reading data from the moisture sensor, Tweeting the data, and sending notifications to your phone. At the end of this section, I’ll include the full code.

Blynk🔗

First head to the Blynk App and open up your project. Click the nut 🔩 symbol on the top right to open up — Project Settings. Then scroll down to Auth Tokens, we’ll be using this token to write to the Blynk App.

Blynk Auth Tokens

I’ll start off by importing a few libraries we’ll need to connect to Wifi and communicate with the Blynk App.

#define BLYNK_PRINT Serial#include "secrets.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>

Within the void setup loop, I’m initiating Blynk.

//Start Blynk
Blynk.begin(auth, ssid, pass);

Writing to Blynk is really simple, it only requires a single line of code and two arguments. The first argument is the virtual pin of the widget we’re writing to, and the second is just the value we’re writing!

//Write to Blynk
Blynk.virtualWrite(V5, sensorValue);

I don’t really want to overlap with my previous articles, so I didn’t explain in depth about the Wifi stuff. Please head over to this article where I talk about setting up my wifi connection on ESP32.

Moisture Sensor 💦

My moisture sensor returns a value in the range of 0 to 4200. 0 means the soil is completely soaked while 4200 means the soil is really dry.
Using the analogRead function we can easily get the reading from the moisture sensor.

//Read Moisture Value
sensorValue = analogRead(sensorPin);

We can take this one step further and convert it to a percentage that’s easier to understand. I used the map function in Arduino to remap the raw moisture data.

int percentValue = 0;
//0 is wet and 4200 is dry
percentValue = map(value, 4200, 0, 0, 100);
//value, lower bound, upper bound, lower bound of target, higher bound of target

Tweeting Data! 🐤

By signing into your Twitter account on the Blynk Tweet widget, you can tweet out different messages! There are a few rules though, you can’t tweet the same message, and you can only tweet in about 5-second intervals.

In this case, I wanted to tweet the time and date along with the current moisture level. To do this I connect my ESP to the Internet and receive the current time using the Network Time Protocol (NTP). NTP is the standard IP (Internet Protocol) that computers synchronize to.

#include <time.h>
int timeoffset = -5 * 60 * 60;
int dst = 3600;
// Start Time from NTP
configTime(timeoffset, dst, "pool.ntp.org", "time.nist.gov");
// Timeoffset represents the UTC offset for your specific timezone. I used this list of timezones.// Dst stands for daylight saving time, set this to 3600 if you have daylight saving and 0 if you don’t.

All we need to do is get the current date and time…

time_t now = time(nullptr);
String time_t = ctime(&now);

Then, Tweet it using the Blynk.tweet() function!

String message = time_t + " The moisture is at " + sensorValue;

Blynk.tweet(message);

Phone Notification — App 📱

Maybe Twitter isn’t your style, but using notifications is more down your alley! In fact, you can set up notifications on your phone that’ll warn you when your plant’s soil is drying out or when it’s turned into swampland. Before I talk about the code, make sure that you have the notification widget setup in Blynk for this to work.

So, the code for sending a notification using Blynk is just Blynk.notify(Whatever you want to say);. However, we want to receive an alert only when the soil is too wet or too dry. So I set up a few conditional statements. (Remember 4200 is very dry, 0 is completely wet.)

void notif(){
if (sensorValue >= 3000){
//TOO DRY
Blynk.notify("Hurry and water your plant! It's too dry!");
Serial.println("Notif sent: Too dry");
}
else if (sensorValue <= 500){ //Change this value as needed
//TOO WET
Blynk.notify("Stop watering! Your plant is too wet!");
Serial.println("Notif sent: Too wet");
}
}

Here are a few example notification messages…

The Different Notifications I’ve set up

Complete Code 👨‍💻

Congrats, we’re done!🥳

#define BLYNK_PRINT Serial#include "secrets.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
#include <time.h>
char auth[] = SECRET_AUTH; //Blynk Auth Token
char ssid[] = SECRET_SSID; //Wifi name from secrets.h
char pass[] = SECRET_PASS; //Wifi password from secrets.h
WiFiClient client;
BlynkTimer timer;
//Variables for sensor data
int sensorPin = 35;
int sensorValue = 0;
int percent = 0;
//Variables for time
int timeoffset = -5 * 60 * 60;
int dst = 3600;
void setup()
{
// Debug console
Serial.begin(9600);
WiFi.mode(WIFI_STA);

//Start Blynk
Blynk.begin(auth, ssid, pass);
Serial.print("Connected");
// Start Time from NTP
configTime(timeoffset, dst, "pool.ntp.org", "time.nist.gov");
timer.setInterval(5000L, read_data); //Every 5 secs run

}
void read_data(){
//Read Moisture Value
sensorValue = analogRead(sensorPin);

//Map Moisture Value
percent = ValuetoPercent(sensorValue);
//Write to Blynk
Blynk.virtualWrite(V5, sensorValue);
Blynk.virtualWrite(V4, percent);

//Debug by printing to Serial
Serial.print("Raw Sensor reading: ");
Serial.println(sensorValue);
Serial.print("Percentage converted: ");
Serial.println(percent);
//Tweet Moisture Value
//Message contains: Time + Value
tweet_value();
//Notify if too wet or too dry
notif();
}int ValuetoPercent(int value)
{
int percentValue = 0;
//0 is wet and 4200 is dry
percentValue = map(value, 4200, 0, 0, 100); //value, lower bound, upper bound, lower bound of target, higher bound of target
return percentValue;

}
void tweet_value(){
time_t now = time(nullptr);
String time_t = ctime(&now);
//Serial.println(time_t);
String message = time_t + " The moisture is at " + sensorValue;
Serial.print(" Tweeted: ");
Serial.println(message);

Blynk.tweet(message);
}
void notif(){
if (sensorValue >= 3000){
//TOO DRY
Blynk.notify("Hurry and water your plant! It's too dry!");
Serial.println("Notif sent: Too dry");
}
else if (sensorValue <= 500){
//TOO WET
Blynk.notify("Stop watering! Your plant is too wet!");
Serial.println("Notif sent: Too wet");
}
}
void loop()
{
Blynk.run();
timer.run();

}

Mistakes to Avoid💨

  • Test each of the parts separately, then put them all together when each part works. I coded the program in 6 parts: reading from the moisture sensor, sending test data to Blynk, creating notifications, and posting test data to twitter (this was broken up further into posting tweets, and getting the time from NTP).
  • If you’re not getting the notifications…
  • Make sure you’re in play mode.
  • The top-right icon should turn into a square.
  • Make sure that the Value Displays are set to the correct pin, the same one you’re writing to from the ESP!
  • Make sure you installed the Blynk Library, you can also use some of their example code to test. Go to File → Examples and scroll to Examples from custom libraries.

If you want to read more articles in the future, give my account a follow!

In the meantime, feel free to contact me at ariel.yc.liu@gmail.com or connect with me on LinkedIn.

You can also read my monthly newsletter here!

Or visit my personal website to see my full portfolio here!

Till next time! 👋

--

--

Ariel Liu

A machine learning enthusiast who’s always learning~