Hi all,
I thought I would share my current home project, partly to keep as a project record as it will expand beyond just watering, and also to share with others who maybe wishing to do something similar.
We recently became the tenants/owners of an allotment, and one of the issues we faced over the last few weeks is getting there every day to keep on top of the watering of the plants/crops, especially in the heat we've just had (I'm in the UK). So I thought I'd put together a solar powered watering system.
I'm keeping it fairly basic for now and just using a timer system so it waters the plants twice a day at set times. Future changes will try to include moisture sensors in the pots which will trigger the system to switch on. There are pros and cons to both the current and proposed systems, so it'll be a case of trial and error until I find the sweet spot.
I think the worst of the hot weather is over now, so it's not to critical but I'm going to fit all the kit tomorrow and get it going for the remainder of the summer.
I'm using a 12v 10w solar panel which will charge the 12v 5ah battery via the charge controller. This will then power the nano via the vin. The nano uses a RTC to keep an eye on the time and when it 'sees' it's time to water the plants it controls a 5v relay to switch on a 12v 2A water pump that sits in the water butt. The pump runs for 10 mins (although this might change once it's installed) and waters the polytunnel plants using a micro irrigation system.
The pump puts out 12l/min @ 0.6bar using a standard hose diameter. The hose diameter is then reduced to 4mm, which is the size of the tubing for the micro irrigation system. Whether or not the 0.6bar is enough to pump the water through the whole of the system I am yet to find out. If it isn't I have another high pressure diaphragm pump that I can fit into the system that will get the job done, but uses more power too. As I'm only using a 5ah battery and a 10w panel, I want to keep power consumption low.
There is a float switch on the IN line of the relay to cut off the relay should the water level of the water butt get too low and to stop the motor burning out.
I've also included a momentary push button to start the pump for a couple of minutes with the ability to stop it again if it hasn't reached the full 2 mins. This is for on demand watering, for example I could install a manifold on the hose and switch off the micro irrigation and switch on a normal hose to use for blasting the kids with or something else.
Future plans are to swap to esp32, install temp and humidity sensors, install wifi (to monitor and control remotely ) and increase watering capability.
I will be going to the plot tomorrow to install what I have up to now and get things going.
The code could do with some refining, however, it works and for now I'm happy with that. I am also happy to take any constructive advice regarding the code.
[Edit - Parts list]
-
Arduino Nano (copy)
-
RTC - DS3231 (diode removed to prevent onboard battery charging)
-
Momentary switch (with 10k pull down resistor on the board)
.......and all the other bits and pieces to connect it all together.
Current build photos
Code (I'm using VS Code to write it)
#include <Arduino.h>
#include "RTClib.h"
#include <SPI.h>
RTC_DS3231 rtc;
//--------------------------------------------------------------------------------------------------
//Variables
bool DEBUG = true; //Turn Serial Output on/off
bool morningWaterComplete = false; //has the morning watering taken place?
bool afternoonWaterComplete = false; //has the afternoon watering taken place?
bool overrideSwitchPressed = false; //has the pump override switch been pressed?
uint8_t moringWaterTime = 07; //Set time for morning watering in 24hr
uint8_t afternoonWaterTime = 18; //Set time for afternoon watering in 24hr
unsigned long minuteCheck = 60000; //Used to check if 1 min has passed, in milliseconds
unsigned long timeElapsed;
unsigned int waterPumpDuration = 10; //Run water pump for 10 min, in minutes
unsigned int overrideDuration = 2; //Run water pump for 2 min, in minutes
int waterPump = 12; //Pin to control water pump
int switchPin = 9; //Pin switch is connected to
int currentButtonState = 0;
int lastButtonState = 0;
int buttonState = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
//--------------------------------------------------------------------------------------------------
//****Forward Declerations******//
void begin_RTC();
void checkTime();
void waterPlants();
void runWaterPump();
void timerOverrideSwicth();
void runWaterPumpOverride();
//--------------------------------------------------------------------------------------------------
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
begin_RTC();
pinMode(waterPump, OUTPUT); //set waterPump as output pin
timeElapsed = millis();
}
//--------------------------------------------------------------------------------------------------
void loop() {
// put your main code here, to run repeatedly:
checkTime();
timerOverrideSwicth();
}
//--------------------------------------------------------------------------------------------------
void begin_RTC(){ //Start RTC.
if(!rtc.begin()){
if(DEBUG) {Serial.println(F("Cound not find RTC!"));}
}
else {
DateTime now = rtc.now();
if(DEBUG) {Serial.println(F("RTC Initiated!"));}
}
DateTime now = rtc.now();
//rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Set RTC time for 1st complile or if RTC looses time.
if(DEBUG) {Serial.println("Time set:");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.println(now.second(), DEC);
}
}
void checkTime(){ //check to see if 1min has elapsed. If so, check if it's time to water the allotment.
if ((millis() - timeElapsed) >= minuteCheck){
timeElapsed = millis();
waterPlants();
}
}
void waterPlants(){ //Check if it's time to water the allotment.
DateTime now = rtc.now();
if ((now.hour() == moringWaterTime) && (morningWaterComplete == false)){ //Turn pump on for morning watering session
if (DEBUG) {Serial.println(F("Beginning Morning Watering"));}
runWaterPump();
if (DEBUG) {Serial.println(F("Morning Watering Complete"));}
morningWaterComplete = true;
afternoonWaterComplete = false;
}
if ((now.hour() == afternoonWaterTime) && (afternoonWaterComplete == false)){ //Turn pump on for afternoon watering session
if (DEBUG) {Serial.println(F("Beginning Afternoon Watering"));}
runWaterPump();
if (DEBUG) {Serial.println(F("Afternoon Watering Complete"));}
morningWaterComplete = false;
afternoonWaterComplete = true;
}
}
void timerOverrideSwicth(){
currentButtonState = digitalRead(switchPin);
if (currentButtonState != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (currentButtonState != buttonState) {
buttonState = currentButtonState;
if ((buttonState == HIGH) && (overrideSwitchPressed == false)){
overrideSwitchPressed = true;
if (DEBUG) {Serial.println("Button Pressed");}
runWaterPumpOverride();
}
else if ((buttonState == HIGH) && (overrideSwitchPressed == true)){
overrideSwitchPressed = false;
digitalWrite(waterPump, LOW);
if (DEBUG) {Serial.println("Button Pressed");}
}
}
}
lastButtonState = currentButtonState;
}
void runWaterPump(){ //Run water pump for 10min
unsigned long waterTimer = millis();
if (DEBUG) {Serial.println("Water Pump - ON");}
while(millis() - waterTimer <= (waterPumpDuration * 60000)){
digitalWrite(waterPump, HIGH);
}
digitalWrite(waterPump, LOW); //turn off water pump
if (DEBUG) {Serial.println("Water Pump - OFF");}
}
void runWaterPumpOverride(){ //Run water pump for 10min
unsigned long waterTimer = millis();
if (DEBUG) {Serial.println("Water Pump Override - ON");}
while(millis() - waterTimer <= (overrideDuration * 60000)){
digitalWrite(waterPump, HIGH);
timerOverrideSwicth();
if (overrideSwitchPressed == false)
break;
}
digitalWrite(waterPump, LOW); //turn off water pump
if (DEBUG) {Serial.println("Water Pump Override - OFF");}
}
Thanks for reading