AWS IOT based Water Sprinkler
- Indraneel Ganguli
- May 11, 2024
- 5 min read
The Need ?
I have some plants in my home garden which needs regular water supply. Normally I or my family member would water the plants every morning, which is fine. But once in a while when i am on vacation and leave my home , it's become a pain to water those plants. Normally i would transfer the pots to my neighbours house or keep outside and ask some one to water it .
But it is still a big pain for me . I am sure many folks are out there like me who also are also facing same issues and need a solution.
The Solution
Need a solution where i can automatically turn on and off the Water sprinkler remotely using scheduler based service . Later it can also be extended via browser based interface.
Ingredients ***
Water Pump
We would need. a water pump which would drive the water out of a container (I have used 5 liters water bottle for the same.
ESP8266 based NodeMCU -
A microprocessor which is very popular in embedded world for enthusiast and is cheap as well.
Relay
Since we need to drive the motor which cannot work with 3.3V , atleast we need to supply 5V.
3.3V and 5V Power Supply Module for MB102
Would need this power module to convert 9V DC battery power to 5V , which can be used to drive the DC water pump.
9 V Battery
Jumper wires
We would need also needs some jumper wires.
High Level Understanding
First we need the water pump motor to conditionally start and stop depending on when you want the watering of the plants to start and stop. This could be time schedules or adhoc request
We would need a microcontroller like ESP8266 to control the pump which would take command from the cloud like AWS.
Need to integrate AWS IOT with the ESP8266 device (NodeMcu)
Hardware Connection -
In the connection above basically we are using relay as a switch for controlling the on/off of the pump. Relay is controlled by NodeMCU which is again connected to internet via WIFI
Software Part
we need to register the NodeMCU to AWS IOT HUB. Go through the article https://how2electronics.com/connecting-esp8266-to-amazon-aws-iot-core-using-mqtt/ to a general idea of it
2. NodeMCU will be connected to AWS IOT via MQTT (which is basically a queue). You will can test the device using MQTT Tester in the console for publishing and receiving message
3. You have to write Arduino Code and upload to nodeMCU which will talk to AWS IOT Core . Basically the code will receive command via MQTT from IOT CORE and send status back. This will also need certificates for communication
You would need the following two files. Keep it in single folder and open it via Arduino SDK.
Sprinkler.ino
#include <ESP8266WiFi.h> #include <WiFiClientSecure.h> #include <PubSubClient.h> #include <ArduinoJson.h> #include <time.h> #include "secrets.h" #include "DHT.h" #define TIME_ZONE -5 #define DHTPIN 4 // Digital pin connected to the DHT sensor #define DHTTYPE DHT11 // DHT 11 DHT dht(DHTPIN, DHTTYPE); float h ; float t; unsigned long lastMillis = 0; unsigned long previousMillis = 0; const long interval = 5000; #define AWS_IOT_PUBLISH_TOPIC "esp8266/pub" #define AWS_IOT_SUBSCRIBE_TOPIC "esp8266/sub" WiFiClientSecure net; BearSSL::X509List cert(cacert); BearSSL::X509List client_crt(client_cert); BearSSL::PrivateKey key(privkey); PubSubClient client(net); time_t now; time_t nowish = 1510592825; void NTPConnect(void) { Serial.print("Setting time using SNTP"); configTime(TIME_ZONE 3600, 0 3600, "pool.ntp.org", "time.nist.gov"); now = time(nullptr); while (now < nowish) { delay(500); Serial.print("."); now = time(nullptr); } Serial.println("done!"); struct tm timeinfo; gmtime_r(&now, &timeinfo); Serial.print("Current time: "); Serial.print(asctime(&timeinfo)); } void messageReceived(char topic, byte payload, unsigned int length) { Serial.print("Received ["); Serial.print(topic); Serial.print("]: "); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); } void connectAWS() { delay(3000); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); Serial.println(String("Attempting to connect to SSID: ") + String(WIFI_SSID)); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(1000); } NTPConnect(); net.setTrustAnchors(&cert); net.setClientRSACert(&client_crt, &key); client.setServer(MQTT_HOST, 8883); client.setCallback(messageReceived); Serial.println("Connecting to AWS IOT"); while (!client.connect(THINGNAME)) { Serial.print("."); delay(1000); } if (!client.connected()) { Serial.println("AWS IoT Timeout!"); return; } // Subscribe to a topic client.subscribe(AWS_IOT_SUBSCRIBE_TOPIC); Serial.println("AWS IoT Connected!"); } void publishMessage() { StaticJsonDocument<200> doc; doc["time"] = millis(); doc["humidity"] = h; doc["temperature"] = t; char jsonBuffer[512]; serializeJson(doc, jsonBuffer); // print to client client.publish(AWS_IOT_PUBLISH_TOPIC, jsonBuffer); } void setup() { Serial.begin(115200); connectAWS(); //dht.begin(); } void loop() { //h = dht.readHumidity(); //t = dht.readTemperature(); h=10 ; t=100 ; if (isnan(h) || isnan(t) ) // Check if any reads failed and exit early (to try again). { Serial.println(F("Failed to read from DHT sensor!")); return; } Serial.print(F("Humidity: ")); Serial.print(h); Serial.print(F("% Temperature: ")); Serial.print(t); Serial.println(F("°C ")); delay(2000); now = time(nullptr); if (!client.connected()) { connectAWS(); } else { client.loop(); if (millis() - lastMillis > 5000) { lastMillis = millis(); publishMessage(); } } }
Secret.h
#include <pgmspace.h> #define SECRET const char WIFI_SSID[] = "<insertYourOwn>"; const char WIFI_PASSWORD[] = "<insertYourOwn>"; #define THINGNAME "sprinkler1" int8_t TIME_ZONE = -5; //NYC(USA): -5 UTC const char MQTT_HOST[] = "a3o6799cqgszz-ats.iot.ap-south-1.amazonaws.com"; static const char cacert[] PROGMEM = R"EOF( -----BEGIN CERTIFICATE----- <insertYourOwn> -----END CERTIFICATE----- )EOF"; // Copy contents from XXXXXXXX-certificate.pem.crt here ▼ static const char client_cert[] PROGMEM = R"KEY( -----BEGIN CERTIFICATE----- <insertYourOwn> -----END CERTIFICATE----- )KEY"; // Copy contents from XXXXXXXX-private.pem.key here ▼ static const char privkey[] PROGMEM = R"KEY( -----BEGIN RSA PRIVATE KEY----- <insertYourOwn> -----END RSA PRIVATE KEY----- )KEY";
Upload the Arduino code to your board .
Scheduling for Event Bridge and Lambda -
You might like to schedule this and hence have a Eventbridge schedule which would trigger a lambda . Lambda would have the code to put messages to MQTT for triggering the nodemcu and the relay
We can have two lambda , one for starting and one for stopping the sprinkler
startSprinkler Lambda code -
import boto3 import json # Replace 'YOUR_TOPIC_NAME' with your AWS IoT Core topic name iot_topic = 'esp8266/sub' def lambda_handler(event, context): # Create IoT client iot_client = boto3.client('iot-data') # Message payload to be sent to IoT Core message = { "gadgetName":"sprinkler1", "state":"on" } # Publish message to IoT Core topic response = iot_client.publish( topic=iot_topic, qos=1, payload=json.dumps(message) ) print("Message published to topic:", iot_topic) print("Response:", response) return { 'statusCode': 200, 'body': json.dumps('Message sent to IoT Core') }
Stop Sprinkler Lambda code -
import boto3 import json # Replace 'YOUR_TOPIC_NAME' with your AWS IoT Core topic name iot_topic = 'esp8266/sub' def lambda_handler(event, context): # Create IoT client iot_client = boto3.client('iot-data') # Message payload to be sent to IoT Core message = { "gadgetName":"sprinkler1", "state":"off" } # Publish message to IoT Core topic response = iot_client.publish( topic=iot_topic, qos=1, payload=json.dumps(message) ) print("Message published to topic:", iot_topic) print("Response:", response) return { 'statusCode': 200, 'body': json.dumps('Message sent to IoT Core') }
Finally would might need a event bridge scheduler as given below and define the schedule using Cron notation .
Some Image of the prototype -
Conclusion
Hope you would have found the article inspiring and would encouraged you to create smart devices and prototypes using IOT cloud services and cheap hardware available off the shelve from amazon.
Have a great day ahead.
















Comments