#include <Relay.h> // Incluir biblioteca de control de relés
// https://github.com/rafaelnsantos/Relay/tree/master
const int relay1Pin = 8; // Reemplace con el número de pin real del relé
const int relay2Pin = 9; // Reemplace con el número de pin real del relé
// Crear objetos de relé
Relay relay1(relay1Pin, true);
Relay relay2(relay2Pin, true);
volatile boolean first;
volatile boolean triggered;
volatile unsigned long overflowCount;
volatile unsigned long startTime;
volatile unsigned long finishTime;
// temporizador desbordamientos (cada 65536 conteos)
ISR (TIMER1_OVF_vect)
{
overflowCount++;
}
ISR (TIMER1_CAPT_vect)
{
// obtener valor del contador antes de que cambie más
unsigned int timer1CounterValue;
timer1CounterValue = ICR1; // ver hoja de datos, página 117 (acceso a registros de 16 bits)
unsigned long overflowCopy = overflowCount;
// si se perdió un desbordamiento
if ((TIFR1 & bit (TOV1)) && timer1CounterValue < 0x7FFF)
overflowCopy++;
// esperar hasta que notemos el último
if (triggered)
return;
if (first)
{
startTime = (overflowCopy << 16) + timer1CounterValue;
first = false;
return;
}
finishTime = (overflowCopy << 16) + timer1CounterValue;
triggered = true;
TIMSK1 = 0; // no más interrupciones por ahora
}
void prepareForInterrupts ()
{
noInterrupts (); // código protegido
first = true;
triggered = false; // rearmar para la próxima vez
// restablecer temporizador 1
TCCR1A = 0;
TCCR1B = 0;
TIFR1 = bit (ICF1) | bit (TOV1); // borrar banderas para que no obtengamos una interrupción falsa
TCNT1 = 0; // Contador a cero
overflowCount = 0; // Por lo tanto, todavía no hay desbordamientos
// Temporizador 1 - cuenta los pulsos del reloj
TIMSK1 = bit (TOIE1) | bit (ICIE1); // interrumpir en el desbordamiento del temporizador 1 y la captura de entrada
// iniciar el temporizador 1, sin prescaler
TCCR1B = bit (CS10) | bit (ICES1); // más Selección de borde de captura de entrada (ascendente en D8)
interrupts ();
}
void setup ()
{
Serial.begin(115200);
Serial.println("Control de ventilador de dos velocidades");
// configurar para interrupciones
prepareForInterrupts ();
}
void loop ()
{
// esperar hasta que tengamos una lectura
if (!triggered)
return;
// el período es el tiempo transcurrido
unsigned long elapsedTime = finishTime - startTime;
// la frecuencia es inversa del período, ajustada por el período del reloj
float freq = F_CPU / float (elapsedTime); // cada tic es de 62.5 ns a 16 MHz
Serial.print ("Tomó: ");
Serial.print (elapsedTime);
Serial.print (" conteos. ");
Serial.print ("Frecuencia: ");
Serial.print (freq);
Serial.println (" Hz. ");
// para que podamos leerlo
delay (500);
// controlar los relés en función de la frecuencia
if (freq >= 10000 && freq <= 20000) {
relay1.turnOn(); // Activar el relé 1 para la velocidad 1 del ventilador
relay2.turnOff(); // Desactivar el relé 2
} else if (freq >= 21000 && freq <= 30000) {
relay1.turnOff(); // Desactivar el relé 1
relay2.turnOn(); // Activar el relé 2 para la velocidad 2 del ventilador
} else {
relay1.turnOff(); // Desactivar ambos relés si la frecuencia está fuera de rango
relay2.turnOff();
}
prepareForInterrupts ();
}