Working moving average filter. IIR filters (low pass, high pass) still have to be implemented via biquad.

Dependencies:   HIDScope biquadFilter mbed

Fork of EMG by Tom Tom

Committer:
MaikOvermars
Date:
Sat Oct 13 15:48:22 2018 +0000
Revision:
22:d2393c670afd
Parent:
21:3ac3c2e9d9ae
Implemented biquad cascade of notch, low pass and high pass filter, all second order.  This is in addition to the moving average and rectifier. Not tested yet on live emg-signal.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vsluiter 0:32bb76391d89 1 #include "mbed.h"
MaikOvermars 21:3ac3c2e9d9ae 2 #include "BiQuad.h"
vsluiter 11:ce72ec658a95 3 #include "HIDScope.h"
vsluiter 0:32bb76391d89 4
vsluiter 4:8b298dfada81 5 //Define objects
MaikOvermars 21:3ac3c2e9d9ae 6 HIDScope scope(2); // We’re going to send 2 channels of data
tomlankhorst 19:2bf824669684 7 AnalogIn emg0( A0 );
tomlankhorst 19:2bf824669684 8 AnalogIn emg1( A1 );
tomlankhorst 19:2bf824669684 9
MaikOvermars 21:3ac3c2e9d9ae 10 Ticker emgSampleTicker;
MaikOvermars 21:3ac3c2e9d9ae 11
MaikOvermars 21:3ac3c2e9d9ae 12 // filter chains for high pass, low pass and notch filters
MaikOvermars 21:3ac3c2e9d9ae 13 BiQuadChain bqc;
MaikOvermars 22:d2393c670afd 14 BiQuad bqlow( 0.0128, 0.0256, 0.0128, -1.6556, 0.7068);
MaikOvermars 22:d2393c670afd 15 BiQuad bqhigh( 0.6458, -1.2917, 0.6458, -1.1620, 0.4213);
MaikOvermars 22:d2393c670afd 16 BiQuad bqnotch( 0.5, 0, 0.5, 0, 0);
MaikOvermars 21:3ac3c2e9d9ae 17 volatile double y[50]= { };
MaikOvermars 21:3ac3c2e9d9ae 18 volatile int n = 0;
MaikOvermars 21:3ac3c2e9d9ae 19 volatile bool full = 0;
vsluiter 2:e314bb3b2d99 20
MaikOvermars 21:3ac3c2e9d9ae 21 void emgSample() {
MaikOvermars 22:d2393c670afd 22 double emgRaw = emg0.read();
MaikOvermars 22:d2393c670afd 23 scope.set(0,emgRaw);
MaikOvermars 21:3ac3c2e9d9ae 24
MaikOvermars 22:d2393c670afd 25 double emgFiltered = bqc.step( emgRaw );
MaikOvermars 22:d2393c670afd 26 scope.set(1,emgFiltered);
MaikOvermars 22:d2393c670afd 27
MaikOvermars 22:d2393c670afd 28 // moving average and rectifier
MaikOvermars 21:3ac3c2e9d9ae 29 y[n] = abs(emgFiltered - 0.45);
MaikOvermars 21:3ac3c2e9d9ae 30 double emgavg = 0;
MaikOvermars 21:3ac3c2e9d9ae 31 if(full == 0){
MaikOvermars 21:3ac3c2e9d9ae 32 for(int i=0;i<50;i++){
MaikOvermars 21:3ac3c2e9d9ae 33 emgavg = emgavg + y[i];
MaikOvermars 21:3ac3c2e9d9ae 34 }
MaikOvermars 21:3ac3c2e9d9ae 35 emgavg = emgavg/(n+1);
MaikOvermars 21:3ac3c2e9d9ae 36 }
MaikOvermars 21:3ac3c2e9d9ae 37 else{
MaikOvermars 21:3ac3c2e9d9ae 38 for(int i=0;i<50;i++){
MaikOvermars 21:3ac3c2e9d9ae 39 emgavg = emgavg + y[i];
MaikOvermars 21:3ac3c2e9d9ae 40 }
MaikOvermars 21:3ac3c2e9d9ae 41 emgavg = emgavg/50;
MaikOvermars 21:3ac3c2e9d9ae 42 }
MaikOvermars 21:3ac3c2e9d9ae 43 n++;
MaikOvermars 21:3ac3c2e9d9ae 44 if(n == 50){
MaikOvermars 21:3ac3c2e9d9ae 45 n = 0;
MaikOvermars 21:3ac3c2e9d9ae 46 full = 1;
MaikOvermars 21:3ac3c2e9d9ae 47 }
MaikOvermars 22:d2393c670afd 48 scope.set(2,emgavg);
vsluiter 11:ce72ec658a95 49 scope.send();
MaikOvermars 21:3ac3c2e9d9ae 50 // do stuff with filtered point emgavg
vsluiter 2:e314bb3b2d99 51 }
vsluiter 0:32bb76391d89 52
MaikOvermars 21:3ac3c2e9d9ae 53
vsluiter 0:32bb76391d89 54 int main()
tomlankhorst 19:2bf824669684 55 {
MaikOvermars 22:d2393c670afd 56 bqc.add( &bqlow ).add( &bqhigh ).add( &bqnotch );
MaikOvermars 21:3ac3c2e9d9ae 57 emgSampleTicker.attach( &emgSample, 0.01 );
MaikOvermars 21:3ac3c2e9d9ae 58
tomlankhorst 14:f83354387756 59 /*empty loop, sample() is executed periodically*/
tomlankhorst 15:0da764eea774 60 while(1) {}
vsluiter 0:32bb76391d89 61 }