Problemas con rutinas en Arduino

Buenas tardes gente,
Estoy realizando un proyecto en el cual debo alternar un extractor de ambiente y un ventilador, ambos dispositivos los manejo con relé.
El extractor de ambiente utiliza 220v de la red casa y el ventilador lo recicle de una base para ventilar laptops y es de 5v, el cual alimento con la tensión que me brinda el mismo Arduino.
Cuando trabaja la función del extractor sola, respeta los tiempos de encendido y apagado, el problema se me presenta cuando activo la función del ventilador, empiezan a conmutar entre si en lapsos de un segundo (se prende uno y se apaga el otro).
Les adjunto las dos funciones para que alguien con mayor experiencia que yo pueda ayudarme, desde ya les agradezco su colaboración.

C:
//------------------------------------------------
// funcion horario extractor
//------------------------------------------------
void horarioExt() {
  byte hora = 0;
  while(hora < 24) {
    if(horario.hour() == hora && ((horario.minute() >= 0) && (horario.minute() <= 39))) {
      digitalWrite(PIN_RELE1, HIGH);  // enciende
      Serial.println("Extractor Encendido");
      break;
    }
    else if(horario.hour() == hora && ((horario.minute() >= 40) && (horario.minute() <= 59))) {
      digitalWrite(PIN_RELE1, LOW);   // apaga
      Serial.println("Extractor Apagado");
      break;
    }
    hora++;
  }
}
//------------------------------------------------
// funcion horario ventilador
//------------------------------------------------
void horarioVen() {
  byte hora = 0;
  while(hora < 24) {
    if(horario.hour() == hora && ((horario.minute() >= 40) && (horario.minute() <= 59))) {
      digitalWrite(PIN_RELE3, LOW);  // enciende
      Serial.println("Ventilador Encendido");
      break;
    }
    else if(horario.hour() == hora && ((horario.minute() >= 0) && (horario.minute() <= 39))) {
      digitalWrite(PIN_RELE3, HIGH);   // apaga
      Serial.println("Ventilador Apagado");
      break;
    }
    hora++;
  }
}
 
No le veo sentido a hacer el bucle de 24 a las horas... Quiero decir que el while recorre todo el día (0..23) hasta que horario.hour() coincide y entonces ajusta el valor del pin, y termina. ¿Para qué hace ese bucle si en las condiciones no importa qué hora sea? Es decir, que da igual que sean las 11 o las 17 horas, el comportamiento solo depende del valor de los minutos.
 
Esta bien lo que me dices y replanteando el código quedaría así, pero solo le estoy quitando el identificador de horas, espero resuelva el problema que planteo, lo pruebo y te aviso luego.

C:
//------------------------------------------------
// funcion horario extractor
//------------------------------------------------
void horarioExt() {
    if(horario.minute() >= 0 && horario.minute() <= 39) {
        digitalWrite(PIN_RELE1, HIGH);  // enciende
        Serial.println("Extractor Encendido");
    }
    else if(horario.minute() >= 40 && horario.minute() <= 59) {
        digitalWrite(PIN_RELE1, LOW);   // apaga
        Serial.println("Extractor Apagado");
    }
}
//------------------------------------------------
// funcion horario ventilador
//------------------------------------------------
void horarioVen() {
    if(horario.minute() >= 40 && horario.minute() <= 59) {
      digitalWrite(PIN_RELE3, LOW);  // enciende
      Serial.println("Ventilador Encendido");
    }
    else if(horario.minute() >= 0 && horario.minute() <= 39) {
      digitalWrite(PIN_RELE3, HIGH);   // apaga
      Serial.println("Ventilador Apagado");
    }
}
 
Última edición:
Bueno quizás estoy diciendo una burrada pero...
No sera que se esta reiniciando el arduino?, porque dices que activas el ventilador de 5v con la misma tensión que el arduino te da.
Sube alguna foto de las conexiones
 
El código esta más simplificado, pero sigo teniendo el problema, es decir:
Cuando conecto Arduino a la Rapberry y cargo el código (extractor sin conectar a la red), el ventilador funciona bien, pero cuando conecto Arduino a la red con respectivo transfo y el extractor a la red, se prende el ventilador y se apaga el extractor, luego se prende el extractor y se apaga el ventilador y esta en ese plan de saltos cada segundo, no me respeta el código.

IMG_20200106_205003515.jpg
Arduino Uno alimenta a la protoboard que contiene un reloj DS-3231 y los rieles de tensión con 5v.
Los pines 2 y 3 conectados a los rele1 y rele2 (derecha) que comandan al extractor y una luz respectivamente (ambos de 220v y con llave térmica).
El pin 4 conectado al rele3 (izquierda) que comanda al ventilador (5v), GND desconectado por los problemas que presento, cabe mencionar que solo presento los problemas cuando esta conectado el ventilador, sino todo marcha de maravilla. Ahora si coloco un motor de 12v en vez del ventilador funciona bien, solo es problema el motor de 5v. (¿por qué?).
El pin 5 conectado al rele4 (izquierda) que comanda a una mini bomba de agua (12v, conectado al pin Vin), solo conectado el común.
En teoria y creo yo está todo bien conectado, pero de igual forma te adjunto el código completo


C:
// librerias
#include <Wire.h>
#include <RTClib.h>

