programador horario

Buenas tardes a todos,

tengo la necesidad de construir un sencillo programado horario de riego porque el modelo comercial que tengo no tiene posibilidad de realizar una función específica. Me serviré de su electroválvula y un Arduino uno, relé y un RTC.

Sencillamente necesito (regar) 2 minutos cada 5 minutos de 11 de la mañana a 7 de la tarde. Es sencillo pero no habitual.

Tengo el material y había recopilado info para realizar un sencillo programa.

Primer problema, ya solucionado, con ‘setTime(19,40,00,2,05,2015)’ no pongo el hora el RTC pero lo hago con ‘RTC.adjust(DateTime(“MAY 21 2016”,“22:35:53”));’

El problema me llega con el programilla que mas o menos monto pero no me deja compilar por múltiples errores y ya me he atascado.

Nótese que soy novato y que en mi pueblo dicen ‘es muy valiente la ignorancia’

Les dejo las dos mini versiones para ver si me pueden corregir:

Version 1

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup()
{ Serial.begin(115200);

  setSyncProvider(RTC.get);      // Vamos a usar el RTC
  setSyncInterval(86400000);        // Sincronizo una vez cada 24 horas

  //setTime(19,40,00,2,05,2015); // Puesto en hora con el otro CONFIGURAR
  pinMode( 13, OUTPUT) ;
  digitalWrite(13 , LOW) ; // Apagamos el LED al empezar

  if (timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");
}
void loop()
{
  boolean esHoraRiego() {
    //Defino horas de riego Inicio a las 11:00 y termina a las 19:30
    byte horaInicio = 11;
    byte minutoInicio = 01;
    byte horaFin = 19;
    byte minutoFin = 30;

    //Para hacer las comparaciones de cuando empezar y cuando terminar, lo paso todo a minutos.

    int momentoInicio = (horaInicio * 60) + minutoInicio;
    int momentoFin = (horaFin * 60) + minutoFin;
    int momentoAhora = (hour() * 60) + minute();

    //Esto es que si hemos pasado o estamos en el momento de inicio , pero antes del momento del fin…
    if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) {
      //devolver “Cierto” en esta función “esHoraRiego”
      return true;
    } else {
      //devolver “Falso” en esta función “esHoraRiego”
      return false;
    }
    }

    { //Muestro por el puerto serie la hora
      Serial.print(“Son las: “);
      Serial.println(String(hour()) + “: ” + String(minute()));
      //comprobamos si es la hora del riego
      if (esHoraRiego()) {
        //Si es la hora del riego, mostramos un mensaje indicándolo por el puerto serie
        Serial.print(“Es hora riego!!”);
        digitalWrite(13 , HIGH) ; // aBRIMOS PIN/LED al empezar
        delay(120000);          // 120 SEGUNDOS DE RIEGO
        Serial.print(“Es hora riego!!”);
        digitalWrite(13 , LOW) ; // CERRAMOS PIN/LED al empezar
        delay(180000);          // 180 SEGUNDOS DE ESPERA

      } else {
        //Muestro por el puerto serie la hora
        Serial.print(“Son las: “);
        Serial.println(String(hour()) + “: ” + String(minute()));
        //Si no es la hora del riego, mostramos un mensaje indicándolo por el puerto serie tambien
        Serial.print(“No es hora riego”);
        delay(108000000);          // 30 MIN DE ESPERA EN MILISEGUNDOS
      }
      }
      }

