chalala
Dependencies: FastAnalogIn NVIC_set_all_priorities mbed-dsp mbed
Fork of ProyFinal by
main.cpp@1:7655383ca5fd, 2015-12-02 (annotated)
- Committer:
- henryclon
- Date:
- Wed Dec 02 20:14:40 2015 +0000
- Revision:
- 1:7655383ca5fd
- Parent:
- 0:2ccf3099b859
- Child:
- 2:6f99f6b825b8
Versi?n nueva con comentarios adecuados
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
henryclon | 0:2ccf3099b859 | 1 | #include "mbed.h" |
henryclon | 0:2ccf3099b859 | 2 | #include "NVIC_set_all_priorities.h" |
henryclon | 0:2ccf3099b859 | 3 | #include <ctype.h> |
henryclon | 0:2ccf3099b859 | 4 | #include "arm_math.h" |
henryclon | 0:2ccf3099b859 | 5 | #include "arm_const_structs.h" |
henryclon | 0:2ccf3099b859 | 6 | #include "FastAnalogIn.h" |
henryclon | 0:2ccf3099b859 | 7 | #include <string> |
henryclon | 0:2ccf3099b859 | 8 | |
henryclon | 1:7655383ca5fd | 9 | //Enrique García Sandoval A01224184 |
henryclon | 1:7655383ca5fd | 10 | //Emmanuel Gonzalez Palacios A01228185 |
henryclon | 1:7655383ca5fd | 11 | |
henryclon | 1:7655383ca5fd | 12 | // Basado en el código de Frank Vannieuwkerke en KL25Z_FFT_Demo |
henryclon | 1:7655383ca5fd | 13 | // https://developer.mbed.org/users/frankvnk/code/KL25Z_FFT_Demo/ |
henryclon | 1:7655383ca5fd | 14 | |
henryclon | 0:2ccf3099b859 | 15 | PwmOut myled(LED_GREEN); |
henryclon | 0:2ccf3099b859 | 16 | Serial pc(USBTX, USBRX); |
henryclon | 0:2ccf3099b859 | 17 | FastAnalogIn Audio(PTC0); |
henryclon | 0:2ccf3099b859 | 18 | |
henryclon | 0:2ccf3099b859 | 19 | ////Parametros//// |
henryclon | 0:2ccf3099b859 | 20 | int SAMPLE_RATE_HZ = 4000; |
henryclon | 0:2ccf3099b859 | 21 | const int FFT_SIZE = 256; |
henryclon | 0:2ccf3099b859 | 22 | |
henryclon | 1:7655383ca5fd | 23 | ////Otras Variables para sampling y FFT//// |
henryclon | 0:2ccf3099b859 | 24 | const static arm_cfft_instance_f32 *S; |
henryclon | 0:2ccf3099b859 | 25 | Ticker samplingTimer; |
henryclon | 0:2ccf3099b859 | 26 | float samples[FFT_SIZE*2]; |
henryclon | 0:2ccf3099b859 | 27 | float magnitudes[FFT_SIZE]; |
henryclon | 0:2ccf3099b859 | 28 | int sampleCounter = 0; |
henryclon | 0:2ccf3099b859 | 29 | //*********// |
henryclon | 0:2ccf3099b859 | 30 | |
henryclon | 0:2ccf3099b859 | 31 | ////Utilidades//// |
henryclon | 1:7655383ca5fd | 32 | void printArr(int bigsize, float arr[]){ //Imprime un arreglo de valores |
henryclon | 0:2ccf3099b859 | 33 | int size = (bigsize/sizeof(arr[0])); |
henryclon | 0:2ccf3099b859 | 34 | pc.printf("\r\n ["); |
henryclon | 0:2ccf3099b859 | 35 | int limit = size - 1; |
henryclon | 0:2ccf3099b859 | 36 | for (int i = 0; i < size; i++){ |
henryclon | 0:2ccf3099b859 | 37 | i == limit ? pc.printf("%.3f", arr[i]): pc.printf("%.3f ,", arr[i]); |
henryclon | 0:2ccf3099b859 | 38 | } |
henryclon | 0:2ccf3099b859 | 39 | pc.printf("] \n"); |
henryclon | 0:2ccf3099b859 | 40 | } |
henryclon | 0:2ccf3099b859 | 41 | |
henryclon | 0:2ccf3099b859 | 42 | int frequencyToBin(float frequency) |
henryclon | 0:2ccf3099b859 | 43 | { |
henryclon | 0:2ccf3099b859 | 44 | float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); |
henryclon | 0:2ccf3099b859 | 45 | return int(frequency / binFrequency); |
henryclon | 0:2ccf3099b859 | 46 | } |
henryclon | 0:2ccf3099b859 | 47 | //*********// |
henryclon | 0:2ccf3099b859 | 48 | |
henryclon | 0:2ccf3099b859 | 49 | ////Sampling//// |
henryclon | 0:2ccf3099b859 | 50 | |
henryclon | 0:2ccf3099b859 | 51 | void samplingCallback() |
henryclon | 0:2ccf3099b859 | 52 | { |
henryclon | 0:2ccf3099b859 | 53 | // Read from the ADC and store the sample data |
henryclon | 0:2ccf3099b859 | 54 | samples[sampleCounter] = (1023 * Audio) - 511.0f; |
henryclon | 0:2ccf3099b859 | 55 | // Complex FFT functions require a coefficient for the imaginary part of the input. |
henryclon | 0:2ccf3099b859 | 56 | // Since we only have real data, set this coefficient to zero. |
henryclon | 0:2ccf3099b859 | 57 | samples[sampleCounter+1] = 0.0; |
henryclon | 0:2ccf3099b859 | 58 | // Update sample buffer position and stop after the buffer is filled |
henryclon | 0:2ccf3099b859 | 59 | sampleCounter += 2; |
henryclon | 0:2ccf3099b859 | 60 | if (sampleCounter >= FFT_SIZE*2) { |
henryclon | 0:2ccf3099b859 | 61 | samplingTimer.detach(); |
henryclon | 0:2ccf3099b859 | 62 | } |
henryclon | 0:2ccf3099b859 | 63 | } |
henryclon | 0:2ccf3099b859 | 64 | |
henryclon | 0:2ccf3099b859 | 65 | void samplingBegin() |
henryclon | 0:2ccf3099b859 | 66 | { |
henryclon | 0:2ccf3099b859 | 67 | // Reset sample buffer position and start callback at necessary rate. |
henryclon | 0:2ccf3099b859 | 68 | sampleCounter = 0; |
henryclon | 0:2ccf3099b859 | 69 | samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); |
henryclon | 0:2ccf3099b859 | 70 | } |
henryclon | 0:2ccf3099b859 | 71 | |
henryclon | 0:2ccf3099b859 | 72 | bool samplingIsDone() |
henryclon | 0:2ccf3099b859 | 73 | { |
henryclon | 0:2ccf3099b859 | 74 | return sampleCounter >= FFT_SIZE*2; |
henryclon | 0:2ccf3099b859 | 75 | } |
henryclon | 0:2ccf3099b859 | 76 | |
henryclon | 0:2ccf3099b859 | 77 | //**********// |
henryclon | 0:2ccf3099b859 | 78 | |
henryclon | 1:7655383ca5fd | 79 | //Funciones para detección de DTMF// |
henryclon | 0:2ccf3099b859 | 80 | int col1 = frequencyToBin(1209); |
henryclon | 0:2ccf3099b859 | 81 | int col2 = frequencyToBin(1336); |
henryclon | 0:2ccf3099b859 | 82 | int col3 = frequencyToBin(1477); |
henryclon | 0:2ccf3099b859 | 83 | int row1 = frequencyToBin(697); |
henryclon | 0:2ccf3099b859 | 84 | int row2 = frequencyToBin(770); |
henryclon | 0:2ccf3099b859 | 85 | int row3 = frequencyToBin(852); |
henryclon | 0:2ccf3099b859 | 86 | int row4 = frequencyToBin(941); |
henryclon | 0:2ccf3099b859 | 87 | string valC1[] = {"1", "4", "7", "*"}; |
henryclon | 0:2ccf3099b859 | 88 | string valC2[] = {"2", "5", "8", "0"}; |
henryclon | 0:2ccf3099b859 | 89 | string valC3[] = {"3", "6", "9", "#"}; |
henryclon | 0:2ccf3099b859 | 90 | |
henryclon | 0:2ccf3099b859 | 91 | |
henryclon | 1:7655383ca5fd | 92 | int maxCol(){ //Magnitud máxima en una columna |
henryclon | 0:2ccf3099b859 | 93 | int col = 0; |
henryclon | 0:2ccf3099b859 | 94 | float max = 0.0; |
henryclon | 0:2ccf3099b859 | 95 | if (magnitudes[col1] > max){ |
henryclon | 0:2ccf3099b859 | 96 | max = magnitudes[col1]; |
henryclon | 0:2ccf3099b859 | 97 | col = 1; |
henryclon | 0:2ccf3099b859 | 98 | } |
henryclon | 0:2ccf3099b859 | 99 | if(magnitudes[col2] > max){ |
henryclon | 0:2ccf3099b859 | 100 | max = magnitudes[col2]; |
henryclon | 0:2ccf3099b859 | 101 | col = 2; |
henryclon | 0:2ccf3099b859 | 102 | } |
henryclon | 0:2ccf3099b859 | 103 | if(magnitudes[col3] > max){ |
henryclon | 0:2ccf3099b859 | 104 | col = 3; |
henryclon | 0:2ccf3099b859 | 105 | } |
henryclon | 0:2ccf3099b859 | 106 | return col; |
henryclon | 0:2ccf3099b859 | 107 | } |
henryclon | 0:2ccf3099b859 | 108 | |
henryclon | 1:7655383ca5fd | 109 | int maxRow(){ //Magnitud máxima en una fila |
henryclon | 0:2ccf3099b859 | 110 | int row = 0; |
henryclon | 0:2ccf3099b859 | 111 | float max = 0.0; |
henryclon | 0:2ccf3099b859 | 112 | if (magnitudes[row1] > max){ |
henryclon | 0:2ccf3099b859 | 113 | max = magnitudes[row1]; |
henryclon | 0:2ccf3099b859 | 114 | row = 1; |
henryclon | 0:2ccf3099b859 | 115 | } |
henryclon | 0:2ccf3099b859 | 116 | if(magnitudes[row2] > max){ |
henryclon | 0:2ccf3099b859 | 117 | max = magnitudes[row2]; |
henryclon | 0:2ccf3099b859 | 118 | row = 2; |
henryclon | 0:2ccf3099b859 | 119 | } |
henryclon | 0:2ccf3099b859 | 120 | if(magnitudes[row3] > max){ |
henryclon | 0:2ccf3099b859 | 121 | max = magnitudes[row3]; |
henryclon | 0:2ccf3099b859 | 122 | row = 3; |
henryclon | 0:2ccf3099b859 | 123 | } |
henryclon | 0:2ccf3099b859 | 124 | if(magnitudes[row4] > max){ |
henryclon | 0:2ccf3099b859 | 125 | row = 4; |
henryclon | 0:2ccf3099b859 | 126 | } |
henryclon | 0:2ccf3099b859 | 127 | return row; |
henryclon | 0:2ccf3099b859 | 128 | } |
henryclon | 0:2ccf3099b859 | 129 | |
henryclon | 1:7655383ca5fd | 130 | string valor(){ //Determina qué tecla se presiona |
henryclon | 0:2ccf3099b859 | 131 | int R = maxRow() - 1; |
henryclon | 0:2ccf3099b859 | 132 | int C = maxCol(); |
henryclon | 0:2ccf3099b859 | 133 | //pc.printf("Las coordenadas son: %i, %i \n", R, C); //debug |
henryclon | 1:7655383ca5fd | 134 | string salida = "---"; |
henryclon | 0:2ccf3099b859 | 135 | switch (C){ |
henryclon | 0:2ccf3099b859 | 136 | case 1: |
henryclon | 0:2ccf3099b859 | 137 | salida = valC1[R]; |
henryclon | 0:2ccf3099b859 | 138 | break; |
henryclon | 0:2ccf3099b859 | 139 | case 2: |
henryclon | 0:2ccf3099b859 | 140 | salida = valC2[R]; |
henryclon | 0:2ccf3099b859 | 141 | break; |
henryclon | 0:2ccf3099b859 | 142 | case 3: |
henryclon | 0:2ccf3099b859 | 143 | salida = valC3[R]; |
henryclon | 0:2ccf3099b859 | 144 | break; |
henryclon | 0:2ccf3099b859 | 145 | } |
henryclon | 0:2ccf3099b859 | 146 | return salida; |
henryclon | 0:2ccf3099b859 | 147 | } |
henryclon | 0:2ccf3099b859 | 148 | //**********// |
henryclon | 0:2ccf3099b859 | 149 | |
henryclon | 0:2ccf3099b859 | 150 | int main(){ |
henryclon | 1:7655383ca5fd | 151 | myled = 0.995; |
henryclon | 0:2ccf3099b859 | 152 | |
henryclon | 0:2ccf3099b859 | 153 | NVIC_set_all_irq_priorities(1); |
henryclon | 0:2ccf3099b859 | 154 | NVIC_SetPriority(UART0_IRQn, 0); |
henryclon | 0:2ccf3099b859 | 155 | |
henryclon | 0:2ccf3099b859 | 156 | // Begin sampling audio |
henryclon | 0:2ccf3099b859 | 157 | samplingBegin(); |
henryclon | 0:2ccf3099b859 | 158 | |
henryclon | 0:2ccf3099b859 | 159 | // Init arm_ccft_32 |
henryclon | 0:2ccf3099b859 | 160 | switch (FFT_SIZE) |
henryclon | 0:2ccf3099b859 | 161 | { |
henryclon | 0:2ccf3099b859 | 162 | case 16: |
henryclon | 0:2ccf3099b859 | 163 | S = & arm_cfft_sR_f32_len16; |
henryclon | 0:2ccf3099b859 | 164 | break; |
henryclon | 0:2ccf3099b859 | 165 | case 32: |
henryclon | 0:2ccf3099b859 | 166 | S = & arm_cfft_sR_f32_len32; |
henryclon | 0:2ccf3099b859 | 167 | break; |
henryclon | 0:2ccf3099b859 | 168 | case 64: |
henryclon | 0:2ccf3099b859 | 169 | S = & arm_cfft_sR_f32_len64; |
henryclon | 0:2ccf3099b859 | 170 | break; |
henryclon | 0:2ccf3099b859 | 171 | case 128: |
henryclon | 0:2ccf3099b859 | 172 | S = & arm_cfft_sR_f32_len128; |
henryclon | 0:2ccf3099b859 | 173 | break; |
henryclon | 0:2ccf3099b859 | 174 | case 256: |
henryclon | 0:2ccf3099b859 | 175 | S = & arm_cfft_sR_f32_len256; |
henryclon | 0:2ccf3099b859 | 176 | break; |
henryclon | 0:2ccf3099b859 | 177 | case 512: |
henryclon | 0:2ccf3099b859 | 178 | S = & arm_cfft_sR_f32_len512; |
henryclon | 0:2ccf3099b859 | 179 | break; |
henryclon | 0:2ccf3099b859 | 180 | case 1024: |
henryclon | 0:2ccf3099b859 | 181 | S = & arm_cfft_sR_f32_len1024; |
henryclon | 0:2ccf3099b859 | 182 | break; |
henryclon | 0:2ccf3099b859 | 183 | case 2048: |
henryclon | 0:2ccf3099b859 | 184 | S = & arm_cfft_sR_f32_len2048; |
henryclon | 0:2ccf3099b859 | 185 | break; |
henryclon | 0:2ccf3099b859 | 186 | case 4096: |
henryclon | 0:2ccf3099b859 | 187 | S = & arm_cfft_sR_f32_len4096; |
henryclon | 0:2ccf3099b859 | 188 | break; |
henryclon | 0:2ccf3099b859 | 189 | } |
henryclon | 0:2ccf3099b859 | 190 | |
henryclon | 0:2ccf3099b859 | 191 | while(true){ |
henryclon | 0:2ccf3099b859 | 192 | // Calculate FFT if a full sample is available. |
henryclon | 0:2ccf3099b859 | 193 | if (samplingIsDone()) { |
henryclon | 0:2ccf3099b859 | 194 | // Run FFT on sample data. |
henryclon | 0:2ccf3099b859 | 195 | arm_cfft_f32(S, samples, 0, 1); |
henryclon | 0:2ccf3099b859 | 196 | // Calculate magnitude of complex numbers output by the FFT. |
henryclon | 0:2ccf3099b859 | 197 | arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); |
henryclon | 0:2ccf3099b859 | 198 | // Restart audio sampling. |
henryclon | 0:2ccf3099b859 | 199 | samplingBegin(); |
henryclon | 1:7655383ca5fd | 200 | |
henryclon | 0:2ccf3099b859 | 201 | //Correr identificacion de tonos |
henryclon | 0:2ccf3099b859 | 202 | printf(valor().c_str()); |
henryclon | 0:2ccf3099b859 | 203 | printf("\r\n"); |
henryclon | 0:2ccf3099b859 | 204 | } |
henryclon | 0:2ccf3099b859 | 205 | |
henryclon | 0:2ccf3099b859 | 206 | |
henryclon | 0:2ccf3099b859 | 207 | } |
henryclon | 0:2ccf3099b859 | 208 | } |