Naved Maududi / Mbed OS CMSIS_FFT_mbed_os_DAC

Dependencies:   Harmonic_analyzer

Files at this revision

API Documentation at this revision

Comitter:
nmaududi
Date:
Tue Oct 29 19:02:07 2019 +0000
Parent:
0:05e2c9ca68e2
Commit message:
Revised_10_29_2019

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-dsp.lib Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Fri Apr 13 08:59:47 2018 +0000
+++ b/main.cpp	Tue Oct 29 19:02:07 2019 +0000
@@ -1,3 +1,23 @@
+/*----------------------------------------------------------------------------
+Code to generate a 1004Hz tone and complete a harmonic analysis on the output
+Note that the PWM output produces the 1004 Hz tone and is routed back into the
+analog input to complete harmonic analysis. In the hardware, the output of the 
+PWM is routed to the analog in by a jumber wire. 
+
+Generate a 1004Hz tone with PWM, No DAC present within the board. PWM is the
+software DAC implementation in order to generate the sine wave
+ -------------------------------------------------------------------------------
+ Note parts of the Code was borrowed online from: Wim Huiskamp 
+ https://os.mbed.com/users/wim/code/SineFromPWM/file/d274003b52e7/main.cpp/
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+ Parts of the FFT analysis code was borrowed from Martin Simpson
+ ----------------------------------------
+ Note parts of the Code was borrowed online from: Martin Simpson
+https://os.mbed.com/users/martinsimpson/code/CMSIS_FFT_mbed_os_DAC/file/05e2c9ca68e2/main.cpp/
+ 
+ *----------------------------------------------------------------------------*/
+
 #include "mbed.h"
 /* Include arm_math.h mathematic functions */
 #include "arm_math.h"
@@ -7,38 +27,85 @@
 #include "math_helper.h"
 
 /* FFT settings */
-#define SAMPLES                 512             /* 256 real party and 256 imaginary parts */
+#define SAMPLES                 512            /* 256 real party and 256 imaginary parts */
 #define FFT_SIZE                SAMPLES / 2     /* FFT size is always the same size as we have samples, so 256 in our case */
 
+//Number of dutycycle steps for output wave
+#define SINE_STEPS        32
+//Frequency of output sine in Hz
+#define SINE_OUT_FREQ     1004
+
+//Constants to compute the sine waveform
+//#define PI                 3.141592f
+#define SINE_STEPS_RAD    (2.0f * PI / (float)SINE_STEPS)
+
+//Table to generate the sine waveform using dutycycles
+float sine_duty[SINE_STEPS];
+
+
+//Frequency of Pulse Width Modulated signal in Hz
+#define PWM_FREQ          200000
+
+//Sampling rate for FFT (50KHz)
+#define FFT_SAMP_FREQ          10000
+
+//Ticker to update the PWM dutycycle
+Ticker pwm_ticker;
+
 /* Global variables */
 float32_t Input[SAMPLES];
 float32_t Output[FFT_SIZE];
 bool      trig=0;
 /* MBED class APIs */
-DigitalOut myled(LED1);
-AnalogIn   myADC(A1);
-AnalogOut  myDAC(D13);
+PwmOut led(LED1);
+AnalogIn   myADC(PA_4);
+//PWM pin
+PwmOut PwmPin (PB_3); // set this pin for the analog output tone for the sine wave
+//AnalogOut  myDAC(D13);
 Serial     pc(USBTX, USBRX);
 Ticker     timer;
-
+static int idx=0;
 void sample(){
     trig=1;
     }
