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();
        }
    }
}