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