Numero Uno / EMG

Dependents:   PID_VelocityExample TheProgram Passief_stuurprogramma Actief_stuurprogramma

Committer:
ewoud
Date:
Tue Oct 27 17:17:11 2015 +0000
Revision:
11:deb12a6f646e
Parent:
10:9f27d04c6183
Child:
12:2eb227a21a93
changed user LED working

Who changed what in which revision?

UserRevisionLine numberNew 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 11:deb12a6f646e 65 statusled=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;
ewoud 10:9f27d04c6183 68 lcd.cls();
ewoud 10:9f27d04c6183 69 lcd.printf("calibrating...\nFlex muscle Y1");
mganseij 4:963e903c2236 70 for(int i = 0; i < 5*Fs; i++)
ewoud 0:b5f7b64b0fe4 71 {
ewoud 0:b5f7b64b0fe4 72 sample_filter();
mganseij 4:963e903c2236 73 if(y1 > cali_max1)
mganseij 4:963e903c2236 74 {
mganseij 4:963e903c2236 75 cali_max1 = y1;
mganseij 4:963e903c2236 76 }
mganseij 7:8ce86cc65126 77 wait(1/(float)Fs);
mganseij 7:8ce86cc65126 78 }
ewoud 11:deb12a6f646e 79 statusled=1;
mganseij 7:8ce86cc65126 80 wait(1); // seperated calibration of muscles, including a wait period of a second between the calibration of each thing.
ewoud 11:deb12a6f646e 81 statusled=0;
ewoud 10:9f27d04c6183 82 lcd.cls();
ewoud 10:9f27d04c6183 83 lcd.printf("calibrating...\nFlex muscle Y2");
mganseij 7:8ce86cc65126 84 for(int i = 0; i < 5*Fs; i++)
mganseij 7:8ce86cc65126 85 {
mganseij 7:8ce86cc65126 86 sample_filter();
mganseij 4:963e903c2236 87 if(y2 > cali_max2)
mganseij 4:963e903c2236 88 {
mganseij 4:963e903c2236 89 cali_max2 = y2;
mganseij 4:963e903c2236 90 }
ewoud 6:49056e5ea42e 91 wait(1/(float)Fs);
mganseij 4:963e903c2236 92 }
ewoud 11:deb12a6f646e 93 statusled=1;
ewoud 9:7da462802e5f 94 wait(1);
ewoud 11:deb12a6f646e 95 statusled=0;
ewoud 10:9f27d04c6183 96 lcd.cls();
ewoud 10:9f27d04c6183 97 lcd.printf("calibrating...\nFlex muscle Y3");
ewoud 9:7da462802e5f 98 for(int i = 0; i < 5*Fs; i++)
ewoud 9:7da462802e5f 99 {
ewoud 9:7da462802e5f 100 sample_filter();
ewoud 9:7da462802e5f 101 if(y3 > cali_max3)
ewoud 9:7da462802e5f 102 {
ewoud 9:7da462802e5f 103 cali_max3 = y3;
ewoud 9:7da462802e5f 104 }
ewoud 9:7da462802e5f 105 wait(1/(float)Fs);
ewoud 9:7da462802e5f 106 }
ewoud 11:deb12a6f646e 107 statusled=1;
ewoud 9:7da462802e5f 108 wait(1);
ewoud 11:deb12a6f646e 109 statusled=0;
ewoud 10:9f27d04c6183 110 lcd.cls();
ewoud 10:9f27d04c6183 111 lcd.printf("calibrating...\nFlex muscle Y4");
ewoud 9:7da462802e5f 112 for(int i = 0; i < 5*Fs; i++)
ewoud 9:7da462802e5f 113 {
ewoud 9:7da462802e5f 114 sample_filter();
ewoud 9:7da462802e5f 115 if(y4 > cali_max4)
ewoud 9:7da462802e5f 116 {
ewoud 9:7da462802e5f 117 cali_max4 = y4;
ewoud 9:7da462802e5f 118 }
ewoud 9:7da462802e5f 119 wait(1/(float)Fs);
ewoud 9:7da462802e5f 120 }
mganseij 4:963e903c2236 121 cali_fact1 = 1.0/cali_max1;
mganseij 4:963e903c2236 122 cali_fact2 = 1.0/cali_max2;
ewoud 9:7da462802e5f 123 cali_fact3 = 1.0/cali_max3;
ewoud 9:7da462802e5f 124 cali_fact4 = 1.0/cali_max4;
mganseij 5:7873900f62da 125 calibrate_go = 0;
ewoud 11:deb12a6f646e 126 statusled=1;
ewoud 11:deb12a6f646e 127 calibrated=true;
ewoud 0:b5f7b64b0fe4 128 }
ewoud 0:b5f7b64b0fe4 129
ewoud 0:b5f7b64b0fe4 130 /*
ewoud 0:b5f7b64b0fe4 131 int main()
ewoud 0:b5f7b64b0fe4 132 {
ewoud 0:b5f7b64b0fe4 133 T1.attach(&samplego, (float)1/Fs);
ewoud 0:b5f7b64b0fe4 134 cali_button.rise(&calibrate);
ewoud 0:b5f7b64b0fe4 135 while(1)
ewoud 0:b5f7b64b0fe4 136 {
ewoud 0:b5f7b64b0fe4 137 if(sample_go)
ewoud 0:b5f7b64b0fe4 138 {
ewoud 0:b5f7b64b0fe4 139 sample_filter();
ewoud 0:b5f7b64b0fe4 140 sample_go = 0;
ewoud 0:b5f7b64b0fe4 141 }
ewoud 0:b5f7b64b0fe4 142 } // while end
ewoud 0:b5f7b64b0fe4 143 } // main end
ewoud 0:b5f7b64b0fe4 144 */