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.
main.cpp@1:4a666bd3fef6, 2019-01-24 (annotated)
- Committer:
- guicat
- Date:
- Thu Jan 24 15:26:56 2019 +0000
- Revision:
- 1:4a666bd3fef6
- Parent:
- 0:05e2c9ca68e2
- Child:
- 2:7945f79d7c8e
Generate simulation sinewave from DAC, captures signal from ADC, process FFT and plot result
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
guicat | 1:4a666bd3fef6 | 1 | /* |
guicat | 1:4a666bd3fef6 | 2 | Original code from MARTIN SIMPSON : CMSIS_FFT_mbed_os_DAC |
guicat | 1:4a666bd3fef6 | 3 | https://os.mbed.com/users/martinsimpson/code/CMSIS_FFT_mbed_os_DAC/file/05e2c9ca68e2/main.cpp/ |
guicat | 1:4a666bd3fef6 | 4 | |
guicat | 1:4a666bd3fef6 | 5 | Modified by Guillaume Cathelain to generate simulation from DAC |
guicat | 1:4a666bd3fef6 | 6 | */ |
guicat | 1:4a666bd3fef6 | 7 | |
martinsimpson | 0:05e2c9ca68e2 | 8 | #include "mbed.h" |
martinsimpson | 0:05e2c9ca68e2 | 9 | /* Include arm_math.h mathematic functions */ |
martinsimpson | 0:05e2c9ca68e2 | 10 | #include "arm_math.h" |
martinsimpson | 0:05e2c9ca68e2 | 11 | /* Include mbed-dsp libraries */ |
martinsimpson | 0:05e2c9ca68e2 | 12 | #include "arm_common_tables.h" |
martinsimpson | 0:05e2c9ca68e2 | 13 | #include "arm_const_structs.h" |
martinsimpson | 0:05e2c9ca68e2 | 14 | #include "math_helper.h" |
martinsimpson | 0:05e2c9ca68e2 | 15 | |
martinsimpson | 0:05e2c9ca68e2 | 16 | /* FFT settings */ |
guicat | 1:4a666bd3fef6 | 17 | #define SAMPLES 2048 /* 0.5 real parts and 0.5 imaginary parts */ |
guicat | 1:4a666bd3fef6 | 18 | #define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 1024/256 in our case */ |
martinsimpson | 0:05e2c9ca68e2 | 19 | |
martinsimpson | 0:05e2c9ca68e2 | 20 | /* Global variables */ |
guicat | 1:4a666bd3fef6 | 21 | float Input[SAMPLES]; |
guicat | 1:4a666bd3fef6 | 22 | float Output[FFT_SIZE]; |
martinsimpson | 0:05e2c9ca68e2 | 23 | /* MBED class APIs */ |
guicat | 1:4a666bd3fef6 | 24 | //DigitalOut myled(LED1); |
martinsimpson | 0:05e2c9ca68e2 | 25 | AnalogIn myADC(A1); |
martinsimpson | 0:05e2c9ca68e2 | 26 | AnalogOut myDAC(D13); |
martinsimpson | 0:05e2c9ca68e2 | 27 | Serial pc(USBTX, USBRX); |
martinsimpson | 0:05e2c9ca68e2 | 28 | Ticker timer; |
guicat | 1:4a666bd3fef6 | 29 | |
guicat | 1:4a666bd3fef6 | 30 | /* Define sine generator settings*/ |
guicat | 1:4a666bd3fef6 | 31 | #define SAMPLE_FREQUENCY (128.0) |
guicat | 1:4a666bd3fef6 | 32 | #define SINE_FREQUENCY (1.0) |
guicat | 1:4a666bd3fef6 | 33 | const float SAMPLE_TIME = 1/SAMPLE_FREQUENCY; |
guicat | 1:4a666bd3fef6 | 34 | const int BUFFER_SIZE = int(SAMPLE_FREQUENCY/SINE_FREQUENCY); |
guicat | 1:4a666bd3fef6 | 35 | float sine[BUFFER_SIZE]; |
guicat | 1:4a666bd3fef6 | 36 | // Create the sinewave buffer |
guicat | 1:4a666bd3fef6 | 37 | void calculate_sinewave(){ |
guicat | 1:4a666bd3fef6 | 38 | for (int i = 0; i < BUFFER_SIZE; i+=1) { |
guicat | 1:4a666bd3fef6 | 39 | float t = i * SAMPLE_TIME; |
guicat | 1:4a666bd3fef6 | 40 | float phase = 2* PI * SINE_FREQUENCY * t; |
guicat | 1:4a666bd3fef6 | 41 | sine[i] = float(0.5 * (cos(phase)) + 0.5); |
guicat | 1:4a666bd3fef6 | 42 | } |
guicat | 1:4a666bd3fef6 | 43 | } |
martinsimpson | 0:05e2c9ca68e2 | 44 | |
guicat | 1:4a666bd3fef6 | 45 | int n=0; |
guicat | 1:4a666bd3fef6 | 46 | void dac_generate(){ |
guicat | 1:4a666bd3fef6 | 47 | myDAC.write(sine[n]); |
guicat | 1:4a666bd3fef6 | 48 | n++; |
guicat | 1:4a666bd3fef6 | 49 | if (n>=BUFFER_SIZE){ |
guicat | 1:4a666bd3fef6 | 50 | n=0; |
martinsimpson | 0:05e2c9ca68e2 | 51 | } |
guicat | 1:4a666bd3fef6 | 52 | } |
guicat | 1:4a666bd3fef6 | 53 | |
martinsimpson | 0:05e2c9ca68e2 | 54 | |
martinsimpson | 0:05e2c9ca68e2 | 55 | int main() { |
guicat | 1:4a666bd3fef6 | 56 | pc.baud(9600); |
guicat | 1:4a666bd3fef6 | 57 | pc.printf("Starting FFT\r\n"); |
guicat | 1:4a666bd3fef6 | 58 | // generate sinewave on myDAC |
guicat | 1:4a666bd3fef6 | 59 | calculate_sinewave(); |
guicat | 1:4a666bd3fef6 | 60 | |
martinsimpson | 0:05e2c9ca68e2 | 61 | float maxValue; // Max FFT value is stored here |
martinsimpson | 0:05e2c9ca68e2 | 62 | uint32_t maxIndex; // Index in Output array where max value is |
guicat | 1:4a666bd3fef6 | 63 | timer.attach(&dac_generate,SAMPLE_TIME); |
guicat | 1:4a666bd3fef6 | 64 | for (int i = 0; i < SAMPLES; i += 2) { |
guicat | 1:4a666bd3fef6 | 65 | wait(SAMPLE_TIME); |
guicat | 1:4a666bd3fef6 | 66 | Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset |
guicat | 1:4a666bd3fef6 | 67 | Input[i + 1] = 0; //Imaginary Part set to zero |
guicat | 1:4a666bd3fef6 | 68 | } |
guicat | 1:4a666bd3fef6 | 69 | // Init the Complex FFT module, intFlag = 0, doBitReverse = 1 |
guicat | 1:4a666bd3fef6 | 70 | //NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256 |
guicat | 1:4a666bd3fef6 | 71 | if (FFT_SIZE==1024){ |
guicat | 1:4a666bd3fef6 | 72 | arm_cfft_f32(&arm_cfft_sR_f32_len1024, Input, 0, 1); |
guicat | 1:4a666bd3fef6 | 73 | } else if (FFT_SIZE==256){ |
martinsimpson | 0:05e2c9ca68e2 | 74 | arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1); |
guicat | 1:4a666bd3fef6 | 75 | } |
martinsimpson | 0:05e2c9ca68e2 | 76 | |
guicat | 1:4a666bd3fef6 | 77 | // Complex Magniture Module put results into Output(Half size of the Input) |
guicat | 1:4a666bd3fef6 | 78 | arm_cmplx_mag_f32(Input, Output, FFT_SIZE); |
martinsimpson | 0:05e2c9ca68e2 | 79 | |
guicat | 1:4a666bd3fef6 | 80 | //Calculates maxValue and returns corresponding value |
guicat | 1:4a666bd3fef6 | 81 | arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); |
guicat | 1:4a666bd3fef6 | 82 | |
guicat | 1:4a666bd3fef6 | 83 | /* FFT graph, only positive frequency */ |
guicat | 1:4a666bd3fef6 | 84 | // for (int i=0; i<FFT_SIZE/2;i++){ |
guicat | 1:4a666bd3fef6 | 85 | // pc.printf("%f\r\n",Output[i]); |
guicat | 1:4a666bd3fef6 | 86 | // } |
guicat | 1:4a666bd3fef6 | 87 | |
guicat | 1:4a666bd3fef6 | 88 | /* FFT results */ |
guicat | 1:4a666bd3fef6 | 89 | // pc.printf("Maximum value is %f\r\n",maxValue); |
guicat | 1:4a666bd3fef6 | 90 | // pc.printf("Index of maximum value is %d\r\n",maxIndex); |
guicat | 1:4a666bd3fef6 | 91 | float freqStep = SAMPLE_FREQUENCY / FFT_SIZE; |
guicat | 1:4a666bd3fef6 | 92 | float maxFreq = maxIndex * freqStep; |
guicat | 1:4a666bd3fef6 | 93 | pc.printf("Frequency of maximum value is %.3f +/- %.3f \r\n",maxFreq,freqStep); |
martinsimpson | 0:05e2c9ca68e2 | 94 | } |