Tacometro auditivo para autos de 4 cilindros y 4 tiempos

Dependencies:   FastAnalogIn NVIC_set_all_priorities TextLCD mbed-dsp mbed

Fork of tacometrojala by Efrain Duarte

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }