const int senyal_output = 23; // pin generacion señal simulación -> en el lab, conectar generador de funciones
const int senyal_entrada = 18; // GPIO pin interrupcion para la entrada de señal
const int sube = 32; // aumenta 1 seg el tiempo de medida, hasta 9 seg.
const int baja = 33; // disminuye 1 seg el tiempo de medida, hasta 1 seg.
const int activa = 35; //activa la señal
volatile int senyal = 0; //servirá para cambiar el nivel de la señal de salida
float frec_senyal = 5.8; // valor de la frecuencia en Hz
float periodo_senyal_ms = 1000 * (1/frec_senyal); // periodo en ms
#define t_pulsacion 200 //tiempo mínimo entre pulsaciones de botón
volatile unsigned long current_millis, last_interrupt=0; //para controlar y evitar rebotes
volatile int contador=0; //cuenta los flancos de bajada
int muestra;
float frec_medida;
volatile int t_medida=5; //tiempo de medida en segundos
volatile int cuenta=0; //lleva la cuenta de las interrupciones por el timer
hw_timer_t * timer = NULL; // estructura de datos del timer para la medición
hw_timer_t * timerS = NULL; // estructura de datos del timer para la señal
void IRAM_ATTR ISR_senyal(){ //Cuenta los flancos de la señal
contador++;
}
void IRAM_ATTR ISR_activa(){ //Al pulsar el boton azul se activan las alarmas de los timers
current_millis=millis();
if(current_millis - last_interrupt > t_pulsacion){ //Solo se ejecuta una vez (elimina los rebotes)
timerWrite(timer, 0); //Timers a 0
timerWrite(timerS, 0);
timerAlarmEnable(timer); //Alarmas de los timers activas
timerAlarmEnable(timerS);
last_interrupt=current_millis; //Se reestablece el tiempo de la última interrupción
}
}
void IRAM_ATTR ISR_sube(){ //Alpulsar el boton verde, aumenta el tiempo de medida de la frecuencia (aumenta 1 segundo)
current_millis=millis();
if(current_millis - last_interrupt > t_pulsacion){ //Solo se ejecuta una vez (elimina los rebotes)
cuenta=0; //Pone a 0 el número de interrupciones del timer
contador=0; //Pone a 0 los flancos
timerAlarmDisable(timer); //Alarmas de los timers deshabilitadas
timerAlarmDisable(timerS);
if(t_medida==9){ //Timepo máximo que puede alcanzar (9 segundos)
Serial.println("Tiempo máximo de 9 segundos alcanzado.");
}
else{
t_medida++; //Suma uno al tiempo de medida
Serial.printf("\nMidiendo cada %d segundos\n", t_medida); //Indica en el puerto serie cada cuantos segundos se esta midiendo
}
timerWrite(timer, 0); //Timer de medición a 0
timerAlarmEnable(timer); //Alarma del timer de medición activa
timerWrite(timerS, 0); //Timer de la señal a 0
timerAlarmEnable(timerS); //Alarma del timer de la señal activa
last_interrupt=current_millis; //Se reestablece el tiempo de la última interrupción
}
}
void IRAM_ATTR ISR_baja(){ //Al pulsar el boton rojo, disminuye el tiempo de medida de la frecuencia (disminuye 1 segundo)
current_millis=millis();
if(current_millis - last_interrupt > t_pulsacion){
cuenta=0; //Pone a 0 el número de interrupciones del timer
contador=0; //Pone a 0 los flancos
timerAlarmDisable(timer); //Alarmas de los timers deshabilitadas
timerAlarmDisable(timerS);
if(t_medida==1){ //Tiempo mínimo que puede alcanzar (1 segundo)
Serial.println("Tiempo mínimo de 1 segundo alcanzado.");
}
else{
t_medida--; //Disminuye uno el tiempo de medida
Serial.printf("\nMidiendo cada %d segundos\n", t_medida); //Indica en el puerto serie cada cuantos segundos se esta midiendo
}
timerWrite(timer, 0); //Timer de medición a 0
timerAlarmEnable(timer); //Alarma del timer de medición activa
timerWrite(timerS, 0); //Timer de la señal a 0
timerAlarmEnable(timerS); //Alarma del timer de la señal activa
last_interrupt=current_millis; //Se reestablece el tiempo de la última interrupción
}
}
void IRAM_ATTR finTimer() { //Cuenta cada segundo para la medición
cuenta++;
}
void IRAM_ATTR finTimerS() { //Activa o desactiva el nivel HIGH de la senyal
senyal=1;
}
void setup(){
pinMode(senyal_output, OUTPUT); //Generador de función
pinMode(senyal_entrada, INPUT); //Lee la función
pinMode(sube, INPUT); //Pulsadores
pinMode(baja, INPUT);
pinMode(activa, INPUT);
Serial.begin(115200); //Velocidad del puerto serie
Serial.println("Prueba frecuencimetro");
attachInterrupt(digitalPinToInterrupt(senyal_entrada),ISR_senyal, FALLING); //Interrupción para contar los flancos de la señal de entrada
attachInterrupt(digitalPinToInterrupt(sube),ISR_sube, RISING); //Interrucción para aumentar el tiempo de medida
attachInterrupt(digitalPinToInterrupt(baja),ISR_baja, RISING); //Interrupción para disminuir el tiempo de medida
attachInterrupt(digitalPinToInterrupt(activa),ISR_activa, RISING); //Interrupción para activar la señal
// 80 MHz / 310 = 258064,52 tics / sec
timer = timerBegin(0, 310, true);
timerAttachInterrupt(timer, &finTimer, true);
timerAlarmWrite(timer, 80e6/310, true); // Se ejecuta a cada segundo
timerAlarmEnable(timer);
timerS = timerBegin(1, 310, true);
timerAttachInterrupt(timerS, &finTimerS, true);
timerAlarmWrite(timerS, ((1/frec_senyal)/2)/(310/80e6), true); //Se ejecuta cada medio periodo
}
void loop()
{
delay(1); //Solo en el simulador, para q no tenga que procesar tantos "if" para nada, y así vaya más rápida
//Cambia el nivel de la señal cuando lo indica el timerS
if(senyal==1){
digitalWrite(senyal_output, !digitalRead(senyal_output));
senyal=0; //Se pone a 0 la señal de salida
}
//Muestra la frecuencia y los flancos en el puerto serie
if(cuenta==t_medida){
cuenta=0; //Pone a 0 el número de interrupciones del timer
frec_medida=((float)contador)/(t_medida);
Serial.printf("Frec: %4.2f Hz - nflancos: %d \n", frec_medida, contador);
contador=0; //Pone a 0 los flancos
}
//El puerto serie lee la nueva frecuencia
if (Serial.available() > 0){
timerAlarmDisable(timer); //Alarmas de los timers deshabilitadas
timerAlarmDisable(timerS);
frec_senyal=Serial.readString().toFloat(); //Lee el puerto serie y lo transforma en coma flotante
contador=0; //Pone a 0 los flancos
cuenta=0; //Pone a 0 el número de interrupciones del timer
timerAlarmWrite(timerS, ((1/frec_senyal)/2)/(310/80e6), true); //Se ejecuta cada medio periodo
timerWrite(timer, 0); //Timers a 0
timerWrite(timerS, 0);
timerAlarmEnable(timer); //Alarmas de los timers activas
timerAlarmEnable(timerS);
Serial.printf("\nMidiendo frecuencia de %4.4f Hz en intervalos de %d segundos\n", frec_senyal, t_medida);
}
}