How to Make a Smart Pot Plant

by tseknoujake in Circuits > Arduino

881 Views, 15 Favorites, 0 Comments

How to Make a Smart Pot Plant

IMG_6546.jpg
SmartPot

Picture this: You've just left your home for the day, the sun is out, and you are on your way to see your friends. On the way over, you get a sinking feeling in your stomach and suddenly remember: "My plant!"

You forgot to water your favourite green friend...

Say goodbye to this issue, with the novel and innovative solution: The SmartPot.

The SmartPot allows you to measure and track the temperature, humidity, light level, and soil moisture percentage of your favourite plant.

And the best part? It can all be done from your favourite technological friend: the smartphone.

The SmartPot uses Telegram to send messages to the device of your choice, serving as a reminder to update the conditions for your plant, in order to ensure the optimal environment. Additionally, the SmartPot makes use of Blynk, Make.com, and the Arduino ESP32 to allow for the best user interface.


In this tutorial, I will demonstrate how you can make your very own SmartPot in a few easy steps!


P.S. I've done all the coding for you all you need to do is make a few minor adjustments, this will be a breeze :)


Note: the Images appear in the order of steps, most steps correlate to an image in the same order...

Supplies

download.jpg
download.jpg
images.jpg
capacitive-soil-moisture-sensor-module-3.jpg
download.jpg
esp32 breadboard keyeyestudio.png
esp32 led strip.jpg
cable-for-data-transfer-and-usb-20-micro-usb-charging-eco-pack.jpg
istockphoto-1330360581-612x612.jpg
  1. ESP32
  2. DHT22 Sensor
  3. Light Senor
  4. Capacitive Soil Moisture sensor
  5. Jumper cables
  6. 12 light LED strip
  7. Data transferrable MicroUSB
  8. Your favourite pot plant
  9. Blynk account
  10. Make.com account
  11. Arduino IDE
  12. Telegram account

Programming the SmartPot in Arduino IDE

In this step my code is presented to you. This is the backbone for the functionality of your SmartPot. Copy and paste this code into your arduino IDE. You will need to edit the bold sections that say TODO with your information to make it work in your environment. Later steps will provide you with the information that you need to input.


The code:


#include <WiFi.h>

#include <HTTPClient.h>

#include <DHT.h>

#include <ESP32Servo.h>

#include <Adafruit_NeoPixel.h>


#define DHTPIN 4

#define DHTTYPE DHT22

#define SOIL_MOISTURE_PIN 34

#define LIGHT_SENSOR_PIN 35

#define LED_PIN 23

#define NUM_LEDS 12


//for blynk

// Replace all TODOs with your details

#define BLYNK_TEMPLATE_ID "TODO_5"

#define BLYNK_TEMPLATE_NAME "TODO_6"

#define BLYNK_AUTH_TOKEN "TODO_7"


/* Comment this out to disable prints and save space */

//#define BLYNK_PRINT Serial

#include <BlynkSimpleEsp32.h>


//


const char* ssid = "TODO_1"; // Replace "TODO" with your WiFi name

const char* password = "TODO_2"; // Replace "TODO" with your WiFi password


//for make.com

// webhook for stats

const char* webhookUrlStats = "TODO_3"; // Replace "TODO" with your first webhook

//webhook for reminder

const char* webhookUrlReminder = "TODO_4"; // Replace "TODO" with your second webhook




int counter = 0;

boolean firstDip = true;


DHT dht(DHTPIN, DHTTYPE);

//Servo myServo;

Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);




// Calibration values

const int DRY_VALUE = 3500; // Adjust this value based on your dry soil reading

const int WET_VALUE = 1500; // Adjust this value based on your wet soil reading

//

void setup() {

 Serial.begin(115200);

 dht.begin();

 Blynk.begin(BLYNK_AUTH_TOKEN, ssid, password);

 pinMode(SOIL_MOISTURE_PIN, INPUT);

 pinMode(LIGHT_SENSOR_PIN, INPUT);

 strip.begin();

 strip.show(); // Initialize all pixels to 'off'


 // Connect to WiFi

 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {

  delay(1000);

  Serial.println("Connecting to WiFi...");

 }

 Serial.println("Connected to WiFi");

 // sendToMake

}


