Generates vibe wave from DAC; Record signal from ADC;Computes envelope; compute FFT; Plot results (graph or frequency of maximal value) Original code from Martin Simpson.
main.cpp
- Committer:
- guicat
- Date:
- 2019-01-29
- Revision:
- 2:7945f79d7c8e
- Parent:
- 1:4a666bd3fef6
File content as of revision 2:7945f79d7c8e:
/* Original code from MARTIN SIMPSON : CMSIS_FFT_mbed_os_DAC https://os.mbed.com/users/martinsimpson/code/CMSIS_FFT_mbed_os_DAC/file/05e2c9ca68e2/main.cpp/ Modified by Guillaume Cathelain to generate simulation from DAC */ #include "mbed.h" /* Include arm_math.h mathematic functions */ #include "arm_math.h" /* Include mbed-dsp libraries */ #include "arm_common_tables.h" #include "arm_const_structs.h" #include "math_helper.h" /* MBED class APIs */ //DigitalOut myled(LED1); AnalogIn myADC(A1); AnalogOut myDAC(D13); Serial pc(USBTX, USBRX); Ticker timer; /* Global variables */ #define SAMPLE_FREQUENCY_UNDEC 1024 // a ajuster selon la frequence de la porteuse const float SAMPLE_TIME_UNDEC = 1.0/SAMPLE_FREQUENCY_UNDEC; const int SAMPLES_UNDEC = 8*SAMPLE_FREQUENCY_UNDEC; /* 8 secondes au total */ /*Decimation settings*/ const uint16_t numTaps = 31; // order(30) + 1 const float32_t firCoeffs[numTaps] = {0.0035214853,0.004185653,0.005849378,0.008574021,0.012351584,0.017101394,0.022671906,0.028847635,0.035360847,0.041907296,0.048164908,0.053814158,0.058558714,0.06214481,0.064378045,0.065136336,0.064378045,0.06214481,0.058558714,0.053814158,0.048164908,0.041907296,0.035360847,0.028847635,0.022671906,0.017101394,0.012351584,0.008574021,0.005849378,0.004185653,0.0035214853}; const uint8_t M = 32; // divise SAMPLE_FREQ_UNDEC. Limite max : M < VIBE_SAMPLES const uint32_t blockSize = 64; const uint32_t numBlocks = SAMPLES_UNDEC/blockSize; static float32_t firState[numTaps + blockSize -1]; static float32_t undecimatedSignal[SAMPLES_UNDEC]; static float decimatedSignal[SAMPLES_UNDEC/M]; static float32_t *pDecimatorInput, *pDecimatorOutput; /* FFT settings */ #define FFT_SIZE SAMPLES_UNDEC/M /* FFT size is always the same size as we have samples, so 1024/256 in our case */ static float fftInput[FFT_SIZE*2]; // initialized with zeros static float fftOutput[FFT_SIZE]; // initialized with zeros static float maxValue; // Max FFT value is stored here static uint32_t maxIndex; // Index in Output array where max value is /* Define simulation settings*/ #define CARRIER_FREQUENCY (256) // ATTENTION multiple de 2 pour que SAMPLE_FREQUENCY multiple de CARRIER_FREQUENCY afin que VIBE_SAMPLES soit entier const int CARRIER_SIZE = SAMPLE_FREQUENCY_UNDEC/CARRIER_FREQUENCY; float carrier[CARRIER_SIZE]; #define MODUL_FREQUENCY 1 const int VIBE_SAMPLES =(SAMPLE_FREQUENCY_UNDEC/CARRIER_FREQUENCY)*int(0.1*CARRIER_FREQUENCY); // multiple de 1/CARRIER_FREQUENCY, durée 0.01s. Durée minimale = 1/CARRIER_FREQUENCY; durée max = 1/MODUL_FREQUENCY const int MODUL_SIZE = SAMPLE_FREQUENCY_UNDEC/MODUL_FREQUENCY; float modul[MODUL_SIZE]; const int SIM_SIZE = MODUL_SIZE; float sim[SIM_SIZE]; // Create the carrier buffer void calculate_carrier(){ for (int i = 0; i < CARRIER_SIZE; i+=1) { float t = i * SAMPLE_TIME_UNDEC; float phase = 2* PI * CARRIER_FREQUENCY * t; carrier[i] = sin(phase); } } // Create the modulator buffer void calculate_modulator(){ for (int i = 0; i < VIBE_SAMPLES; i+=1) { modul[i] = 1.0; } for (int i = VIBE_SAMPLES; i < MODUL_SIZE; i+=1) { modul[i] = 0.0; } } // Calculate the sim signal void calculate_sim(){ calculate_carrier(); calculate_modulator(); for (int i = 0;i<SIM_SIZE;i+=1){ int i_carrier = i - CARRIER_SIZE*int(float(i)/CARRIER_SIZE); sim[i] = 0.5*modul[i]*carrier[i_carrier]+0.5; } } // Create the modulated signal int n=0; void dac_generate(){ myDAC.write(sim[n]); n++; if (n>=SIM_SIZE){ n=0; } } int main() { /* Init serial communication*/ // pc.baud(115200); //should be higher pc.baud(2000000); /* DAC simulation*/ calculate_sim(); timer.attach(&dac_generate,SAMPLE_TIME_UNDEC); /* DAC record */ for (int i = 0; i < SAMPLES_UNDEC; i += 1) { wait(SAMPLE_TIME_UNDEC); undecimatedSignal[i] = abs(myADC.read() - 0.5f); //Real part NB removing DC offset } /* Decimation*/ arm_fir_decimate_instance_f32 S; arm_fir_decimate_init_f32(&S, numTaps, M,(float32_t *)&firCoeffs[0], (float32_t *)&firState[0], blockSize); pDecimatorInput = &undecimatedSignal[0]; pDecimatorOutput = &decimatedSignal[0]; for(int i=0; i < numBlocks; i++) { arm_fir_decimate_f32(&S, pDecimatorInput + (i * blockSize), pDecimatorOutput + (i * blockSize/M), blockSize); } /* Init FFT*/ float meanDecimatedSignal; arm_mean_f32(decimatedSignal,SAMPLES_UNDEC/M,&meanDecimatedSignal); for (int i = 0; i < 2*FFT_SIZE; i += 2) { fftInput[i] = decimatedSignal[i/2] - meanDecimatedSignal; fftInput[i+1] = 0; } if (FFT_SIZE==1024){ arm_cfft_f32(&arm_cfft_sR_f32_len1024, fftInput, 0, 1); } else if (FFT_SIZE==512){ arm_cfft_f32(&arm_cfft_sR_f32_len512, fftInput, 0, 1); } else if (FFT_SIZE==256){ arm_cfft_f32(&arm_cfft_sR_f32_len256, fftInput, 0, 1); } else if (FFT_SIZE==128){ arm_cfft_f32(&arm_cfft_sR_f32_len128, fftInput, 0, 1); } /* Compute FFT and max value */ arm_cmplx_mag_f32(fftInput, fftOutput, FFT_SIZE); arm_max_f32(fftOutput, FFT_SIZE/2, &maxValue, &maxIndex); /* GRAPHS*/ // /* PLOT DECIMATOR INPUT BUFFER */ // for (int i = 0; i < SAMPLES_UNDEC; i += 1) { // pc.printf("%f\r\n",undecimatedSignal[i]); // } // /* PLOT DECIMATOR OUTPUT BUFFER */ // for (int i = 0; i < SAMPLES_UNDEC/M; i += 1) { // pc.printf("%f\r\n",decimatedSignal[i]); // } // /* FFT graph, only positive frequency */ // for (int i=0; i<FFT_SIZE/2;i++){ // pc.printf("%f\r\n",fftOutput[i]); // } /* FFT RESULT */ // pc.printf("Maximum value is %f\r\n",maxValue); // pc.printf("Index of maximum value is %d\r\n",maxIndex); float freqStep = (SAMPLE_FREQUENCY_UNDEC/float(M)) / float(FFT_SIZE); float maxFreq = maxIndex * freqStep; pc.printf("Frequency of maximum value is %.3f +/- %.3f \r\n",maxFreq,freqStep); }