#include <ZMPT101B.h>
#include <ACS712.h>
// Definición de pines
#define RESET 15
#define LED 32
#define VOLTAJE 34
#define CORRIENTE 33
#define BUZZER_ALARM 19
#define SCR_CONTROL 25 // Pin para control del SCR
// Variables configurables
const float VAC_MIN = 105.5; // Voltaje mínimo permitido
const float VAC_MAX = 120.5; // Voltaje máximo permitido
const float AMP_MAX = 20.0; // Corriente máxima permitida
// Constantes para calibración
const float SENSITIVITY = 500.0f; // Sensibilidad del sensor de voltaje
const float CORRECTION_FACTOR = 20.0f; // Factor de corrección para corriente
const float VREFERENCE = 3.3; // Voltaje de referencia
const int ACTectionRange = 20; // Rango del sensor de corriente (20A)
// Constantes para filtrado
const int NUM_SAMPLES = 10; // Número de muestras para promedio
const float HYSTERESIS = 2.0; // Histeresis para evitar oscilaciones
// Instancias de sensores
ZMPT101B voltageSensor(VOLTAJE, 50.0); // 50Hz para México
ACS712 currentSensor(CORRIENTE, VREFERENCE, 1023, 20); // Pin, Vref, ADC resolution, mA per A
// Variables para el monitoreo
volatile float voltage = 0.0;
volatile float current = 0.0;
volatile float power = 0.0;
float lastVoltage = 0.0;
float lastCurrent = 0.0;
// Constantes para el control
const unsigned long MEDICION_INTERVAL = 1000; // Intervalo entre mediciones en ms
const unsigned long DEBOUNCE_TIME = 50; // Tiempo de debounce en ms
// Variables de control
unsigned long lastMeasurement = 0;
bool lastState = true; // Estado anterior del SCR
void setup() {
Serial.begin(115200);
// Configuración de pines
pinMode(LED, OUTPUT);
pinMode(BUZZER_ALARM, OUTPUT);
pinMode(SCR_CONTROL, OUTPUT);
pinMode(RESET, INPUT_PULLUP);
pinMode(VOLTAJE, INPUT);
// Estado inicial
digitalWrite(SCR_CONTROL, HIGH);
digitalWrite(LED, LOW);
digitalWrite(BUZZER_ALARM, LOW);
}
void controlCarga(bool activar) {
if (activar != lastState) {
digitalWrite(SCR_CONTROL, activar ? HIGH : LOW);
digitalWrite(LED, activar ? LOW : HIGH);
digitalWrite(BUZZER_ALARM, activar ? LOW : HIGH);
lastState = activar;
}
}
float readVoltage() {
float sum = 0;
for (int i = 0; i < NUM_SAMPLES; i++) {
// Para pruebas con potenciómetro
float rawValue = analogRead(VOLTAJE);
float voltage = (rawValue * VREFERENCE) / 1023.0;
sum += voltage;
delay(1);
}
return sum / NUM_SAMPLES;
}
float readACCurrentValue() {
float sum = 0;
for (int i = 0; i < NUM_SAMPLES; i++) {
float rawValue = analogRead(CORRIENTE);
float voltage = (rawValue * VREFERENCE) / 1023.0;
sum += voltage;
delay(1);
}
return (sum / NUM_SAMPLES) * ACTectionRange;
}
void loop() {
unsigned long currentMillis = millis();
// Realizar mediciones solo si ha pasado el intervalo
if (currentMillis - lastMeasurement >= MEDICION_INTERVAL) {
lastMeasurement = currentMillis;
// Medición de parámetros con filtrado
voltage = readVoltage();
current = readACCurrentValue();
power = voltage * current;
// Aplicar histeresis para evitar oscilaciones
bool voltageInRange = (voltage >= (VAC_MIN - HYSTERESIS) && voltage <= (VAC_MAX + HYSTERESIS));
bool currentInRange = (current <= (AMP_MAX + HYSTERESIS));
// Solo cambiar estado si los valores están fuera del rango con histeresis
if (voltage < (VAC_MIN - HYSTERESIS) || voltage > (VAC_MAX + HYSTERESIS) ||
current > (AMP_MAX + HYSTERESIS)) {
controlCarga(false);
} else if (voltage > (VAC_MIN + HYSTERESIS) && voltage < (VAC_MAX - HYSTERESIS) &&
current < (AMP_MAX - HYSTERESIS)) {
controlCarga(true);
}
// Mostrar datos en Serial Monitor
Serial.println("=== Medición AC ===");
Serial.printf("Voltaje: %.2f V\n", voltage);
Serial.printf("Corriente: %.2f A\n", current);
Serial.printf("Potencia: %.2f W\n", power);
Serial.printf("Estado Carga: %s\n", (lastState ? "ACTIVA" : "DESACTIVADA"));
Serial.println("===================");
}
// Manejo del botón de reset con debounce
if (digitalRead(RESET) == LOW) {
delay(DEBOUNCE_TIME);
if (digitalRead(RESET) == LOW) {
controlCarga(true); // Reactivar la carga
}
}
}