Version 2

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t
void setup() {
  { Serial.begin(115200);

  setSyncProvider(RTC.get);      // Vamos a usar el RTC
  setSyncInterval(86400000);        // Sincronizo una vez cada 24 horas

  //setTime(19,40,00,2,05,2015); // Esto no pone en hora el rtcPuesto en hora con el otro CONFIGURAR
  pinMode( 13, OUTPUT) ;
  digitalWrite(13 , LOW) ; // Apagamos el LED al empezar

  if (timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");
}

}

void loop() {
  
    //Defino horas de riego Inicio a las 11:00 y termina a las 19:30
    byte horaInicio = 11;
    byte minutoInicio = 01;
    byte horaFin = 19;
    byte minutoFin = 30;

    //Para hacer las comparaciones de cuando empezar y cuando terminar, lo paso todo a minutos.

    int momentoInicio = (horaInicio * 60) + minutoInicio;
    int momentoFin = (horaFin * 60) + minutoFin;
    int momentoAhora = (hour() * 60) + minute();

    
    if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) {
      //devolver “Cierto” en esta función “esHoraRiego”
      Serial.print(“Son las: “);
      Serial.println(String(hour()) + “: ” + String(minute()));
      Serial.print(“Es hora riego!!”);      
        digitalWrite(13 , HIGH) ; // aBRIMOS PIN/LED al empezar
        delay(120000);          // 120 SEGUNDOS DE RIEGO
        Serial.print(“Es hora riego!!”);
        digitalWrite(13 , LOW) ; // CERRAMOS PIN/LED al empezar
        delay(180000);          // 180 SEGUNDOS DE ESPERA
    } else {
      //Muestro por el puerto serie la hora
        Serial.print(“Son las: “);
        Serial.println(String(hour()) + “: ” + String(minute()));
        //Si no es la hora del riego, mostramos un mensaje indicándolo por el puerto serie tambien
        Serial.print(“No es hora riego”);
        delay(108000000);          // 30 MIN DE ESPERA 
    }

}

Les agradecería sus comentarios :slight_smile:

Sería mucho más fácil si también incluyes los mensajes de error que te envía, así te podemos ayudar más rápidamente.

EDIT:

He bajado la librería e intenté compilarla, lo primero es que tenías unos errores con {

y también tenías definida la función esHoraRiego() dentro de loop, debías definirla fuera de.

Por último me daba un error con la librería time, lo que hice fue bajar la última versión desde Librería Time, y todo quedó solucionado:
Versión 1

#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

void setup(){
  Serial.begin(115200);

  setSyncProvider(RTC.get);      // Vamos a usar el RTC
  setSyncInterval(86400000);        // Sincronizo una vez cada 24 horas

  pinMode( 13, OUTPUT) ;
  digitalWrite(13 , LOW) ; // Apagamos el LED al empezar

  if (timeStatus() != timeSet){
    Serial.println("Unable to sync with the RTC");
  }else{
    Serial.println("RTC has set the system time");
  }
}

void loop(){
  //Muestro por el puerto serie la hora
  Serial.print("Son las: ");
  Serial.println(String(hour()) + ": " + String(minute()));
  //comprobamos si es la hora del riego
  if (esHoraRiego()) {
    //Si es la hora del riego, mostramos un mensaje indicándolo por el puerto serie
    Serial.print("Es hora riego!!");
    digitalWrite(13 , HIGH) ; // aBRIMOS PIN/LED al empezar
    delay(120000);          // 120 SEGUNDOS DE RIEGO
    Serial.print("Es hora riego!!");
    digitalWrite(13 , LOW) ; // CERRAMOS PIN/LED al empezar
    delay(180000);          // 180 SEGUNDOS DE ESPERA
  } else {
    //Muestro por el puerto serie la hora
    Serial.print("Son las: ");
    Serial.println(String(hour()) + ": " + String(minute()));
    //Si no es la hora del riego, mostramos un mensaje indicándolo por el puerto serie tambien
    Serial.print("No es hora riego");
    delay(108000000);          // 30 MIN DE ESPERA EN MILISEGUNDOS
  }
}

boolean esHoraRiego() {
  //Defino horas de riego Inicio a las 11:00 y termina a las 19:30
  byte horaInicio = 11;
  byte minutoInicio = 01;
  byte horaFin = 19;
  byte minutoFin = 30;

  //Para hacer las comparaciones de cuando empezar y cuando terminar, lo paso todo a minutos.

  int momentoInicio = (horaInicio * 60) + minutoInicio;
  int momentoFin = (horaFin * 60) + minutoFin;
  int momentoAhora = (hour() * 60) + minute();

  //Esto es que si hemos pasado o estamos en el momento de inicio , pero antes del momento del fin…
  if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) {
    //devolver "Cierto" en esta función "esHoraRiego"
    return true;
  } else {
    //devolver "Falso" en esta función "esHoraRiego"
    return false;
  }
}

