Emg filter function script for a uni project. Made by Teun van der Molen

Dependencies:   HIDScope MODSERIAL mbed

Fork of frdm_EMG by Teun van der Molen

Revision:
10:b11eacb391ea
Parent:
9:2b9240084724
Child:
11:d8dd024f9784
--- a/main.cpp	Wed Sep 23 15:53:10 2015 +0000
+++ b/main.cpp	Fri Sep 25 08:53:19 2015 +0000
@@ -3,15 +3,30 @@
 #include "math.h" 
 // Define the HIDScope and Ticker object
 HIDScope    scope(3);
+
 Ticker      scopeTimer;
 Ticker      biquadTicker;
+
+
 DigitalOut  light(LED2);
 DigitalIn    knop(SW3);
-int tel = 0; // timer thing for caliration length (see for loop in main)
-double c=5; //calibration value
+AnalogIn    an_in(A0);  //The input from the emg board, make sure that the jumper pin on the EMG board corresponds with the value in the brackets here!!! (see bb pptx for details on jumper placement, default is A0)
+
+
+
+
+    light = 1; //Light is off by default
+double c = 5; //calibration value (in volts)
 double n = 0; // counter for calibration
 bool calib = false; //changes into false when calibration is done (reset program for new calibration); 
-double v1=0, v2=0, u=0, y=0,     fy=0, fv1=0, fv2=0, fu=0;
+double v1=0, v2=0, u=0, y=0,     fy=0, fv1=0, fv2=0, fu=0,     ny=0, nv1=0, nv2=0, nu=0;;
+
+
+//Notch filter  (n stand for notch filter (this is in fact the very first filter but is rarely changed) to alter this filter add "n" to all coefficents example: nb0,nb1 etc.)
+const double nb0 = 0.8206743576788857,nb1 = -1.5610153912536877,nb2 = 0.8206743576788857,na1 = -1.5610153912536877,na2 = 0.6413487153577715; //Notch filter  Fc = 50 Hz  Fs 1000Hz
+
+
+// 100 Hz filters (obsolete)
 
 //const double b0 = 0.9999999999999999,b1 = 1.9999999999999998,b2 = 0.9999999999999999, a1 = 1.9999999999999998 ,a2 = 0.9999999999999998; //low-pass Fc = 50hz fs = 100hz
 //const double fb0 = 0.02008333102602092 ,fb1 = 0.04016666205204184 ,fb2 = 0.02008333102602092, fa1 = -1.5610153912536877 ,fa2 = 0.6413487153577715; //low-pass Fc = 5hz fs = 100hz
@@ -20,59 +35,59 @@
 //const double b0 = 0.0009446914586925257,b1 = 0.0018893829173850514,b2 = 0.0009446914586925257,a1 = -1.911196288237583,a2 = 0.914975054072353; //low-pass Fc = 1hz fs = 100hz
 //const double b0 = 0.956542835577484, b1 = -1.913085671154968, b2 = 0.956542835577484, a1 = -1.911196288237583, a2 = 0.914975054072353; //high-pass Fc  =  1hz fs = 100hz
 
-const double b0 = 0.00008765553769759188,b1 = 0.00017531107539518376,b2 = 0.00008765553769759188,a1 = -1.9733440008737442,a2 = 0.9736946230245347;//low-pass Fc = 3Hz fs = 1000hz
-//const double b0 = 0.00034604125149151127,b1 = 0.0006920825029830225, b2 = 0.00034604125149151127 ,a1 = -1.9466970561224466 ,a2 = 0.9480812211284125; //low-pass Fc = 6Hz fs = 1000hz
+
+
+// 1000 Hz filters (f stands for the seccond filter, so make sure the first coefiecients are b0,b1 etc. and the seccond filter is  fb0,fb1,fb2 etc.)
+
+//const double b0 = 0.00008765553769759188,b1 = 0.00017531107539518376,b2 = 0.00008765553769759188,a1 = -1.9733440008737442,a2 = 0.9736946230245347;//low-pass Fc = 3Hz fs = 1000hz
+const double fb0 = 0.00034604125149151127,fb1 = 0.0006920825029830225, fb2 = 0.00034604125149151127 ,fa1 = -1.9466970561224466 ,fa2 = 0.9480812211284125; //low-pass Fc = 6Hz fs = 1000hz
 //const double fb0 = 0.9149684297741606, fb1 = -1.8299368595483212, fb2 = 0.9149684297741606 ,fa1 = -1.8226935021735358, fa2 = 0.8371802169231065; // High-pass Fc = 20Hz fs = 1000hz
 //const double fb0 = 0.8948577513857248 ,fb1 = -1.7897155027714495, fb2 = 0.8948577513857248,fa1 = -1.7786300789392977,fa2 = 0.8008009266036016; // High-pass Fc = 25Hz fs = 1000Hz
 //const double b0 = 0.005542711916075981,b1 = 0.011085423832151962,b2 = 0.005542711916075981,a1 = -1.7786300789392977,a2 = 0.8008009266036016; //Low-pass Fc = 25Hz fs=1000Hz
 //const double fb0 = 0.9780302754084559,fb1 = -1.9560605508169118,fb2 = 0.9780302754084559,fa1 = -1.9555778328194147,fa2 = 0.9565432688144089; //high-pass Fc = 6hz fs = 1000hz
