Guillaume Cathelain / Mbed OS Env_simDAC

Dependencies:   mbed-dsp

Files at this revision

API Documentation at this revision

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