+    
+//Ticker calls this fucntion to update the PWM dutycycle
+void pwm_duty_updater() {
+  
+  
+  PwmPin.write(sine_duty[idx]);  // Set the dutycycle % to next value in array
+  idx++;                         // Increment the idx
+  if (idx == SINE_STEPS) idx=0;  // Reset the idx when the end has been reached  
+
+}
 
 int main() {
+  
+  int i;
+  
+  // Init the duty cycle array
+  for (i=0; i<SINE_STEPS; i++) {
+    sine_duty[i] = ( sin(i * SINE_STEPS_RAD) + 1.0f ) / 2.0f;  // convert sine (-1.0 .. +1.0) into dutycycle (0.0 .. 1.0)
+  }  
+    
+  // Set PWM frequency to 200 KHz (period = 5 us)
+  PwmPin.period( 1.0f / (float) PWM_FREQ);
+
+  // Init the Ticker to call the dutycyle updater at the required interval
+  // The update should be at (SINE_STEPS * SINE_OUT_FREQ) 
+  pwm_ticker.attach(&pwm_duty_updater, 1.0f / (float)(SINE_STEPS * SINE_OUT_FREQ));
 
     //arm_cfft_instance_f32 S;   // ARM CFFT module
     float maxValue;            // Max FFT value is stored here
-    uint32_t maxIndex;         // Index in Output array where max value is
+    float maxIndex;         // Index in Output array where max value is
     bool once=0;
-    pc.baud(115200);
+    pc.baud(9600);
     pc.printf("Starting FFT\r\n");
-    while(1) {
-            timer.attach_us(&sample,20); //20us 50KHz sampling rate
+            timer.attach_us(&sample,100); //20us 50KHz sampling rate
             for (int i = 0; i < SAMPLES; i += 2) {
                 while (trig==0){}
                 trig=0;
-                Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset
+                Input[i] = myADC.read(); //Real part NB 
                 Input[i + 1] = 0;               //Imaginary Part set to zero
                 }
             timer.detach();
@@ -48,26 +115,30 @@
 
         // Complex Magniture Module put results into Output(Half size of the Input)
         arm_cmplx_mag_f32(Input, Output, FFT_SIZE);
-        
+        // DC values present, need to remove that portion
+      for (int i = 0; i < 127; ++i)
+        Output[i] = Output[i + 1]; // copy next element left
+     
         //Calculates maxValue and returns corresponding value
-        arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex);
-
-        if (once==0){
-            pc.printf("Maximum is %f\r\n",maxValue);
-            once = 1;
+        maxValue = Output[0];
+        maxIndex = 0;
+        for (int i=0; i<FFT_SIZE/2 ; i++){
+            if (Output[i]>maxValue){
+                maxValue = Output[i];
+                maxIndex = i;
+                }
+         }
+       led.period( 1.0/ (((10000.0/2.0)/128.00)*maxIndex+39.06)*1000);// LED blinking at 1 sec if fundamental frequency is 1004 Hz
+       led.write(0.5f);      // 50% duty cycle, relative to period
+        float freq_bin;
+       if (once==0){
+        for (int i=0; i<FFT_SIZE/2 ; i++){
+            freq_bin = ((FFT_SAMP_FREQ /2)/128.00)*i+39.06; // DC value shows up in the FFT analysis, removing the DC part, as result, need to add 39.68 Hz
+            pc.printf("Frequency bin is %f\r\n",freq_bin); //Each bin 10KHz/2/128 = 39.06Hz resolution
+            wait_us(100); 
+            pc.printf("Maximum output is %f\r\n",(Output[i]/maxValue)*0.9f);
+            wait_us(100); 
             }
-       
-        //maxValue /= 100.0f;
-        
-        myDAC=1.0f;     //SYNC Pulse to DAC Output
-        wait_us(20);    //Used on Oscilliscope set trigger level to the highest
-        myDAC=0.0f;     //point on this pulse (all FFT data will be scaled
-                        //90% of Max Value
-        
-        for (int i=0; i<FFT_SIZE/2 ; i++){
-            myDAC=(Output[i]/maxValue)*0.9f; // Scale to Max Value and scale to 90%
-            wait_us(10); //Each pulse of 10us is 50KHz/256 = 195Hz resolution
-            }
-        myDAC=0.0f;
-        }
+           once = 1;
+           }
 }
\ No newline at end of file
--- a/mbed-dsp.lib	Fri Apr 13 08:59:47 2018 +0000
+++ b/mbed-dsp.lib	Tue Oct 29 19:02:07 2019 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/mbed_official/code/mbed-dsp/#3762170b6d4d
+https://os.mbed.com/teams/MESA-Project-2/code/Harmonic_analyzer/#1c28ca64ca38