#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
/* en display
W = ESPERANDO LA PRIMER SEÑAL
D = DETECTADA ESPERANDO LA FALTA DE SEÑAL EN 4 HORAS
A = ACTIVADO LA GENERACION EMPIEZA EN 3 1/2 HORAS
G = GENERANDO LOS PULSOS EN HORA Y MEDIA
P = EN PAUSA UNAS 4 HORAS
*/
// Pines de conexión
const int entradaPin = 2; // señal de entrada
const int ledPin = 13; // EN AUTOMATICO l
const int salidaPin = 12; // SALIDA PULSOS
const int ledPin6 = 6; // PAUSA
const int ledPin4 = 4; // espera adicional
// Variables de tiempo
unsigned long tiempoInicio;
//unsigned long tiempoInicio1;
unsigned long tiempoInicioEsperaAdicional;
unsigned long tiempoInicioPausa;
int tiempoInicioFlancoAlto;
int tiempoFlancoAlto;
unsigned long tiempoInicioPulsos;
unsigned long tiempoInicioPulsos2;
// Variables configurables
//unsigned long tiempoTotalPulsos = 35 * 1000; // Tiempo total en milisegundos
//unsigned long tiempoTotalPulsos = 2 * 60 * 60 * 1000; // 2 horas en milisegundos
//unsigned long tiempoTotalPulsos = 30 * 60 * 1000; // 30 minutos en milisegundos
unsigned int cantidadPulsos = 5; // Cantidad de pulsos
const unsigned long duracionPulso = 200; // 200 milisegundos
// Intervalos de tiempo calculados
//unsigned long intervaloActivacion = (tiempoTotalPulsos / cantidadPulsos *200) / cantidadPulsos; // Intervalo calculado entre pulsos
//unsigned long intervaloActivacion = round((tiempoTotalPulsos / cantidadPulsos * 200) / cantidadPulsos); // Intervalo calculado entre pulsos
//unsigned long intervaloActivacion = 8500; // Intervalo calculado entre pulsos
unsigned long tiempoEspera = 1000; // 3 minutos entre pulsos
const unsigned long pausaDeteccion = 6000; // 4 hora de pausa
const unsigned long intervalo = 5000; // 4 horas sin señal
const unsigned long esperaAdicional = 3000; // 3 1/2 horas antes de empezar
const unsigned long duracionMinimaPulso = 200; // 200 milisegundos
// Variables de estado
bool seDetectd = false;
bool enPausaDeteccion = false;
bool enEsperaAdicional = false;
bool enGeneracionPulsos = false;
bool esperandoPrimeraSenal = true; // Variable para esperar la primera señal después de la pausa
int contadorActivaciones = 0;
// Contador de pulsos
long contadorPulsos = 0;
bool estadoAnterior = LOW;
bool detectandoFlanco = false;
// Variable para detectar la primera señal
bool primeraSenalDetectada = false;
// Dirección en la EEPROM para almacenar contadorPulsos
int addrContadorPulsos = 0;
// Inicialización de la pantalla LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Dirección I2C 0x27 para una pantalla LCD de 16x2
void setup() {
pinMode(entradaPin, INPUT);
pinMode(ledPin, OUTPUT);
pinMode(salidaPin, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin4, OUTPUT);
// Inicializa la pantalla LCD
lcd.init(); // Asegura la inicialización de la pantalla LCD
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("COUNTER: ");
lcd.setCursor(0, 1);
//EEPROM.put(addrContadorPulsos, 43330);
// Lee el valor de contadorPulsos desde la EEPROM al iniciar
EEPROM.get(addrContadorPulsos, contadorPulsos);
lcd.print(contadorPulsos); // Muestra el valor inicial de contadorPulsos
lcd.setCursor(15, 1);
lcd.print("W");
tiempoInicio = millis();
}
void loop() {
bool estadoActual = digitalRead(entradaPin);
// Detectar flanco ascendente
if (estadoActual == HIGH && estadoAnterior == LOW) {
tiempoInicioFlancoAlto = millis();
detectandoFlanco = true;
}
// Detectar flanco descendente
if (estadoActual == LOW && estadoAnterior == HIGH && detectandoFlanco) {
detectandoFlanco = false;
tiempoFlancoAlto = millis() - tiempoInicioFlancoAlto;
// Verifica si la duración del pulso alto fue mayor o igual a 200 ms
if (tiempoFlancoAlto >= duracionMinimaPulso) {
// Incrementa el contador de pulsos
contadorPulsos++;
// Actualiza la pantalla LCD con el contador de pulsos
lcd.setCursor(0, 1);
lcd.print(contadorPulsos);
guardarEnEEPROM();
// Reinicia el contador si se detecta una señal válida
seDetectd = true;
tiempoInicio = millis();
contadorActivaciones = 0; // Reinicia el contador de activaciones
//digitalWrite(ledPin4, LOW); // Apaga el LED en pin 4 cuando se detecta una señal
// Marca que se ha detectado la primera señal
primeraSenalDetectada = true;
lcd.setCursor(15, 1);
lcd.print("D");
}
}
estadoAnterior = estadoActual;
if (enPausaDeteccion) {
// Verifica si la pausa de detección ha terminado
if (millis() - tiempoInicioPausa >= pausaDeteccion) {
enPausaDeteccion = false;
digitalWrite(ledPin6, LOW); // Apaga el LED en pin 6
esperandoPrimeraSenal = true; // Marca que ahora se espera la primera señal antes de iniciar la detección de falta de señal
lcd.setCursor(15, 1);
lcd.print("W");
primeraSenalDetectada = false; // Reinicia la detección de la primera señal
}
} else if (enEsperaAdicional) {
// Verifica si la espera adicional ha terminado
if (millis() - tiempoInicioEsperaAdicional >= esperaAdicional) {
enEsperaAdicional = false;
digitalWrite(ledPin4, LOW); // Apaga el LED en pin 4
lcd.setCursor(15, 1);
lcd.print("G");
enGeneracionPulsos = true;
digitalWrite(ledPin, HIGH); // Enciende el LED principal al iniciar la generación de pulsos
tiempoInicioPulsos = millis();
contadorActivaciones = 0;
}
} else if (enGeneracionPulsos) {
// Genera los pulsos con delay para bloquear el loop
for (int i = 0; i < cantidadPulsos; i++) {
digitalWrite(salidaPin, HIGH); // Activa la salida
//delay(duracionPulso); // Mantiene la salida activa por la duración del pulso
delay(200); // duracion de cada pulso
digitalWrite(salidaPin, LOW); // Desactiva la salida
// delay(intervaloActivacion); // Espera el intervalo de activación
// Incrementa el contador de pulsos global
contadorPulsos++;
// Actualiza la pantalla LCD con el contador de pulsos
lcd.setCursor(0, 1);
lcd.print(contadorPulsos);
guardarEnEEPROM();
contadorActivaciones++;
tiempoInicioPulsos2 = millis();
while (millis() - tiempoInicioPulsos2 < tiempoEspera) {
// Aquí puedes agregar código adicional que se ejecutará durante el delay
// Pero evita hacer operaciones que tomen demasiado tiempo para no afectar la precisión del tiempo de espera.
}
}
// Al terminar la función, activa la pausa de detección inmediatamente
tiempoInicioPausa = millis(); // Reinicia el tiempo de pausa para la detección
enPausaDeteccion = true;
enGeneracionPulsos = false;
digitalWrite(ledPin6, HIGH); // Enciende el LED en pin 6 para indicar pausa de detección
lcd.setCursor(15, 1);
lcd.print("P");
digitalWrite(ledPin, LOW); // Apaga el LED principal al terminar la generación de pulsos
digitalWrite(salidaPin, LOW); // Asegura que la salida está desactivada
} else {
if (esperandoPrimeraSenal) {
// Espera la primera señal para empezar a detectar la ausencia de señal
if (seDetectd) {
esperandoPrimeraSenal = false;
seDetectd = false;
tiempoInicio = millis();
}
} else if (!seDetectd && primeraSenalDetectada) {
// Verifica si han pasado 5 segundos sin señal después de la primera señal detectada
if (millis() - tiempoInicio >= intervalo) {
digitalWrite(ledPin4, HIGH); // Enciende el LED en pin 4 para indicar espera adicional
lcd.setCursor(15, 1);
lcd.print("A");
tiempoInicioEsperaAdicional = millis(); // Inicia la espera adicional de 6 segundos
enEsperaAdicional = true;
primeraSenalDetectada = false; // Resetea la detección de la primera señal para el próximo ciclo
}
} else {
// Resetea el indicador de señal detectada
seDetectd = false;
}
}
}
void guardarEnEEPROM() {
// Guarda contadorPulsos en la dirección especificada de la EEPROM
EEPROM.put(addrContadorPulsos, contadorPulsos);
}