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

main.cpp

Committer:
teunman
Date:
2015-09-25
Revision:
10:b11eacb391ea
Parent:
9:2b9240084724
Child:
11:d8dd024f9784

File content as of revision 10:b11eacb391ea:

#include "mbed.h"
#include "HIDScope.h"
#include "math.h" 
// Define the HIDScope and Ticker object
HIDScope    scope(3);

Ticker      scopeTimer;
Ticker      biquadTicker;


DigitalOut  light(LED2);
DigitalIn    knop(SW3);
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,     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
//const double b0 = 0.8005910266528649,b1 = -1.6011820533057297,b2 = 0.8005910266528649,a1 = -1.5610153912536877,a2 = 0.6413487153577715; //high-pass Fc = 5hz fs = 100hz
//const double b0 = 0.007820199259120319,b1 = 0.015640398518240638,b2 = 0.007820199259120319,a1 = -1.7347238224240125,a2 = 0.7660046194604936; //low-pass Fc = 3hz fs = 100hz
//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



// 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 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






// 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,an_in);
   
    scope.send();
    
 
        
        
}
 
 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 = 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);                          //Rectifier                                         y is the rectified output
     
     
     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);                         //Optional final rectifier (default should be off)           
}
 
 
 

 
 
 
 
int main()
{
    
    // Attach the data read and send function at 1000 Hz
    scopeTimer.attach_us(&scopeSend, 1e5);   
    // Attach the filter calculation function at 1000 Hz
    biquadTicker.attach(&computeBiquad,0.0001f);
     
     
     
    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){     //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;                 
                            wait(0.1);
        
                        }//end for 
        
          
          
          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
         } //end else if
             
      else{
            light = 1; //light stays off by default
            }
            
            
    } //END while
}//END main