// definición de pines
#define PIN_RELE1 2      // pin extractor
#define PIN_RELE2 3      // pin luz
#define PIN_RELE3 4      // pin ventilador
#define PIN_RELE4 5      // pin bomba de agua

// definición de reloj
RTC_DS3231 reloj;
DateTime horario;

//------------------------------------------------
// inicialización del programa
//------------------------------------------------
void setup() {
  Serial.begin(9600);
  // inicio reloj
  if (!reloj.begin()) {
    Serial.println("Módulo RTC no encontrado...!");
    Serial.println("----------------------------");
    Serial.println(" ");
    while(1);
  } else {
    Serial.println("Módulo RTC iniciado...!");
    //reloj.adjust(DateTime(__DATE__, __TIME__));   // actualiza a predeterminado (Fecha - Hora del sistema)
    Serial.println("----------------------------");
    Serial.println(" ");
  }
  // configuración de pines
  pinMode(PIN_RELE1, OUTPUT);
  pinMode(PIN_RELE2, OUTPUT);
  pinMode(PIN_RELE3, OUTPUT);
  pinMode(PIN_RELE4, OUTPUT);
}

//------------------------------------------------
// programa principal
//------------------------------------------------
void loop() {
  horario = reloj.now();  // actualiza fecha y hora
  horarioExt();           // llama función horario extractor
  horarioLuz();           // llama función horario luz
  horarioVen();           // llama función horario ventilador
  horarioRie();           // llama función horario riego
  Serial.println("");
  // retardo 200 milisegundos
  delay(200);
}

//------------------------------------------------
// funcion horario extractor
//------------------------------------------------
void horarioExt() {
  if(horario.minute() >= 0 && horario.minute() <= 39) {
    digitalWrite(PIN_RELE1, HIGH);  // enciende
    Serial.println("Extractor Encendido");
  }
  else if(horario.minute() >= 40 && horario.minute() <= 59) {
    digitalWrite(PIN_RELE1, LOW);   // apaga
    Serial.println("Extractor Apagado");
  }
}

//------------------------------------------------
// funcion horario luz
//------------------------------------------------
void horarioLuz() {
  if(horario.hour() >= 8 && horario.hour() <= 23) {
    digitalWrite(PIN_RELE2, HIGH);    // enciende
    Serial.println("Luz Encendida");
  }
  else if(horario.hour() >= 0 && horario.hour() <=7) {
    digitalWrite(PIN_RELE2, LOW);     // apaga
    Serial.println("Luz Apagada");
  }
}

//------------------------------------------------
// funcion horario ventilador
//------------------------------------------------
void horarioVen() {
  if(horario.minute() >= 40 && horario.minute() <= 59) {
    digitalWrite(PIN_RELE3, LOW);  // enciende
    Serial.println("Ventilador Encendido");
  }
  else if(horario.minute() >= 0 && horario.minute() <= 39) {
    digitalWrite(PIN_RELE3, HIGH);   // apaga
    Serial.println("Ventilador Apagado");
  }
}

//------------------------------------------------
// funcion horario riego
//------------------------------------------------
void horarioRie() {
  if(horario.hour() == 5 && horario.minute() == 30 && horario.second() == 0) {
    digitalWrite(PIN_RELE4, LOW);     // enciende
    Serial.println("Riego Encendido");
  }
  else if(horario.hour() == 5 && horario.minute() == 30 && horario.second() == 8) {
    digitalWrite(PIN_RELE4, HIGH);    // apaga
    Serial.println("Riego Apagado");
  }
  else {
    digitalWrite(PIN_RELE4, HIGH);    // apaga
    Serial.println("Riego Apagado");
  }
}
 
Última edición:
Cambia el delay() para que espere 1 segundo.

Las funciones tienen resolución de 1 segundo, así que quizás no tiene mucho sentido llamarlas cada 1/5 de segundo.
 
Última edición por un moderador:
Lo primero que he pensado yo también es que la fuente de 5V no da o que el ventilador mete ruido eléctrico.
Por descartar yo probaría el código con dos simples leds y si funciona ya sabes que hay problemas con la alimentación.
Me inclino por el tema de ruido, ya que he probado con motor de 12V reciclado (sabe Dios de que aparato) y no he tenido el problema que me da el motor de 5V, me imagino por que la tensión de 12V la saco de Vin (pero es mucho viento) y la de 5V del mismo circuito de Arduino.
Cambia el delay() para que espere 1 segundo.

Las funciones tienen resolución de 1 segundo, así que quizás no tiene mucho sentido llamarlas cada 1/5 de segundo.
Ok, voy a corregir eso, lo que buscaba en realidad con ese delay(200) era asegurarme de que la rutina de riego se ejecute si o si ya que debe ver los segundos.
Yo se que la velocidad del 328 es muy alta, en el orden de los micro segundos pero por ahí no descarto un retardo involuntario que evite el encendido o apagado de la bomba.
 
Última edición:
Bueno, quiero comentarles que ya solucione el problema optando por incluir un transfo de 6V, esos de celular (el tema es que no quería adicionar componentes, pero ni modo) y manejándolo con su respectivo relé.
Gracias gente por sus comentarios, me ayudaron a optimizar el código.
Saludos cordiales.
 
Atrás
Arriba