void loop() {

 Blynk.run();

 float humidity = dht.readHumidity();

 float temperature = dht.readTemperature();



 Serial.print("Humidity: ");

 Serial.print(humidity);

 Serial.print(" %\t");

 Serial.print("Temperature: ");

 Serial.print(temperature);

 Serial.println(" *C");


 int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);

 int moisturePercentage = map(soilMoistureValue, DRY_VALUE, WET_VALUE, 0, 100);

 moisturePercentage = constrain(moisturePercentage, 0, 100); // Ensure the percentage is between 0 and 100

 Serial.print("Soil Moisture Percentage: ");

 Serial.print(moisturePercentage);

 Serial.println("%");


 updateLEDStrip(moisturePercentage);


 // if moisture level <20% we want to send a notification and then every 8 hours remind the user they need to water

 if ((moisturePercentage <= 20) && (counter == 0)) {


  // set counter to 8 hours (28800 seconds in 8 hours)

  firstDip = false;

  counter = 28800;

  waterReminder(moisturePercentage);

 } else if (!firstDip) {

  counter--;

 }


 if (moisturePercentage>20){

  firstDip=true;

  counter=0;

 }


 int lightValue = analogRead(LIGHT_SENSOR_PIN);

 int lightPercentage = map(lightValue, 0, 4095, 100, 0);

 Serial.print("Light Level (Percentage): ");

 Serial.print(lightPercentage);

 Serial.println("%");


 //writes temp to blynk guage

 Blynk.virtualWrite(V1, temperature);

 //writes humidity to blynk guage

 Blynk.virtualWrite(V2, humidity);

 //writes moisture to blynk guage

 Blynk.virtualWrite(V3, moisturePercentage );

 //writes light percentage to blynk guage

 Blynk.virtualWrite(V4, lightPercentage);




 // Send data to Make.com

 // sendToMake(humidity, temperature, moisturePercentage, lightPercentage);


 delay(1000); // Wait for 1 second before the next reading

}


BLYNK_WRITE(V0) {

 // Call sendToMake with current readings

 int switchValue = param.asInt(); // Get the value of the switch


 if (switchValue == 1) { // If the switch is ON

  // Call sendToMake with current readings

  float humidity = dht.readHumidity();

  float temperature = dht.readTemperature();

  int soilMoistureValue = analogRead(SOIL_MOISTURE_PIN);

  int moisturePercentage = map(soilMoistureValue, DRY_VALUE, WET_VALUE, 0, 100);

  moisturePercentage = constrain(moisturePercentage, 0, 100);

  int lightValue = analogRead(LIGHT_SENSOR_PIN);

  int lightPercentage = map(lightValue, 0, 4095, 100, 0);


  sendToMake(humidity, temperature, moisturePercentage, lightPercentage);

 }


}


void updateLEDStrip(int moisturePercentage) {

 // LED strip update code remains the same

 int ledsOn = map(moisturePercentage, 0, 100, 1, NUM_LEDS);


 for (int i = 0; i < NUM_LEDS; i++) {

  if (i < ledsOn) {

   uint32_t color;

   if (moisturePercentage >= 80) {

    color = strip.Color(0, 255, 0); // Green

   } else if (moisturePercentage >= 50) {

    int red = map(moisturePercentage, 50, 80, 255, 0);

    int green = map(moisturePercentage, 50, 80, 165, 255);

    color = strip.Color(red, green, 0);

   } else if (moisturePercentage >= 10) {

    int green = map(moisturePercentage, 10, 50, 0, 165);

    color = strip.Color(255, green, 0);

   } else {

    color = strip.Color(255, 0, 0); // Red

   }

   strip.setPixelColor(i, color);

  } else {

   strip.setPixelColor(i, strip.Color(0, 0, 0)); // Turn off

  }

 }

 strip.show();

}


void sendToMake(float humidity, float temperature, int moisturePercentage, int lightPercentage) {

 if (WiFi.status() == WL_CONNECTED) {

  HTTPClient http;


  http.begin(webhookUrlStats);

  http.addHeader("Content-Type", "application/json");


  String jsonData = "{\"humidity\":" + String(humidity, 2) + ",";

  jsonData += "\"temperature\":" + String(temperature, 2) + ",";

  jsonData += "\"moisturePercentage\":" + String(moisturePercentage) + ",";

  jsonData += "\"lightPercentage\":" + String(lightPercentage) + "}";


  Serial.println("Sending JSON data: " + jsonData); // Debug output for JSON data


  int httpResponseCode = http.POST(jsonData);


  if (httpResponseCode > 0) {

   String response = http.getString();

   Serial.println(httpResponseCode);

   Serial.println(response);

  } else {

   Serial.print("Error on sending POST: ");

   Serial.println(httpResponseCode);

  }


  http.end();

 } else {

  Serial.println("Error in WiFi connection");

 }

}


void waterReminder(int moisturePercentage ) {


 if (WiFi.status() == WL_CONNECTED) {

  HTTPClient http;


  http.begin(webhookUrlReminder);

  http.addHeader("Content-Type", "application/json");


  // Construct the message

  String message = "Please water me! My water level is " + String(moisturePercentage) + "%";


  // Create JSON payload

  String jsonData = "{\"message\":\"" + message + "\"}";


  Serial.println("Sending JSON data: " + jsonData); // Debug output for JSON data


  // Send the POST request

  int httpResponseCode = http.POST(jsonData);


  if (httpResponseCode > 0) {

   String response = http.getString();

   Serial.println(httpResponseCode);

   Serial.println(response);

  } else {

   Serial.print("Error on sending POST: ");

   Serial.println(httpResponseCode);

  }


  http.end();

 } else {

  Serial.println("Error in WiFi connection");

 }


}

