We run in a busy world where we find it difficult to water plants on time. It was found that gardeners used so much water in their gardens or on their balconies that they lost track of things. The result is that the plants are often either too dry or have to deal with floods. As far as the environment is concerned, it is necessary to take precautions against possible floods beforehand and to be careful not to waste too much water unnecessarily. Otherwise, we will have to deal with serious consequences in the future, such as water shortages, droughts, and so on. With Automatic Plant Watering Systems, you don't need to worry about your plants being thirsty.
The idea is to measure temperature, humidity automatically, and moisture levels, transmit them wirelessly via BT and can control a hose if necessary, which can also be controlled remotely via an app from anywhere in the world. The moisture and temperature data are constantly fed to a TinyML model to water the plant based on the inference. An automatic plant watering system ensures that plants get just the right amount of water at just the right time. You can use the Automatic Plant Watering System to care for all your plants effortlessly 24*7.
I'll be using the Nordic Thingy:53 which has numerous in-built sensors (Temperature, Humidity, Pressure, Gas, Inertial measurement unit (IMU), Magnetometer, Low-power accelerometer, Color, and light sensor), and a Gas sensor to measure temperature, humidity levels using edge impulse.
NodeMCU is programmed to control the functioning of the water pump and to measure the soil moisture level.
We will be setting up the Nordic Thingy 53 for edge impulse classification.
IDE setup- Connect the development board to your computer
- Use a USB cable to connect the development board to your computer. Then, set the power switch to 'on'.
- Download the latest Edge Impulse firmware: Edge Impulse firmware: nordic-thingy53-full.zip
- Open nRF Connect for Desktop and launch the Programmer app. Move the power switch SW1 to the OFF position. Take off the top cover to access the SW2 button. Press SW2 while switching SW1 to the ON position.
- Update the firmware
We will use edge impulse to build & train the TensorFlow Lite model. We will be collecting the gas sensor data for the following cases
- Temperature
- Humidity
- Pressure
We will be creating an edge impulse project named Thingy 53: Env sensing. Running the following command will require your edge impulse email & password.
edge-impulse-daemon
We have a 65% & 35% split for training and testing data. Next, we create Impulse and add the processing block with Flattern that Flatten an axis into a single value, useful for slow-moving averages like temperature data, in combination with other blocks. Next, we add a Keras Classification learning block, then click on Save Impulse. Next, we click the Generate features to train the model. After a few minutes, we can see the output in the Feature Explorer.
You can visualize the features using the feature explorer.
Connect the soil moisture sensor and water pump to the nodemcu as shown below. The main goal of this project is to implement a cost-effective and efficient solution for watering our plants automatically using IoT that uses sensors, Wi-Fi-enabled microcontrollers, and cloud systems. This can be done by sending the soil moisture data to the cloud to be accessed anywhere and anytime. A smartphone or tablet application is also provided to automate the process of watering plants. This device can measure soil humidity/moisture in percentage (%). When the soil is wet, it will have a higher resistance between AO and GND pins, if it is dry it will have lower resistance between AO and GND pins. A TinyML model is generated to water the plants automatically.
Connections:
NodeMCU ------------------------------------- Soil Moisture Sensor
VCC -> Vcc
GND -> Ground
IO32 -> Signal
NodeMCU ------------------------------------- Water pump
VCC -> Vcc
IO22 -> Signal
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
#define SENSOR_PIN 32
#define PUMP 22
int sensorValue = 0, set_time[3] = {7, 14, 23}; // variable to store the value coming from the sensor
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
Wire.begin();
setDS3231time(30, 42, 16, 5, 13, 10, 16);
pinMode(32, INPUT); //MOISTURE SENSOR
pinMode(22, OUTPUT); //WATER PUMP
BLEDevice::init("PLANT NODE 1");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue("PLANT NODE 1 CONNECTED");
pService->start();
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Characteristic defined! Now you can read it in your phone!");
}
void loop() {
/* BLE COM */
std::string REC = pumpCharacteristic->readValue();
if (REC == "water") {
Serial.println("Watering the plant");
digitalWrite(PUMP, LOW);
delay(3000);
digitalWrite(PUMP, HIGH);
}
else {
digitalWrite(PUMP, HIGH);
}
int cur_hour = getHour();
int watered = 0;
for (int x = 0, x < 3; x++) {
if (cur_hour == set_time[i])
{
/* Soil Moisture sensor */
sensorValue = analogRead(sensorPin);
if (sensorValue < 520) && (watered == 0) {
Serial.println("Watering the plant");
digitalWrite(PUMP, LOW);
delay(3000);
digitalWrite(PUMP, HIGH);
watered = 1;
}
else {
digitalWrite(PUMP, HIGH);
}
}
}
delay(1000);
}
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val) {
return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val) {
return ( (val / 16 * 10) + (val % 16) );
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year) {
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x0E); // select register
Wire.write(0b00011100); // write register bitmap, bit 7 is /EOS
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year) {
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
// request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void getHour() {
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// retrieve data from DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
// send it to the serial monitor
return hour;
}
We made a mobile app to control the pump via BLE.
This project can be implemented to reduce water wastage by reducing the usage of water. This might be a simple/tiny project but can make a huge impact in saving water (Indicator 6.4.1 - Change in water use efficiency over time)
Resources:
https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/ug_thingy53_gs.html#updating-through-usb
Comments