control for robotic arm that can play chess using a granular gripper

Dependencies:   Encoder mbed HIDScope Servo MODSERIAL

Fork of chessRobot by a steenbeek

Committer:
annesteenbeek
Date:
Tue Oct 20 12:58:13 2015 +0200
Revision:
78:0cc7c64ba94c
Parent:
75:9995528bf8b7
Child:
80:8f030bd5dd15
started merging EMG

Who changed what in which revision?

UserRevisionLine numberNew contents of line
annesteenbeek 78:0cc7c64ba94c 1 #include "emg.h"
bjornnijhuis 75:9995528bf8b7 2 #include "filter_constants.h" // All constants for EMG processing
bjornnijhuis 75:9995528bf8b7 3 #include "mbed.h"
bjornnijhuis 75:9995528bf8b7 4
annesteenbeek 78:0cc7c64ba94c 5 #define enableLed
bjornnijhuis 75:9995528bf8b7 6 // Define objects
bjornnijhuis 75:9995528bf8b7 7 AnalogIn emg1(A0); // Analog input 1
bjornnijhuis 75:9995528bf8b7 8 AnalogIn emg2(A1); // Analog input 2
annesteenbeek 78:0cc7c64ba94c 9 #ifdef enableLEd
annesteenbeek 78:0cc7c64ba94c 10 DigitalOut ledred(LED_RED); // Red led
annesteenbeek 78:0cc7c64ba94c 11 DigitalOut ledgreen(LED_GREEN); // Green led
annesteenbeek 78:0cc7c64ba94c 12 DigitalOut ledblue(LED_BLUE); // Blue led
annesteenbeek 78:0cc7c64ba94c 13 #else
annesteenbeek 78:0cc7c64ba94c 14 DigitalOut ledred(d0); // Red led
annesteenbeek 78:0cc7c64ba94c 15 DigitalOut ledgreen(d0); // Green led
annesteenbeek 78:0cc7c64ba94c 16 DigitalOut ledblue(d0); // Blue led
annesteenbeek 78:0cc7c64ba94c 17 #endif
bjornnijhuis 75:9995528bf8b7 18 Ticker sample_tick; // Ticker for sampling
bjornnijhuis 75:9995528bf8b7 19 Ticker output; // Ticker for PC output
bjornnijhuis 75:9995528bf8b7 20 Timer normalizing_timer; // Timer for normalizing
bjornnijhuis 75:9995528bf8b7 21 Timer EMG_timer; // Timer for switch statement
bjornnijhuis 75:9995528bf8b7 22
bjornnijhuis 75:9995528bf8b7 23 // Define program constants
bjornnijhuis 75:9995528bf8b7 24 const int on = 0; // On-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 25 const int off = 1; // Off-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 26 const int sample = 0; // Constant for mode switching for program readability
bjornnijhuis 75:9995528bf8b7 27 const int normalize = 1; // Constant for mode switching for program readability
bjornnijhuis 75:9995528bf8b7 28
bjornnijhuis 75:9995528bf8b7 29
bjornnijhuis 75:9995528bf8b7 30 //**********************************************************************************************
bjornnijhuis 75:9995528bf8b7 31 bool mode = normalize; // Set program mode
bjornnijhuis 75:9995528bf8b7 32 //**********************************************************************************************
bjornnijhuis 75:9995528bf8b7 33
bjornnijhuis 75:9995528bf8b7 34 // Initialize sampling constants
bjornnijhuis 75:9995528bf8b7 35 double emg_val1 = 0, emg_val2 = 0, emg_filt_val1 = 0, emg_filt_val2 = 0;
bjornnijhuis 75:9995528bf8b7 36
bjornnijhuis 75:9995528bf8b7 37 // Initialize normalizing parameters
bjornnijhuis 75:9995528bf8b7 38 double max_vol_cont1 = 0; // Maximum voluntary contraction for scaling EMG1
bjornnijhuis 75:9995528bf8b7 39 double max_vol_cont2 = 0; // Maximum voluntary contraction for scaling EMG2
bjornnijhuis 75:9995528bf8b7 40 int channel = 1; // Channel for normalizing (EMG1 or EMG2)
bjornnijhuis 75:9995528bf8b7 41
bjornnijhuis 75:9995528bf8b7 42 // Initialize movement parameters
bjornnijhuis 75:9995528bf8b7 43 int DOF = 1; // Switch variable for controlled DOF: 1=x 2=y 3=z
bjornnijhuis 75:9995528bf8b7 44 bool pump = false; // Pump switch
bjornnijhuis 75:9995528bf8b7 45 bool thr_pass1 = false; // Processing threshold passed for signal 1?
bjornnijhuis 75:9995528bf8b7 46 bool thr_pass2 = false; // Processing threshold passed for signal 2?
bjornnijhuis 75:9995528bf8b7 47 double velocity = 0; // Forward velocity
bjornnijhuis 75:9995528bf8b7 48 double x_velocity = 0; // x component for velocity
bjornnijhuis 75:9995528bf8b7 49 double y_velocity = 0; // y component for velocity
bjornnijhuis 75:9995528bf8b7 50 double z_velocity = 0; // z component for velocity
bjornnijhuis 75:9995528bf8b7 51
bjornnijhuis 75:9995528bf8b7 52
bjornnijhuis 75:9995528bf8b7 53 // Reusable BiQuad filter
bjornnijhuis 75:9995528bf8b7 54 double biquad(double u, double &v1, double &v2, const double a1, const double a2, const double b0, const double b1, const double b2, const double gain)
bjornnijhuis 75:9995528bf8b7 55 {
bjornnijhuis 75:9995528bf8b7 56 double v = u - a1*v1-a2*v2;
bjornnijhuis 75:9995528bf8b7 57 double y = gain*(b0*v+b1*v1+b2*v2);
bjornnijhuis 75:9995528bf8b7 58 v2 = v1;
bjornnijhuis 75:9995528bf8b7 59 v1=v;
bjornnijhuis 75:9995528bf8b7 60 return y;
bjornnijhuis 75:9995528bf8b7 61 }
bjornnijhuis 75:9995528bf8b7 62
bjornnijhuis 75:9995528bf8b7 63
bjornnijhuis 75:9995528bf8b7 64 // Apply filters: applies all necesary filters and averaging methods to input signal value
bjornnijhuis 75:9995528bf8b7 65 double filtera(double emg_val)
bjornnijhuis 75:9995528bf8b7 66 {
bjornnijhuis 75:9995528bf8b7 67 // Filtering signal
bjornnijhuis 75:9995528bf8b7 68 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 69 emg_filt_val = biquad(emg_val,f11_v1,f11_v2,f11_a1,f11_a2,f11_b0,f11_b1,f11_b2,f11_gain); // Apply bandstop
bjornnijhuis 75:9995528bf8b7 70 emg_filt_val = biquad(emg_filt_val,f12_v1,f12_v2,f12_a1,f12_a2,f12_b0,f12_b1,f12_b2,f12_gain);
bjornnijhuis 75:9995528bf8b7 71 emg_filt_val = biquad(emg_filt_val,f13_v1,f13_v2,f13_a1,f13_a2,f13_b0,f13_b1,f13_b2,f13_gain);
bjornnijhuis 75:9995528bf8b7 72 emg_filt_val = biquad(emg_filt_val,f21_v1,f21_v2,f21_a1,f21_a2,f21_b0,f21_b1,f21_b2,f21_gain); // Apply highpass
bjornnijhuis 75:9995528bf8b7 73 emg_filt_val = biquad(emg_filt_val,f22_v1,f22_v2,f22_a1,f22_a2,f22_b0,f22_b1,f22_b2,f22_gain);
bjornnijhuis 75:9995528bf8b7 74 emg_filt_val = biquad(emg_filt_val,f23_v1,f23_v2,f23_a1,f23_a2,f23_b0,f23_b1,f23_b2,f23_gain);
bjornnijhuis 75:9995528bf8b7 75 emg_filt_val = biquad(emg_filt_val,f31_v1,f31_v2,f31_a1,f31_a2,f31_b0,f31_b1,f31_b2,f31_gain); // Apply lowpass
bjornnijhuis 75:9995528bf8b7 76 emg_filt_val = biquad(emg_filt_val,f32_v1,f32_v2,f32_a1,f32_a2,f32_b0,f32_b1,f32_b2,f32_gain);
bjornnijhuis 75:9995528bf8b7 77 emg_filt_val = biquad(emg_filt_val,f33_v1,f33_v2,f33_a1,f33_a2,f33_b0,f33_b1,f33_b2,f33_gain);
bjornnijhuis 75:9995528bf8b7 78
bjornnijhuis 75:9995528bf8b7 79 // Rectify signal
bjornnijhuis 75:9995528bf8b7 80 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 81
bjornnijhuis 75:9995528bf8b7 82 // Averaging signal
bjornnijhuis 75:9995528bf8b7 83 emg_filt_val = biquad(emg_filt_val,a11_v1,a11_v2,a11_a1,a11_a2,a11_b0,a11_b1,a11_b2,a11_gain); // Apply avg. lowpass
bjornnijhuis 75:9995528bf8b7 84 emg_filt_val = biquad(emg_filt_val,a12_v1,a12_v2,a12_a1,a12_a2,a12_b0,a12_b1,a12_b2,a12_gain);
bjornnijhuis 75:9995528bf8b7 85 emg_filt_val = biquad(emg_filt_val,a13_v1,a13_v2,a13_a1,a13_a2,a13_b0,a13_b1,a13_b2,a13_gain);
bjornnijhuis 75:9995528bf8b7 86
bjornnijhuis 75:9995528bf8b7 87 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 88 }
bjornnijhuis 75:9995528bf8b7 89 double filterb(double emg_val)
bjornnijhuis 75:9995528bf8b7 90 {
bjornnijhuis 75:9995528bf8b7 91 // Filtering signal
bjornnijhuis 75:9995528bf8b7 92 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 93 emg_filt_val = biquad(emg_val,f11_v1b,f11_v2b,f11_a1,f11_a2,f11_b0,f11_b1,f11_b2,f11_gain); // Apply bandstop
bjornnijhuis 75:9995528bf8b7 94 emg_filt_val = biquad(emg_filt_val,f12_v1b,f12_v2b,f12_a1,f12_a2,f12_b0,f12_b1,f12_b2,f12_gain);
bjornnijhuis 75:9995528bf8b7 95 emg_filt_val = biquad(emg_filt_val,f13_v1b,f13_v2b,f13_a1,f13_a2,f13_b0,f13_b1,f13_b2,f13_gain);
bjornnijhuis 75:9995528bf8b7 96 emg_filt_val = biquad(emg_filt_val,f21_v1b,f21_v2b,f21_a1,f21_a2,f21_b0,f21_b1,f21_b2,f21_gain); // Apply highpass
bjornnijhuis 75:9995528bf8b7 97 emg_filt_val = biquad(emg_filt_val,f22_v1b,f22_v2b,f22_a1,f22_a2,f22_b0,f22_b1,f22_b2,f22_gain);
bjornnijhuis 75:9995528bf8b7 98 emg_filt_val = biquad(emg_filt_val,f23_v1b,f23_v2b,f23_a1,f23_a2,f23_b0,f23_b1,f23_b2,f23_gain);
bjornnijhuis 75:9995528bf8b7 99 emg_filt_val = biquad(emg_filt_val,f31_v1b,f31_v2b,f31_a1,f31_a2,f31_b0,f31_b1,f31_b2,f31_gain); // Apply lowpass
bjornnijhuis 75:9995528bf8b7 100 emg_filt_val = biquad(emg_filt_val,f32_v1b,f32_v2b,f32_a1,f32_a2,f32_b0,f32_b1,f32_b2,f32_gain);
bjornnijhuis 75:9995528bf8b7 101 emg_filt_val = biquad(emg_filt_val,f33_v1b,f33_v2b,f33_a1,f33_a2,f33_b0,f33_b1,f33_b2,f33_gain);
bjornnijhuis 75:9995528bf8b7 102
bjornnijhuis 75:9995528bf8b7 103 // Rectify signal
bjornnijhuis 75:9995528bf8b7 104 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 105
bjornnijhuis 75:9995528bf8b7 106 // Averaging signal
bjornnijhuis 75:9995528bf8b7 107 emg_filt_val = biquad(emg_filt_val,a11_v1b,a11_v2b,a11_a1,a11_a2,a11_b0,a11_b1,a11_b2,a11_gain); // Apply avg. lowpass
bjornnijhuis 75:9995528bf8b7 108 emg_filt_val = biquad(emg_filt_val,a12_v1b,a12_v2b,a12_a1,a12_a2,a12_b0,a12_b1,a12_b2,a12_gain);
bjornnijhuis 75:9995528bf8b7 109 emg_filt_val = biquad(emg_filt_val,a13_v1b,a13_v2b,a13_a1,a13_a2,a13_b0,a13_b1,a13_b2,a13_gain);
bjornnijhuis 75:9995528bf8b7 110
bjornnijhuis 75:9995528bf8b7 111 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 112 }
bjornnijhuis 75:9995528bf8b7 113
bjornnijhuis 75:9995528bf8b7 114 // Create velocity steps: Converts continious velocity input signal to stepped output
bjornnijhuis 75:9995528bf8b7 115 double velocity_step(double velocity)
bjornnijhuis 75:9995528bf8b7 116 {
bjornnijhuis 75:9995528bf8b7 117 if (velocity <= 0.33) {
bjornnijhuis 75:9995528bf8b7 118 velocity=0.33;
bjornnijhuis 75:9995528bf8b7 119 } else if(velocity <= 0.66) {
bjornnijhuis 75:9995528bf8b7 120 velocity=0.66;
bjornnijhuis 75:9995528bf8b7 121 } else if(velocity > 0.66) {
bjornnijhuis 75:9995528bf8b7 122 velocity=1;
bjornnijhuis 75:9995528bf8b7 123 }
bjornnijhuis 75:9995528bf8b7 124 return velocity;
bjornnijhuis 75:9995528bf8b7 125 }
bjornnijhuis 75:9995528bf8b7 126
bjornnijhuis 75:9995528bf8b7 127 // Output velocity components
bjornnijhuis 75:9995528bf8b7 128 void EMG_velocity(double &x_velocity, double &y_velocity, double &z_velocity, double emg_val, bool thr_pass1, int &DOF, int emg_time)
bjornnijhuis 75:9995528bf8b7 129 {
bjornnijhuis 75:9995528bf8b7 130 if (emg_time == 0) {
bjornnijhuis 75:9995528bf8b7 131 EMG_timer.start();
bjornnijhuis 75:9995528bf8b7 132 }
bjornnijhuis 75:9995528bf8b7 133
bjornnijhuis 75:9995528bf8b7 134 if (emg_val > LPT) {
bjornnijhuis 75:9995528bf8b7 135 if (emg_time > LST) {
bjornnijhuis 75:9995528bf8b7 136 if(emg_time > UST) {
bjornnijhuis 75:9995528bf8b7 137 // Output velocities -------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 138 velocity = (emg_val - LPT)*(1/(1-LPT));
bjornnijhuis 75:9995528bf8b7 139
bjornnijhuis 75:9995528bf8b7 140 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 141 velocity = velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 142 } else {
bjornnijhuis 75:9995528bf8b7 143 velocity = - velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 144 }
bjornnijhuis 75:9995528bf8b7 145
bjornnijhuis 75:9995528bf8b7 146 switch(DOF) {
bjornnijhuis 75:9995528bf8b7 147 case 1 :
bjornnijhuis 75:9995528bf8b7 148 x_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 149 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 150 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 151 break;
bjornnijhuis 75:9995528bf8b7 152 case 2 :
bjornnijhuis 75:9995528bf8b7 153 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 154 y_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 155 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 156 break;
bjornnijhuis 75:9995528bf8b7 157 case 3 :
bjornnijhuis 75:9995528bf8b7 158 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 159 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 160
bjornnijhuis 75:9995528bf8b7 161 // z-velocity is not controlled continiously, but set to fixed value +/- 1
bjornnijhuis 75:9995528bf8b7 162 if(velocity > 0) {
bjornnijhuis 75:9995528bf8b7 163 z_velocity = 1;
bjornnijhuis 75:9995528bf8b7 164 } else if( velocity < 0) {
bjornnijhuis 75:9995528bf8b7 165 z_velocity = -1;
bjornnijhuis 75:9995528bf8b7 166 } else {
bjornnijhuis 75:9995528bf8b7 167 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 168 }
bjornnijhuis 75:9995528bf8b7 169 break;
bjornnijhuis 75:9995528bf8b7 170 }
bjornnijhuis 75:9995528bf8b7 171 }
bjornnijhuis 75:9995528bf8b7 172 }
bjornnijhuis 75:9995528bf8b7 173 } else {
bjornnijhuis 75:9995528bf8b7 174 if((emg_time > LST)&&(emg_time < UST)) {
bjornnijhuis 75:9995528bf8b7 175 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 176 // Switch channel -----------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 177 DOF = DOF + 1;
bjornnijhuis 75:9995528bf8b7 178 if (DOF == 4) {
bjornnijhuis 75:9995528bf8b7 179 DOF = 1;
bjornnijhuis 75:9995528bf8b7 180 }
bjornnijhuis 75:9995528bf8b7 181 } else {
bjornnijhuis 75:9995528bf8b7 182 // Switch pump ---------------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 183 pump = !pump;
bjornnijhuis 75:9995528bf8b7 184 }
bjornnijhuis 75:9995528bf8b7 185 }
bjornnijhuis 75:9995528bf8b7 186 // No input: set all value to zero ---------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 187 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 188 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 189 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 190 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 191 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 192 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 193 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 194 }
bjornnijhuis 75:9995528bf8b7 195 }
bjornnijhuis 75:9995528bf8b7 196
bjornnijhuis 75:9995528bf8b7 197 void EMG_check(bool &thr_pass1, bool &thr_pass2, double &x_velocity, double &y_velocity, double &z_velocity, double emg_filt_val1, double emg_filt_val2, int emg_time)
bjornnijhuis 75:9995528bf8b7 198 {
bjornnijhuis 75:9995528bf8b7 199 if (emg_filt_val1 > UPT) {
bjornnijhuis 75:9995528bf8b7 200 thr_pass1 = true;
bjornnijhuis 75:9995528bf8b7 201 }
bjornnijhuis 75:9995528bf8b7 202 if (emg_filt_val2 > UPT) {
bjornnijhuis 75:9995528bf8b7 203 thr_pass2 = true;
bjornnijhuis 75:9995528bf8b7 204 }
bjornnijhuis 75:9995528bf8b7 205
bjornnijhuis 75:9995528bf8b7 206 if ((thr_pass1 == true) && (thr_pass2 == true)) {
bjornnijhuis 75:9995528bf8b7 207 // If both true terminate
bjornnijhuis 75:9995528bf8b7 208 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 209 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 210 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 211 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 212 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 213 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 214 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 215
bjornnijhuis 75:9995528bf8b7 216 } else {
bjornnijhuis 75:9995528bf8b7 217 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 218 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val1, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 219 } else if(thr_pass2) {
bjornnijhuis 75:9995528bf8b7 220 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val2, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 221 }
bjornnijhuis 75:9995528bf8b7 222 }
bjornnijhuis 75:9995528bf8b7 223 }
bjornnijhuis 75:9995528bf8b7 224
bjornnijhuis 75:9995528bf8b7 225
annesteenbeek 78:0cc7c64ba94c 226 void readEMG(){
bjornnijhuis 75:9995528bf8b7 227 if(mode==normalize && normalizing_timer.read_ms() == 0) { // Start normalizing timer
bjornnijhuis 75:9995528bf8b7 228 normalizing_timer.reset();
bjornnijhuis 75:9995528bf8b7 229 normalizing_timer.start();
bjornnijhuis 75:9995528bf8b7 230 }
bjornnijhuis 75:9995528bf8b7 231
bjornnijhuis 75:9995528bf8b7 232 if(mode ==normalize) {
bjornnijhuis 75:9995528bf8b7 233 emg_val1 = emg1.read(); // Sample EMG value 1 from AnalogIn
bjornnijhuis 75:9995528bf8b7 234 emg_val2 = emg2.read(); // Sample EMG value 2 from AnalogIn
bjornnijhuis 75:9995528bf8b7 235
bjornnijhuis 75:9995528bf8b7 236 emg_filt_val1 = filtera(emg_val1); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 237 emg_filt_val2 = filterb(emg_val2); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 238
bjornnijhuis 75:9995528bf8b7 239
bjornnijhuis 75:9995528bf8b7 240 /* Determining normalizing constants
bjornnijhuis 75:9995528bf8b7 241 - Read value from EMG and average as above
bjornnijhuis 75:9995528bf8b7 242 - If mode "normalizing" and normalizing timer below ending time:
bjornnijhuis 75:9995528bf8b7 243 * store averaged EMG value 1 in max_vol_cont1 while overwriting previous value when current value > previous value
bjornnijhuis 75:9995528bf8b7 244 - If normalizing time exceeded, wait for given time
bjornnijhuis 75:9995528bf8b7 245 - Switch channels: redo above procedure for EMG value 2
bjornnijhuis 75:9995528bf8b7 246 - Switch to sampling mode
bjornnijhuis 75:9995528bf8b7 247 */
bjornnijhuis 75:9995528bf8b7 248
bjornnijhuis 75:9995528bf8b7 249 // First normalizing step: channel 1
bjornnijhuis 75:9995528bf8b7 250 if (normalizing_timer.read_ms() <= normalize_time && channel == 1) {
bjornnijhuis 75:9995528bf8b7 251 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 252 ledgreen.write(on);
bjornnijhuis 75:9995528bf8b7 253 if (emg_filt_val1 > max_vol_cont1) {
bjornnijhuis 75:9995528bf8b7 254 max_vol_cont1 = emg_filt_val1;
bjornnijhuis 75:9995528bf8b7 255 }
bjornnijhuis 75:9995528bf8b7 256 // Second normalizing step: wait time, switch channel
bjornnijhuis 75:9995528bf8b7 257 } else if (normalizing_timer.read_ms() > normalize_time && channel == 1) {
bjornnijhuis 75:9995528bf8b7 258 channel = 2;
bjornnijhuis 75:9995528bf8b7 259 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 260 ledred.write(on);
bjornnijhuis 75:9995528bf8b7 261 // Third normalizing step: channel 2
bjornnijhuis 75:9995528bf8b7 262 } else if (normalizing_timer.read_ms() >= (normalize_time + normalize_wait) && normalizing_timer.read_ms() <= (2*normalize_time + normalize_wait) && channel == 2) {
bjornnijhuis 75:9995528bf8b7 263 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 264 ledgreen.write(on);
bjornnijhuis 75:9995528bf8b7 265 if (emg_filt_val2 > max_vol_cont2) {
bjornnijhuis 75:9995528bf8b7 266 max_vol_cont2 = emg_filt_val2;
bjornnijhuis 75:9995528bf8b7 267 }
bjornnijhuis 75:9995528bf8b7 268 // Final normalizing step: stop normalizing process, start outputting velocities
bjornnijhuis 75:9995528bf8b7 269 } else if (normalizing_timer.read_ms() > (2*normalize_time + normalize_wait)) {
bjornnijhuis 75:9995528bf8b7 270 normalizing_timer.stop();
bjornnijhuis 75:9995528bf8b7 271 normalizing_timer.reset();
bjornnijhuis 75:9995528bf8b7 272 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 273 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 274 ledblue.write(on);
bjornnijhuis 75:9995528bf8b7 275 mode = sample;
bjornnijhuis 75:9995528bf8b7 276 }
bjornnijhuis 75:9995528bf8b7 277 }
bjornnijhuis 75:9995528bf8b7 278
bjornnijhuis 75:9995528bf8b7 279
bjornnijhuis 75:9995528bf8b7 280 if(mode ==sample) {
bjornnijhuis 75:9995528bf8b7 281 emg_val1 = emg1.read(); // Sample EMG value 1 from AnalogIn
bjornnijhuis 75:9995528bf8b7 282 emg_val2 = emg2.read(); // Sample EMG value 2 from AnalogIn
bjornnijhuis 75:9995528bf8b7 283
bjornnijhuis 75:9995528bf8b7 284 // Normalize EMG values using pre-determined coefficients
bjornnijhuis 75:9995528bf8b7 285 if(max_vol_cont1 != 0 && max_vol_cont2 != 0) { // Safety check: normalizing coefficients have to be set first
bjornnijhuis 75:9995528bf8b7 286 emg_val1 = emg_val1 / max_vol_cont1; // Normalize EMG-value 1
bjornnijhuis 75:9995528bf8b7 287 emg_val2 = emg_val2 / max_vol_cont2; // Normalize EMG-value 2
bjornnijhuis 75:9995528bf8b7 288
bjornnijhuis 75:9995528bf8b7 289 emg_filt_val1 = filtera(emg_val1); // Filter and average signal 1
bjornnijhuis 75:9995528bf8b7 290 emg_filt_val2 = filterb(emg_val2); // Filter and average signal 2
bjornnijhuis 75:9995528bf8b7 291
bjornnijhuis 75:9995528bf8b7 292 if (emg_filt_val1 > 1) { // Safety-function: set max. output to 1, even if muscle contraction exceeds max. voluntary contraction
bjornnijhuis 75:9995528bf8b7 293 emg_filt_val1 = 1;
bjornnijhuis 75:9995528bf8b7 294 }
bjornnijhuis 75:9995528bf8b7 295 if (emg_filt_val2 > 1) { // Safety-function: set max. output to 1, even if muscle contraction exceeds max. voluntary contraction
bjornnijhuis 75:9995528bf8b7 296 emg_filt_val2 = 1;
bjornnijhuis 75:9995528bf8b7 297 }
bjornnijhuis 75:9995528bf8b7 298
bjornnijhuis 75:9995528bf8b7 299 /* Checking EMG input:
bjornnijhuis 75:9995528bf8b7 300 - Make sure only one DOF is actuated at a time
bjornnijhuis 75:9995528bf8b7 301 - Distinct between switching function and motion from one EMG-signal
bjornnijhuis 75:9995528bf8b7 302 */
bjornnijhuis 75:9995528bf8b7 303
bjornnijhuis 75:9995528bf8b7 304 EMG_check(thr_pass1, thr_pass2, x_velocity, y_velocity, z_velocity, emg_filt_val1, emg_filt_val2, EMG_timer.read_ms());
bjornnijhuis 75:9995528bf8b7 305
bjornnijhuis 75:9995528bf8b7 306 } else {
bjornnijhuis 75:9995528bf8b7 307 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 308 ledred.write(on);
bjornnijhuis 75:9995528bf8b7 309 ledblue.write(off);
bjornnijhuis 75:9995528bf8b7 310 }
bjornnijhuis 75:9995528bf8b7 311 }
bjornnijhuis 75:9995528bf8b7 312
bjornnijhuis 75:9995528bf8b7 313 // Graphical output to HIDScope for debugging/ program check
annesteenbeek 78:0cc7c64ba94c 314
bjornnijhuis 75:9995528bf8b7 315
bjornnijhuis 75:9995528bf8b7 316
bjornnijhuis 75:9995528bf8b7 317 }
bjornnijhuis 75:9995528bf8b7 318