Control de riego usando un modulo de relevadores controlados por un RTC DS3231

Buenos días, mi nombre es Isaí, soy estudiante de preparatoria, y estoy trabajando en un control de riego para un invernadero. Estoy usando un modulo de 4 relevadores, 3 los usaré para activar 3 electrovalvulas y uno para activar una bomba; tengo un problema, al momento de activarse el primer relé y al mismo tiempo se activa el relé que va a la bomba, esto está todo bien, pero el segundo y tercer relé no se activan a la hora especifica, más bien, no se activan en ningun momento, ni al momento de activarse este segundo y tercer relé tampoco se activa el relé que va a la bomba, solo hace el funcionamiento correcto el primer relé, quisiera saber si me podrían ayudar, este es mi codigo:

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include <TimeAlarms.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h> 
#define bomba 5

// introduce segundos de riego 1-59
int TR=15; //TIEMPO DE RETRASO

void setup() {
  lcd.init();
  lcd.backlight();
 lcd.setCursor(0, 0);
lcd.print("Hora:");
Serial.begin(9600);
 

  //Pines de salida a los relevadores
  pinMode(bomba,OUTPUT);
  digitalWrite(bomba, HIGH);
  
   pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  
   pinMode(7, OUTPUT);
  digitalWrite(7, HIGH );
  
   pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);


  // Set time fija el horario inicial del reloj (HH:MM:SS:DD:MM:YY)  sólo una vez
 setTime(11,35,30,20,7,23);
  RTC.set(now());
  
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
    Serial.println("Fallo de RTC");

  else
   Serial.println("Sincronizado con RTC");
  // Crear las alarmas (HH:MM:SS:FUNCIÓN)
  //Horas de Válvula 1
  {
  Alarm.alarmRepeat(11, 36, 0, EV1ON);  
  Alarm.alarmRepeat(11, 36, TR, EV1OFF);  
  
  Alarm.alarmRepeat(11, 39, 0, EV1ON);  
  Alarm.alarmRepeat(11, 39, TR, EV1OFF);  
  
  Alarm.alarmRepeat(11, 43, 0, EV1ON);  
  Alarm.alarmRepeat(11, 43, TR, EV1OFF);}


  //Horas de la Válvula 2
  {
  Alarm.alarmRepeat(11, 37, 0, EV2ON);  
  Alarm.alarmRepeat(11, 37, TR, EV2OFF);  
  
  Alarm.alarmRepeat(11, 40, 0, EV2ON);  
  Alarm.alarmRepeat(11, 40, TR, EV2OFF);  
  
  Alarm.alarmRepeat(11, 42, 0, EV2ON);  
  Alarm.alarmRepeat(11, 42, TR, EV2OFF);
  }

//Horas de la Válvula 3    
{
  Alarm.alarmRepeat(11, 38, 0, EV3ON);  
  Alarm.alarmRepeat(11, 38, TR, EV3OFF);  
  
  Alarm.alarmRepeat(11, 41, 0, EV3ON);  
  Alarm.alarmRepeat(11, 41, TR, EV3OFF);  
  
  Alarm.alarmRepeat(11, 42, 0, EV3ON);  
  Alarm.alarmRepeat(11, 42, TR, EV1OFF);
}
}
 
void loop() {
  // Mostrar el reloj en el monitor serial
  digitalClockDisplay();
  LCDClockDisplay();
  
 
  // Esperar 1 segundo y procesar las Alarmas mientras tanto...
  // El metodo Alarm.delay() procesa en el fondo las alarmas y llamara a las funciones indicadas
  Alarm.delay(1000);


}
 
//Encendido electroválvula 1
void EV1ON()
{
  digitalWrite(8, LOW);
  Serial.println("EV Pin8 ON");
  digitalWrite(bomba, LOW);
}
 //Apagado electroválvula 1
void EV1OFF()
{
  digitalWrite(bomba, HIGH);
  Serial.println("EV Pin8 OFF");
  digitalWrite(8, HIGH);
  }
 
void EV2ON()
{
digitalWrite(7, LOW);
Serial.println("EV Pin9 ON");
  digitalWrite(bomba, LOW);
}
 