-const double fb0 = 0.9911535113858849,fb1 = -1.9823070227717698,fb2 = 0.9911535113858849,fa1 = -1.9822287623675816,fa2 = 0.982385283175958; //High-pass Fc = 2Hz fs = 1000Hz
+const double b0 = 0.9911535113858849,b1 = -1.9823070227717698,b2 = 0.9911535113858849,a1 = -1.9822287623675816,a2 = 0.982385283175958; //High-pass Fc = 2Hz fs = 1000Hz
 //const double fb0 = 0.0036216786873927774,fb1 = 0.007243357374785555,fb2 = 0.0036216786873927774,fa1 = -1.8226935021735358,fa2 = 0.8371802169231065; ///Low-pass Fc = 20 Hz Fs = 1000Hz
 
 
 
-// Read the analog input
-AnalogIn    an_in(A0);
+
 
-AnalogOut   an_out(DAC0_OUT); 
-// The data read and send function
+
+// The data read and send function for HIDscope (can send any value to the HIDscope for read out)
 void scopeSend()
 {
     scope.set(0,c);
     scope.set(1,fy);
-    scope.set(2,n);
+    scope.set(2,an_in);
    
     scope.send();
     
-    //while(calib == true and n <= 200.00) {
-        
-      //  c = c + fy;
-    
-        //n ++;
-        
-        //}
+ 
         
         
 }
  
- void computeBiquad(){
+ void computeBiquad(){  //The filter function (is called at the same frequency of the scope function (not sure if timing is fully correct here) and does the filter calculations)
    
-  
+   double nv = an_in - na1*nv1 - na2*nv2;   //notch filter at 50Hz for laptop adapter           ny is the filtered output
+    ny= nb0*nv + nb1*nv1 +nb2*nv2;
+    nv2=nv1;
+    nv1=nv;
      
-    double v = an_in - a1*v1 - a2*v2;
+    double v = ny - a1*v1 - a2*v2;          //First filter (see filters to check values)        y is the filtered output
     y= b0*v + b1*v1 +b2*v2;
     v2=v1;
     v1=v;
      
-       y = abs(y);
+       y = abs(y);                          //Rectifier                                         y is the rectified output
      
      
-     double fv = y - fa1*fv1 - fa2*fv2;
+     double fv = y - fa1*fv1 - fa2*fv2;     //Second Filter (see filters to check values)       fy is the filtered output
     fy= fb0*fv + fb1*fv1 + fb2*fv2;
     fv2=fv1;
     fv1=fv;
     
-    fy = abs(fy);
+    //fy = abs(fy);                         //Optional final rectifier (default should be off)           
 }
  
  
@@ -84,50 +99,50 @@
  
 int main()
 {
-    light = 1;
     
     // Attach the data read and send function at 1000 Hz
     scopeTimer.attach_us(&scopeSend, 1e5);   
-    //scopeTimer.attach_us(&calibrate, 1e5);
+    // Attach the filter calculation function at 1000 Hz
     biquadTicker.attach(&computeBiquad,0.0001f);
-     //float i = 1;
-    while(1) {
-      if (fy >=  c and calib == false){
-          light = 0;
-          }
+     
+     
+     
+    while(1) {  //the everlasting while loop
+    
+    
+            if (fy >=  c and calib == false){    //if there is no calibration going on and the filtered emg is above calibration the light goes on
+                light = 0;
+                }
         
       
-      else if (knop == 0){
-          c = 0;
-          n = 0;
-          //for (tel = 0; tel == 20; tel ++){
-          light = 0;
-          calib = true;
-          for(;calib == true and n <= 20.00; n = n + 1) {
+            else if (knop == 0){     //pressing the button starts calibration
+                
+                c = 0;
+                n = 0;
+                light = 0;      //light is on during calibration
+                calib = true;
+                    
+                       for(;calib == true and n <= 20.00; n = n + 1) {      //this loop ads the calibration value from the output of the filter, this also decides the time of calibration (see wait in combination with the n maximum)
         
-        c = c + fy;
-    
-        //n ++;
+                            c = c + fy;                 
+                            wait(0.1);
         
-        wait(0.1);
-        
-        } //while
-        
-       // }
+                        }//end for 
         
           
           
-          light = 1;
-          calib = false; // shuts of calibration
-          c = c/n;  //take the average
-          tel = 0;
+          light = 1;        // light is off for a while after calibration
+          calib = false;    // shuts of calibration
+          c = c/n;          //take the average of the emg output during calibration and set the calibration value
+        
           
-          wait(5); // you can only calibrate every this amount of seconds
-         } //if
-          
-          
+          wait(5);           // you can only calibrate every this amount of seconds
+         } //end else if
+             
       else{
-            light = 1;
+            light = 1; //light stays off by default
             }
-    }
-}
\ No newline at end of file
+            
+            
+    } //END while
+}//END main
\ No newline at end of file