This project is set up as a node on a larger system. The system being my home server! This node controls watering my vegetable patch when I'm not home.
We use MQTT protocol to listen and publish status and commands to and from our garden IoT. This means I can control it remotely via the server.
The system uses a small MCU, the StampS3 to be precise. Tiny but very capable of this task. We run a relay from this board to a pump placed in a large water tank. The system is self-sufficient, running solely on solar power. We simply connect the solar charger up to the MCU via 5V USB and run 12v power to the relay.
System diagramA large waterproof container houses the electronics. A general-purpose power outlet will work, and we can utilise the waterproof cable passthrough for the solar panel and motor wires. I use a solar kit similar to this, 25W 12v panel and acompatible 12V 8Ah LiFePO battery.
Use a compatible relay for your MCU, make sure it is 3.3v is you are using standard gpio pins as if you use a 5V relay it may not trigger correctly.
Make sure to use a sufficient water pump that can handle pulling water up though a reservoir and along a long length of tubing. It will need to be a decent diameter to avoid burning the motor out and pressure build-up.
This part of the project needs some more thought as currently we just use a large tube with holes along the length of it so it trickles water along the garden bed. The issue is the drop I pressure along the tube as water leaks out of the closer holes first - this means some areas are more watered than others.
Server DetailsThe server I run uses NodeRED. This means I can listen for MQTT very easily and run a scheduled watering or remotely activate the pump. This also means I can easily integrate it into any existing workflows I use. For instance, I use Telegram to send mobile notifications as well as send commands. I set up a workflow to inform me of the node status and pump operation. Furthermore, I use NodeRED UI to display the current status and control the device. Such as when it was last activated and the remaining water.
MCU CodeBelow is the code loaded on the Stamps3 MCU. I use an LED library and MQTT library to publish and subscribe to MQTT fields. I use VSCode and platform.io to develop and compile code for this project.
You may have to alter this code if you use a different MCU but it will be fairly similar. Remember to add you wifi creds and mqtt address. This code is very simple, it monitors the topic 'waterpump' for changes to status or control, and then performs tasks accordingly. There is considerable room for improvement in this code, such as implementing a deep sleep mode and wake-up upon status change.
If these tools are new to you I recommend looking up an MQTT with Node-RED tutorial such as this.
#include <WiFi.h>
#include <PubSubClient.h>
#include <FastLED.h>
#include "esp_task_wdt.h"
// Wi-Fi credentials
const char* ssid = "x";//change this
const char* password = "x"; //change this
// MQTT broker
const char* mqtt_server = "192.168.0.x"; //change this
const int mqtt_port = 188x; //change this
const char* status_topic = "waterpump/status";
const char* control_topic = "waterpump/control";
WiFiClient espClient;
PubSubClient client(espClient);
// Pins
#define PIN_LED 21
#define NUM_LEDS 1
#define RELAY_PIN 3 // relay GPIO pin
CRGB leds[NUM_LEDS];
unsigned long lastStatusPublish = 0;
const unsigned long statusInterval = 60 * 1000; // every 60 seconds
void setLedColor(CRGB color) {
leds[0] = color;
FastLED.show();
}
void setup_wifi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED) {
Serial.println("\nWiFi connected");
Serial.println(WiFi.localIP());
setLedColor(CRGB::Green);
} else {
Serial.println("\nWiFi failed to connect");
setLedColor(CRGB::Red);
}
}
void publishStatus(const char* msg) {
client.publish(status_topic, msg, true); // retained = true
Serial.print("Status published: ");
Serial.println(msg);
}
void callback(char* topic, byte* payload, unsigned int length) {
String message;
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("]: ");
Serial.println(message);
if (message == "ON") {
digitalWrite(RELAY_PIN, HIGH);
setLedColor(CRGB::Blue);
publishStatus("PUMP ON");
} else if (message == "OFF") {
digitalWrite(RELAY_PIN, LOW);
setLedColor(CRGB::Green);
publishStatus("PUMP OFF");
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("M5StampClient", status_topic, 0, true, "OFFLINE")) {
Serial.println("connected");
client.subscribe(control_topic);
setLedColor(CRGB::Green);
publishStatus("ONLINE");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" retrying in 5s");
setLedColor(CRGB::Red);
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
FastLED.addLeds<WS2812, PIN_LED, GRB>(leds, NUM_LEDS);
setLedColor(CRGB::Red);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
// Watchdog: timeout after 10 seconds
esp_task_wdt_init(10, true);
esp_task_wdt_add(NULL);
}
void loop() {
esp_task_wdt_reset();
if (WiFi.status() != WL_CONNECTED) {
setup_wifi(); // try to reconnect
}
if (!client.connected()) {
reconnect();
}
client.loop();
// Heartbeat: send "ONLINE" every 60s
if (millis() - lastStatusPublish > statusInterval) {
publishStatus("ONLINE");
lastStatusPublish = millis();
}
}In future, I hope to add some more monitoring features to this node. I would like humidity and temperature, as well as perhaps water reservoir data via some water level sensor or calculated by how much the pump has been used. Moisture sensors could be used to make watering more effective and not just scheduled for every few days.
The water tank is the only part of this project which requires attention. Refilling the water tank is the last step for automation. Maybe I will add a water funnel from the roof at some point to reduce the need for manual refills.
I will be revising this project in the coming months to improve it, ready for the spring growth season! A better solar panel setup, good irrigation tubing, reliable code that doesn't reset sometimes, maybe some more sensors and features!
Thanks for reading!













Comments