La segunda versión compiló sin problemas.

Sólo hice que código compile, no revisé nada sobre su función.

Muchos errores

boolean esHoraRiego();

si defines a esHoraRiego como variable boolean o mejor bool terminas con ;

bool esHoraRiego;

Forma correcta

   //Esto es que si hemos pasado o estamos en el momento de inicio , pero antes del momento del fin…
    if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) {
      //devolver "Cierto" en esta función "esHoraRiego"
      return true;
    } else {
      //devolver "Falso" en esta función "esHoraRiego"
      return false;
    }

Esto es válido dentro de una función del tipo

bool funcionMomento(){
    //Esto es que si hemos pasado o estamos en el momento de inicio , pero antes del momento del fin…
    if ((momentoInicio <= momentoAhora) && (momentoAhora < momentoFin)) {
      //devolver "Cierto" en esta función "esHoraRiego"
      return true;
    } else {
      //devolver "Falso" en esta función "esHoraRiego"
      return false;
    }
]

Pero tu lo has hecho dentro de void loop(){ asi que en este contexto no es válido.
O sea

if () {
        } else {
        }

debe tener elementos que resolver en su interior pero no puede devolver un return algo;

  1. { //Muestro por el puerto serie la hora
    No se puede abrir una llave de este modo.

  2. para que quieres un RTC si luego usas

delay(120000);  
delay(180000);  
delay(108000000);

SI usas un RTC no hace falta el uso de delay o bien hay otras maneras que no detienen el código.

Esto es respecto del código 1.

Muchas gracias a gepd y surbyte por su ayuda,

se demuestra mi torpeza y poca lucidez a según que horas. También algún problema con la librería time y que empiezo a cambiar líneas ya desesperado.

Sobre el punto 4 del comentario de surbyte comentar lo siguiente:

Para este sencillo cometido no es necesario usar un RTC porque es habilitar un periodo de tiempo y luego una frecuencia de riego. Lo utilizo para posibles reinicios o cortes de alimentación. Todavía no me veo capaz de sacarle mas partido (todo llegará) y pensé (quizás no sea así) que parar el código iba a ser mas ligero en consumo de energía, por si la alimentación es con batería, aunque me inutiliza la placa para otros usos. Una vez lo ponga a funcionar tengo que volver sobre el tema porque hay un par de funciones sencillas que me gustaría implementar, como controlar la temperatura y la iluminación)

Muchas gracias y un saludo,

jfandos:
Muchas gracias a gepd y surbyte por su ayuda,

se demuestra mi torpeza y poca lucidez a según que horas. También algún problema con la librería time y que empiezo a cambiar líneas ya desesperado.

Sobre el punto 4 del comentario de surbyte comentar lo siguiente:

Para este sencillo cometido no es necesario usar un RTC porque es habilitar un periodo de tiempo y luego una frecuencia de riego. Lo utilizo para posibles reinicios o cortes de alimentación. Todavía no me veo capaz de sacarle mas partido (todo llegará) y pensé (quizás no sea así) que parar el código iba a ser mas ligero en consumo de energía, por si la alimentación es con batería, aunque me inutiliza la placa para otros usos. Una vez lo ponga a funcionar tengo que volver sobre el tema porque hay un par de funciones sencillas que me gustaría implementar, como controlar la temperatura y la iluminación)

Muchas gracias y un saludo,

