//Update No.: 7 ( Beta Version) July 23_2016
//Developed by : Hernando Bolaños
//***********************************************************************************************************************************************
//Disclaim Note:
//THIS SOFTWARE IS PROVIDED BY THE DEVELOPER "AS IS" AND ANY EXPRESSED OR
//IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//IN NO EVENT SHALL THE DEVELOPER OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
//INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
//SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
//STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
//IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//THE POSSIBILITY OF SUCH DAMAGE.
//*************************************************************************************************************************************************
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x3F,16,2); // set the LCD address to 0x3F for a 16 chars and 2 line display- use IC2SCAN to search bus Hex Address
//ctrol
int conta=0; //Variable used to counter of flow meter pulses
int pin=7; //Variable used to define flow meter input
int inputPulsa=4; //Variable used to define flow meter input
int estadoCero=0; //variable set counter start state
float volumenfit=0; //Variable for volume calculatios
char data = 99; //Variable for storing received data
char data1=0; //Variable for red on serial 1 port
int Tiempo=0; // varible not used
int modolocal=10; //Variable used to define local mode input
int modoremoto=11; //Variable used to define remote mode input
int LOCINCMD_OPEN=12; // Variable used to define open cmd input from pushbutton
int LOCINCMD_CLOSE=8; // Variable used to define close cmd input from pushbutton
int OUTCMD_VALV=2; //variable to set the output to solenoid valve
int p1=0; //variable not used
int estadosalida=0; //varoable to set start status of relay
int volumen=0; //Variable to report irrigation volume
unsigned long time; //Variable uset to define time
unsigned long tempo=0; // variable to set tieme selected
unsigned long tinicio=0; // variable to set starting time of irrigation
unsigned long tfinal; //variable to calculate finishing time of irrigation
unsigned long tactual; //Variable to calculate actual time of the irrigation
unsigned long caudal=0; // varibale to define flow
int estado_out2; // Variable to define output state to field valve
float tcorrido=0; //Variable to define accumulatted time
float tfincalc=0; // variable to calculate final time
unsigned long durationdown; // variable to set flow meter pulse input
unsigned long durationup; //variable to set flow meter pulse input
unsigned long frecuencia; // Variable to calculate frequency of flow meter pulses
unsigned long periodo; // Variable to calculate T of flowmeter pulses
int comando=100; // Variable to remove remote commands
//Keypad
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
{'1','2','3','A',},
{'4','5','6','B',},
{'7','8','9','C'},
{'*','0','#','D',}
};
byte rowPins[ROWS] = {22,24,26, 28}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {30,32,34,36}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
// Smile byte
byte smiley[8] = {
B00000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
};
void setup() {
Serial.begin(9600); //Start serial port 0
Serial1.begin(9600); //start seriral port 1
pinMode(pin, INPUT); //Sets digital pin 7 as INPUT pin de pulsos
pinMode(6, OUTPUT); //Sets digital pin 6 as OUTPUT con esl estado del pin de pulsos
pinMode(4, INPUT); //Sets digital pin 4 as INPUT PULSADOR DE RESET DE CONTADORES de pulso y vol
pinMode(9, OUTPUT); //Sets digital pin 9 as output VERIFICAR PARA QUE SE USA ESTA SALIDA
pinMode(10, INPUT); // Sets digita pin 10 as input local/mode switch
pinMode (11, INPUT); // Sets digital pin 11 as input remote/mode switch
pinMode(12, INPUT); // Sets digital pin 12 as input open push buttonEntrada de mando abrir -localmente
pinMode(8, INPUT); // Sets digital pin 8 as input close push buttonEntrada de mado cerrar - localmente
pinMode(2,OUTPUT); // Sets digita pin 2 as output open solenoid valve
digitalWrite(2,HIGH); //Start output to solenoid valve close- wait for commands
lcd.init(); //Start lcd
lcd.backlight(); //Turn on lcd backscreen light
lcd.createChar(0, smiley); //smile byte symbol
lcd.begin(16, 2);
lcd.write(byte(0));
delay(2000);
lcd.setCursor(0,0);
lcd.print("APP_Eco Riego_V1"); //Boot message
lcd.setCursor(0,1);
lcd.print("by:Hernando B.");
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Sel_Tiempo_Riego"); //Irrigation time selection message
delay(2000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T1:1min T2:2min"); //Time selection options message
delay(1000);
lcd.setCursor(0,1);
lcd.print("T3:3min T4:5min"); //Time selection options message
delay(1000);
}
void flujo()
{
durationdown = pulseIn(pin, LOW);
durationup = pulseIn(pin, HIGH);
Serial.println("duration");
Serial.println(durationdown);
Serial.println(durationup);
unsigned long periodo = durationdown;
Serial.println("frequency:");
unsigned long frecuencia = 1000000/(periodo);
Serial.println(frecuencia);
Serial.println("Flow L/Min:");
unsigned long caudal = frecuencia/7.5;
Serial.println(caudal);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("Flow(L/M):");
lcd.setCursor(12,1);
lcd.println(abs(caudal));
delay(1000);
}
void loop() {
flujo();
delay(1000);
//Keypad inputs reading
char key = keypad.getKey();
if (key != NO_KEY){
Serial.println(key); }
// when characters arrive over the serial port...
if (Serial.available()) {
// wait a bit for the entire message to arrive
delay(500);
// clear the screen
lcd.clear();
// read all the available characters
while (Serial.available() > 0) {
// display each character to the LCD
lcd.setCursor(2,1);
lcd.print(Serial.read());
Serial.println(data1);
}
}
int estado_local = digitalRead(modolocal);
// Local mode commands
if ( estado_local == HIGH) {
lcd.clear();
lcd.setCursor( 0,1);
lcd.print("Local Mode");
Serial.println("Local Mode");
delay(100);
if (key == '3') { //Option 1 irrigation
tempo=1;
Serial.println(" 1 min Irrigation");
lcd.setCursor( 0,1);
lcd.println(" 1min__Irrig");
delay(500);
}
if (key == '6') { //Option 2 Irrigation
tempo=2;
Serial.println(" 2 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println("2mins__Irrig");
delay(500);
}
if (key == '9') { //Option 3 Irrigation
tempo=3;
Serial.println(" 3 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println("3mins___Irrig");
delay(500);
}
if (key == '#') { //Option 4 Irrigation
tempo=5;
Serial.println("5 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println(" 5mins Irrig");
delay(500);
}
int comando_apertura = digitalRead(LOCINCMD_OPEN);
int comando_cierre = digitalRead(LOCINCMD_CLOSE);
if (comando_apertura == HIGH) {
digitalWrite(OUTCMD_VALV, LOW);
Serial.println(" Local Keypad open valve command sent");
lcd.setCursor( 0,1);
lcd.println("CMD/LOCAL/Open/Valv1");
tinicio=millis(); //Time stamp for open valve
tfinal= (tempo*1000*60)+tinicio; //End time calculation
Serial.println(tinicio);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("Tinic:");
lcd.setCursor(7,0);
lcd.println(tinicio);
Serial.println("End time (s):");
Serial.println(tfinal);
lcd.setCursor( 0,0);
lcd.println("tfinal:");
lcd.setCursor(7,0);
lcd.println(tfinal);
lcd.setCursor(0,1);
lcd.println("start counter T");
delay(2000);
Serial.println("start counter(s)");
delay(3000);
}
Serial.println(estado_out2);
Serial.println(tempo);
delay(100);
int estado_out2 = digitalRead(OUTCMD_VALV);
if (tempo > 0) {
if (estado_out2 == LOW) {
tactual = millis();
Serial.println("System Time");
Serial.println(tactual);
Serial.println(tinicio);
Serial.println("Automatic irrigation - Time acumulated(s):");
Serial.println((tactual-tinicio)/1000);
lcd.setCursor( 0,0);
lcd.println("Tprogreso(s):");
lcd.setCursor(13,0);
lcd.println(abs(tactual-tinicio)/1000);
Serial.println("End Time selected (ms):");
Serial.println(tfinal);
delay (1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("EndTime(s):");
lcd.setCursor(11,1);
lcd.println(abs(tempo*60));
delay(1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("Flow(L/M):");
lcd.setCursor(12,1);
lcd.println(abs(caudal));
delay(1000);
}
if(tfinal <= tactual) {
if (estado_out2 == LOW){
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println(" Close Command sent to solenoid valve");
Serial.println("End automatic Irrigation");
delay(3000);
int volumen = tempo*29;
Serial.println("Irrigation Volume Aprox. (Lts):");
Serial.println(volumen);
delay(2000);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("End Auto Irrigation");
lcd.setCursor(0,1);
lcd.clear();
lcd.println("VolAproxLts:");
lcd.setCursor(12,0);
lcd.println(volumen);
delay(4000);
tempo=0;}
}
}
if (key == 'A') {
digitalWrite(OUTCMD_VALV, LOW);
Serial.println(" Keypad Open command sent to solenoid valve ");
lcd.setCursor( 0,1);
lcd.println("CMD/LOCAL/Open/Valv1");
tinicio=millis(); //Time stamp
tfinal= (tempo*1000*60)+tinicio; //end time calculations
Serial.println(tinicio);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("Tinic:");
lcd.setCursor(7,0);
lcd.println(tinicio);
Serial.println("End Time selected (s):");
Serial.println(tfinal);
lcd.setCursor( 0,0);
lcd.println("End Time:");
lcd.setCursor(7,0);
lcd.println(tfinal);
lcd.setCursor(0,1);
lcd.println("Start Counter T");
delay(2000);
Serial.println("Start Counter(s)");
delay(5000);
}
Serial.println(estado_out2);
Serial.println(tempo);
delay(100);
// int estado_out2 = digitalRead(OUTCMD_VALV);
if (tempo > 0) {
if (estado_out2 == LOW) {
tactual = millis();
Serial.println("System Time:");
Serial.println(tactual);
Serial.println(tinicio);
Serial.println("Time Accumulated Irrigation(s):");
Serial.println((tactual-tinicio)/1000);
lcd.setCursor( 0,0);
lcd.println("Taccumu(s):");
lcd.setCursor(13,0);
lcd.println(abs(tactual-tinicio)/1000);
Serial.println("End time selected (ms):");
Serial.println(tfinal);
delay (1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("tfinal(s):");
lcd.setCursor(11,1);
lcd.println(abs(tempo*60));
delay(1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("Caudal(L/M):");
lcd.setCursor(12,1);
lcd.println(abs(caudal));
delay(1000);
}
if(tfinal <= tactual) {
if (estado_out2 == LOW){
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println(" Close command sent to solenoid Valve");
Serial.println("End Automatic Irrigation");
delay(3000);
int volumen = tempo*29;
Serial.println("Volume aprox. of irrigation(Lts):");
Serial.println(volumen);
delay(2000);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("End automatic Iirgation");
lcd.setCursor(0,1);
lcd.clear();
lcd.println("VolAproxLts:");
lcd.setCursor(12,0);
lcd.println(volumen);
delay(4000);
tempo=0;}
}
}
if ( comando_cierre == HIGH) {
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println(" Close command sent to solenoid valve");
lcd.setCursor( 0,1);
lcd.println("CMD/Loc/Close/V1");
delay(500);
}
if ( key == 'B') {
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println(" Close command sent from keypad to solenoid valve");
lcd.setCursor( 0,1);
lcd.println("CMD/Keyp/Close/Valv1");
}
if ( key == 'C') { //Time of continuos operation fo the system
time = millis();
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Continous operation Time:");
delay(1000);
lcd.setCursor(0,1);
Serial.println("Cont. Operation Time");
Serial.println(time);
delay(100);
lcd.print(time);
delay(4000);
}
if (key == '*') { // Clock reset from keypad
tfinal=0;
Serial.println("Clock reset from keypad");
Serial.println("Irrigation aborted (Lts):");
Serial.println(29*(tactual-tinicio)/60000);
lcd.setCursor(0,1);
lcd.print("Clock reset from keypad");
delay(2000);
}
if (key == '2') { // flow report if "2" key is pressed
flujo();
}
}
//REMOTE MODE - BLUETOOTH
int estado_remoto = digitalRead(modoremoto); //Lee selector de mando (Local/Remoto)
if ( estado_remoto == HIGH) { // Mode switch status checking
Serial.println ("REMOTE MODE SWITCH");
delay(100);
lcd.setCursor( 0,1);
lcd.println("REMOTE MODE");
delay(100);
if(Serial1.available() > 0) // Send data when receive data
{delay(300);
data = Serial1.read(); //Read and store data
Serial1.print(data);
Serial1.print("\n");
Serial.print(data);
Serial.print("\n");
if(data == '*') { // Reset Bluetooth
lcd.setCursor( 0,1);
lcd.println("Reset_BTOOTH");
delay(100);
tempo=0; // time initial status
tfinal=0;
Serial1.print(" Btooth reset of timer !!! ");
lcd.setCursor( 0,1);
lcd.println("CMD/RESET/T_BTH");
delay(100);
}
if (data == '3') { //Option 1 selected from APP
tempo=1;
Serial.println(" 1 min Irrigation");
lcd.setCursor( 0,1);
lcd.println("1 min___Irrig");
delay(500);
}
if (data == '6') { //option 2 selected from APP
tempo=2;
Serial.println(" 2 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println("2 mins__Irrig");
delay(500);
}
if (data == '9') { //Option 3 selected from APP
tempo=3; //
Serial.println(" 3 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println(" mins___Irrig");
delay(500);
}
if (data == '#') { //Option 4 selected from APP
tempo=5;
Serial.println("5 mins Irrigation");
lcd.setCursor( 0,1);
lcd.println(" 5 mins Irrig");
delay(1000);
}
if(data == '0') {
int comando=1;
digitalWrite(OUTCMD_VALV, LOW);
Serial.println("Open command send to solenoid valve");
lcd.setCursor( 0,1);
lcd.println("CMD/BTOOT/Open/Val1");
tinicio=millis(); //Time stamp
tfinal= (tempo*1000*60)+tinicio; //end time calculation
Serial.println(tinicio);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("Tstart:");
lcd.setCursor(7,0);
lcd.println(tinicio);
Serial.println("End Time selected (s):");
Serial.println(tfinal);
lcd.setCursor( 0,0);
lcd.println("tend:");
lcd.setCursor(7,0);
lcd.println(tfinal);
lcd.setCursor(0,1);
lcd.println("Start Counter T");
delay(2000);
Serial.println("Starting time counter(s)");
delay(3000);
}
}
if(data == '1') { // close command from APP
digitalWrite(OUTCMD_VALV, HIGH);
Serial1.println(" close command send to solenoid valve from APP !!! ");
Serial.println(" close command send to solenoid valve from APP !!! !!! ");
lcd.setCursor( 0,1);
lcd.println("close: 1 Remote-BT");
delay(100);
}
}
int estado_out2 = digitalRead(OUTCMD_VALV);
if (comando=1)
if (estado_out2 == LOW){
if (tempo > 0) {
tactual = millis();
Serial.println("System Time:");
Serial.println(tactual);
Serial.println(tinicio);
Serial.println("Time accumulated Irrigation(s):");
Serial.println((tactual-tinicio)/1000);
lcd.setCursor( 0,0);
lcd.println("Taccum(s):");
lcd.setCursor(13,0);
lcd.println(abs(tactual-tinicio)/1000);
Serial.println("End time selected(ms):");
Serial.println(tfinal);
delay (1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("Tend(s):");
lcd.setCursor(11,1);
lcd.println(abs(tempo*60));
delay(1000);
lcd.clear();
lcd.setCursor( 0,1);
lcd.println("Flow(L/Min):");
lcd.setCursor(12,1);
lcd.println(abs(caudal));
delay(1000);
if(tfinal <= tactual) {
int estado_out2 = digitalRead(OUTCMD_VALV);
if (estado_out2 == LOW){
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println(" Close Command from code -safety trigger");
Serial.println("End Automatic Irrigation");
delay(4000);
int volumen = tempo*29;
Serial.println("Volumen aprox. of Irrigation (Lts):");
Serial.println(volumen);
delay(3000);
lcd.clear();
lcd.setCursor( 0,0);
lcd.println("End Autom Irrigat");
lcd.setCursor(0,1);
lcd.clear();
lcd.println("VolAproxLts:");
lcd.setCursor(12,0);
lcd.println(volumen);
delay(4000);
int tempo=0;
int comando=100;}
}
}
if (key == '*') { //If "*" key is pressed reset the clock
tempo=0;
tfinal=0;
Serial.println("Time reset pressed through keypad");
lcd.setCursor(0,1);
lcd.print(" keypad Time Reset");
delay(300);
}
}
// FAIL MODEM CLOSE COMMAND TO SOLENOID VALVE FOR SAFETY
if (estado_remoto ==0)
if (estado_local ==0)
{
Serial.println ("ALARM: SYSTEM FAILURE CALL TECHNICAL SERVICE ");
delay (500);
lcd.setCursor(1,0);
lcd.print("Alarma:L/R-UNDEFINED");
lcd.setCursor(0,1);
lcd.print("CALL TECHNICAL SERV");
lcd.setCursor(0,0);
lcd.print("TURN OFF THE SYSTEM");
int (estadosalida =digitalRead (2));
Serial.println(estadosalida);
delay(500);
if (estadosalida == LOW) { //IF SOLENOID VALVE IS OPEN FOR SAFETY CODE CLOSE ITl
digitalWrite(OUTCMD_VALV, HIGH);
Serial.println("CLOSE TRIGGER SENT BY PROGRAM !!! ");
Serial1.println("CLOSE TRIGGER SEND BY PROGRAM!!! ");
lcd.setCursor( 0,0);
lcd.println("CLOSE VALVE:Program");
lcd.setCursor( 0,1);
lcd.println("HARDWARE FAILURE");
delay(500);}
}
}
Comments