void EV2OFF()
{
  digitalWrite(bomba, HIGH);
  Serial.println("EV Pin9 OFF");
  digitalWrite(7, HIGH);
}

 void EV3ON()
{
  digitalWrite(6, LOW);
 Serial.println("EV Pin10 ON");
    digitalWrite(bomba, LOW);
}
 void EV3OFF()
{
  digitalWrite(bomba, HIGH);
  Serial.println("EV Pin10 OFF");
  digitalWrite(6, HIGH);
  }
 
//   Funciones para la impresión de la hora
void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.println();
}
 
void printDigits(int digits) {
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

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


void LCDClockDisplay(){
  // digital clock display of the time
  lcd.setCursor(0, 1);
  lcd.print(hour());
  printDigitsLCD(minute());
  printDigitsLCD(second());
  
  }

TimeAlarms es una librería que debes revisar como esa preconfigurada. Mira el TimeAlarms.h y revisa cuantas alarmas estas permitidas por defecto. Es posible que no te este leyendo las dos que justamente no funcionan.

2 Likes

En principio las alarmas las tienes que cargar en orden cronológico, o sea según el horario de menor a mayor (lo acabo de probar y funciona) no como las cargas ahora según nro. de válvula.
Revisa luego lo que te dice @Surbyte.

Saludos

1 Like

Pero ademas repites varias programaciones para los mismos llamados y eso no funciona, los callbacks terminan quedando para los ultimos seleccionados.
En la valvula 1 pones

    Alarm.alarmRepeat(11, 36, 0, EV1ON);  
    Alarm.alarmRepeat(11, 36, TR, EV1OFF);  
    
    Alarm.alarmRepeat(11, 39, 0, EV1ON);  
    Alarm.alarmRepeat(11, 39, TR, EV1OFF);  
    
    Alarm.alarmRepeat(11, 43, 0, EV1ON);  
    Alarm.alarmRepeat(11, 43, TR, EV1OFF);

Y entonces que hace? se queda con accionar en 11:43:00 y apagar en 11:43:TR
lo mismo las demas
Si quieres que eso cambie entonces cuando se termina de ejecturar la que esta a 11:36:00 creas la llamada a 11:39:00 y lo mismo cuando se ejecute este llamado.
Asi repite para los demas.
Para hacerlo no puedes creer una nueva instancia. Debes usar el constructor disponible en la librería.
Ahora no recuerdo como se hacia.
Te dejo link

1 Like

Bueno, tuve que desempolvar algunos sketch pero al final esto funciona.

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#include <TimeAlarms.h>
//#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h> 
#define bomba 5
#define dtNBR_ALARMS  0   // max is 255
#define INCREMENTO    2
// introduce segundos de riego 1-59
int TR = 30; //TIEMPO DE RETRASO
char buffer[20];
int secondAnt;

AlarmID_t EV1ONAlarm;
AlarmID_t EV1OFFAlarm;
AlarmID_t EV2ONAlarm;
AlarmID_t EV2OFFAlarm;
AlarmID_t EV3ONAlarm;
AlarmID_t EV3OFFAlarm;


int startTime[3][3] = {{11,36,0},
                       {11,37,0},
                       {11,38,0}};

int stopTime [3][3] = {{11,36,TR},
                       {11,37,TR},
                       {11,38,TR}};

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Hora:");
  Serial.begin(9600);
 

  //Pines de salida a los relevadores
  pinMode(bomba,OUTPUT);
  digitalWrite(bomba, HIGH);
  
  pinMode(8, OUTPUT);
  digitalWrite(8, HIGH);
  
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH );
  
  pinMode(6, OUTPUT);
  digitalWrite(6, HIGH);

  // Set time fija el horario inicial del reloj (HH:MM:SS:DD:MM:YY)  sólo una vez
  setTime(11,35,45,20,7,23);
  RTC.set(now());
  
  setSyncProvider(RTC.get);
  if (timeStatus() != timeSet)
    Serial.println("Fallo de RTC");
  else
   Serial.println("Sincronizado con RTC");
  // Crear las alarmas (HH:MM:SS:FUNCIÓN)
  
  //Horas de Válvula 1
    EV1ONAlarm  = Alarm.alarmRepeat(startTime[0][0], startTime[0][1], startTime[0][2], EV1ON);  
    EV1OFFAlarm = Alarm.alarmRepeat( stopTime[0][0],  stopTime[0][1],  stopTime[0][2], EV1OFF);  
    
  //Horas de la Válvula 2
  
    EV2ONAlarm  = Alarm.alarmRepeat(startTime[1][0], startTime[1][1], startTime[1][2], EV2ON);  
    EV2OFFAlarm = Alarm.alarmRepeat( stopTime[1][0],  stopTime[1][1],  stopTime[1][2], EV2OFF);  
  
  //Horas de la Válvula 3    
    EV3ONAlarm  = Alarm.alarmRepeat(startTime[2][0], startTime[2][1], startTime[2][2], EV3ON);  
    EV3OFFAlarm = Alarm.alarmRepeat( stopTime[2][0],  stopTime[2][1],  stopTime[2][2], EV3OFF);  
    secondAnt = second();
}
 
