Guillaume Cathelain / Mbed OS Env_simDAC

Dependencies:   mbed-dsp

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?

UserRevisionLine numberNew 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 }