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
- Committer:
- efrain95
- Date:
- 2016-11-19
- Revision:
- 4:9fae1f1b731a
- Parent:
- 3:1c6625b2d363
File content as of revision 4:9fae1f1b731a:
// Audio Spectrum Display // Copyright 2013 Tony DiCola (tony@tonydicola.com) // Code ported from the guide at http://learn.adafruit.com/fft-fun-with-fourier-transforms?view=all // mods by Tony Abbey to simplify code to drive tri-colour LED as a "colour organ" #include "mbed.h" #include "NVIC_set_all_priorities.h" #include <ctype.h> #include "arm_math.h" #include "arm_const_structs.h" #include "FastAnalogIn.h" #include <string> #include "TextLCD.h" FastAnalogIn Audio(PTC2); Serial pc(USBTX, USBRX); TextLCD lcd(PTB0,PTB1,PTC9,PTC8,PTA5,PTA4, TextLCD::LCD16x2); // rs, e, d4-d7 //#define RGBW_ext // Disable this line when you want to use the KL25Z on-board RGB LED. #ifndef RGBW_ext // RGB direct output to PWM channels - on-board RGB LED PwmOut gled(LED_GREEN); PwmOut rled(LED_RED); PwmOut bled(LED_BLUE); #else // HSI to RGBW conversion with direct output to external PWM channels - RGBW LED // hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5); //Red, Green, Blue, White #endif // Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !! // More info at https://mbed.org/questions/1387/How-can-I-access-the-FTFA_FOPT-register-/ extern "C" void NMI_Handler() { DigitalIn test(PTA4); } //////////////////////////////////////////////////////////////////////////////// // CONFIGURATION // These values can be changed to alter the behavior of the spectrum display. // KL25Z limitations // ----------------- // - When used with the Spectrogram python script : // There is a substantial time lag between the music and the screen output. // Max allowed SAMPLE_RATE_HZ is 40000 // Max allowed FFT_SIZE is 64 //////////////////////////////////////////////////////////////////////////////// // A value >= 1000 and <= 1000 + PIXEL_COUNT fixes the output to a single frequency // window = a single color. int SAMPLE_RATE_HZ = 1000; // Sample rate of the audio in hertz. float freq=0; // Useful for turning the LED display on and off with commands from the serial port. const int FFT_SIZE = 512; // Size of the FFT. //////////////////////////////////////////////////////////////////////////////// // INTERNAL STATE // These shouldn't be modified unless you know what you're doing. //////////////////////////////////////////////////////////////////////////////// const static arm_cfft_instance_f32 *S; Ticker samplingTimer; float samples[FFT_SIZE*2]; float magnitudes[FFT_SIZE]; int sampleCounter = 0; int maxFrequencyValue = 0; float maxValue=0.0; int posicion=0; int counter=0; int FFTFrequency = 0; float filtro[FFT_SIZE]; // Convert a frequency to the appropriate FFT bin it will fall within. int frequencyToBin(float frequency) { float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE); return int(frequency / binFrequency); } //////////////////////////////////////////////////////////////////////////////// // SAMPLING FUNCTIONS //////////////////////////////////////////////////////////////////////////////// void samplingCallback() { // Read from the ADC and store the sample data samples[sampleCounter] = (1023 * Audio) - 511.0f; // Complex FFT functions require a coefficient for the imaginary part of the input. // Since we only have real data, set this coefficient to zero. samples[sampleCounter+1] = 0.0; // Update sample buffer position and stop after the buffer is filled sampleCounter += 2; if (sampleCounter >= FFT_SIZE*2) { samplingTimer.detach(); } } void aplicarfiltro() { float aux; for(int i=0;i<=FFT_SIZE;i++) { aux=filtro[i]*magnitudes[i]; magnitudes[i]=aux; } } void generarfiltro() { for(int i=0;i<=FFT_SIZE;i++) { if(i>9) { if(i<82) { filtro[i]=1.0; } } if(i<10) { filtro[i]=0.0; } if(i>81) { filtro[i]=0; } } } void samplingBegin() { // Reset sample buffer position and start callback at necessary rate. sampleCounter = 0; samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ); } bool samplingIsDone() { return sampleCounter >= FFT_SIZE*2; } //////////////////////////////////////////////////////////////////////////////// // FREQUENCY //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // MAIN FUNCTION //////////////////////////////////////////////////////////////////////////////// int main() { NVIC_set_all_irq_priorities(1); NVIC_SetPriority(UART0_IRQn, 0); lcd.cls(); lcd.printf("RPM: "); lcd.locate(0,1); lcd.printf("F= "); const int columnafrec=3; const int columnarpm=5; const int filafrec=1; const int filarpm=0; // Begin sampling audio samplingBegin(); // Init arm_ccft_32 switch (FFT_SIZE) { case 16: S = & arm_cfft_sR_f32_len16; break; case 32: S = & arm_cfft_sR_f32_len32; break; case 64: S = & arm_cfft_sR_f32_len64; break; case 128: S = & arm_cfft_sR_f32_len128; break; case 256: S = & arm_cfft_sR_f32_len256; break; 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; } while(true) { // Calculate FFT if a full sample is available. if (samplingIsDone()) { // Run FFT on sample data. arm_cfft_f32(S, samples, 0, 1); // Calculate magnitude of complex numbers output by the FFT. arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); //generar y aplicar filtro de 20hz y 200hz generarfiltro(); aplicarfiltro(); //Obtaining the value of the frequency posicion=0; counter=0; maxValue=0.0; do{ counter++; if(magnitudes[counter]>maxValue){ maxValue=magnitudes[counter]; posicion=counter; } }while(counter<256); // Restart audio sampling. samplingBegin(); } freq=(float) posicion; freq=freq*1.953125; if(freq<25) { lcd.locate(columnarpm,filarpm); lcd.printf("<750 "); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } if(freq>=25 ) { if(freq<39) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(750+(freq-25)*20.83)); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } } if(freq>=39 ) { if(freq<54) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(1000+(freq-39)*33.33)); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } } if(freq>=54 ) { if(freq<=61 ) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(1500+(freq-54)*71.42)); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } } if(freq>61 ) { if(freq<=82 ) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",((int)(2000+(freq-62)*23.8))); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } } if(freq>82 ) { if(freq<=102 ) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(2500+(freq-83)*25)); lcd.locate(columnafrec,filafrec); lcd.printf("%i ",(int)freq); } } if(freq>102 ) { if(freq<=107) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(3000+(freq-103)*100)); lcd.locate(columnafrec,filafrec); lcd.printf("%i",(int)freq); } } if(freq>107 ) { if(freq<=129) { lcd.locate(columnarpm,filarpm); lcd.printf("%i ",(int)(3500+(freq-108)*22.72)); lcd.locate(columnafrec,filafrec); lcd.printf("%i",(int)freq); } } if(freq>129) { if(freq<=133) { lcd.locate(columnarpm,filarpm); lcd.printf("4000 "); lcd.locate(columnafrec,filafrec); lcd.printf("%i",(int)freq); } } if(freq>133) { lcd.locate(columnarpm,filarpm); lcd.printf("4000>"); lcd.locate(columnafrec,filafrec); lcd.printf("%i",(int)freq); } } }