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