Test code to calibrate EMG - MVC measurement

Dependencies:   HIDScope MODSERIAL mbed

Fork of emgCalibration by Martijn Kern

Committer:
Vigilance88
Date:
Fri Oct 16 12:14:39 2015 +0000
Revision:
5:d7ee4a5612af
Parent:
4:329e1022cbd3
fixed serial com

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Paashaas 0:d8312eea7c50 1 #include "mbed.h"
Paashaas 0:d8312eea7c50 2 #include "HIDScope.h"
Vigilance88 1:93d79d6e96bc 3 #include "MODSERIAL.h"
Paashaas 0:d8312eea7c50 4
Vigilance88 1:93d79d6e96bc 5 #define SAMPLING_RATE 0.002
Vigilance88 1:93d79d6e96bc 6
Vigilance88 1:93d79d6e96bc 7 MODSERIAL pc(USBTX,USBRX);
Vigilance88 1:93d79d6e96bc 8 AnalogIn emg1(A0); // onderste board
Paashaas 0:d8312eea7c50 9 AnalogIn emg2(A1); // 2e board
Paashaas 0:d8312eea7c50 10 AnalogIn emg3(A2); // 3e board
Paashaas 0:d8312eea7c50 11 AnalogIn emg4(A3); // bovenste board
Paashaas 0:d8312eea7c50 12
Vigilance88 5:d7ee4a5612af 13 Ticker sample_timer; // naam van de emg-ticker
Vigilance88 4:329e1022cbd3 14 DigitalOut red(LED_RED);
Vigilance88 4:329e1022cbd3 15 DigitalOut green(LED_GREEN);
Vigilance88 4:329e1022cbd3 16 DigitalOut blue(LED_BLUE);
Vigilance88 4:329e1022cbd3 17
Vigilance88 5:d7ee4a5612af 18 int const window=150; //30 samples
Vigilance88 5:d7ee4a5612af 19 int i=0; //buffer index
Vigilance88 5:d7ee4a5612af 20 double bicepsbuffer [window];
Vigilance88 1:93d79d6e96bc 21
Vigilance88 4:329e1022cbd3 22 //HIDScope scope(4); // aantal kanalen voor je HIDScope
Paashaas 0:d8312eea7c50 23
Vigilance88 5:d7ee4a5612af 24 double avg1=0;
Vigilance88 3:3981bbe6d7b8 25 int muscle;
Vigilance88 3:3981bbe6d7b8 26 double tijd;
Vigilance88 3:3981bbe6d7b8 27 double y5;
Vigilance88 3:3981bbe6d7b8 28
Vigilance88 3:3981bbe6d7b8 29
Paashaas 0:d8312eea7c50 30 //highpass filter 20 Hz
Paashaas 0:d8312eea7c50 31 const double numhigh_1 = 0.956543225556877;
Paashaas 0:d8312eea7c50 32 const double numhigh_2 = -1.91308645113754;
Paashaas 0:d8312eea7c50 33 const double numhigh_3 = 0.956543225556877;
Paashaas 0:d8312eea7c50 34 const double denhigh_2 = -1.91197067426073;
Paashaas 0:d8312eea7c50 35 const double denhigh_3 = 0.9149758348014341;
Paashaas 0:d8312eea7c50 36
Paashaas 0:d8312eea7c50 37 //biquad 1
Vigilance88 1:93d79d6e96bc 38 const double notch1gain = 1.000000;
Vigilance88 1:93d79d6e96bc 39 const double notch1_b0 = 1;
Vigilance88 1:93d79d6e96bc 40 const double notch1_b1 = -1.61816176147 * notch1gain;
Vigilance88 1:93d79d6e96bc 41 const double notch1_b2 = 1.00000000000 * notch1gain;
Vigilance88 1:93d79d6e96bc 42 const double notch1_a1 = -1.58071559235 * notch1gain;
Vigilance88 1:93d79d6e96bc 43 const double notch1_a2 = 0.97319685401 * notch1gain;
Vigilance88 1:93d79d6e96bc 44
Paashaas 0:d8312eea7c50 45 //biquad 2
Vigilance88 1:93d79d6e96bc 46 const double notch2gain = 0.973674;
Vigilance88 1:93d79d6e96bc 47 const double notch2_b0 = 1 * notch2gain;
Vigilance88 1:93d79d6e96bc 48 const double notch2_b1 = -1.61816176147 * notch2gain;
Vigilance88 1:93d79d6e96bc 49 const double notch2_b2 = 1.00000000000 * notch2gain;
Vigilance88 1:93d79d6e96bc 50 const double notch2_a1 = -1.61244708381 * notch2gain;
Vigilance88 1:93d79d6e96bc 51 const double notch2_a2 = 0.97415116257 * notch2gain;
Paashaas 0:d8312eea7c50 52
Paashaas 0:d8312eea7c50 53 //lowpass filter 7 Hz - envelop
Paashaas 0:d8312eea7c50 54 const double numlow_1 = 0.000119046743110057;
Paashaas 0:d8312eea7c50 55 const double numlow_2 = 0.000238093486220118;
Paashaas 0:d8312eea7c50 56 const double numlow_3 = 0.000119046743110057;
Paashaas 0:d8312eea7c50 57 const double denlow_2 = -1.968902268531908;
Paashaas 0:d8312eea7c50 58 const double denlow_3 = 0.9693784555043481;
Paashaas 0:d8312eea7c50 59
Vigilance88 1:93d79d6e96bc 60 //EMG variables
Vigilance88 1:93d79d6e96bc 61 double emg_biceps; double biceps_power; double bicepsMVC = 0;
Vigilance88 1:93d79d6e96bc 62 double emg_triceps; double triceps_power; double tricepsMVC = 0;
Vigilance88 1:93d79d6e96bc 63 double emg_flexor; double flexor_power; double flexorMVC = 0;
Vigilance88 1:93d79d6e96bc 64 double emg_extens; double extens_power; double extensMVC = 0;
Vigilance88 1:93d79d6e96bc 65
Vigilance88 1:93d79d6e96bc 66
Paashaas 0:d8312eea7c50 67 // storage variables definieren
Paashaas 0:d8312eea7c50 68 double f1_v1 = 0, f1_v2 = 0, f2_v1 = 0, f2_v2 = 0, f3_v1 = 0, f3_v2 = 0, f4_v1 = 0, f4_v2 = 0;
Paashaas 0:d8312eea7c50 69
Paashaas 0:d8312eea7c50 70 double biquad( double u, double &v1, double &v2, const double a1, const double a2, const double b0, const double b1, const double b2)
Paashaas 0:d8312eea7c50 71
Paashaas 0:d8312eea7c50 72 {
Paashaas 0:d8312eea7c50 73 double v = u - a1*v1 - a2*v2;
Paashaas 0:d8312eea7c50 74 double y = b0*v + b1*v1 + b2*v2;
Paashaas 0:d8312eea7c50 75 v2=v1;
Paashaas 0:d8312eea7c50 76 v1=v;
Paashaas 0:d8312eea7c50 77 return y;
Paashaas 0:d8312eea7c50 78 }
Vigilance88 1:93d79d6e96bc 79
Vigilance88 1:93d79d6e96bc 80
Vigilance88 1:93d79d6e96bc 81
Vigilance88 1:93d79d6e96bc 82 void sample_filter()
Vigilance88 1:93d79d6e96bc 83 {
Paashaas 0:d8312eea7c50 84
Paashaas 0:d8312eea7c50 85 // double u1=..., u2...;
Paashaas 0:d8312eea7c50 86 double u1 = emg1.read();
Paashaas 0:d8312eea7c50 87 double y1 = biquad(u1, f1_v1, f1_v2, denhigh_2, denhigh_3, numhigh_1, numhigh_2, numhigh_3);
Vigilance88 1:93d79d6e96bc 88 double y2 = biquad(y1, f2_v1, f2_v2, notch1_a1, notch1_a2, notch1_b0, notch1_b1, notch1_b2);
Vigilance88 1:93d79d6e96bc 89 double y3 = biquad(y2, f3_v1, f3_v2, notch2_a1, notch2_a2, notch2_b0, notch2_b1, notch2_b2);
Vigilance88 1:93d79d6e96bc 90 double y4 = abs(y3);
Vigilance88 1:93d79d6e96bc 91 double y5 = biquad(y4, f4_v1, f4_v2, denlow_2, denlow_3, numlow_1, numlow_2, numlow_3);
Vigilance88 1:93d79d6e96bc 92
Vigilance88 1:93d79d6e96bc 93 biceps_power=y5;
Vigilance88 4:329e1022cbd3 94 //scope.set(0,u1);
Vigilance88 4:329e1022cbd3 95 //scope.set(1,y4);
Vigilance88 4:329e1022cbd3 96 //scope.set(2,biceps_power);
Vigilance88 4:329e1022cbd3 97 //scope.send();
Vigilance88 1:93d79d6e96bc 98
Vigilance88 1:93d79d6e96bc 99 }
Vigilance88 1:93d79d6e96bc 100
Vigilance88 1:93d79d6e96bc 101
Vigilance88 1:93d79d6e96bc 102 //Start sampling
Vigilance88 1:93d79d6e96bc 103 void start_sampling(void)
Vigilance88 1:93d79d6e96bc 104 {
Vigilance88 1:93d79d6e96bc 105 sample_timer.attach(&sample_filter,0.002); //500 Hz EMG
Vigilance88 5:d7ee4a5612af 106 blue=0; green=0;
Vigilance88 5:d7ee4a5612af 107 pc.printf("||- started sampling -|| \r\n");
Vigilance88 1:93d79d6e96bc 108 }
Vigilance88 1:93d79d6e96bc 109
Vigilance88 1:93d79d6e96bc 110 //stop sampling
Vigilance88 1:93d79d6e96bc 111 void stop_sampling(void)
Vigilance88 1:93d79d6e96bc 112 {
Vigilance88 1:93d79d6e96bc 113 sample_timer.detach();
Vigilance88 5:d7ee4a5612af 114 blue=1; green=1;
Vigilance88 5:d7ee4a5612af 115 pc.printf("||- stopped sampling -|| \r\n");
Paashaas 0:d8312eea7c50 116 }
Vigilance88 1:93d79d6e96bc 117
Vigilance88 2:174b10062c61 118 void calibrate_emg()
Vigilance88 1:93d79d6e96bc 119 {
Vigilance88 1:93d79d6e96bc 120 //double sampletime=0;
Vigilance88 1:93d79d6e96bc 121 //sampletime=+SAMPLE_RATE;
Vigilance88 1:93d79d6e96bc 122 //
Vigilance88 1:93d79d6e96bc 123 // if(sampletime<5)
Vigilance88 1:93d79d6e96bc 124 //int muscle=1;
Vigilance88 1:93d79d6e96bc 125 //for(int index=0; index<2500;index++){ //measure 5 seconds@500hz = 2500 samples
Vigilance88 1:93d79d6e96bc 126
Vigilance88 3:3981bbe6d7b8 127 if(muscle==1){
Vigilance88 1:93d79d6e96bc 128
Vigilance88 1:93d79d6e96bc 129 if(biceps_power>bicepsMVC){
Vigilance88 1:93d79d6e96bc 130 printf("+ ");
Vigilance88 1:93d79d6e96bc 131 bicepsMVC=biceps_power;
Vigilance88 1:93d79d6e96bc 132 }
Vigilance88 1:93d79d6e96bc 133 else
Vigilance88 1:93d79d6e96bc 134 printf("- ");
Vigilance88 2:174b10062c61 135 }
Vigilance88 1:93d79d6e96bc 136
Vigilance88 1:93d79d6e96bc 137 if(muscle==2){
Vigilance88 1:93d79d6e96bc 138
Vigilance88 1:93d79d6e96bc 139 if(triceps_power>tricepsMVC){
Vigilance88 1:93d79d6e96bc 140 tricepsMVC=triceps_power;
Vigilance88 1:93d79d6e96bc 141 }
Vigilance88 1:93d79d6e96bc 142 }
Vigilance88 1:93d79d6e96bc 143
Vigilance88 1:93d79d6e96bc 144 if(muscle==3){
Vigilance88 1:93d79d6e96bc 145
Vigilance88 1:93d79d6e96bc 146 if(flexor_power>flexorMVC){
Vigilance88 1:93d79d6e96bc 147 flexorMVC=flexor_power;
Vigilance88 1:93d79d6e96bc 148 }
Vigilance88 1:93d79d6e96bc 149 }
Vigilance88 1:93d79d6e96bc 150
Vigilance88 1:93d79d6e96bc 151 if(muscle==4){
Vigilance88 1:93d79d6e96bc 152
Vigilance88 1:93d79d6e96bc 153 if(extens_power>extensMVC){
Vigilance88 1:93d79d6e96bc 154 extensMVC=extens_power;
Vigilance88 1:93d79d6e96bc 155 }
Vigilance88 1:93d79d6e96bc 156 }
Vigilance88 1:93d79d6e96bc 157
Vigilance88 1:93d79d6e96bc 158 //}
Vigilance88 1:93d79d6e96bc 159 tijd = tijd + 0.002;
Paashaas 0:d8312eea7c50 160
Vigilance88 1:93d79d6e96bc 161
Vigilance88 1:93d79d6e96bc 162
Vigilance88 1:93d79d6e96bc 163 }
Vigilance88 1:93d79d6e96bc 164
Paashaas 0:d8312eea7c50 165 int main()
Paashaas 0:d8312eea7c50 166 {
Vigilance88 4:329e1022cbd3 167 pc.baud(115200);
Vigilance88 5:d7ee4a5612af 168 red=1; green=1; blue=1;
Vigilance88 1:93d79d6e96bc 169 Ticker timer;
Vigilance88 2:174b10062c61 170
Vigilance88 5:d7ee4a5612af 171 pc.printf("|-- Robot Started --| \r\n");
Vigilance88 3:3981bbe6d7b8 172 pc.printf("Testcode calibration \r\n");
Vigilance88 1:93d79d6e96bc 173 wait(1);
Vigilance88 3:3981bbe6d7b8 174 pc.printf("+ means current sample is higher than stored MVC\r\n");
Vigilance88 3:3981bbe6d7b8 175 pc.printf("- means current sample is lower than stored MVC\r\n");
Vigilance88 1:93d79d6e96bc 176 wait(3);
Vigilance88 5:d7ee4a5612af 177 pc.printf(" Biceps is first. "); wait(1);
Vigilance88 3:3981bbe6d7b8 178 pc.printf(" Press any key to begin... "); wait(1);
Vigilance88 3:3981bbe6d7b8 179 char input;
Vigilance88 3:3981bbe6d7b8 180 input=pc.getc();
Vigilance88 5:d7ee4a5612af 181 pc.putc(input);
Vigilance88 3:3981bbe6d7b8 182 pc.printf(" \r\n Starting in 3... \r\n"); wait(1);
Vigilance88 3:3981bbe6d7b8 183 pc.printf(" \r\n Starting in 2... \r\n"); wait(1);
Vigilance88 3:3981bbe6d7b8 184 pc.printf(" \r\n Starting in 1... \r\n"); wait(1);
Vigilance88 1:93d79d6e96bc 185
Vigilance88 1:93d79d6e96bc 186 start_sampling();
Vigilance88 2:174b10062c61 187 muscle=1;
Vigilance88 1:93d79d6e96bc 188 timer.attach(&calibrate_emg,0.002);
Vigilance88 1:93d79d6e96bc 189 wait(5);
Vigilance88 1:93d79d6e96bc 190 timer.detach();
Vigilance88 5:d7ee4a5612af 191 pc.printf("\r\n MVC = %f \r\n",bicepsMVC);
Vigilance88 1:93d79d6e96bc 192
Vigilance88 3:3981bbe6d7b8 193 pc.printf("Calibrate_emg() exited \r\n");
Vigilance88 3:3981bbe6d7b8 194 pc.printf("Measured time: %f seconds \r\n",tijd);
Vigilance88 5:d7ee4a5612af 195 tijd=0;
Vigilance88 1:93d79d6e96bc 196
Vigilance88 5:d7ee4a5612af 197 // Triceps:
Vigilance88 5:d7ee4a5612af 198 pc.printf(" Triceps is next "); wait(1);
Vigilance88 5:d7ee4a5612af 199 pc.printf(" Press any key to begin... "); wait(1);
Vigilance88 5:d7ee4a5612af 200 input=pc.getc();
Vigilance88 5:d7ee4a5612af 201 pc.putc(input);
Vigilance88 5:d7ee4a5612af 202 pc.printf(" \r\n Starting in 3... \r\n"); wait(1);
Vigilance88 5:d7ee4a5612af 203 pc.printf(" \r\n Starting in 2... \r\n"); wait(1);
Vigilance88 5:d7ee4a5612af 204 pc.printf(" \r\n Starting in 1... \r\n"); wait(1);
Vigilance88 5:d7ee4a5612af 205 start_sampling();
Vigilance88 5:d7ee4a5612af 206 muscle=1;
Vigilance88 5:d7ee4a5612af 207 timer.attach(&calibrate_emg,0.002);
Vigilance88 5:d7ee4a5612af 208 wait(5);
Vigilance88 5:d7ee4a5612af 209 timer.detach();
Vigilance88 5:d7ee4a5612af 210 pc.printf("\r\n Triceps MVC = %f \r\n",tricepsMVC);
Vigilance88 1:93d79d6e96bc 211
Vigilance88 5:d7ee4a5612af 212 pc.printf("Calibrate_emg() exited \r\n");
Vigilance88 5:d7ee4a5612af 213 pc.printf("Measured time: %f seconds \r\n",tijd);
Vigilance88 5:d7ee4a5612af 214 tijd=0;
Vigilance88 5:d7ee4a5612af 215
Vigilance88 5:d7ee4a5612af 216 //Flexor:
Vigilance88 5:d7ee4a5612af 217
Vigilance88 5:d7ee4a5612af 218 //Extensor:
Vigilance88 5:d7ee4a5612af 219
Vigilance88 5:d7ee4a5612af 220 stop_sampling();
Paashaas 0:d8312eea7c50 221 while (true){
Vigilance88 1:93d79d6e96bc 222
Vigilance88 1:93d79d6e96bc 223 wait(1);
Paashaas 0:d8312eea7c50 224 }
Paashaas 0:d8312eea7c50 225 }