NoOneInParticular
Lurker
First dev. Using soil moisture sensors and relays to control a garden irrigation system. Everything is working but as I anticipate expanding I am looking for pointers to create more efficiency. Regards.
#include <Wire.h>
#include "Shifter.h"
#include "LiquidCrystal_I2C.h"
/**
*
* This program will create an irrigation system that will read soil moisture input values from
* sensors and if needed trigger relays that will enable solenoids that will turn on water
* to the specified zones and water them as needed.
*
*/
#define SER_Pin 4 //SER_IN (DS) IC PIN 14
#define RCLK_Pin 3 //L_CLOCK (ST_CP) IC PIN 12
#define SRCLK_Pin 2 //CLOCK (SH_CP) IC PIN 11
#define BUTTON_PIN 7 // Digital input from button switch
#define NUM_REGISTERS 2 // how many shift registers are in the chain
// Irrigation output settings
#define IRRIGATION_RUN_TIME 15000 // 900000 // Time to run water when dry (15 minutes)
// Analog moisture sensor settings
#define SENSOR_CHECK_TIME 80000 // 14400000
#define SENSOR_INIT_TIME 2000
#define SENSOR_INPUT_PIN A0 // Input pin for analog sensor readings
#define SENSOR_THRESHOLD 514 // Readings below this trigger irrigation relays
#define BUTTON_WAIT_TIME 500
// LCD output controller+
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
// Creat a set of new characters
const uint8_t charBitmap[][8] = {
{ 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
{ 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
{ 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
{ 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
{ 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
{ 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
{ 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
// Initialize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);
/**
* Default all relay pins to HIGH which turns them off. Also turn all ouput pins for
* soil moisture sensors to LOW which turns them off so that we are now powering them by default.
*/
void setup() {
// Enable serial debugging output
Serial.begin(9600);
lcd.noBacklight();
lcd.begin(16,2); // initialize the lcd
for ( int i = 0; i < charBitmapSize; i++ ) {
lcd.createChar ( i, (uint8_t *)charBitmap );
}
// Set all relay pins to HIGH
for(int i = 0; i <= 7; i++)
shifter.setPin(i, HIGH) ;
shifter.write(); //send changes to the chain and display them
// Set all sensor power pins to LOW
for(int i = 8; i <= 15; i++)
shifter.setPin(i, LOW) ;
shifter.write(); //send changes to the chain and display them
}
float convertSensorToFloat(int value) {
return 100 * (1.0-(value/1023.0));
}
/**
* This will read the moisture sensor reading from the sensor connected to the specified pin
*/
unsigned int readSoilMoistureSensor(int pin) {
lcd.clear();
lcd.print("READING MOISTURE");
lcd.setCursor(0,1);
lcd.print("ZONE ");
lcd.print(pin-7);
Serial.print("Turning on pin ");
Serial.print(pin);
Serial.println("");
// Turn sensor on
shifter.setPin(pin, HIGH);
shifter.write();
Serial.println("Waiting for sensor");
// Delay for a few seconds for init
delay(SENSOR_INIT_TIME);
// Read analog value from SENSOR_INPUT_PIN
unsigned int sensorReading = analogRead(SENSOR_INPUT_PIN);
float percent = convertSensorToFloat(sensorReading);
Serial.print("Read sensor value: ");
Serial.print(sensorReading);
Serial.println("");
lcd.setCursor(7, 1);
lcd.print("= ");
lcd.print(percent, 0);
lcd.print("%");
// Turn sensor off
Serial.println("Turning off sensor");
shifter.setPin(pin, LOW);
shifter.write();
delay(BUTTON_WAIT_TIME);
return sensorReading;
}
/**
* Check to see if the button is currently being pressed
*/
boolean checkButton() {
if(digitalRead(BUTTON_PIN) == HIGH)
return true;
return false;
}
/**
* Turn on the irrigation relay to enable watering on the specified zone.
*/
void startIrrigationRelay(int pin) {
// Turn on the mapped relay for this sensor
Serial.print("Turning on irrigation pin: ");
Serial.println(pin);
shifter.setPin(pin, LOW); //set RELAY pin 1 ON
shifter.write();
lcd.clear();
lcd.print("WATERING ZONE ");
lcd.print(pin + 1);
lcd.setCursor(0,1);
lcd.print("REMAINING ");
int current = 0;
delay(BUTTON_WAIT_TIME);
while((current <= IRRIGATION_RUN_TIME) > 0) {
lcd.print(pin);
lcd.setCursor(10,1);
lcd.print(" ");
lcd.setCursor(10,1);
lcd.print((IRRIGATION_RUN_TIME - current) / 1000);
delay(50);
current += 50;
if(checkButton() == true) {
shifter.setPin(pin, HIGH);
shifter.write();
return;
}
}
// Turn of the relay
Serial.println("Turning off irrigation relay");
shifter.setPin(pin, HIGH);
shifter.write();
}
boolean waitForCancel(int timeout) {
int current = 0;
while( (current <= timeout ) > 0) {
if(checkButton() == true) {
delay(BUTTON_WAIT_TIME);
return true;
}
current += 50;
delay(50);
}
return false;
}
/**
*
*/
void startMenu() {
lcd.clear();
lcd.backlight();
lcd.print("ALL ZONES ");
lcd.setCursor(0,1);
lcd.print("PUSH ON OR WAIT");
delay(BUTTON_WAIT_TIME);
// Read from the button for All Zones
int current = 0;
while( (3000 - current) > 0) {
if(checkButton() == true) {
lcd.clear();
lcd.print("ALL ZONES ");
lcd.setCursor(0,1);
lcd.print("WATERING");
delay(BUTTON_WAIT_TIME);
// Turn on all relays
for(int i = 0; i <= 7; i++) {
shifter.setPin(i, LOW); //set RELAY pin 1 ON
shifter.write();
delay(50);
}
// Wait for default irrigation time and cancel if needed
waitForCancel(IRRIGATION_RUN_TIME);
// Turn off all relays
for(int i = 0; i <= 7; i++) {
shifter.setPin(i, HIGH); //set RELAY pin 1 ON
shifter.write();
delay(50);
}
lcd.clear();
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
return;
}
current += 50;
delay(50);
}
// Start cycle through the zones
for(int i = 8; i <= 15; i++) {
unsigned int moisture = readSoilMoistureSensor(i);
// Print out the current zone information
lcd.clear();
lcd.print("ZONE ");
lcd.print(i-7);
lcd.print(" = ");
lcd.print(convertSensorToFloat(moisture), 0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("PUSH ON OR WAIT");
// Read from the button
int current = 0;
while( (3000 - current) > 0) {
if(checkButton() == true) {
startIrrigationRelay(i - 8);
return;
}
current += 50;
delay(50);
}
}
}
boolean checkForInput() {
if(checkButton() == true) {
delay(BUTTON_WAIT_TIME);
return true;
}
return false;
}
void loop() {
Serial.println("Waiting for 5 seconds");
lcd.home (); // go home
lcd.backlight();
// Delay for 4 hours
lcd.clear();
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
int current = 0;
while( (SENSOR_CHECK_TIME - current) > 0) {
if(checkForInput()) {
startMenu();
}
// Turn off backlight after 2 minutes
if(current >= 120000) {
lcd.noBacklight();
}
current += 50;
delay(50);
}
lcd.clear();
// Iterate through each soil sensor
for(int sensorPin = 8; sensorPin <= 15; sensorPin++) {
if(checkButton() == true) {
startMenu();
}
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
// Read the moisture value from the sensor
unsigned int value = readSoilMoistureSensor(sensorPin);
// Check for moisture threshold
if(value >= SENSOR_THRESHOLD) {
// Turn on the water value for some time
startIrrigationRelay(sensorPin - 8);
}
int current = 0;
while( (2000 - current) > 0) {
if(checkForInput()) {
startMenu();
}
current += 50;
delay(50);
}
}
}
#include <Wire.h>
#include "Shifter.h"
#include "LiquidCrystal_I2C.h"
/**
*
* This program will create an irrigation system that will read soil moisture input values from
* sensors and if needed trigger relays that will enable solenoids that will turn on water
* to the specified zones and water them as needed.
*
*/
#define SER_Pin 4 //SER_IN (DS) IC PIN 14
#define RCLK_Pin 3 //L_CLOCK (ST_CP) IC PIN 12
#define SRCLK_Pin 2 //CLOCK (SH_CP) IC PIN 11
#define BUTTON_PIN 7 // Digital input from button switch
#define NUM_REGISTERS 2 // how many shift registers are in the chain
// Irrigation output settings
#define IRRIGATION_RUN_TIME 15000 // 900000 // Time to run water when dry (15 minutes)
// Analog moisture sensor settings
#define SENSOR_CHECK_TIME 80000 // 14400000
#define SENSOR_INIT_TIME 2000
#define SENSOR_INPUT_PIN A0 // Input pin for analog sensor readings
#define SENSOR_THRESHOLD 514 // Readings below this trigger irrigation relays
#define BUTTON_WAIT_TIME 500
// LCD output controller+
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
// Creat a set of new characters
const uint8_t charBitmap[][8] = {
{ 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
{ 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
{ 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
{ 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
{ 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
{ 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
{ 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
{ 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
};
int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));
// Initialize shifter using the Shifter library
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS);
/**
* Default all relay pins to HIGH which turns them off. Also turn all ouput pins for
* soil moisture sensors to LOW which turns them off so that we are now powering them by default.
*/
void setup() {
// Enable serial debugging output
Serial.begin(9600);
lcd.noBacklight();
lcd.begin(16,2); // initialize the lcd
for ( int i = 0; i < charBitmapSize; i++ ) {
lcd.createChar ( i, (uint8_t *)charBitmap );
}
// Set all relay pins to HIGH
for(int i = 0; i <= 7; i++)
shifter.setPin(i, HIGH) ;
shifter.write(); //send changes to the chain and display them
// Set all sensor power pins to LOW
for(int i = 8; i <= 15; i++)
shifter.setPin(i, LOW) ;
shifter.write(); //send changes to the chain and display them
}
float convertSensorToFloat(int value) {
return 100 * (1.0-(value/1023.0));
}
/**
* This will read the moisture sensor reading from the sensor connected to the specified pin
*/
unsigned int readSoilMoistureSensor(int pin) {
lcd.clear();
lcd.print("READING MOISTURE");
lcd.setCursor(0,1);
lcd.print("ZONE ");
lcd.print(pin-7);
Serial.print("Turning on pin ");
Serial.print(pin);
Serial.println("");
// Turn sensor on
shifter.setPin(pin, HIGH);
shifter.write();
Serial.println("Waiting for sensor");
// Delay for a few seconds for init
delay(SENSOR_INIT_TIME);
// Read analog value from SENSOR_INPUT_PIN
unsigned int sensorReading = analogRead(SENSOR_INPUT_PIN);
float percent = convertSensorToFloat(sensorReading);
Serial.print("Read sensor value: ");
Serial.print(sensorReading);
Serial.println("");
lcd.setCursor(7, 1);
lcd.print("= ");
lcd.print(percent, 0);
lcd.print("%");
// Turn sensor off
Serial.println("Turning off sensor");
shifter.setPin(pin, LOW);
shifter.write();
delay(BUTTON_WAIT_TIME);
return sensorReading;
}
/**
* Check to see if the button is currently being pressed
*/
boolean checkButton() {
if(digitalRead(BUTTON_PIN) == HIGH)
return true;
return false;
}
/**
* Turn on the irrigation relay to enable watering on the specified zone.
*/
void startIrrigationRelay(int pin) {
// Turn on the mapped relay for this sensor
Serial.print("Turning on irrigation pin: ");
Serial.println(pin);
shifter.setPin(pin, LOW); //set RELAY pin 1 ON
shifter.write();
lcd.clear();
lcd.print("WATERING ZONE ");
lcd.print(pin + 1);
lcd.setCursor(0,1);
lcd.print("REMAINING ");
int current = 0;
delay(BUTTON_WAIT_TIME);
while((current <= IRRIGATION_RUN_TIME) > 0) {
lcd.print(pin);
lcd.setCursor(10,1);
lcd.print(" ");
lcd.setCursor(10,1);
lcd.print((IRRIGATION_RUN_TIME - current) / 1000);
delay(50);
current += 50;
if(checkButton() == true) {
shifter.setPin(pin, HIGH);
shifter.write();
return;
}
}
// Turn of the relay
Serial.println("Turning off irrigation relay");
shifter.setPin(pin, HIGH);
shifter.write();
}
boolean waitForCancel(int timeout) {
int current = 0;
while( (current <= timeout ) > 0) {
if(checkButton() == true) {
delay(BUTTON_WAIT_TIME);
return true;
}
current += 50;
delay(50);
}
return false;
}
/**
*
*/
void startMenu() {
lcd.clear();
lcd.backlight();
lcd.print("ALL ZONES ");
lcd.setCursor(0,1);
lcd.print("PUSH ON OR WAIT");
delay(BUTTON_WAIT_TIME);
// Read from the button for All Zones
int current = 0;
while( (3000 - current) > 0) {
if(checkButton() == true) {
lcd.clear();
lcd.print("ALL ZONES ");
lcd.setCursor(0,1);
lcd.print("WATERING");
delay(BUTTON_WAIT_TIME);
// Turn on all relays
for(int i = 0; i <= 7; i++) {
shifter.setPin(i, LOW); //set RELAY pin 1 ON
shifter.write();
delay(50);
}
// Wait for default irrigation time and cancel if needed
waitForCancel(IRRIGATION_RUN_TIME);
// Turn off all relays
for(int i = 0; i <= 7; i++) {
shifter.setPin(i, HIGH); //set RELAY pin 1 ON
shifter.write();
delay(50);
}
lcd.clear();
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
return;
}
current += 50;
delay(50);
}
// Start cycle through the zones
for(int i = 8; i <= 15; i++) {
unsigned int moisture = readSoilMoistureSensor(i);
// Print out the current zone information
lcd.clear();
lcd.print("ZONE ");
lcd.print(i-7);
lcd.print(" = ");
lcd.print(convertSensorToFloat(moisture), 0);
lcd.print("%");
lcd.setCursor(0,1);
lcd.print("PUSH ON OR WAIT");
// Read from the button
int current = 0;
while( (3000 - current) > 0) {
if(checkButton() == true) {
startIrrigationRelay(i - 8);
return;
}
current += 50;
delay(50);
}
}
}
boolean checkForInput() {
if(checkButton() == true) {
delay(BUTTON_WAIT_TIME);
return true;
}
return false;
}
void loop() {
Serial.println("Waiting for 5 seconds");
lcd.home (); // go home
lcd.backlight();
// Delay for 4 hours
lcd.clear();
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
int current = 0;
while( (SENSOR_CHECK_TIME - current) > 0) {
if(checkForInput()) {
startMenu();
}
// Turn off backlight after 2 minutes
if(current >= 120000) {
lcd.noBacklight();
}
current += 50;
delay(50);
}
lcd.clear();
// Iterate through each soil sensor
for(int sensorPin = 8; sensorPin <= 15; sensorPin++) {
if(checkButton() == true) {
startMenu();
}
lcd.print(" MAMAW'S");
lcd.setCursor(0,1);
lcd.print(" SPRINKLERS");
// Read the moisture value from the sensor
unsigned int value = readSoilMoistureSensor(sensorPin);
// Check for moisture threshold
if(value >= SENSOR_THRESHOLD) {
// Turn on the water value for some time
startIrrigationRelay(sensorPin - 8);
}
int current = 0;
while( (2000 - current) > 0) {
if(checkForInput()) {
startMenu();
}
current += 50;
delay(50);
}
}
}