Bien te comprendo pero no funciona como te has imaginado.
Si se cortará la luz se reinicia toda la operación y ese delay vuelve a ejecutarse suponiendo que estuvieras dentro de tus horarios de riego.
Lo mejor es que armes una pequeña máquina de estados o mejor dicho porque no lo vas a entender, una variable lleva un estado o una tarea a cumplir, esa tarea se guarda en EEPROM.
Si ocurre algo como un corte, pues al reiniciar lee en que tarea está y sigue.
Eso sin olvidar cuantos ciclos dentro del período de tiempo que estaba le falta por cumplir.
Ahora a este análisis que he hecho le encuentro un pequeño error y es que grabar en lal EEPROM del Arduino tiene limite y si lo haces muy seguido terminamos dañando esa memoria.
Entonces la solucion es detectar que se corta la energia y tener solo unos segudos (que es una vida) para el arduino para decirle, ahhh se cortó la energía entonces guardo en la EEPROM.

Ni se me había ocurrido este planteamiento, esta claro que tengo ir paso a paso :blush:

Bueno te recomiendo que veas esta librería TimeAlarm Library

Mira este ejemplo

/*
 * TimeAlarmExample.pde
 *
 * Este ejemplo llama a funciones desde las 8:30 am y las 5:45 pm (17:45)
 * y simulan encender las lueces a la noche y apagarlas por la mañana.
 * Un timer semanal esta seteado para los sabados a las 8:30:30
 *
 * Un timer es llamado cada 15 segundos
 * El otro timer es llamado una sola vez cada 10 segundos
 *
 * Un arranca esta fijado para las 8:29 am Jun 6 2015
 */
 
#include <Time.h>
#include <TimeAlarms.h>

void setup()
{
  Serial.begin(9600);
  setTime(8,29,0,1,1,11); // set time to Saturday 8:29:00am Jan 1 2011
  // create the alarms 
  Alarm.alarmRepeat(8,30,0, MorningAlarm);  // 8:30am every day
  Alarm.alarmRepeat(17,45,0,EveningAlarm);  // 5:45pm every day 
  Alarm.alarmRepeat(dowSaturday,8,30,30,WeeklyAlarm);  // 8:30:30 every Saturday 

 
  Alarm.timerRepeat(15, Repeats);            // timer for every 15 seconds    
  Alarm.timerOnce(10, OnceOnly);             // called once after 10 seconds 
}

void  loop(){  
  digitalClockDisplay();
  Alarm.delay(1000); // wait one second between clock display
}

// functions to be called when an alarm triggers:
void MorningAlarm(){
  Serial.println("Alarm: - turn lights off");    
}

void EveningAlarm(){
  Serial.println("Alarm: - turn lights on");           
}

void WeeklyAlarm(){
  Serial.println("Alarm: - its Monday Morning");      
}

void ExplicitAlarm(){
  Serial.println("Alarm: - this triggers only at the given date and time");       
}

void Repeats(){
  Serial.println("15 second timer");         
}

void OnceOnly(){
  Serial.println("This timer only triggers once");  
}

void digitalClockDisplay()
{
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println(); 
}

void printDigits(int digits)
{
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

como ves solo te sugiero y te muestro con qué hacerlo, la idea es que tu puedas unir lo mejor de lo tuyo y lo mejor de esta librería.
Aun no resolvemos el tema de lo que ocurre si se corta la energía. Ya lo veremos.

Y yo lo agradezco,

porque lo que pretendo es aprender.

En cuanto al corte de energía para este ejemplo y para mi caso no considero necesario el volcado a la eprom porque la tarea que se queda cortada no debe seguir en el punto en que se quedó sino en función de la hora en que vuelva la energía. Entiendo que con el RTC que he colocado al volver la corriente tendremos la hora correcta.

Un solo detalle.
El DS1307 es un mediocre RTC.
DS1307 tiene una estabilidad por mes de +/-1 minuto y no hay mucho que se puede hacer.
Yo usaría un DS3231 que es por demás estable.