Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 2:7945f79d7c8e, committed 2019-01-29
- Comitter:
- guicat
- Date:
- Tue Jan 29 07:20:48 2019 +0000
- Parent:
- 1:4a666bd3fef6
- Commit message:
- First commit
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Thu Jan 24 15:26:56 2019 +0000 +++ b/main.cpp Tue Jan 29 07:20:48 2019 +0000 @@ -13,82 +13,150 @@ #include "arm_const_structs.h" #include "math_helper.h" -/* FFT settings */ -#define SAMPLES 2048 /* 0.5 real parts and 0.5 imaginary parts */ -#define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 1024/256 in our case */ - -/* Global variables */ -float Input[SAMPLES]; -float Output[FFT_SIZE]; /* MBED class APIs */ //DigitalOut myled(LED1); AnalogIn myADC(A1); AnalogOut myDAC(D13); Serial pc(USBTX, USBRX); Ticker timer; - -/* Define sine generator settings*/ -#define SAMPLE_FREQUENCY (128.0) -#define SINE_FREQUENCY (1.0) -const float SAMPLE_TIME = 1/SAMPLE_FREQUENCY; -const int BUFFER_SIZE = int(SAMPLE_FREQUENCY/SINE_FREQUENCY); -float sine[BUFFER_SIZE]; -// Create the sinewave buffer -void calculate_sinewave(){ - for (int i = 0; i < BUFFER_SIZE; i+=1) { - float t = i * SAMPLE_TIME; - float phase = 2* PI * SINE_FREQUENCY * t; - sine[i] = float(0.5 * (cos(phase)) + 0.5); + +/* 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(sine[n]); + myDAC.write(sim[n]); n++; - if (n>=BUFFER_SIZE){ + if (n>=SIM_SIZE){ n=0; } } int main() { - pc.baud(9600); - pc.printf("Starting FFT\r\n"); - // generate sinewave on myDAC - calculate_sinewave(); + /* Init serial communication*/ +// pc.baud(115200); //should be higher + pc.baud(2000000); + /* DAC simulation*/ + calculate_sim(); + timer.attach(&dac_generate,SAMPLE_TIME_UNDEC); - float maxValue; // Max FFT value is stored here - uint32_t maxIndex; // Index in Output array where max value is - timer.attach(&dac_generate,SAMPLE_TIME); - for (int i = 0; i < SAMPLES; i += 2) { - wait(SAMPLE_TIME); - Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset - Input[i + 1] = 0; //Imaginary Part set to zero + /* 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 the Complex FFT module, intFlag = 0, doBitReverse = 1 - //NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256 - if (FFT_SIZE==1024){ - arm_cfft_f32(&arm_cfft_sR_f32_len1024, Input, 0, 1); - } else if (FFT_SIZE==256){ - arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1); + + /* 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; } - // Complex Magniture Module put results into Output(Half size of the Input) - arm_cmplx_mag_f32(Input, Output, FFT_SIZE); - - //Calculates maxValue and returns corresponding value - arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); - - /* FFT graph, only positive frequency */ + 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",Output[i]); +// pc.printf("%f\r\n",fftOutput[i]); // } - /* FFT results */ + /* 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 / FFT_SIZE; + 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); + pc.printf("Frequency of maximum value is %.3f +/- %.3f \r\n",maxFreq,freqStep); } \ No newline at end of file