Afinador Guitarra Incompleto
Dependencies: NVIC_set_all_priorities FastAnalogIn TextLCD mbed-dsp mbed
Revision 1:b5bd45c95e36, committed 2015-12-02
- 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
--- 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