//variables para la generación de la señal
const int senyal_out = 18;
unsigned long tp1=0;// control señal frecuencia en el pin 18
float frec_inicio = 10;
volatile bool generando=0;
const int activa=25;
float periodo_senyal_ms;
volatile bool funcionar=0;
//variables del timer para medir
volatile int cuenta; //indica que ha saltado la alarma del timer
volatile int tiempo=1;// tiempo en segundos entre cálculos de la frecuencia
//variables de la frecuencia medida
volatile float flancos=0;// acumula el número de flancos de subidad de la señal a medir
const int senyal=23;
float frecserial;
// variables para modificar el tiempo entre medidas
const int sube=32;
const int baja=33;
const int rebote=100;//varibles para filtrar los rebotes
volatile unsigned long int last_interrupt=0;
volatile bool down=0;
volatile bool up=0;
//timers
hw_timer_t * timer = NULL; // estructura de datos del timer encargado del medidor
hw_timer_t * timer2 = NULL; // timer encargado de la generación de la función
//ISR para marcar el tiempo de medida
void IRAM_ATTR finTimer() {
cuenta=1;// permite la ejecución de informafrecuencia()
}
//ISR para generar la señal
void IRAM_ATTR finTimer2() {
digitalWrite(senyal_out,!digitalRead(senyal_out));// cambia el valor de salida cada medio periodo
}
//ISR para medir cada flanco ascendente de subida
void IRAM_ATTR ISR_frecuencia(){
flancos++;
}
//ISR del botón de subida que cambia el tiempo de toma de muestras
void IRAM_ATTR ISR_sube(){
if (millis() - last_interrupt > rebote) {
if(down==0){//Dento de este if colocamos lo queremos que haga, el resto es para eliminar rebotes
if(tiempo!=9){
tiempo++;
flancos=0;
timerWrite(timer,0);//ponemos los pulsos y el timer para ejecutar una medida nueva de 0 con el nuevo tiempo
timerAlarmWrite(timer, tiempo*(1/3.5e-6), true); // modificamos la alarma conforme al nuevo tiempo.Se ejecuta a cada tiempo segundos
}
last_interrupt = millis();
down=1;
}
else {
last_interrupt = millis();
down=0;
}
}
}
//ISR del botón de bajada que cambia el tiempo de toma de muestras
void IRAM_ATTR ISR_baja(){
if (millis() - last_interrupt > rebote) {
if(up==0){//Dento de este if colocamos lo queremos que haga, el resto es para eliminar rebotes
if(tiempo!=1){
tiempo--;
//flancos=0;
timerWrite(timer,0);
timerAlarmWrite(timer, tiempo*(1/3.5e-6), true);
}
last_interrupt = millis();
up=1;
}
else{
last_interrupt = millis();
up=0;
}
}
}
//ISR del botón que habilita o deshabilita la generación de la señal
void IRAM_ATTR ISR_habilita(){
if (millis() - last_interrupt > rebote) {
if(funcionar==0){//Dento de este if colocamos lo queremos que haga, el resto es para eliminar rebotes
generando=!generando;
if(generando==true){
timerAlarmEnable(timer2);
}
else {
timerAlarmDisable(timer2);
}
last_interrupt = millis();
funcionar=1;
}
else{
last_interrupt = millis();
funcionar=0;
}
}
}
void setup() {
Serial.begin(9600);
pinMode(senyal_out, OUTPUT);
attachInterrupt(digitalPinToInterrupt(senyal),ISR_frecuencia,RISING);
attachInterrupt(digitalPinToInterrupt(sube),ISR_sube,CHANGE);
attachInterrupt(digitalPinToInterrupt(baja),ISR_baja,CHANGE);
attachInterrupt(digitalPinToInterrupt(activa),ISR_habilita,CHANGE);
timer = timerBegin(0, 280, true);
timerAttachInterrupt(timer, &finTimer, true);
timerAlarmWrite(timer, tiempo*(1/3.5e-6), true);
timerAlarmEnable(timer);
timer2 = timerBegin(1, 80, true);
timerAttachInterrupt(timer2, &finTimer2, true);
timerAlarmWrite(timer2, 1000000 * (1/frec_inicio)/2, true);
}
void loop() {
if (Serial.available()){ //Solo se ejecuta si hay datos que leer
frec_inicio = Serial.parseFloat();
Serial.printf("Ahora la frecuencia es ");
Serial.println(frec_inicio);
Serial.read();//limpiamos el puerto serie de datos no requeridos, sobre todo del intro necesario para mandar la medida
timerWrite(timer2,0);
timerAlarmWrite(timer2, 1000000 * (1/frec_inicio)/2, true);// modificamos la alarma con respecto a la nueva frecuencia
}
if (cuenta==1) {
frecserial=(float)flancos/tiempo;// calculo de la frecuencia en Hz
flancos=0;
Serial.printf("Frecuencia %4.5f Hz, n-Flancos: %.0f, tiempo: %d s.\n", frecserial, flancos, tiempo);
//Serial.println(frecserial);
cuenta=0;
}
}