void loop() {
  // Mostrar el reloj en el monitor serial
  int h, m, s;

  if (second() != secondAnt) {
    h = hour();
    m = minute();
    s = second();
    digitalClockDisplay(h, m, s);
    LCDClockDisplay(h, m, s);
    secondAnt = s;
  }
    
  // Esperar 1 segundo y procesar las Alarmas mientras tanto...
  // El metodo Alarm.delay() procesa en el fondo las alarmas y llamara a las funciones indicadas
  Alarm.delay(10);
}
 
//Encendido electroválvula 1
void EV1ON() {
  digitalWrite(8, LOW);
  Serial.print("EV1 Pin8 ON  ");
  digitalWrite(bomba, LOW);
  startTime[0][1] += INCREMENTO; // le sumo 3 min
  if (startTime[0][1] > 59) { // si me paso de 60 min sumo 1 hora
    startTime[0][1] %= 60;    // ajusto a % 60
    startTime[0][2] += 1;     // incremento la hora
    startTime[0][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }
  Serial.print("Cambio startTime EVION a hora : ");
  
  digitalClockDisplay(startTime[0][0], startTime[0][1], startTime[0][2]);
  Alarm.free(EV1ONAlarm);
  EV1ONAlarm = dtINVALID_ALARM_ID;
  EV1ONAlarm = Alarm.alarmRepeat(startTime[0][0], startTime[0][1], startTime[0][2], EV1ON);  
}
 //Apagado electroválvula 1
void EV1OFF() {
  digitalWrite(bomba, HIGH);
  Serial.print("EV1 Pin8 OFF ");
  digitalWrite(8, HIGH);
  stopTime[0][1] += INCREMENTO; // le sumo 3 min
  if (stopTime[0][1] > 59) { // si me paso de 60 min sumo 1 hora
    stopTime[0][1] %= 60;    // ajusto a % 60
    stopTime[0][2] += 1;     // incremento la hora
    stopTime[0][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }

  Serial.print("Cambio stopTime EVIOFF a hora : ");

  digitalClockDisplay(stopTime[0][0], stopTime[0][1], stopTime[0][2]);
  Alarm.free(EV1OFFAlarm);
  EV1OFFAlarm = dtINVALID_ALARM_ID;
  EV1OFFAlarm = Alarm.alarmRepeat(stopTime[0][0], stopTime[0][1], stopTime[0][2], EV1OFF);  
}
 
void EV2ON() {
  digitalWrite(7, LOW);
  Serial.print("EV2 Pin9 ON  ");
  digitalWrite(bomba, LOW);
  startTime[1][1] += INCREMENTO; // le sumo 3 min
  if (startTime[1][1] > 59) { // si me paso de 60 min sumo 1 hora
    startTime[1][1] %= 60;    // ajusto a % 60
    startTime[1][2] += 1;     // incremento la hora
    startTime[1][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }
  Serial.print("Cambio startTime EV2ON a hora : ");
  
  digitalClockDisplay(startTime[1][0], startTime[1][1], startTime[1][2]);
  Alarm.free(EV2ONAlarm);
  EV2ONAlarm = dtINVALID_ALARM_ID;
  EV2ONAlarm = Alarm.alarmRepeat(startTime[1][0], startTime[1][1], startTime[1][2], EV2ON);  
}
 
void EV2OFF() {
  digitalWrite(bomba, HIGH);
  Serial.print("EV2 Pin9 OFF ");
  digitalWrite(7, HIGH);
  stopTime[1][1] += INCREMENTO; // le sumo 3 min
  if (stopTime[1][1] > 59) { // si me paso de 60 min sumo 1 hora
    stopTime[1][1] %= 60;    // ajusto a % 60
    stopTime[1][2] += 1;     // incremento la hora
    stopTime[1][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }
  Serial.print("Cambio stopTime EV2OFF a hora : ");
  
  digitalClockDisplay(stopTime[1][0], stopTime[1][1], stopTime[1][2]);
  Alarm.free(EV2OFFAlarm);
  EV2OFFAlarm = dtINVALID_ALARM_ID;
  EV2OFFAlarm = Alarm.alarmRepeat(stopTime[1][0], stopTime[1][1], stopTime[1][2], EV2OFF);  
}

void EV3ON() {
  digitalWrite(6, LOW);
  Serial.print("EV3 Pin10 ON  ");
  digitalWrite(bomba, LOW);
  startTime[2][1] += INCREMENTO; // le sumo 3 min
  if (startTime[2][1] > 59) { // si me paso de 60 min sumo 1 hora
    startTime[2][1] %= 60;    // ajusto a % 60
    startTime[2][2] += 1;     // incremento la hora
    startTime[2][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }
  Serial.print("Cambio startTime EV3ON a hora : ");
  
  digitalClockDisplay(startTime[2][0], startTime[2][1], startTime[2][2]);
  Alarm.free(EV3ONAlarm);
  EV3ONAlarm = dtINVALID_ALARM_ID;
  EV3ONAlarm = Alarm.alarmRepeat(startTime[2][0], startTime[2][1], startTime[2][2], EV3ON);  

}
 
void EV3OFF() {
  digitalWrite(bomba, HIGH);
  Serial.print("EV3 Pin10 OFF ");
  digitalWrite(6, HIGH);
  stopTime[2][1] += INCREMENTO; // le sumo 3 min
  if (stopTime[2][1] > 59) { // si me paso de 60 min sumo 1 hora
    stopTime[2][1] %= 60;    // ajusto a % 60
    stopTime[2][2] += 1;     // incremento la hora
    stopTime[2][2] %= 24;    // si paso de 24, lo seinto hasta aca la comprobación
  }

  Serial.print("Cambio stopTime EV2OFF a hora : ");
  
  digitalClockDisplay(stopTime[2][0], stopTime[2][1], stopTime[2][2]);
  Alarm.free(EV3OFFAlarm);
  EV3OFFAlarm = dtINVALID_ALARM_ID;
  EV3OFFAlarm = Alarm.alarmRepeat(stopTime[2][0], stopTime[2][1], stopTime[2][2], EV3OFF);  
}
 
// Funciones para la impresión de la hora
void digitalClockDisplay(int h, int m, int s) {
  sprintf(buffer, "%02d:%02d:%02d", h, m, s);
  Serial.println(buffer);
}

void LCDClockDisplay(int h, int m, int s) {
  // digital clock display of the time
  lcd.setCursor(0, 1);
  sprintf(buffer, "%02d:%02d:%02d", h, m, s);
  lcd.print(buffer);
}
1 Like

Por defecto la librería viene configurada para un máximo de 6 alarmas en los micros AVR para ahorrar memoria.
Se puede editar el archivo TimeAlarms.h y ampliar esa cantidad.
Se debe cambiar

#if defined(__AVR__)
#define dtNBR_ALARMS 6   // max is 255   *** Esta es la línea a cambiar

a por ej.,

#if defined(__AVR__)
#define dtNBR_ALARMS 20   // max is 255

Como dice la documentación, hay que tener en cuenta que cada entrada ocupa 11 bytes de memoria, en este caso las 20 entradas ocupan 220 bytes.

El archivo TimeAlarms.h a modificar es el que se encuentra en la carpeta de instalación de la librería.

1 Like

Muchas gracias por la ayuda

Igualmente, muchas gracias, ya cambie lo de la libreria y funcionó perfectamente.

Excelente!
Saludos

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.