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