Hatkat

controlador de lampara acuario

Aug 29th, 2025 (edited)
35
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.65 KB | None | 0 0
  1. #include <ThreeWire.h>
  2. #include <RtcDS1302.h>
  3.  
  4. // Configuración de pines para DS1302 (DAT, CLK, RST)
  5. ThreeWire myWire(7, 6, 5); // DAT=pin7, CLK=pin6, RST=pin5
  6. RtcDS1302<ThreeWire> Rtc(myWire);
  7.  
  8. // Configuración del relé y botón
  9. const int RELE_PIN = 4;
  10. const int BOTON_PIN = 2;
  11.  
  12. // Horarios de control (formato 24 horas)
  13. const int HORA_ENCENDER = 11; // HORA DE ENCENDIDO DE LA LAMPARA
  14. const int HORA_APAGAR = 18; // HORA DE APAGADO DE LA LAMPARA
  15.  
  16. // Estados del sistema
  17. bool estadoRele = false; // Estado actual del relé (true=encendido, false=apagado)
  18.  
  19. // Variables para control del botón - MEJORADAS
  20. volatile bool botonPresionado = false;
  21. volatile unsigned long ultimoTiempoBoton = 0;
  22. const unsigned long tiempoDebounce = 750; // Aumentado de 200ms a 500ms
  23. unsigned long tiempoUltimaAccion = 0; // Nueva variable para evitar acciones muy seguidas
  24. const unsigned long tiempoMinimoEntreAcciones = 2000; // 2 segundos mínimo entre acciones
  25.  
  26. // Variables para control de tiempo
  27. int ultimaHoraVerificada = -1;
  28.  
  29. // Variables para estado del botón - NUEVAS
  30. bool estadoBotonAnterior = HIGH;
  31. bool botonEstable = HIGH;
  32. unsigned long tiempoUltimoCambioBoton = 0;
  33.  
  34. void setup() {
  35. Serial.begin(9600);
  36. Serial.println("=== CONTROL DE RELE - BOTON + HORARIOS (CORREGIDO) ===");
  37.  
  38. // Configurar pin del relé (lógica normal: HIGH=encendido, LOW=apagado)
  39. pinMode(RELE_PIN, OUTPUT);
  40. digitalWrite(RELE_PIN, LOW); // Empezar apagado
  41. estadoRele = false;
  42.  
  43. // Configurar pin del botón con pull-up interno
  44. pinMode(BOTON_PIN, INPUT_PULLUP);
  45. // CAMBIO: No usar interrupción, usar lectura directa para mejor control
  46. // attachInterrupt(digitalPinToInterrupt(BOTON_PIN), manejarInterrupcionBoton, FALLING);
  47.  
  48. // Inicializar RTC
  49. Rtc.Begin();
  50. delay(100);
  51.  
  52. if (!Rtc.GetIsRunning()) {
  53. Serial.println("Iniciando RTC...");
  54. Rtc.SetIsRunning(true);
  55. }
  56.  
  57. if (Rtc.GetIsWriteProtected()) {
  58. Serial.println("Deshabilitando protección de escritura...");
  59. Rtc.SetIsWriteProtected(false);
  60. }
  61.  
  62. // CONFIGURACIÓN DE HORA ACTUAL - SOLO LA PRIMERA VEZ
  63. // ⚠️ DESCOMENTA Y AJUSTA LA HORA, LUEGO COMENTA OTRA VEZ ⚠️
  64. //Serial.println("Configurando hora actual...");
  65. //RtcDateTime newTime = RtcDateTime(2025, 9, 21, 18, 52, 0); // Año, Mes, Día, Hora, Minuto, Segundo
  66. //Rtc.SetDateTime(newTime);
  67. //Serial.println("Hora configurada correctamente");
  68.  
  69. Serial.println("Sistema iniciado");
  70. Serial.println("LOGICA: HIGH=ENCENDIDO, LOW=APAGADO");
  71. Serial.println("BOTON: Cambia estado con debounce mejorado");
  72. Serial.println("HORARIOS: 11:00 AM = ON, 6:00 PM = OFF");
  73. Serial.println("PROTECCION: 2 segundos mínimo entre acciones");
  74. Serial.println("========================");
  75.  
  76. // Inicializar tiempo de última acción
  77. tiempoUltimaAccion = millis();
  78. }
  79.  
  80. void loop() {
  81. // Leer hora actual del RTC
  82. RtcDateTime now = Rtc.GetDateTime();
  83.  
  84. if (!now.IsValid()) {
  85. Serial.println("ERROR: No se puede leer el RTC");
  86. digitalWrite(RELE_PIN, LOW); // Apagar por seguridad
  87. estadoRele = false;
  88. delay(5000);
  89. return;
  90. }
  91.  
  92. // PRIMERO: Verificar horarios automáticos
  93. verificarHorarioAutomatico(now);
  94.  
  95. // SEGUNDO: Procesar botón con nuevo método mejorado
  96. procesarBotonMejorado();
  97.  
  98. // Mostrar estado cada minuto
  99. mostrarEstado(now);
  100.  
  101. delay(50); // Reducido para mejor respuesta del botón
  102. }
  103.  
  104. void procesarBotonMejorado() {
  105. bool estadoBotonActual = digitalRead(BOTON_PIN);
  106. unsigned long tiempoActual = millis();
  107.  
  108. // Detectar cambio de estado del botón
  109. if (estadoBotonActual != estadoBotonAnterior) {
  110. tiempoUltimoCambioBoton = tiempoActual;
  111. estadoBotonAnterior = estadoBotonActual;
  112. }
  113.  
  114. // Verificar si el botón está estable después del debounce
  115. if ((tiempoActual - tiempoUltimoCambioBoton) > tiempoDebounce) {
  116. // Si el estado estable cambió (de HIGH a LOW = pulsación)
  117. if (botonEstable == HIGH && estadoBotonActual == LOW) {
  118. // Verificar que haya pasado suficiente tiempo desde la última acción
  119. if ((tiempoActual - tiempoUltimaAccion) > tiempoMinimoEntreAcciones) {
  120. // Procesar la pulsación del botón
  121. estadoRele = !estadoRele;
  122. actualizarRele();
  123. tiempoUltimaAccion = tiempoActual;
  124.  
  125. Serial.print("BOTON PRESIONADO - Relé ahora: ");
  126. Serial.println(estadoRele ? "ENCENDIDO" : "APAGADO");
  127. } else {
  128. Serial.println("BOTON IGNORADO - Muy pronto después de última acción");
  129. }
  130. }
  131. botonEstable = estadoBotonActual;
  132. }
  133. }
  134.  
  135. void verificarHorarioAutomatico(RtcDateTime now) {
  136. int horaActual = now.Hour();
  137. unsigned long tiempoActual = millis();
  138.  
  139. // Solo verificar cuando cambia la hora
  140. if (horaActual != ultimaHoraVerificada) {
  141. ultimaHoraVerificada = horaActual;
  142.  
  143. // Verificar que haya pasado suficiente tiempo desde la última acción
  144. if ((tiempoActual - tiempoUltimaAccion) > tiempoMinimoEntreAcciones) {
  145. // A las 12:00 PM - SIEMPRE encender
  146. if (horaActual == HORA_ENCENDER) {
  147. estadoRele = true;
  148. actualizarRele();
  149. tiempoUltimaAccion = tiempoActual;
  150. Serial.println("*** HORARIO 12:00 PM: FORZADO A ENCENDIDO ***");
  151. }
  152. // A las 6:00 PM - SIEMPRE apagar
  153. else if (horaActual == HORA_APAGAR) {
  154. estadoRele = false;
  155. actualizarRele();
  156. tiempoUltimaAccion = tiempoActual;
  157. Serial.println("*** HORARIO 6:00 PM: FORZADO A APAGADO ***");
  158. }
  159. }
  160. }
  161. }
  162.  
  163. void actualizarRele() {
  164. // Actualizar físicamente el relé con un pequeño delay para estabilidad
  165. digitalWrite(RELE_PIN, estadoRele ? HIGH : LOW);
  166. delay(10); // Pequeño delay para estabilizar la señal
  167.  
  168. // Verificación adicional
  169. bool estadoFisico = digitalRead(RELE_PIN);
  170. if (estadoFisico != estadoRele) {
  171. Serial.println("WARNING: Estado físico no coincide, reintentando...");
  172. delay(50);
  173. digitalWrite(RELE_PIN, estadoRele ? HIGH : LOW);
  174. }
  175. }
  176.  
  177. void mostrarEstado(RtcDateTime now) {
  178. static int ultimoMinutoMostrado = -1;
  179.  
  180. if (now.Minute() != ultimoMinutoMostrado) {
  181. ultimoMinutoMostrado = now.Minute();
  182.  
  183. Serial.print("Hora: ");
  184. if (now.Hour() < 10) Serial.print("0");
  185. Serial.print(now.Hour());
  186. Serial.print(":");
  187. if (now.Minute() < 10) Serial.print("0");
  188. Serial.print(now.Minute());
  189.  
  190. Serial.print(" | Relé: ");
  191. Serial.print(estadoRele ? "ON" : "OFF");
  192.  
  193. Serial.print(" | Pin: ");
  194. Serial.print(digitalRead(RELE_PIN) ? "HIGH" : "LOW");
  195.  
  196. Serial.print(" | Botón: ");
  197. Serial.println(digitalRead(BOTON_PIN) ? "HIGH" : "LOW");
  198. }
  199. }
Advertisement
Add Comment
Please, Sign In to add comment