Afinador Guitarra Incompleto
Dependencies: NVIC_set_all_priorities FastAnalogIn TextLCD mbed-dsp mbed
main.cpp
- Committer:
- ratak477
- Date:
- 2015-12-02
- Revision:
- 1:b5bd45c95e36
- Parent:
- 0:2b9337ff25fe
File content as of revision 1:b5bd45c95e36:
#include "mbed.h" #include "TextLCD.h" #include "FastAnalogIn.h" #include "arm_math.h" //Librería que contiene funciones de tranformada de fourier #include "arm_const_struct.h" #include "NVIC_set_all_priorities.h" //Librería para modificar todas las solicitudes de interrupciones al mismo tiempo #include <ctype.h> TextLCD lcd(PTE20,PTE21,PTE22,PTE23,PTE29,PTE30); Serial pc(USBTX,USBRX); FastAnalogIn Mic(PTB0); int SAMPLE_RATE_HZ = 4000; // Frecuencian de muestreo en HZ del sistema const int FFT_SIZE = 1024; // Número de valores para la transformada rápida float freq = 4000.0/1024.0; // Frecuencia de activación de la interrupción de muestreo float max[2]; // Arreglo que almacena la frecuencia y magnitud mayores del espectro de Fourier // Configuraciones necesarias para el correcto funcionaiento del programa const static arm_cfft_instance_f32 *S; Ticker samplingTimer; //objeto creado para habilitar las interrupciones con lso métodos de ticker float samples[FFT_SIZE*2]; //Arreglo en el que se almacenan las muestras del tomadas ADC float magnitudes[FFT_SIZE]; //Arreglo donde se almacenan las magnitudes de la FFT int sampleCounter = 0; //Contador del número de muestras tomadas // FUNCIONES DE MUESTREO //Esta función permite realizar el muestreo de datos, se realiza como interrupción para asegurar el tiempo de muestreo deseado void samplingCallback() { // Lectura del ADC y almacenamiento del dato samples[sampleCounter] = (1023 * Mic) - 511.0f; //Se ajusta el valor de un rango de 0-1 a 0-511 // La función que calcula la transformada requiere de un valor imaginario, en este caso se le asigna 0 // ya que los valores muestreados son solamente reales. samples[sampleCounter+1] = 0.0; // Se ajusta la posición en el arreglo para almacenar el siguiente valor real sampleCounter += 2; // En caso de que el valor de sample counter sobrepase el tamaño del arreglo de almacenamiento se retira la interrupción // de muestreo del programa if (sampleCounter >= FFT_SIZE*2) { samplingTimer.detach(); } } //Esta función permite reiniciar el contador de muestras e insertar nuevamente la interrupción de muestreo void samplingBegin() { sampleCounter = 0; //Se reinicia el contador de muestras samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); //Se incertala interrupción de muestreo la cual es llamada con la frecuencia de Sample_rate_hz } //Función booleana que funciona como bandera para indicar que el meustreo de datos ha sido finalizado bool samplingIsDone() { return sampleCounter >= FFT_SIZE*2; } int main () { lcd.cls(); // Clear the screen //Configuración de las solicitudes de interrupción NVIC_set_all_irq_priorities(1); //Configuración de la velocidad de la comunicación serial pc.baud (38400); //Velocidad de la comunicación USB // Se incerta la interrupción de muestreo del ADC samplingBegin(); // Init arm_ccft_32 el registro cambiara dependiendo de la variable FFT_SIZE switch (FFT_SIZE) { case 512: S = & arm_cfft_sR_f32_len512; break; case 1024: S = & arm_cfft_sR_f32_len1024; break; case 2048: S = & arm_cfft_sR_f32_len2048; break; case 4096: S = & arm_cfft_sR_f32_len4096; break; } while(1) { // Se calcula la FFT si se ha terminado el muestreo if (samplingIsDone()) { arm_cfft_f32(S, samples, 0, 1); arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); for (int i = 1; i < FFT_SIZE/2+1; ++i) { if (magnitudes[i]>max[1]){ max[0]=i*freq; max[1]=magnitudes[i]; //Habilitar solo para debuggeo } } float oct[7] = {16.35,18.35,20.60,21.82,24.5,27.5,30.86}; float n; float nueva_oct[7]; float nueva_octf; for (int i = 0; i <= 6; i = i+1){ if ( max[0] >= 14.35 && max[0]<= 34.22) { n = 0; } if (max[0]> 34.22 && max[0]<= 63.56) { n = 1; } if (max[0] > 63.56 && max[0] <= 127.14) { n = 2; } if (max[0] > 127.14 && max[0] <= 254.28) { n = 3; } if (max[0] > 254.28 && max[0]<= 508.26) { n = 4; } if (max[0] > 508.26 && max[0] <= 1017.13) { n = 5; } if (max[0] > 1017.13 && max[0] <= 2034.26) { n = 6; } if (max[0] > 2034.26 && max[0] <= 4068.54) { n = 7; } float power1 = pow((float)2,(float)n); nueva_oct[i] = oct[i]*power1; } nueva_octf = nueva_oct[6] + 1.84*pow(2,n); if (max[0] >= (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/2) && max[0] < (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/2)) { if (max[0] < (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/8)) { lcd.cls(); // Clear the screen lcd.printf("C %1.0f Aprieta",n); wait(0.1); } if (max[0] > (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/4)) { lcd.cls(); // Clear the screen lcd.printf("C %1.0f Afloja",n); wait(0.1); } if (max[0] <= (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/4) && max[0] >= (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/8)) { lcd.cls(); // Clear the screen lcd.printf("C %1.0f",n); wait(0.1); } } if (max[0] >= (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/2) && max[0] < (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/2)) { if (max[0] < (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/4)) { lcd.cls(); // Clear the screen lcd.printf("D %1.0f Aprieta",n); wait(0.1); } if (max[0] > (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/4)) { lcd.cls(); // Clear the screen lcd.printf("D %1.0f Afloja",n); wait(0.1); } if (max[0] <= (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/4) && max[0] >= (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/4)) { lcd.cls(); // Clear the screen lcd.printf("D %1.0f",n); wait(0.1); } } if (max[0]>= (nueva_oct[2] - (nueva_oct[2] - nueva_oct[1])/2) && max[0]< (nueva_oct[2] + (nueva_oct[3] - nueva_oct[2])/2)) { if (max[0]< (nueva_oct[2] - (nueva_oct[2] - nueva_oct[1])/4)) { lcd.cls(); // Clear the screen lcd.printf("E %1.0f Aprieta",n); wait(0.1); } if (max[0]> (nueva_oct[2] + (nueva_oct[3] - nueva_oct[2])/4)) { lcd.cls(); // Clear the screen lcd.printf("E %1.0f Afloja",n); wait(0.1); } if (max[0]<= (nueva_oct[2] + (nueva_oct[3] - nueva_oct[2])/4) && max[0]>= (nueva_oct[2] - (nueva_oct[2] - nueva_oct[1])/4)) { lcd.cls(); // Clear the screen lcd.printf("E %1.0f",n); wait(0.1); } } if (max[0]>= (nueva_oct[3] - (nueva_oct[3] - nueva_oct[2])/2) && max[0]< (nueva_oct[3] + (nueva_oct[4] - nueva_oct[3])/2)) { if (max[0]< (nueva_oct[3] - (nueva_oct[3] - nueva_oct[2])/4)) { lcd.cls(); // Clear the screen lcd.printf("F %1.0f Aprieta",n); wait(0.1); } if (max[0]> (nueva_oct[3] + (nueva_oct[4] - nueva_oct[3])/4)) { lcd.cls(); // Clear the screen lcd.printf("F %1.0f Afloja",n); wait(0.1); } if (max[0]<= (nueva_oct[3] + (nueva_oct[4] - nueva_oct[3])/4) && max[0]>= (nueva_oct[3] - (nueva_oct[3] - nueva_oct[2])/4)) { lcd.cls(); // Clear the screen lcd.printf("F %1.0f",n); wait(0.1); } } if (max[0]>= (nueva_oct[4] - (nueva_oct[4] - nueva_oct[3])/2) && max[0]< (nueva_oct[4] + (nueva_oct[5] - nueva_oct[4])/2)) { if (max[0]< (nueva_oct[4] - (nueva_oct[4] - nueva_oct[3])/4)) { lcd.cls(); // Clear the screen lcd.printf("G %1.0f Aprieta",n); wait(0.1); } if (max[0]> (nueva_oct[4] + (nueva_oct[5] - nueva_oct[4])/4)) { lcd.cls(); // Clear the screen lcd.printf("G %1.0f Afloja",n); wait(0.1); } if (max[0]<= (nueva_oct[4] + (nueva_oct[5] - nueva_oct[4])/4) && max[0]>= (nueva_oct[4] - (nueva_oct[4] - nueva_oct[3])/4)) { lcd.cls(); // Clear the screen lcd.printf("G %1.0f",n); wait(0.1); } } if (max[0]>= (nueva_oct[5] - (nueva_oct[5] - nueva_oct[4])/2) && max[0]< (nueva_oct[5] + (nueva_oct[6] - nueva_oct[5])/2)) { if (max[0]< (nueva_oct[5] - (nueva_oct[5] - nueva_oct[4])/4)) { lcd.cls(); // Clear the screen lcd.printf("A %1.0f Aprieta",n); wait(0.1); } if (max[0]> (nueva_oct[5] + (nueva_oct[6] - nueva_oct[5])/4)) { lcd.cls(); // Clear the screen lcd.printf("A %1.0f Afloja",n); wait(0.1); } if (max[0]<= (nueva_oct[5] + (nueva_oct[6] - nueva_oct[5])/4) && max[0]>= (nueva_oct[5] - (nueva_oct[5] - nueva_oct[4])/4)) { lcd.cls(); // Clear the screen lcd.printf("A %1.0f",n); wait(0.1); } } if (max[0]>= (nueva_oct[6] - (nueva_oct[6] - nueva_oct[5])/2) && max[0]< (nueva_oct[6] + (nueva_octf - nueva_oct[6])/2)) { if (max[0]< (nueva_oct[6] - (nueva_oct[6] - nueva_oct[5])/4)) { lcd.cls(); // Clear the screen lcd.printf("B %1.0f Aprieta",n); wait(0.1); } if (max[0]> (nueva_oct[6] + (nueva_octf - nueva_oct[6])/4)) { lcd.cls(); // Clear the screen lcd.printf("B %1.0f Afloja",n); wait(0.1); } if (max[0]<= (nueva_oct[6] + (nueva_octf - nueva_oct[6])/4) && max[0]>= (nueva_oct[6] - (nueva_oct[6] - nueva_oct[5])/4)) { lcd.cls(); // Clear the screen lcd.printf("B %1.0f",n); wait(0.1); } } lcd.locate(0,1); lcd.printf("%f",max[0]); lcd.locate(0,0); //Se reinician las variables máximas max[0]=0; max[1]=0; // Se vuelve a incertar la interrupción de muestreo samplingBegin(); } } }