/*
Project: Soil Moisture Controller
Description: Keeps soil moisture within a certain range.
If sensor indicates soil is dry
Run pump for PUMP_TIME milliseconds (default 45s)
Wait for SOAK_TIME milliseconds (default 10 mins)
Repeat
NOTE: Initial Flow rate is 1L/3min
Creation date: 10/16/23
Author: AnonEngineering
Gregnor — 10/15/23 at 12:10 AM Arduino #coding-help
License: https://en.wikipedia.org/wiki/Beerware
*/
const unsigned long PUMP_TIME = 2000;
const unsigned long SOAK_TIME = 10000;
const int DRY_VAL = 380; // value to be considered dry
const int WET_VAL = 280; // value to be considered watered
const int STATUS_LEDS[3] = {4, 3, 2}; // dry, norm, wet
const int PUMP_PIN = 9; // pump control pin
const int SENSOR_PIN = A0; // higher values = drier
int state = 0;
int lastSenseValue = -1;
unsigned long lastPump = 0;
unsigned long lastSoak = 0;
void setIndicators(int value) {
for (int i = 0; i <= 2; i++) {
digitalWrite(STATUS_LEDS[i], LOW);
}
digitalWrite(STATUS_LEDS[value], HIGH);
}
void setup() {
Serial.begin(9600);
for (int i = 0; i <= 2; i++) {
pinMode(STATUS_LEDS[i], OUTPUT);
}
pinMode(PUMP_PIN, OUTPUT);
}
void loop() {
int sensorValue = analogRead(SENSOR_PIN);
if (sensorValue != lastSenseValue) {
lastSenseValue = sensorValue;
Serial.print("Sensor reading: ");
Serial.println(sensorValue);
}
if (state == 0) { // measure
if (sensorValue >= DRY_VAL) { // dry, run pump
setIndicators(0);
digitalWrite(PUMP_PIN, HIGH);
lastPump = millis();
state = 1;
} else if (sensorValue <= WET_VAL) { // wet
setIndicators(2);
lastSoak = millis();
state = 2;
} else { // nominal
setIndicators(1);
lastSoak = millis();
state = 2;
}
}
if (state == 1) { // needs water
if (millis() - lastPump > PUMP_TIME) {
lastSoak = millis();
state = 2;
digitalWrite(PUMP_PIN, LOW);
}
}
if (state == 2) { // wait to soak
if (millis() - lastSoak > SOAK_TIME) {
state = 0;
}
}
}
/*
#define PUMP_PIN 2 // Water Pump Power
#define SENSOR_PIN A0 // Capacitive soil humidity sensor, higher values mean more dry. 420 bone dry, 220 in a cup of water. Possible this need calibration for every sensor
int dry_level = 380; // value to be considered dry
int wet_level = 280; // value to be reached to be considered watered
// const unsigned long the_delay = 10000; // time between readings. Not used yet
const unsigned long pump_on_time = 4500; // watering time for pump to be @45sec NOTE: Initial Flow rate is 1ltr/3min measured. Could use recalibration depending on plant.
const unsigned long water_dispersion = 6000; // time for water to disperse through the medium to be @10min Could use recalibration depending on pot size and soil medium
// const unsigned long follow_water = 30000; // time on a follow up water if soild humidity not reached @30sec. Not used yet
unsigned long PT = 0;
boolean water_start = true; // Only to make start of watering true
boolean pump_running = true;
boolean water_disTime = true;
boolean timer = true; // Marker to make sure only one update on PT is done
boolean water_cycle = true;
// boolean water_follow = true; // Is another pump running. Not used yet
void setup() {
Serial.begin(9600);
pinMode(PUMP_PIN, OUTPUT);
}
void loop() {
unsigned long currentTime = millis();
int sensorValue = analogRead(SENSOR_PIN);
if (water_cycle == false) {
if (sensorValue > dry_level) {
water_cycle = true;
water_start = true;
}
}
if (water_start == true) { // Only to make start of watering true
digitalWrite(PUMP_PIN, HIGH);
pump_running = true;
water_start = false;
}
if (water_cycle == true) {
do {
if (water_disTime == false) {
do { // Start of watering
digitalWrite(PUMP_PIN, HIGH);
pump_running = true;
if (timer == false) { // Timer Set-up
PT = currentTime;
timer = true;
}
if (currentTime - PT >= pump_on_time) { // Timer
digitalWrite(PUMP_PIN, LOW);
pump_running = false;
timer = false;
}
} while (pump_running == true);
}
if (pump_running == false) { // Start of Water Dispersion
water_disTime = true;
if (timer == false) { // Timer Set-up
PT = currentTime;
timer = true;
}
if (currentTime - PT >= water_dispersion) { // Timer
water_disTime = false;
timer = false;
sensorValue = analogRead(SENSOR_PIN);
if (sensorValue < wet_level) { water_cycle = false; }
}
}
} while (water_dispersion == true);
}
while (water_cycle = true)
;
}
*/
Pump
ON
Dry
Norm
Wet
Drier
Wetter