Filter for EMG signals The signal will be filtered using a notch, highpass and lowpass filter. The filtered signal will be compared to a preset threshold and according to the strength of the signal the program will perform an action. In this case it will assign a colour to a led.
Dependencies: HIDScope MODSERIAL mbed
Fork of EMGfilter24 by
main.cpp@2:6402a7071ba3, 2016-10-25 (annotated)
- Committer:
- s1601822
- Date:
- Tue Oct 25 12:53:45 2016 +0000
- Revision:
- 2:6402a7071ba3
- Parent:
- 1:6081dc1ecd1f
- Child:
- 3:faed8b7f6542
Shows the raw and filtered EMG signal in HIDscope
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Iknowright | 0:41226c0fd285 | 1 | #include "mbed.h" |
Iknowright | 0:41226c0fd285 | 2 | #include "BiQuad.h" |
Iknowright | 0:41226c0fd285 | 3 | #include "HIDScope.h" |
Iknowright | 0:41226c0fd285 | 4 | #include "MODSERIAL.h" |
Nickname | 1:6081dc1ecd1f | 5 | #include <cmath> |
Iknowright | 0:41226c0fd285 | 6 | |
Nickname | 1:6081dc1ecd1f | 7 | MODSERIAL pc(USBTX, USBRX); |
Nickname | 1:6081dc1ecd1f | 8 | Ticker emgSampleTicker; |
Nickname | 1:6081dc1ecd1f | 9 | AnalogIn emg0(A0); |
Nickname | 1:6081dc1ecd1f | 10 | AnalogIn emg1(A1); |
Nickname | 1:6081dc1ecd1f | 11 | DigitalOut ledje(LED_GREEN); |
Nickname | 1:6081dc1ecd1f | 12 | HIDScope scope(2); |
Nickname | 1:6081dc1ecd1f | 13 | |
Nickname | 1:6081dc1ecd1f | 14 | double hf_b0 = 0.9355; |
Nickname | 1:6081dc1ecd1f | 15 | double hf_b1 = -1.8711; |
Nickname | 1:6081dc1ecd1f | 16 | double hf_b2 = 0.9355; |
Nickname | 1:6081dc1ecd1f | 17 | double hf_a1 = -1.8669; |
Nickname | 1:6081dc1ecd1f | 18 | double hf_a2 = 0.8752; |
Iknowright | 0:41226c0fd285 | 19 | |
Nickname | 1:6081dc1ecd1f | 20 | double lf_b0 = 8.7656e-5; |
Nickname | 1:6081dc1ecd1f | 21 | double lf_b1 = 1.17531e-4; |
Nickname | 1:6081dc1ecd1f | 22 | double lf_b2 = 8.7656e-5; |
Nickname | 1:6081dc1ecd1f | 23 | double lf_a1 = -1.9733; |
Nickname | 1:6081dc1ecd1f | 24 | double lf_a2 = 0.9737; |
Nickname | 1:6081dc1ecd1f | 25 | |
Nickname | 1:6081dc1ecd1f | 26 | double v1 = 0, v2 = 0, u = 0; |
Iknowright | 0:41226c0fd285 | 27 | |
Nickname | 1:6081dc1ecd1f | 28 | /** Sample function |
Nickname | 1:6081dc1ecd1f | 29 | * this function samples the emg and sends it to HIDScope |
Nickname | 1:6081dc1ecd1f | 30 | **/ |
Nickname | 1:6081dc1ecd1f | 31 | void sample() |
Nickname | 1:6081dc1ecd1f | 32 | { |
Nickname | 1:6081dc1ecd1f | 33 | // Set the sampled emg values in channel 0 (the first channel) and 1 (the second channel) in the 'HIDScope' instance named 'scope' |
Nickname | 1:6081dc1ecd1f | 34 | scope.set(0, emg0.read() ); |
s1601822 | 2:6402a7071ba3 | 35 | /* Repeat the step above if required for more channels of required (channel 0 up to 5 = 6 channels) |
Nickname | 1:6081dc1ecd1f | 36 | * Ensure that enough channels are available (HIDScope scope( 2 )) |
Nickname | 1:6081dc1ecd1f | 37 | * Finally, send all channels to the PC at once */ |
Nickname | 1:6081dc1ecd1f | 38 | scope.send(); |
Nickname | 1:6081dc1ecd1f | 39 | // To indicate that the function is working, the LED is toggled |
s1601822 | 2:6402a7071ba3 | 40 | ledje = ledje; |
Nickname | 1:6081dc1ecd1f | 41 | } |
Iknowright | 0:41226c0fd285 | 42 | |
Iknowright | 0:41226c0fd285 | 43 | |
Iknowright | 0:41226c0fd285 | 44 | int main(){ |
Nickname | 1:6081dc1ecd1f | 45 | |
Nickname | 1:6081dc1ecd1f | 46 | /**Attach the 'sample' function to the timer 'sample_timer'. |
Nickname | 1:6081dc1ecd1f | 47 | * this ensures that 'sample' is executed every... 0.002 seconds = 500 Hz |
Nickname | 1:6081dc1ecd1f | 48 | */ |
Nickname | 1:6081dc1ecd1f | 49 | emgSampleTicker.attach(&sample, 0.002); |
Nickname | 1:6081dc1ecd1f | 50 | // empty loop, sample() is executed periodically |
Nickname | 1:6081dc1ecd1f | 51 | while(1) { |
Iknowright | 0:41226c0fd285 | 52 | |
Nickname | 1:6081dc1ecd1f | 53 | double emgFilter(); |
Nickname | 1:6081dc1ecd1f | 54 | { |
Iknowright | 0:41226c0fd285 | 55 | |
Nickname | 1:6081dc1ecd1f | 56 | //High Pass Filter (biquad) |
Nickname | 1:6081dc1ecd1f | 57 | double hf_v = u - hf_a1*v1 - hf_a2*v2; |
Nickname | 1:6081dc1ecd1f | 58 | double hf_y = hf_b0*hf_v + hf_b1*v1 + hf_b2*v2; |
Iknowright | 0:41226c0fd285 | 59 | v2 = v1; |
Nickname | 1:6081dc1ecd1f | 60 | v1 = hf_v; |
Iknowright | 0:41226c0fd285 | 61 | |
Nickname | 1:6081dc1ecd1f | 62 | //Rectification |
Nickname | 1:6081dc1ecd1f | 63 | double rect_y = fabs(hf_y); |
Nickname | 1:6081dc1ecd1f | 64 | |
Nickname | 1:6081dc1ecd1f | 65 | //Low Pass Filter (biquad) |
Nickname | 1:6081dc1ecd1f | 66 | double lf_v = rect_y - lf_a1*v1 - lf_a2*v2; |
Nickname | 1:6081dc1ecd1f | 67 | double lf_y = lf_b0*hf_v + lf_b1*v1 + lf_b2*v2; |
Iknowright | 0:41226c0fd285 | 68 | v2 = v1; |
Nickname | 1:6081dc1ecd1f | 69 | v1 = lf_v; |
Nickname | 1:6081dc1ecd1f | 70 | |
Nickname | 1:6081dc1ecd1f | 71 | while(1){ |
Nickname | 1:6081dc1ecd1f | 72 | |
s1601822 | 2:6402a7071ba3 | 73 | scope.set(1, lf_y); |
s1601822 | 2:6402a7071ba3 | 74 | scope.send(); |
Nickname | 1:6081dc1ecd1f | 75 | |
Nickname | 1:6081dc1ecd1f | 76 | } |
Nickname | 1:6081dc1ecd1f | 77 | |
Nickname | 1:6081dc1ecd1f | 78 | } |
Nickname | 1:6081dc1ecd1f | 79 | |
Iknowright | 0:41226c0fd285 | 80 | } |
Nickname | 1:6081dc1ecd1f | 81 | } |