Giving Your ESP32 Wifi Access

Locate the following given section in the code, completing the instructions given in bold:


const char* ssid = "TODO_1"; // Replace "TODO" with your WiFi name

const char* password = "TODO_2"; // Replace "TODO" with your WiFi password



(If your WiFi doesn't have a password, leave this section blank) eg:

const char* password = ""; 

Connecting Components to Board

IMG_6536.jpeg
IMG_6537.jpg
IMG_6538.jpg
IMG_6539.jpg
  1. Connect DHT22 to pin 4
  2. Connect Soil Moisture Sensor to pin 34
  3. Connect Light sensor to pin 35
  4. Connect LEDs to pin 23

Making Your Telegram Bot

Follow the steps on the following link. Note that you don't have to add any features to the bot.

How to Create a Telegram Bot With No Coding? | Directual.com


Make.com Scenario No.1

0.png
1.png
2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png
  1. Go to make.com > "scenarios" > "Create a new scenario"
  2. Now click the big plus and search "custom webhook" then select the following option seen in the first image
  3. Click "Add"
  4. Name this webhook to "webhook1" then select this connection under "connections"
  5. Copy the address and go to your Arduino IDE and where it says "TODO_3", replace this text with the copied address
  6. Click "add another module"
  7. Search "Telegram Bot send text" and select the module shown in the image above
  8. Click under connections select "Add"
  9. Under connection name, name it "bot1" and under token, go to the chat with your BotFather and copy your telegram bot token (BotFather should have sent it to you, if not just message BotFather /start), then click save
  10. Now under chatID, to acquire your chatID, search for RawDataBot on telegram and message it /start, RawDataBot should send you your ID. Paste this chatID into this field.
  11. Copy the following message and paste this in:

"Hello! Thanks for checking up on me!

Humidity Level: {{2.humidity}}%

Temperature: {{2.temperature}} °C

Soil Moisture Percentage: {{2.moisturePercentage}}%

Light Level: {{2.lightPercentage}}%"


Your final product should look like the above image, now click "OK".


Before we are finished with this scenario, set scheduling to "ON" and make sure the scheduling is on "Immediately as data arrives"


Make sure you've saved this scenario.

Make.com Scenario No.2

FLVZW8KLZSFO2ML.png
F5CWULILZTV3NKS.png
FYYP6GALZTV3P91.png
22.png
  1. Create another new scenario
  2. Again add the same custom webhook module but this time add a new one and name it "webhook2"
  3. Copy address to clipboard and where your code says "TODO_4" replace this text with the copied address (like we've done before, the address should be different to your previous one)
  4. Now add a new module like before and search: "Telegram Bot send text" and select the module shown in the image above
  5. Select the connection "bot1" and insert your personal chat ID like before.
  6. Under the text field paste the following text in:

"Warning:

{{3.message}}"


Finally click "OK" and set Scheduling to "ON" and scheduling setting to "On Demand" like earlier. Save and exit make.com

Blynk Configuration

10.png
11.png
12.png
13.png
14.png
15.png
16.png
17.png
18.png
19.png
20.png
21.png
23.png
24.png
25.png
26.png
27.png
28.png
  1. Open Blynk > "Developer Zone" > "My templates" then click new template
  2. Name this template "Smart Pot" and select "ESP32" under he hardware field
  3. Go to "DataStreams" > "New Data stream" > "virtual pin" then set the configuration to the same as above (for Integer V0)
  4. Create 4 more new data virtual pins and set the information as seen above (for TEMP V1, Humidity V2, Moisture V3 and light percentage V4)
  5. Now save. Go home and click "Add first device" and name it "decive1" then save.
  6. Now click on the pop up in the top left corner now replace TODO_5 with your template ID, replaced TODO_6 with your template name, and replace TODO_7 with your Auth token.


You are officially done the coding section of this Instructable!


Now you can design your web dashboard:

  1. Go to Web Dashboard
  2. Click "Edit"
  3. Drag 1 switch and 4 gauges onto your dashboard in your desired design
  4. Now click the settings cog on your switch and edit your settings to look the exact same as my settings
  5. Now do this for the rest of the gauges and copy what I've done for each of them (see images above). You can obviously change the colours to your preference.
  6. Once your dashboard looks similar to the one seen above you can click "save and apply"


You are now done your blynk dashboard. You can also make a dashboard on the mobile app in a similar manner if you want to see your plant stats on the go.

Finishing Touches

All thats left to do now is to upload the code to your arduino and set up all the sensors in a way around your plant that suits you best. Make sure you can see the LED strip (this indicates the water moisture level) and make sure the light sensor is on the outside of the pot in order to accurately detect light.


Also make sure the soil moisture sensor is deep in the soil in order to get the most accurate readings