Tacometro auditivo para autos de 4 cilindros y 4 tiempos
Dependencies: FastAnalogIn NVIC_set_all_priorities TextLCD mbed-dsp mbed
Fork of tacometrojala by
main.cpp
00001 // Audio Spectrum Display 00002 // Copyright 2013 Tony DiCola (tony@tonydicola.com) 00003 // Code ported from the guide at http://learn.adafruit.com/fft-fun-with-fourier-transforms?view=all 00004 // mods by Tony Abbey to simplify code to drive tri-colour LED as a "colour organ" 00005 00006 #include "mbed.h" 00007 #include "NVIC_set_all_priorities.h" 00008 #include <ctype.h> 00009 #include "arm_math.h" 00010 #include "arm_const_structs.h" 00011 #include "FastAnalogIn.h" 00012 #include <string> 00013 #include "TextLCD.h" 00014 00015 FastAnalogIn Audio(PTC2); 00016 Serial pc(USBTX, USBRX); 00017 TextLCD lcd(PTB0,PTB1,PTC9,PTC8,PTA5,PTA4, TextLCD::LCD16x2); // rs, e, d4-d7 00018 00019 00020 //#define RGBW_ext // Disable this line when you want to use the KL25Z on-board RGB LED. 00021 00022 00023 #ifndef RGBW_ext 00024 // RGB direct output to PWM channels - on-board RGB LED 00025 PwmOut gled(LED_GREEN); 00026 PwmOut rled(LED_RED); 00027 PwmOut bled(LED_BLUE); 00028 #else 00029 // HSI to RGBW conversion with direct output to external PWM channels - RGBW LED 00030 // hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5); //Red, Green, Blue, White 00031 #endif 00032 00033 // Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !! 00034 // More info at https://mbed.org/questions/1387/How-can-I-access-the-FTFA_FOPT-register-/ 00035 extern "C" void NMI_Handler() { 00036 DigitalIn test(PTA4); 00037 } 00038 00039 00040 //////////////////////////////////////////////////////////////////////////////// 00041 // CONFIGURATION 00042 // These values can be changed to alter the behavior of the spectrum display. 00043 // KL25Z limitations 00044 // ----------------- 00045 // - When used with the Spectrogram python script : 00046 // There is a substantial time lag between the music and the screen output. 00047 // Max allowed SAMPLE_RATE_HZ is 40000 00048 // Max allowed FFT_SIZE is 64 00049 //////////////////////////////////////////////////////////////////////////////// 00050 // A value >= 1000 and <= 1000 + PIXEL_COUNT fixes the output to a single frequency 00051 // window = a single color. 00052 int SAMPLE_RATE_HZ = 1000; // Sample rate of the audio in hertz. 00053 float freq=0; 00054 // Useful for turning the LED display on and off with commands from the serial port. 00055 const int FFT_SIZE = 512; // Size of the FFT. 00056 00057 //////////////////////////////////////////////////////////////////////////////// 00058 // INTERNAL STATE 00059 // These shouldn't be modified unless you know what you're doing. 00060 //////////////////////////////////////////////////////////////////////////////// 00061 const static arm_cfft_instance_f32 *S; 00062 Ticker samplingTimer; 00063 float samples[FFT_SIZE*2]; 00064 float magnitudes[FFT_SIZE]; 00065 int sampleCounter = 0; 00066 int maxFrequencyValue = 0; 00067 float maxValue=0.0; 00068 int posicion=0; 00069 int counter=0; 00070 int FFTFrequency = 0; 00071 float filtro[FFT_SIZE]; 00072 00073 // Convert a frequency to the appropriate FFT bin it will fall within. 00074 int frequencyToBin(float frequency) 00075 { 00076 float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); 00077 return int(frequency / binFrequency); 00078 } 00079 00080 00081 00082 //////////////////////////////////////////////////////////////////////////////// 00083 // SAMPLING FUNCTIONS 00084 //////////////////////////////////////////////////////////////////////////////// 00085 00086 void samplingCallback() 00087 { 00088 // Read from the ADC and store the sample data 00089 samples[sampleCounter] = (1023 * Audio) - 511.0f; 00090 // Complex FFT functions require a coefficient for the imaginary part of the input. 00091 // Since we only have real data, set this coefficient to zero. 00092 samples[sampleCounter+1] = 0.0; 00093 // Update sample buffer position and stop after the buffer is filled 00094 sampleCounter += 2; 00095 if (sampleCounter >= FFT_SIZE*2) { 00096 samplingTimer.detach(); 00097 } 00098 } 00099 void aplicarfiltro() 00100 { 00101 float aux; 00102 for(int i=0;i<=FFT_SIZE;i++) 00103 { 00104 aux=filtro[i]*magnitudes[i]; 00105 magnitudes[i]=aux; 00106 } 00107 } 00108 void generarfiltro() 00109 { 00110 00111 for(int i=0;i<=FFT_SIZE;i++) 00112 { 00113 if(i>9) 00114 { 00115 if(i<82) 00116 { 00117 filtro[i]=1.0; 00118 } 00119 } 00120 if(i<10) 00121 { 00122 filtro[i]=0.0; 00123 } 00124 if(i>81) 00125 { 00126 filtro[i]=0; 00127 } 00128 } 00129 } 00130 void samplingBegin() 00131 { 00132 // Reset sample buffer position and start callback at necessary rate. 00133 sampleCounter = 0; 00134 samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); 00135 } 00136 00137 bool samplingIsDone() 00138 { 00139 return sampleCounter >= FFT_SIZE*2; 00140 } 00141 00142 //////////////////////////////////////////////////////////////////////////////// 00143 // FREQUENCY 00144 //////////////////////////////////////////////////////////////////////////////// 00145 //////////////////////////////////////////////////////////////////////////////// 00146 // MAIN FUNCTION 00147 //////////////////////////////////////////////////////////////////////////////// 00148 00149 int main() 00150 { 00151 NVIC_set_all_irq_priorities(1); 00152 NVIC_SetPriority(UART0_IRQn, 0); 00153 lcd.cls(); 00154 lcd.printf("RPM: "); 00155 lcd.locate(0,1); 00156 lcd.printf("F= "); 00157 const int columnafrec=3; 00158 const int columnarpm=5; 00159 const int filafrec=1; 00160 const int filarpm=0; 00161 00162 // Begin sampling audio 00163 samplingBegin(); 00164 00165 // Init arm_ccft_32 00166 switch (FFT_SIZE) 00167 { 00168 case 16: 00169 S = & arm_cfft_sR_f32_len16; 00170 break; 00171 case 32: 00172 S = & arm_cfft_sR_f32_len32; 00173 break; 00174 case 64: 00175 S = & arm_cfft_sR_f32_len64; 00176 break; 00177 case 128: 00178 S = & arm_cfft_sR_f32_len128; 00179 break; 00180 case 256: 00181 S = & arm_cfft_sR_f32_len256; 00182 break; 00183 case 512: 00184 S = & arm_cfft_sR_f32_len512; 00185 break; 00186 case 1024: 00187 S = & arm_cfft_sR_f32_len1024; 00188 break; 00189 case 2048: 00190 S = & arm_cfft_sR_f32_len2048; 00191 break; 00192 case 4096: 00193 S = & arm_cfft_sR_f32_len4096; 00194 break; 00195 } 00196 00197 while(true) { 00198 // Calculate FFT if a full sample is available. 00199 if (samplingIsDone()) { 00200 // Run FFT on sample data. 00201 arm_cfft_f32(S, samples, 0, 1); 00202 // Calculate magnitude of complex numbers output by the FFT. 00203 arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); 00204 //generar y aplicar filtro de 20hz y 200hz 00205 generarfiltro(); 00206 aplicarfiltro(); 00207 //Obtaining the value of the frequency 00208 posicion=0; 00209 counter=0; 00210 maxValue=0.0; 00211 do{ 00212 counter++; 00213 if(magnitudes[counter]>maxValue){ 00214 maxValue=magnitudes[counter]; 00215 posicion=counter; 00216 } 00217 00218 }while(counter<256); 00219 00220 // Restart audio sampling. 00221 samplingBegin(); 00222 } 00223 freq=(float) posicion; 00224 freq=freq*1.953125; 00225 if(freq<25) 00226 { 00227 lcd.locate(columnarpm,filarpm); 00228 lcd.printf("<750 "); 00229 lcd.locate(columnafrec,filafrec); 00230 lcd.printf("%i ",(int)freq); 00231 } 00232 if(freq>=25 ) 00233 { 00234 if(freq<39) 00235 { 00236 lcd.locate(columnarpm,filarpm); 00237 lcd.printf("%i ",(int)(750+(freq-25)*20.83)); 00238 lcd.locate(columnafrec,filafrec); 00239 lcd.printf("%i ",(int)freq); 00240 } 00241 } 00242 if(freq>=39 ) 00243 { 00244 if(freq<54) 00245 { 00246 lcd.locate(columnarpm,filarpm); 00247 lcd.printf("%i ",(int)(1000+(freq-39)*33.33)); 00248 lcd.locate(columnafrec,filafrec); 00249 lcd.printf("%i ",(int)freq); 00250 00251 } 00252 } 00253 if(freq>=54 ) 00254 { 00255 if(freq<=61 ) 00256 { 00257 lcd.locate(columnarpm,filarpm); 00258 lcd.printf("%i ",(int)(1500+(freq-54)*71.42)); 00259 lcd.locate(columnafrec,filafrec); 00260 lcd.printf("%i ",(int)freq); 00261 } 00262 } 00263 if(freq>61 ) 00264 { 00265 if(freq<=82 ) 00266 { 00267 lcd.locate(columnarpm,filarpm); 00268 lcd.printf("%i ",((int)(2000+(freq-62)*23.8))); 00269 lcd.locate(columnafrec,filafrec); 00270 lcd.printf("%i ",(int)freq); 00271 } 00272 } 00273 if(freq>82 ) 00274 { 00275 if(freq<=102 ) 00276 { 00277 lcd.locate(columnarpm,filarpm); 00278 lcd.printf("%i ",(int)(2500+(freq-83)*25)); 00279 lcd.locate(columnafrec,filafrec); 00280 lcd.printf("%i ",(int)freq); 00281 } 00282 } 00283 if(freq>102 ) 00284 { 00285 if(freq<=107) 00286 { 00287 lcd.locate(columnarpm,filarpm); 00288 lcd.printf("%i ",(int)(3000+(freq-103)*100)); 00289 lcd.locate(columnafrec,filafrec); 00290 lcd.printf("%i",(int)freq); 00291 } 00292 } 00293 if(freq>107 ) 00294 { 00295 if(freq<=129) 00296 { 00297 lcd.locate(columnarpm,filarpm); 00298 lcd.printf("%i ",(int)(3500+(freq-108)*22.72)); 00299 lcd.locate(columnafrec,filafrec); 00300 lcd.printf("%i",(int)freq); 00301 } 00302 } 00303 if(freq>129) 00304 { 00305 00306 if(freq<=133) 00307 { 00308 lcd.locate(columnarpm,filarpm); 00309 lcd.printf("4000 "); 00310 lcd.locate(columnafrec,filafrec); 00311 lcd.printf("%i",(int)freq); 00312 } 00313 } 00314 if(freq>133) 00315 { 00316 lcd.locate(columnarpm,filarpm); 00317 lcd.printf("4000>"); 00318 lcd.locate(columnafrec,filafrec); 00319 lcd.printf("%i",(int)freq); 00320 } 00321 } 00322 00323 }
Generated on Fri Jul 15 2022 22:16:01 by 1.7.2