Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: PID_VelocityExample TheProgram Passief_stuurprogramma Actief_stuurprogramma
EMG.h@9:7da462802e5f, 2015-10-23 (annotated)
- Committer:
- ewoud
- Date:
- Fri Oct 23 09:21:17 2015 +0000
- Revision:
- 9:7da462802e5f
- Parent:
- 7:8ce86cc65126
- Child:
- 10:9f27d04c6183
updated calibration for four muscles
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ewoud | 0:b5f7b64b0fe4 | 1 | #include "biquadFilter.h" |
ewoud | 0:b5f7b64b0fe4 | 2 | #include <cmath> |
ewoud | 0:b5f7b64b0fe4 | 3 | |
ewoud | 0:b5f7b64b0fe4 | 4 | |
mganseij | 4:963e903c2236 | 5 | const int Fs = 200; // sampling frequency |
mganseij | 3:0662d78d9092 | 6 | const double low_b1 = 0.000944691843840; //filter coefficients - second order butterworth filters at 2 hz low and 25 hz high, coefficents based on Fs of 512. |
mganseij | 3:0662d78d9092 | 7 | const double low_b2 = 0.001889383687680; |
mganseij | 3:0662d78d9092 | 8 | const double low_b3 = 0.000944691843840; |
mganseij | 3:0662d78d9092 | 9 | const double low_a2 = -1.911197067426073; // a1 is normalized to 1 |
mganseij | 3:0662d78d9092 | 10 | const double low_a3 = 0.914975834801434; |
mganseij | 3:0662d78d9092 | 11 | const double high_b1 = 0.569035593728849; |
mganseij | 3:0662d78d9092 | 12 | const double high_b2 = -1.138071187457699; |
mganseij | 3:0662d78d9092 | 13 | const double high_b3 = 0.569035593728849; |
mganseij | 3:0662d78d9092 | 14 | const double high_a2 = -0.942809041582063; // a1 is normalized to 1 |
mganseij | 3:0662d78d9092 | 15 | const double high_a3 = 0.333333333333333; |
ewoud | 0:b5f7b64b0fe4 | 16 | biquadFilter highpass1(high_a2, high_a3, high_b1, high_b2, high_b3); // different objects for different inputs, otherwise the v1 and v2 variables get fucked up |
ewoud | 0:b5f7b64b0fe4 | 17 | biquadFilter highpass2(high_a2, high_a3, high_b1, high_b2, high_b3); |
ewoud | 0:b5f7b64b0fe4 | 18 | biquadFilter highpass3(high_a2, high_a3, high_b1, high_b2, high_b3); |
ewoud | 0:b5f7b64b0fe4 | 19 | biquadFilter highpass4(high_a2, high_a3, high_b1, high_b2, high_b3); |
ewoud | 0:b5f7b64b0fe4 | 20 | biquadFilter lowpass1(low_a2, low_a3, low_b1, low_b2, low_b3); |
ewoud | 0:b5f7b64b0fe4 | 21 | biquadFilter lowpass2(low_a2, low_a3, low_b1, low_b2, low_b3); |
ewoud | 0:b5f7b64b0fe4 | 22 | biquadFilter lowpass3(low_a2, low_a3, low_b1, low_b2, low_b3); |
ewoud | 0:b5f7b64b0fe4 | 23 | biquadFilter lowpass4(low_a2, low_a3, low_b1, low_b2, low_b3); |
ewoud | 0:b5f7b64b0fe4 | 24 | |
ewoud | 0:b5f7b64b0fe4 | 25 | AnalogIn input1(A0); // declaring the 4 inputs |
ewoud | 0:b5f7b64b0fe4 | 26 | AnalogIn input2(A1); |
ewoud | 0:b5f7b64b0fe4 | 27 | AnalogIn input3(A2); |
ewoud | 0:b5f7b64b0fe4 | 28 | AnalogIn input4(A3); |
ewoud | 0:b5f7b64b0fe4 | 29 | double u1; double y1; // declaring the input variables |
ewoud | 0:b5f7b64b0fe4 | 30 | double u2; double y2; |
ewoud | 0:b5f7b64b0fe4 | 31 | double u3; double y3; |
ewoud | 0:b5f7b64b0fe4 | 32 | double u4; double y4; |
ewoud | 0:b5f7b64b0fe4 | 33 | |
ewoud | 0:b5f7b64b0fe4 | 34 | Ticker T1; |
ewoud | 0:b5f7b64b0fe4 | 35 | volatile bool sample_go; |
mganseij | 5:7873900f62da | 36 | volatile bool calibrate_go; |
mganseij | 3:0662d78d9092 | 37 | |
ewoud | 0:b5f7b64b0fe4 | 38 | InterruptIn cali_button(PTA4); // initialize interrupt button for calibration stuff |
mganseij | 1:b73e3dc74d7c | 39 | double cali_fact1 = 8; |
mganseij | 1:b73e3dc74d7c | 40 | double cali_fact2 = 8; // calibration factor to normalize filter output to a scale of 0 - 1 |
ewoud | 9:7da462802e5f | 41 | double cali_fact3 = 8; |
ewoud | 9:7da462802e5f | 42 | double cali_fact4 = 8; |
ewoud | 0:b5f7b64b0fe4 | 43 | |
ewoud | 0:b5f7b64b0fe4 | 44 | void sample_filter() |
ewoud | 0:b5f7b64b0fe4 | 45 | { |
ewoud | 0:b5f7b64b0fe4 | 46 | u1 = input1; u2 = input2; u3 = input3; u4 = input4; // sample |
ewoud | 0:b5f7b64b0fe4 | 47 | y1 = highpass1.step(u1); y2 = highpass2.step(u2); y3 = highpass3.step(u3); y4 = highpass4.step(u4); // filter order is: high-pass --> rectify --> low-pass |
ewoud | 0:b5f7b64b0fe4 | 48 | y1 = fabs(y1); y2 = fabs(y2); y3 = fabs(y3); y4 = fabs(y4); |
ewoud | 2:84ff5b0f5406 | 49 | y1 = lowpass1.step(y1)*cali_fact1; y2 = lowpass2.step(y2)*cali_fact2; y3 = lowpass3.step(y3)*cali_fact1; y4 = lowpass4.step(y4)*cali_fact1; // roughly normalize to a scale of 0 - 1, where 0 is minimum and 1 is roughly the maximum output of dennis. |
ewoud | 0:b5f7b64b0fe4 | 50 | } |
mganseij | 5:7873900f62da | 51 | |
mganseij | 5:7873900f62da | 52 | |
mganseij | 5:7873900f62da | 53 | void calibratego() |
mganseij | 5:7873900f62da | 54 | { |
mganseij | 5:7873900f62da | 55 | calibrate_go = 1; |
mganseij | 5:7873900f62da | 56 | } |
mganseij | 5:7873900f62da | 57 | |
ewoud | 0:b5f7b64b0fe4 | 58 | void samplego() // ticker function, set flag to true every sample interval |
ewoud | 0:b5f7b64b0fe4 | 59 | { |
ewoud | 0:b5f7b64b0fe4 | 60 | sample_go = 1; |
ewoud | 0:b5f7b64b0fe4 | 61 | } |
ewoud | 0:b5f7b64b0fe4 | 62 | |
ewoud | 0:b5f7b64b0fe4 | 63 | void calibrate() // function to calibrate the emg signals from the user. It takes 5 seconds of measurements of maximum output, then takes the max and normalizes to that. |
ewoud | 0:b5f7b64b0fe4 | 64 | { |
ewoud | 6:49056e5ea42e | 65 | outofboundsled=0; |
ewoud | 9:7da462802e5f | 66 | cali_fact1 = 1; cali_fact2 = 1; cali_fact3 = 1; cali_fact4 = 1; |
ewoud | 9:7da462802e5f | 67 | double cali_max1 = 0; double cali_max2 = 0; double cali_max3 = 0; double cali_max4 = 0; |
mganseij | 4:963e903c2236 | 68 | for(int i = 0; i < 5*Fs; i++) |
ewoud | 0:b5f7b64b0fe4 | 69 | { |
ewoud | 0:b5f7b64b0fe4 | 70 | sample_filter(); |
mganseij | 4:963e903c2236 | 71 | if(y1 > cali_max1) |
mganseij | 4:963e903c2236 | 72 | { |
mganseij | 4:963e903c2236 | 73 | cali_max1 = y1; |
mganseij | 4:963e903c2236 | 74 | } |
mganseij | 7:8ce86cc65126 | 75 | wait(1/(float)Fs); |
mganseij | 7:8ce86cc65126 | 76 | } |
ewoud | 9:7da462802e5f | 77 | outofboundsled=1; |
mganseij | 7:8ce86cc65126 | 78 | wait(1); // seperated calibration of muscles, including a wait period of a second between the calibration of each thing. |
ewoud | 9:7da462802e5f | 79 | outofboundsled=0; |
mganseij | 7:8ce86cc65126 | 80 | for(int i = 0; i < 5*Fs; i++) |
mganseij | 7:8ce86cc65126 | 81 | { |
mganseij | 7:8ce86cc65126 | 82 | sample_filter(); |
mganseij | 4:963e903c2236 | 83 | if(y2 > cali_max2) |
mganseij | 4:963e903c2236 | 84 | { |
mganseij | 4:963e903c2236 | 85 | cali_max2 = y2; |
mganseij | 4:963e903c2236 | 86 | } |
ewoud | 6:49056e5ea42e | 87 | wait(1/(float)Fs); |
mganseij | 4:963e903c2236 | 88 | } |
ewoud | 9:7da462802e5f | 89 | outofboundsled=1; |
ewoud | 9:7da462802e5f | 90 | wait(1); |
ewoud | 9:7da462802e5f | 91 | outofboundsled=0; |
ewoud | 9:7da462802e5f | 92 | for(int i = 0; i < 5*Fs; i++) |
ewoud | 9:7da462802e5f | 93 | { |
ewoud | 9:7da462802e5f | 94 | sample_filter(); |
ewoud | 9:7da462802e5f | 95 | if(y3 > cali_max3) |
ewoud | 9:7da462802e5f | 96 | { |
ewoud | 9:7da462802e5f | 97 | cali_max3 = y3; |
ewoud | 9:7da462802e5f | 98 | } |
ewoud | 9:7da462802e5f | 99 | wait(1/(float)Fs); |
ewoud | 9:7da462802e5f | 100 | } |
ewoud | 9:7da462802e5f | 101 | outofboundsled=1; |
ewoud | 9:7da462802e5f | 102 | wait(1); |
ewoud | 9:7da462802e5f | 103 | outofboundsled=0; |
ewoud | 9:7da462802e5f | 104 | for(int i = 0; i < 5*Fs; i++) |
ewoud | 9:7da462802e5f | 105 | { |
ewoud | 9:7da462802e5f | 106 | sample_filter(); |
ewoud | 9:7da462802e5f | 107 | if(y4 > cali_max4) |
ewoud | 9:7da462802e5f | 108 | { |
ewoud | 9:7da462802e5f | 109 | cali_max4 = y4; |
ewoud | 9:7da462802e5f | 110 | } |
ewoud | 9:7da462802e5f | 111 | wait(1/(float)Fs); |
ewoud | 9:7da462802e5f | 112 | } |
mganseij | 4:963e903c2236 | 113 | cali_fact1 = 1.0/cali_max1; |
mganseij | 4:963e903c2236 | 114 | cali_fact2 = 1.0/cali_max2; |
ewoud | 9:7da462802e5f | 115 | cali_fact3 = 1.0/cali_max3; |
ewoud | 9:7da462802e5f | 116 | cali_fact4 = 1.0/cali_max4; |
mganseij | 5:7873900f62da | 117 | calibrate_go = 0; |
ewoud | 6:49056e5ea42e | 118 | outofboundsled=1; |
ewoud | 0:b5f7b64b0fe4 | 119 | } |
ewoud | 0:b5f7b64b0fe4 | 120 | |
ewoud | 0:b5f7b64b0fe4 | 121 | /* |
ewoud | 0:b5f7b64b0fe4 | 122 | int main() |
ewoud | 0:b5f7b64b0fe4 | 123 | { |
ewoud | 0:b5f7b64b0fe4 | 124 | T1.attach(&samplego, (float)1/Fs); |
ewoud | 0:b5f7b64b0fe4 | 125 | cali_button.rise(&calibrate); |
ewoud | 0:b5f7b64b0fe4 | 126 | while(1) |
ewoud | 0:b5f7b64b0fe4 | 127 | { |
ewoud | 0:b5f7b64b0fe4 | 128 | if(sample_go) |
ewoud | 0:b5f7b64b0fe4 | 129 | { |
ewoud | 0:b5f7b64b0fe4 | 130 | sample_filter(); |
ewoud | 0:b5f7b64b0fe4 | 131 | sample_go = 0; |
ewoud | 0:b5f7b64b0fe4 | 132 | } |
ewoud | 0:b5f7b64b0fe4 | 133 | } // while end |
ewoud | 0:b5f7b64b0fe4 | 134 | } // main end |
ewoud | 0:b5f7b64b0fe4 | 135 | */ |