Hay faltas de ortografía y de expresividad, pero es un código "tal cual".
Es el que está funcionando en mi arduino UNO.
Espero que se entienda. Si tienes problemas con él, no dudes en mandar un correo y te
atenderemos cumplidamente.
/*
riego11 Ver 1.1 Junio/Julio 2014.
Una vez comprobado el funcionamiento se añade una tarjeta SD para grabar al configuración y un log de cada vez que se riega
Se corrige el bug de ejecutar. No funciona o no lo hace correctamente
Se cambia la secuencia del loop. Hay que conseguir que vaya más rapida la comunicación.
*/
#include <Wire.h>
#include <DS1307.h>
#include <Shifter.h>
#include <SdFat.h>
#include <stdlib.h>
#include <stdlib.h>
#define SER_Pin 5 // dataPin
#define RCLK_Pin 7 // lacthPin
#define SRCLK_Pin 6 // clockPin
#define NUM_REGISTERS 1
//Pinlluvia se suprime, ahora se configura desde el ini
//#define PIN_LLUVIA 9 // Se pone en la entrada 9 pero puede cambiar
// Aquí se definen cuántos registros de desplazamiento hay en la cadena...
Shifter shifter(SER_Pin, RCLK_Pin, SRCLK_Pin, NUM_REGISTERS); // Se inicializa el registro de desplazamiento usando la librería “Shifter”
DS1307 clock;//el reloj
//El sd y los ficheros
SdFat g_sd;
SdFile g_fichero; //Solo se puyede abrir uno cada vez así que da igual como se llame la variable
//Aqui son todo variables globales (g_ ...), al fin y al cabo no es un PC...
//Variables para la rx del serie
String g_s_cadena_in; // datos que llegan
boolean g_s_inicio_sn;
boolean g_s_fin_sn;
//Los tiempos de los reles
struct RELES {
int r_tiempo;
int hora_inicio;
int opcion;
int ultima_regada;
boolean activado_sn;
};
RELES g_reles[8];
//Para enviar los estados de cada cosa al monitoreo
char g_estado_reles;
int g_estado_io;
int g_estado_an[6];
//Los pines digitales pueden ser salida o entrada. Por defecto se ponen todos como salida
//y luiego en el setup se definen quien es quien
boolean g_salida_sn[14];//Ojo es "salida" pero puede ser "entrada" si esto es a false
boolean g_activada_sn[14]; //si la entrada esta activada
boolean g_monitorizar_sn; //si se monitorizan los datos en el PC
boolean g_ejecutar_sn; //Se ejecuta lo que tenga reles[]
int g_ejecutar_rele;
int g_ejecutar_minuto_inicio;
int g_minuto_dia;//Se carga aqui el momento
int g_hoy; //el nº de días transcurridos desde el 2000, o sea hoy
int g_pin_lluvia; //que pin es el detector de lluvia
int g_lluvia_ultima;//Cuando llovió la ultima vez
boolean g_lluvia_grabada; //para grabar sólo una vez
//Archivos de cabecera... por no meterlos en un .h
void vdl_arduino_leer_fechas_log_reles();
void vdl_arduino_transmitir_log_reles();
void vdl_arduino_grabar_log_reles(int rele,boolean manual_sn);
void vdl_arduino_grabar_programacion_reles();
void vdl_arduino_leer_programacion_reles();
void vdl_arduino_leer_ini();
void vdl_arduino_reloj_minuto_dia_hoy();
//---------------------------------------------------------------------
// Cuando se resetea con el boton del arduino o cuando carga un programa
// o cuando se conecta el programa de monitorización, pasa por aqui salvo
// que este pulsado el boton de No setup
//---------------------------------------------------------------------
void setup()
{
int a;
Serial.begin(115200); // abre el puerto serie, y le asigna la velocidad de 115200 bps
g_monitorizar_sn = true; //Por defecto se monitoriza
//Hace falta hacer la ejecución dentro del loop por que sino parece que se vuelve loco el arduino
g_ejecutar_sn = false;
g_ejecutar_rele = 0;
g_ejecutar_minuto_inicio = 0;
g_s_cadena_in = ""; // datos que llegan
g_s_inicio_sn = false;
g_s_fin_sn = false;
g_s_cadena_in.reserve(128); //la cadena de entrada del serie
g_minuto_dia = 0; //Para el envio de la fecha y hora
g_hoy = 0; //a fecha de hoy cuantos dias pasan del 2000
g_lluvia_ultima = 0; //Para el control de la lluvia
g_pin_lluvia = 9; //Un por defecto
g_lluvia_grabada = false;
// Para el envio del estado de todo el arduino
g_estado_reles = 0x00; //reles (8)
g_estado_io = 0x0000; //14 e o s
for(a=0;a < 6;a++) g_estado_an[a] = 0; //6 analogicas
//Se inicia el reloj
Wire.begin(); //Hace falta par el DS1307 (el reloj)
clock.begin();
vdl_arduino_reloj_minuto_dia_hoy();
//Los pines que no estan aqui es por que estan reservados para E/S y reles
//0 y 1 son para el puerto serie
//5 6 y 7 son para los reles
//La tarjeta SD reserva 10,11,12 y 13 para ella
//el 2,3 8,9 son las entradas optoacopladas del relay shield (INPUT)
for(a=0;a < 14; a++)
{
g_salida_sn[a] = true; //por defecto todas salidas
g_activada_sn[a] = false; //al arrancar todas la IN sin activar
}
//La config por defecto
pinMode(2, INPUT); //2,3,8,9 -> Optoacopladas de la relay shield
g_salida_sn[2] = false;
pinMode(3, INPUT);
g_salida_sn[3] = false;
pinMode(4, OUTPUT); //Libre (es la única????)
pinMode(8, INPUT);
g_salida_sn[8] = false;
pinMode(9, INPUT);
g_salida_sn[9] = false;
//Inicializa el SD
if (!g_sd.begin(SS, SPI_HALF_SPEED)) g_sd.initErrorHalt();
vdl_arduino_leer_ini(); //carga config.ini
//La programacion del riego. Por defecto se ponen estos valores que luego se cambian desde el programa de monitoreo
for(a=0;a < 8; a++)
{
g_reles[a].r_tiempo = 15; //Minutos
g_reles[a].activado_sn = false;
g_reles[a].opcion = 1; //por defecto diario (ojo que las opciones empiezan en 1
g_reles[a].ultima_regada = 0; //el nº de dia del ultimo dia que se rego
}
g_reles[0].hora_inicio = 1080;
g_reles[1].hora_inicio = 1090;
g_reles[2].hora_inicio = 1100;
g_reles[3].hora_inicio = 1110;
g_reles[4].hora_inicio = 1120;
g_reles[5].hora_inicio = 1130;
g_reles[6].hora_inicio = 1140;
g_reles[7].hora_inicio = 1160;
vdl_arduino_leer_programacion_reles(); //Ahora se lee la programacion del ficherito reles.cfg
vdl_arduino_leer_fechas_log_reles(); //Y ahora carga la fecha de la ultimas regadas
}
//
// Y ahora ya las funciones mias
//
//---------------------------------------------------------------------
// Lee el log los reles y se queda con la fecha más alta
//---------------------------------------------------------------------
void vdl_arduino_leer_fechas_log_reles()
{
int a,leer,tamano,offset,ff,rr;
unsigned char dato;
char cadena[64];
char rele_n[2];
char lit[5];
int fechas[8];
for(a=0;a < 8;a++) fechas[a] = 0;
if(!g_fichero.open("reles.log", O_READ))
{
Serial.println("{error reles log en fechas}");
delay(100);
}
else {
tamano= g_fichero.fileSize();
leer=0;
cadena[0] = 0x00;
offset = 0;
while(leer < tamano)
{
dato = g_fichero.read();
leer++;
if(dato == 0x0d || dato == 0x0a)
{
//si es 0d o 0a el siguiente será o 0d o 0a así que paso de él
dato = g_fichero.read();
leer++;
cadena[offset] = 0x00;
//Puede haber al final del fichero algun 0x0d o 0x0a
if(cadena[0] != 0x00)
{
rele_n[0] = cadena[0];
rele_n[1] = 0x00;
lit[0] = cadena[1];
lit[1] = cadena[2];
lit[2] = cadena[3];
lit[3] = cadena[4];
lit[4] = 0x00;
rr = atoi(rele_n);
ff = atoi(lit);
if(ff > fechas[rr]) fechas[rr] = ff;
}
for(a=0;a < offset;a++) cadena[a] = 0x00;
offset = 0;
}
else cadena[offset++] = dato;
} //fin while
g_fichero.close();
}
//Y ahora se supone que tengo las fechas de la ultima regada
for(a=0;a < 8; a++) g_reles[a].ultima_regada = fechas[a];
}
//---------------------------------------------------------------------
// Lee el log los reles y lo manda por el serie
//---------------------------------------------------------------------
void vdl_arduino_transmitir_log_reles()
{
int a,leer,tamano,offset;
unsigned char dato;
char cadena[64],envio[64];
if(!g_fichero.open("reles.log", O_READ))
{
Serial.println("{error reles log en TX}");
delay(100);
}
else {
tamano= g_fichero.fileSize();
//Serial.print("tamano: ");
//Serial.println(tamano,DEC);
leer=0;
cadena[0] = 0x00;
offset = 0;
while(leer < tamano)
{
dato = g_fichero.read();
leer++;
if(dato == 0x0d || dato == 0x0a)
{
//si es 0d o 0a el siguiente será o 0d o 0a así que paso de él
dato = g_fichero.read();
leer++;
cadena[offset] = 0x00;
//Puede haber al final del fichero algun 0x0d o 0x0a
if(cadena[0] != 0x00)
{
sprintf(envio,"{L%s}",cadena);
Serial.write(envio);
delay(100);
}
for(a=0;a < offset;a++) cadena[a] = 0x00;
offset = 0;
}
else cadena[offset++] = dato;
} //fin while
g_fichero.close();
}
}
//---------------------------------------------------------------------
// Graba un registro de cada vez que se activa un rele
// Si el rele == 9 es le de lluvia. OJO! que no es el pin 9 (puede ser
// cualquier pin el de lluvia, a pesar de que coincide que es el 9 en
// este montaje) es el inexistente rele 9
//---------------------------------------------------------------------
void vdl_arduino_grabar_log_reles(int rele,boolean manual_sn)
{
//int horas,minutos;
char cadena[32];
if(!g_fichero.open("reles.log", O_RDWR | O_CREAT | O_APPEND))
{
Serial.println("{falla abriendo reles.log para grabar}");
delay(100);
}
else {
//Grabo la fecha en ascii por que me da igual grabar 4 caracteres que dos int y luego se puede leer
if(rele != 9) //el rele 9 NO EXISTE ES LOG DE LLUVIA
{
if(manual_sn) sprintf(cadena,"%d%d manual",rele,g_hoy);
else sprintf(cadena,"%d%d",rele,g_hoy);
}
else {
//si manual_sn es que se ha activa y sino es que se ha descativado
if(manual_sn) sprintf(cadena,"%d%d on",rele,g_hoy);
else sprintf(cadena,"%d%d off",rele,g_hoy);
}
g_fichero.println(cadena);
g_fichero.close();
}
}
//---------------------------------------------------------------------
// Borra el registro de cada vez que se activa un rele
//---------------------------------------------------------------------
void vdl_arduino_borrar_log_reles()
{
if(!g_sd.remove("reles.log"))
{
Serial.println("{falla borrando reles.log}");
delay(100);
}
}
//---------------------------------------------------------------------
// Graba el archivo de la progamacion de los reles
//---------------------------------------------------------------------
void vdl_arduino_grabar_programacion_reles()
{
int a,rele,horas,minutos;
char cadena[32];
if(!g_fichero.open("reles.cfg", O_RDWR | O_CREAT | O_TRUNC))
{
Serial.println("{falla abriendo reles.cfg para grabar}");
delay(100);
}
else {
for(rele=0;rele < 8;rele++)
{
for(a=0;a < 11;a++) cadena[a] = 0x00;
horas = g_reles[rele].hora_inicio/60;
minutos = g_reles[rele].hora_inicio - (horas*60);
sprintf(cadena,"%d%02d:%02d%03d%d",rele,horas,minutos,g_reles[rele].r_tiempo,g_reles[rele].opcion);
g_fichero.println(cadena);
}
g_fichero.close();
}
}
//---------------------------------------------------------------------
// Lee el archivo de la progamacion de los reles
//---------------------------------------------------------------------
void vdl_arduino_leer_programacion_reles()
{
int a,leer,tamano,offset;
unsigned char dato;
char cadena[16];
char rele_num[2],hh[3],mm[3],r_tiempo[4],r_opcion[2];
if(!g_fichero.open("reles.cfg", O_READ))
{
Serial.println("{No puede leer reles.cfg}");
delay(100);
}
else {
tamano= g_fichero.fileSize();
//Serial.print("tamano: ");
//Serial.println(tamano,DEC);
leer=0;
cadena[0] = 0x00;
offset = 0;
while(leer < tamano)
{
dato = g_fichero.read();
leer++;
if(dato == 0x0d || dato == 0x0a)
{
//si es 0d o 0a el siguiente será o 0d o 0a así que paso de él
dato = g_fichero.read();
leer++;
cadena[offset] = 0x00;
//Puede haber al final del fichero algun 0x0d o 0x0a
if(cadena[0] != 0x00)
{
rele_num[0] = cadena[0];
rele_num[1] = 0x00;
hh[0] = cadena[1];
hh[1] = cadena[2];
hh[2] = 0x00;
//se pasa de los dos puntos :
mm[0] = cadena[4];
mm[1] = cadena[5];
mm[2] = 0x00;
r_tiempo[0] = cadena[6];
r_tiempo[1] = cadena[7];
r_tiempo[2] = cadena[8];
r_tiempo[3] = 0x00;
r_opcion[0] = cadena[9];
r_opcion[1] = 0x00;
g_reles[atoi(rele_num)].hora_inicio = atoi(hh)*60+atoi(mm);
g_reles[atoi(rele_num)].r_tiempo = atoi(r_tiempo);
g_reles[atoi(rele_num)].opcion = atoi(r_opcion);
}
for(a=0;a < offset;a++) cadena[a] = 0x00;
offset = 0;
}
else cadena[offset++] = dato;
} //fin while
g_fichero.close();
}
}
//---------------------------------------------------------------------
// Lee el archivo de configuracion inicial config.ini
//---------------------------------------------------------------------
void vdl_arduino_leer_ini()
{
int a,leer,tamano,offset;
unsigned char dato;
char cadena[16],cual[4],num[3];
//Ahora se lee la configuración del ficherito .ini
if(!g_fichero.open("config.ini", O_READ))
{
Serial.println("{No puede leer config.ini}");
delay(100);
}
else {
tamano= g_fichero.fileSize();
leer=0;
cadena[0] = 0x00;
offset = 0;
while(leer < tamano)
{
dato = g_fichero.read();
leer++;
if(dato == 0x0d || dato == 0x0a)
{
//si es 0d o 0a el siguiente será o 0d o 0a así que paso de él
dato = g_fichero.read();
leer++;
cadena[offset] = 0x00;
strncpy(cual,cadena,3);
cual[3] = 0x00;
if(strlen(cadena) == 5)
{
num[0] = cadena[4];
num[1] = 0x00;
}
else {
num[0] = cadena[4];
num[1] = cadena[5];
num[2] = cadena[6];
}
if(strcmp(cual,"MON") == 0)
{
if(strcmp(num,"1") == 0) g_monitorizar_sn = true;
else g_monitorizar_sn = false;
}
if(strcmp(cual,"RES") == 0); //NO se hace nada, ya se encargan las librarias de cada cosa
if(strcmp(cual,"ENT") == 0)
{
pinMode(atoi(num),INPUT);
g_salida_sn[atoi(num)] = false;
}
if(strcmp(cual,"SAL") == 0) pinMode(atoi(num),OUTPUT);
if(strcmp(cual,"LLU") == 0) g_pin_lluvia = atoi(num);
for(a=0;a < offset;a++) cadena[a] = 0x00;
offset = 0;
}
else cadena[offset++] = dato;
} //fin while
g_fichero.close();
}
}
//---------------------------------------------------------------------
// Devuelve el nº de dias desde el 2000
// Ver 1.1:
// clock.year es el nº de año - 2000 siempre así que se puede devolver un int
//---------------------------------------------------------------------
int vdl_arduino_dias_transcurridos(int dia,int mes,int anno)
{
int dias;
int dias_mes[12] = {0,31,59,90,120,151,181,212,243,273,304,334};
if(anno%4 == 0) dias_mes[2] = 60; //bisiesto
dias = (anno*365) + (anno/4) + dias_mes[mes-1] + dia;
return dias;
}
//---------------------------------------------------------------------
// Lee el reloj y actualiza el minuto de dia
//---------------------------------------------------------------------
void vdl_arduino_reloj_minuto_dia_hoy()
{
boolean error_sn = false;
clock.getTime();
//Tengo la sospecha de que esto a veces arroja valores raros, así que le hago un pequeño control
if(clock.minute < 0 || clock.minute > 59) {clock.minute = 0; error_sn = true;}
if(clock.hour < 0 || clock.hour > 23) {clock.hour = 0; error_sn = true;}
if(!error_sn)
{
g_minuto_dia = clock.minute + (clock.hour*60);
g_hoy = vdl_arduino_dias_transcurridos(clock.dayOfMonth,clock.month,clock.year);
}
}
//---------------------------------------------------------------------
// Envia los datos de monitoreo
//---------------------------------------------------------------------
void vdl_arduino_monitoreo()
{
int a;
Serial.print("{T");
Serial.write(clock.hour);
Serial.write(clock.minute);
Serial.write(clock.second);
Serial.write(clock.dayOfMonth);
Serial.write(clock.month);
Serial.write(highByte(clock.year));
Serial.write(lowByte(clock.year));
Serial.write(clock.dayOfWeek);
Serial.write(g_estado_reles);
Serial.write(highByte(g_estado_io));
Serial.write(lowByte(g_estado_io));
for(a=0;a < 8;a++)
{
Serial.write(highByte(g_reles[a].ultima_regada));
Serial.write(lowByte(g_reles[a].ultima_regada));
}
for(a=0;a < 6;a++)
{
Serial.write(highByte(g_estado_an[a]));
Serial.write(lowByte(g_estado_an[a]));
}
Serial.println("}");
/*
Serial.print(highByte(g_estado_io),HEX);
Serial.print("-");
Serial.println(lowByte(g_estado_io),HEX);
*/
}
//---------------------------------------------------------------------
// ON/OFF digital
// Mirar la nota de on_off_rele
//---------------------------------------------------------------------
void vdl_arduino_on_off_digital(int salida,boolean arriba_sn)
{
if(arriba_sn)
{
digitalWrite(salida, HIGH); //LED on
g_estado_io = g_estado_io | (0x0001<<salida);
}
else {
digitalWrite(salida, LOW); // turn the LED off
g_estado_io = g_estado_io & (~(0x0001<<salida));
}
//g_estado_io = g_estado_io ^ (0x0001<<salida);
}
//---------------------------------------------------------------------
// ON/OFF de un rele
// g_estado_reles = g_estado_reles ^ (0x01<<rele);
// Como la comunicación serie va como va cabe la posibilidad de pasar
// mas de una vez por aquí con la misma orden, así que no se puede usat el XOR
//---------------------------------------------------------------------
void vdl_arduino_on_off_rele(int rele,boolean salida_sn)
{
if(salida_sn)
{
shifter.setPin(rele, HIGH);
shifter.write();
g_estado_reles = g_estado_reles | (0x01<<rele);
}
else {
shifter.setPin(rele, LOW);
shifter.write();
g_estado_reles = g_estado_reles & (~(0x01<<rele));
}
//Serial.print("rele on_off ");
//Serial.println(g_estado_reles,HEX);
}
//---------------------------------------------------------------------
// Lecturas Entradas digitales
//---------------------------------------------------------------------
void vdl_arduino_lectura_entradas_digitales()
{
int a,lectura;
for(a=0;a < 14;a++)
{
if(!g_salida_sn[a]) //Es una entrada
{
lectura = digitalRead(a);
if(lectura == HIGH)
{
if(!g_activada_sn[a])
{
g_activada_sn[a] = true; //para que no este desactivandola todo el rato
g_estado_io = g_estado_io ^ (0x0001<<a);
}
} //si esta arriba
else { //else esta abajo
if(g_activada_sn[a])
{
g_activada_sn[a] = false;
g_estado_io = g_estado_io ^ (0x0001<<a);
}
}//esta abajo
} //es entrada
}//for
}
//-------------------------------------------------------------------------------------------------------------------
// Si esta activado un rele lo desactiva y si esta desactivado lo activa
//------------------------------------------------------------------------------------------------------------------
void vdl_arduino_programa_rele_on_off(int rele,boolean activar_sn)
{
if(activar_sn)
{
if(!g_reles[rele].activado_sn)
{
vdl_arduino_on_off_rele(rele,true);
g_reles[rele].activado_sn = true;
vdl_arduino_grabar_log_reles(rele,false); //log NO manual.
} //if no se ha activado
}
else {
if(g_reles[rele].activado_sn)
{
vdl_arduino_on_off_rele(rele,false);
g_reles[rele].activado_sn = false;
g_reles[rele].ultima_regada = g_hoy;
} //si estaba activado
}
}
//-------------------------------------------------------------------------------------------------------------------
// Esto podría estar perfectamente en el loop pero así queda más claro, además da la posibilidad para más adelante
// de activar una bandera que impida la ejecución del programa (un posible boton en el programa del monitoreo
// de "no ejecutar programa")
// Hago un cambio con la rutina anterio; antes se comprobaba que fuera despues de la hora para desactivarlo
// Ahora no: si no esta entre el tiempo de regar se da la orden de desactivar si esta activado.
// Esto se hace por que ha habido veces que me he encontrado reles activos sin tener que estarlo. como no sé
// quien los activa ni por que si no esta entre los minutos de activar se desactiva y ya
//------------------------------------------------------------------------------------------------------------------
void vdl_arduino_programa_reles()
{
int rele;
for(rele=0;rele < 8;rele++)
{
if(g_reles[rele].r_tiempo != 0)
{
//Primero se comprueba que hoy toca regar (la opcion puede ser desde 1 hasta 4)
if( (g_hoy - g_reles[rele].ultima_regada) >= g_reles[rele].opcion )
{
//De seguido se comprueba que sea la hora
if(g_minuto_dia >= g_reles[rele].hora_inicio && g_minuto_dia < (g_reles[rele].hora_inicio+g_reles[rele].r_tiempo))
{
vdl_arduino_programa_rele_on_off(rele,true);
}
else {
vdl_arduino_programa_rele_on_off(rele,false);
}
} //if g_hoy toca regar
} //si < 0 o > 1440
} //for rele
}
//-------------------------------------------------------------------------------------------------------------------
// Se puede pedir desde el programa de monitoreo que se ejecute el programa que haya para los reles
// Se ejecuta de manera secuancial lo que haya en g_reles[]
//------------------------------------------------------------------------------------------------------------------
boolean vdl_arduino_ejecutar(boolean ejecutar_sn)
{
if(g_reles[g_ejecutar_rele].r_tiempo != 0)
{
if(!g_reles[g_ejecutar_rele].activado_sn)
{
g_reles[g_ejecutar_rele].activado_sn = true;
g_ejecutar_minuto_inicio = g_minuto_dia;
vdl_arduino_on_off_rele(g_ejecutar_rele,true);
vdl_arduino_grabar_log_reles(g_ejecutar_rele,false); //log NO manual.
} //if no se ha activado
//Y si ya ha pasado su tiempo se para y se sigue a por el siguiente
if(g_minuto_dia >= (g_ejecutar_minuto_inicio+g_reles[g_ejecutar_rele].r_tiempo))
{
vdl_arduino_on_off_rele(g_ejecutar_rele,false);
g_reles[g_ejecutar_rele].activado_sn = false;
g_reles[g_ejecutar_rele].ultima_regada = g_hoy;
g_ejecutar_minuto_inicio = 1441; //sino hay nada impedirá la ejecución
g_ejecutar_rele++;
if(g_ejecutar_rele > 7) ejecutar_sn = false;
} //if tiempo ytranscurrido
} //si hay definido tiempo que activar
else {
g_ejecutar_rele++;
if(g_ejecutar_rele > 7) ejecutar_sn = false;
}
return ejecutar_sn; //y asi se ponme a false la global
}
//-------------------------------------------------------------------------------------------------------------------
// controla el pin de la lluvia y graba un log cuando se activa y cuado se desactiva
//------------------------------------------------------------------------------------------------------------------
void vdl_arduino_control_lluvia()
{
int rele;
//El detector es normalmente abierto. O sea, esta en alto si NO esta conectado (pero le he cambiado la logica y lo dejo abajo)
if(g_activada_sn[g_pin_lluvia])
{
if(g_hoy != g_lluvia_ultima)
{
g_lluvia_ultima = g_hoy;
//si esta activo y hoy todavia no se ha activado se pone el dia de los reles a hoy
//asi no regara si le toca y se retrasa el proceso del regado en tantos dias como sea necesario
for(rele=0;rele < 8;rele++)
{
g_reles[rele].ultima_regada = g_hoy;
} //for
} //si hoy != g_lluvia_ultima
if(!g_lluvia_grabada)
{
vdl_arduino_grabar_log_reles(9,true);
g_lluvia_grabada = true;
}
} //if activada_sn[]
else {
if(g_lluvia_grabada)
{
vdl_arduino_grabar_log_reles(9,false);
g_lluvia_grabada = false;
}
}
}
//---------------------------------------------------------------------
// actua en función de la cadena recibida por el serie
// si recibe una orden de activar una salida o un rele devuelve el nº
// de lo que hay que activar: 0-14 salidas 100-108 reles
//---------------------------------------------------------------------
void vdl_arduino_mensaje_recibido()
{
if(g_s_inicio_sn && g_s_fin_sn)
{
//vdl_arduino_on_off_digital(12,true);
switch(g_s_cadena_in.charAt(0))
{
case 'M': { //arranca el monitoreo
Serial.flush();
Serial.println("{#}"); //qsl
g_monitorizar_sn = true;
} break;
case 'N': { //detiene el monitoreo
Serial.flush();
Serial.println("{#}"); //qsl
g_monitorizar_sn = false;
} break;
case 'H': { //pone la fecha y hora
char lit_int[3];
int desp,dia,mes,anno,hora,minuto,segundo,dia_semana;
dia=mes=anno=hora=minuto=segundo=dia_semana=0;
for(desp=0;desp < 6;desp++)
{
lit_int[0] = g_s_cadena_in.charAt( (desp*2)+1 );
lit_int[1] = g_s_cadena_in.charAt( (desp*2)+2 );
lit_int[2] = 0x00;
switch(desp)
{
case 0: dia = atoi(lit_int); break;
case 1: mes = atoi(lit_int); break;
case 2: anno = atoi(lit_int)+2000; break;
case 3: hora = atoi(lit_int); break;
case 4: minuto = atoi(lit_int); break;
case 5: segundo = atoi(lit_int); break;
} //sw
} //for desp
lit_int[0] = g_s_cadena_in.charAt(13);
lit_int[1] = 0x00;
lit_int[2] = 0x00;
dia_semana = atoi(lit_int);
clock.fillByYMD(anno,mes,dia);
clock.fillByHMS(hora,minuto,segundo);
switch(dia_semana)
{
case 1: clock.fillDayOfWeek(MON); break;
case 2: clock.fillDayOfWeek(TUE); break;
case 3: clock.fillDayOfWeek(WED); break;
case 4: clock.fillDayOfWeek(THU); break;
case 5: clock.fillDayOfWeek(FRI); break;
case 6: clock.fillDayOfWeek(SAT); break;
case 7: clock.fillDayOfWeek(SUN); break;
}
clock.setTime();
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'R': { //La programacion de cada relé
char lit[4];
int rele,hh,mm;//,tiempo;
lit[0] = g_s_cadena_in.charAt(1);
lit[1] = g_s_cadena_in.charAt(2);
lit[2] = 0x00;
rele = atoi(lit);
lit[0] = g_s_cadena_in.charAt(3);
lit[1] = g_s_cadena_in.charAt(4);
lit[2] = 0x00;
hh = atoi(lit);
lit[0] = g_s_cadena_in.charAt(6);
lit[1] = g_s_cadena_in.charAt(7);
lit[2] = 0x00;
mm = atoi(lit);
g_reles[rele].hora_inicio = (hh*60)+mm;
lit[0] = g_s_cadena_in.charAt(8);
lit[1] = g_s_cadena_in.charAt(9);
lit[2] = g_s_cadena_in.charAt(10);
lit[3] = 0x00;
g_reles[rele].r_tiempo = atoi(lit);
lit[0] = g_s_cadena_in.charAt(11);
lit[1] = 0x00;
g_reles[rele].opcion = atoi(lit);
//g_reles[rele].ultima_regada = 0;
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'G': { //graba el fichero reles.cf con lo que se ha enviado desde el PC
vdl_arduino_grabar_programacion_reles();
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'C': {//Si pide la configuracion se le envia la config y el estado de cada I/O
// OJO! Antes de pedir la config es prudent parar el monitoreo sino puede fallar
int desp;
Serial.flush();
Serial.println("{#}"); //qsl
//delay(300);
delay(100);
//primero se lee del SD y así de paso se renueva por si acaso se ha modificado a mano
vdl_arduino_leer_programacion_reles();
Serial.flush();
Serial.print("{X");
for(desp=0;desp < 8;desp++)
{
//Serial.write(desp);
Serial.write(highByte(g_reles[desp].hora_inicio));
Serial.write(lowByte(g_reles[desp].hora_inicio));
Serial.write(highByte(g_reles[desp].r_tiempo));
Serial.write(lowByte(g_reles[desp].r_tiempo));
Serial.write(g_reles[desp].opcion);
}
Serial.println("}");
} break;
case 'L': { //Se envia lo que se lea en el fichero del log
Serial.flush();
Serial.println("{#}"); //qsl
delay(100);
vdl_arduino_transmitir_log_reles();
} break;
case 'D': { //graba el fichero reles.cf con lo que se ha enviado desde el PC
vdl_arduino_borrar_log_reles();
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'A': {//activa o desactiva una salida concreta o rele o e/s digital
char lit[4];//001-013 salidas 101-108 reles
int activar = 0;
lit[0] = g_s_cadena_in.charAt(1);
lit[1] = g_s_cadena_in.charAt(2);
lit[2] = g_s_cadena_in.charAt(3);
lit[3] = 0x00;
activar = atoi(lit);
if(activar > 0)
{
if(activar >= 100 && activar < 109)
{
vdl_arduino_on_off_rele(activar-100,true); //100 en todos //activar reles
vdl_arduino_grabar_log_reles(activar-100,true); //log manual
}
if(activar >= 600 && activar < 609) vdl_arduino_on_off_rele(activar-600,false);//desactivar reles
if(activar >= 1 && activar < 14) vdl_arduino_on_off_digital(activar,true);//activar E/S digital
if(activar >= 501 && activar < 514) vdl_arduino_on_off_digital(activar-500,false);//desactivar E/S digital
}
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'E': { //ejecutar el programa de los reles
g_ejecutar_sn = true;
g_ejecutar_rele = 0;
Serial.flush();
Serial.println("{#}"); //qsl
} break;
case 'Q': { //Se poen a cero las cecha de ultima regada
int rele;
for(rele=0;rele < 8;rele++) g_reles[rele].ultima_regada = 0;
Serial.flush();
Serial.println("{#}"); //qsl
} break;
} //fin sw
g_s_cadena_in = "";
g_s_inicio_sn = false;
g_s_fin_sn = false;
//vdl_arduino_on_off_digital(12,false); //Apago el 12
} //si inicio y fin
}
//---------------------------------------------------------------------
// El main de esto
//---------------------------------------------------------------------
void loop()
{
//g_monitorizar_sn = false;
//PENDIENTE: Cambiar el parpadeo con la función milis (o una interrupcion), de manera que se quite el delay del encencido
//del pin. Se hace una función parapeo(pin) y ya.
//Se quita el monitoreo del pin de parpadeo del PC para evitar que esté siempre encendido y en su lugar se pone
//un pulsador que sirva de test. Así si que quiere compobar la comuncación serie, se pulsa el pulsador y se vé si va o no
//Así nos ahorraremos milisegundos (incluso es posible quitar todos los delays del loop
vdl_arduino_on_off_digital(4,true);
delay(100); //100 milisegundos que tarde desde que se enciende hasta que envia el mensaje al PC
//Se envia el monitoreo. Se hace en dos puntos, al activar el 13 y al desactivarlo, por que si no no se entra de la desactivacion
//ademas as se pueden monitorear los cambios que se producen en el programa.
//Si se quita el parpadeo solo se monitoreara el final del loop() y este habra que quitar
if(g_monitorizar_sn) vdl_arduino_monitoreo();
vdl_arduino_reloj_minuto_dia_hoy(); //actualizar el minuto de dia (g_minuto_dia) y el nº de dias (g_hoy)
vdl_arduino_lectura_entradas_digitales(); //Si hay un pin digital arriba (y es in) se registra en su variable
//Los reles se programan por hora a la que empezar, tiempo que debe estar actuando y dias transcurridos desde la ultima activacion
if(!g_ejecutar_sn) vdl_arduino_programa_reles(); //si se ha pedido una ejecucion se pasa del programa
//Si se pide una ejecución desde el programa de monitoreo
if(g_ejecutar_sn) g_ejecutar_sn = vdl_arduino_ejecutar(g_ejecutar_sn);
//Se controla si llueve y se grabar un log si es que si
vdl_arduino_control_lluvia();
vdl_arduino_on_off_digital(4,false); //Apago el 13 Se acabo la secuencia
delay(100); //segun la demora puede que la pantalla no sea capaz de ir tan rapido
if(g_monitorizar_sn) vdl_arduino_monitoreo();
} // end loop
//------------------------------------------------------------------------
// Este evento ocurre cuando entran nuevos datos al serie.
// Esta funcion corre entre cada vez que el loop se ejecuta, asi que mucho
// ojo con meter delays aqui por que ralentizara todo el proceso
// Esta funcion es como el loop propiedad del arduino no hay que ponerle otro nombre
//------------------------------------------------------------------------
void serialEvent()
{
while(Serial.available())
{
char in_car = (char)Serial.read();
//Serial.print(in_car);
if(in_car == '{') g_s_inicio_sn = true;
else {
if(in_car == '}') g_s_fin_sn = true;
else {
//ignoro los finales de mensaje estandar
if(in_car != 0x0d && in_car != 0x0a) g_s_cadena_in += in_car;
}
}
} //while
//Serial.println(g_s_cadena_in);
vdl_arduino_mensaje_recibido(); //miro si hay mensajes en el serie
} //end serialEvent