Afinador Guitarra Incompleto

Dependencies:   NVIC_set_all_priorities FastAnalogIn TextLCD mbed-dsp mbed

Files at this revision

API Documentation at this revision

Comitter:
ratak477
Date:
Wed Dec 02 15:36:45 2015 +0000
Parent:
0:2b9337ff25fe
Commit message:
Guitar Tuner for FRDM-KL25Z. LCD display enabled 16x2. Fast Analog Microphone. FFT.

Changed in this revision

CMSIS_DSP_401.lib Show diff for this revision Revisions of this file
NVIC_set_all_priorities.lib Show annotated file Show diff for this revision Revisions of this file
arm_const_struct.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/CMSIS_DSP_401.lib	Sat Nov 21 00:12:06 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/emh203/code/CMSIS_DSP_401/#3d9c67d97d6f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NVIC_set_all_priorities.lib	Wed Dec 02 15:36:45 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/frankvnk/code/NVIC_set_all_priorities/#8acd3bf521ff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arm_const_struct.h	Wed Dec 02 15:36:45 2015 +0000
@@ -0,0 +1,86 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2013 ARM Limited. All rights reserved.
+*
+* $Date:        17. January 2013
+* $Revision:    V1.4.1
+*
+* Project:      CMSIS DSP Library
+* Title:        arm_const_structs.h
+*
+* Description:  This file has constant structs that are initialized for
+*               user convenience.  For example, some can be given as
+*               arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*   - Redistributions of source code must retain the above copyright
+*     notice, this list of conditions and the following disclaimer.
+*   - Redistributions in binary form must reproduce the above copyright
+*     notice, this list of conditions and the following disclaimer in
+*     the documentation and/or other materials provided with the
+*     distribution.
+*   - Neither the name of ARM LIMITED nor the names of its contributors
+*     may be used to endorse or promote products derived from this
+*     software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len16 = {
+      16, twiddleCoef_16, armBitRevIndexTable16, ARMBITREVINDEXTABLE__16_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len32 = {
+      32, twiddleCoef_32, armBitRevIndexTable32, ARMBITREVINDEXTABLE__32_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len64 = {
+      64, twiddleCoef_64, armBitRevIndexTable64, ARMBITREVINDEXTABLE__64_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len128 = {
+      128, twiddleCoef_128, armBitRevIndexTable128, ARMBITREVINDEXTABLE_128_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len256 = {
+      256, twiddleCoef_256, armBitRevIndexTable256, ARMBITREVINDEXTABLE_256_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len512 = {
+      512, twiddleCoef_512, armBitRevIndexTable512, ARMBITREVINDEXTABLE_512_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024 = {
+      1024, twiddleCoef_1024, armBitRevIndexTable1024, ARMBITREVINDEXTABLE1024_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048 = {
+      2048, twiddleCoef_2048, armBitRevIndexTable2048, ARMBITREVINDEXTABLE2048_TABLE_LENGTH
+   };
+
+   const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096 = {
+      4096, twiddleCoef_4096, armBitRevIndexTable4096, ARMBITREVINDEXTABLE4096_TABLE_LENGTH
+   };
+
+#endif
+
--- a/main.cpp	Sat Nov 21 00:12:06 2015 +0000
+++ b/main.cpp	Wed Dec 02 15:36:45 2015 +0000
@@ -1,65 +1,135 @@
 #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();
-    wait(0.01);
-    for(int i = 8; i >= 0; i--)
+   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)
     {
-        lcd.cls();
-        lcd.printf("%d",i);
-        wait(1);
+    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;
     }
-    lcd.cls();
-    lcd.printf("Perro");
-    */
-    
-    lcd.cls();      // Clear the screen
-    float freq = 140;
+   
+    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 (freq >= 14.35 && freq <= 34.22)
+        if ( max[0] >= 14.35 && max[0]<= 34.22)
         {
             n = 0;
         }
-        if (freq > 34.22 && freq <= 63.56)
+        if (max[0]> 34.22 && max[0]<= 63.56)
         {
             n = 1;
         }
-        if (freq > 63.56 && freq <= 127.14)
+        if (max[0] > 63.56 && max[0] <= 127.14)
         {
             n = 2;
         }
-        if (freq > 127.14 && freq <= 254.28)
+        if (max[0] > 127.14 && max[0] <= 254.28)
         {
             n = 3;
         }
-        if (freq > 254.28 && freq <= 508.26)
+        if (max[0] > 254.28 && max[0]<= 508.26)
         {
             n = 4;
         }
-        if (freq > 508.26 && freq <= 1017.13)
+        if (max[0] > 508.26 && max[0] <= 1017.13)
         {
             n = 5;
         }
-        if (freq > 1017.13 && freq <= 2034.26)
+        if (max[0] > 1017.13 && max[0] <= 2034.26)
         {
             n = 6;
         }
-        if (freq > 2034.26 && freq <= 4068.54)
+        if (max[0] > 2034.26 && max[0] <= 4068.54)
         {
             n = 7;
         }
@@ -70,49 +140,182 @@
     
     nueva_octf = nueva_oct[6] + 1.84*pow(2,n);
     
-    if (freq >= (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/2) && freq < (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/2))
+    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 (freq < (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/8))
+        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 (freq > (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/4))
+        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 (freq <= (nueva_oct[0] + (nueva_oct[1] - nueva_oct[0])/4) && freq >= (nueva_oct[0] - (nueva_oct[1] - nueva_oct[0])/8))
+        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 (freq >= (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/2) && freq < (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/2))
+    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 (freq < (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/4))
+        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 (freq > (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/4))
+        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 (freq <= (nueva_oct[1] + (nueva_oct[2] - nueva_oct[1])/4) && freq >= (nueva_oct[1] - (nueva_oct[1] - nueva_oct[0])/4))
+        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);
+           
         }
     }
     
     
     
-    //lcd.printf("%2.0f%",oct[0]);
-    wait(0.01);
-    lcd.locate(0,1);
-    lcd.printf("%f",nueva_octf);
+    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);
+        } 
+    }
     
-    while (true)
+    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))
     {
-        float MicF = Mic;
-        pc.printf("%2.2f\n",MicF);    
-        wait (0.1);
+        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);
+        } 
     }
-}
\ No newline at end of file
+    
+    
+    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();
+        }
+    }
+}
+    
\ No newline at end of file