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:
Fri Oct 30 10:32:49 2015 +0100
Revision:
130:2542f844ba1e
Parent:
127:831f03471efb
changes

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"
annesteenbeek 80:8f030bd5dd15 4 #include "buttons.h"
bjornnijhuis 75:9995528bf8b7 5
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
bjornnijhuis 75:9995528bf8b7 9 Ticker sample_tick; // Ticker for sampling
bjornnijhuis 75:9995528bf8b7 10 Ticker output; // Ticker for PC output
bjornnijhuis 75:9995528bf8b7 11 Timer normalizing_timer; // Timer for normalizing
bjornnijhuis 75:9995528bf8b7 12 Timer EMG_timer; // Timer for switch statement
bjornnijhuis 75:9995528bf8b7 13
bjornnijhuis 75:9995528bf8b7 14 // Define program constants
bjornnijhuis 75:9995528bf8b7 15 const int on = 0; // On-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 16 const int off = 1; // Off-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 17
annesteenbeek 80:8f030bd5dd15 18 bool ledsEnable = false;
bjornnijhuis 75:9995528bf8b7 19 // Initialize sampling constants
bjornnijhuis 75:9995528bf8b7 20 double emg_val1 = 0, emg_val2 = 0, emg_filt_val1 = 0, emg_filt_val2 = 0;
bjornnijhuis 75:9995528bf8b7 21
bjornnijhuis 75:9995528bf8b7 22 // Initialize normalizing parameters
bjornnijhuis 75:9995528bf8b7 23 double max_vol_cont1 = 0; // Maximum voluntary contraction for scaling EMG1
bjornnijhuis 75:9995528bf8b7 24 double max_vol_cont2 = 0; // Maximum voluntary contraction for scaling EMG2
bjornnijhuis 75:9995528bf8b7 25 int channel = 1; // Channel for normalizing (EMG1 or EMG2)
bjornnijhuis 75:9995528bf8b7 26
bjornnijhuis 75:9995528bf8b7 27 // Initialize movement parameters
bjornnijhuis 75:9995528bf8b7 28 int DOF = 1; // Switch variable for controlled DOF: 1=x 2=y 3=z
annesteenbeek 127:831f03471efb 29 bool enablePump = false; // Pump switch
bjornnijhuis 75:9995528bf8b7 30 bool thr_pass1 = false; // Processing threshold passed for signal 1?
bjornnijhuis 75:9995528bf8b7 31 bool thr_pass2 = false; // Processing threshold passed for signal 2?
bjornnijhuis 75:9995528bf8b7 32 double velocity = 0; // Forward velocity
bjornnijhuis 75:9995528bf8b7 33 double x_velocity = 0; // x component for velocity
bjornnijhuis 75:9995528bf8b7 34 double y_velocity = 0; // y component for velocity
bjornnijhuis 75:9995528bf8b7 35 double z_velocity = 0; // z component for velocity
bjornnijhuis 75:9995528bf8b7 36
bjornnijhuis 75:9995528bf8b7 37
bjornnijhuis 75:9995528bf8b7 38 // Reusable BiQuad filter
bjornnijhuis 75:9995528bf8b7 39 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 40 {
bjornnijhuis 75:9995528bf8b7 41 double v = u - a1*v1-a2*v2;
bjornnijhuis 75:9995528bf8b7 42 double y = gain*(b0*v+b1*v1+b2*v2);
bjornnijhuis 75:9995528bf8b7 43 v2 = v1;
bjornnijhuis 75:9995528bf8b7 44 v1=v;
bjornnijhuis 75:9995528bf8b7 45 return y;
bjornnijhuis 75:9995528bf8b7 46 }
bjornnijhuis 75:9995528bf8b7 47
bjornnijhuis 75:9995528bf8b7 48
bjornnijhuis 75:9995528bf8b7 49 // Apply filters: applies all necesary filters and averaging methods to input signal value
bjornnijhuis 75:9995528bf8b7 50 double filtera(double emg_val)
bjornnijhuis 75:9995528bf8b7 51 {
bjornnijhuis 75:9995528bf8b7 52 // Filtering signal
bjornnijhuis 75:9995528bf8b7 53 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 54 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 55 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 56 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 57 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 58 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 59 emg_filt_val = biquad(emg_filt_val,f23_v1,f23_v2,f23_a1,f23_a2,f23_b0,f23_b1,f23_b2,f23_gain);
MartijnGJ 113:7af0ae9a24c0 60 //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
MartijnGJ 113:7af0ae9a24c0 61 //emg_filt_val = biquad(emg_filt_val,f32_v1,f32_v2,f32_a1,f32_a2,f32_b0,f32_b1,f32_b2,f32_gain);
MartijnGJ 113:7af0ae9a24c0 62 //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 63
bjornnijhuis 75:9995528bf8b7 64 // Rectify signal
bjornnijhuis 75:9995528bf8b7 65 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 66
bjornnijhuis 75:9995528bf8b7 67 // Averaging signal
bjornnijhuis 75:9995528bf8b7 68 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 69 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 70 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 71
bjornnijhuis 75:9995528bf8b7 72 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 73 }
bjornnijhuis 75:9995528bf8b7 74 double filterb(double emg_val)
bjornnijhuis 75:9995528bf8b7 75 {
bjornnijhuis 75:9995528bf8b7 76 // Filtering signal
bjornnijhuis 75:9995528bf8b7 77 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 78 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 79 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 80 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 81 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 82 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 83 emg_filt_val = biquad(emg_filt_val,f23_v1b,f23_v2b,f23_a1,f23_a2,f23_b0,f23_b1,f23_b2,f23_gain);
MartijnGJ 113:7af0ae9a24c0 84 //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
MartijnGJ 113:7af0ae9a24c0 85 //emg_filt_val = biquad(emg_filt_val,f32_v1b,f32_v2b,f32_a1,f32_a2,f32_b0,f32_b1,f32_b2,f32_gain);
MartijnGJ 113:7af0ae9a24c0 86 //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 87
bjornnijhuis 75:9995528bf8b7 88 // Rectify signal
bjornnijhuis 75:9995528bf8b7 89 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 90
bjornnijhuis 75:9995528bf8b7 91 // Averaging signal
bjornnijhuis 75:9995528bf8b7 92 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 93 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 94 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 95
bjornnijhuis 75:9995528bf8b7 96 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 97 }
bjornnijhuis 75:9995528bf8b7 98
bjornnijhuis 75:9995528bf8b7 99 // Create velocity steps: Converts continious velocity input signal to stepped output
bjornnijhuis 75:9995528bf8b7 100 double velocity_step(double velocity)
bjornnijhuis 75:9995528bf8b7 101 {
bjornnijhuis 75:9995528bf8b7 102 if (velocity <= 0.33) {
bjornnijhuis 75:9995528bf8b7 103 velocity=0.33;
bjornnijhuis 75:9995528bf8b7 104 } else if(velocity <= 0.66) {
bjornnijhuis 75:9995528bf8b7 105 velocity=0.66;
bjornnijhuis 75:9995528bf8b7 106 } else if(velocity > 0.66) {
bjornnijhuis 75:9995528bf8b7 107 velocity=1;
bjornnijhuis 75:9995528bf8b7 108 }
bjornnijhuis 75:9995528bf8b7 109 return velocity;
bjornnijhuis 75:9995528bf8b7 110 }
bjornnijhuis 75:9995528bf8b7 111
bjornnijhuis 75:9995528bf8b7 112 // Output velocity components
bjornnijhuis 75:9995528bf8b7 113 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 114 {
bjornnijhuis 75:9995528bf8b7 115 if (emg_time == 0) {
bjornnijhuis 75:9995528bf8b7 116 EMG_timer.start();
bjornnijhuis 75:9995528bf8b7 117 }
bjornnijhuis 75:9995528bf8b7 118
bjornnijhuis 75:9995528bf8b7 119 if (emg_val > LPT) {
bjornnijhuis 75:9995528bf8b7 120 if (emg_time > LST) {
bjornnijhuis 75:9995528bf8b7 121 if(emg_time > UST) {
bjornnijhuis 75:9995528bf8b7 122 // Output velocities -------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 123 velocity = (emg_val - LPT)*(1/(1-LPT));
bjornnijhuis 75:9995528bf8b7 124
bjornnijhuis 75:9995528bf8b7 125 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 126 velocity = velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 127 } else {
bjornnijhuis 75:9995528bf8b7 128 velocity = - velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 129 }
bjornnijhuis 75:9995528bf8b7 130
bjornnijhuis 75:9995528bf8b7 131 switch(DOF) {
bjornnijhuis 75:9995528bf8b7 132 case 1 :
bjornnijhuis 75:9995528bf8b7 133 x_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 134 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 135 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 136 break;
bjornnijhuis 75:9995528bf8b7 137 case 2 :
bjornnijhuis 75:9995528bf8b7 138 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 139 y_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 140 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 141 break;
bjornnijhuis 75:9995528bf8b7 142 case 3 :
bjornnijhuis 75:9995528bf8b7 143 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 144 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 145
bjornnijhuis 75:9995528bf8b7 146 // z-velocity is not controlled continiously, but set to fixed value +/- 1
bjornnijhuis 75:9995528bf8b7 147 if(velocity > 0) {
bjornnijhuis 75:9995528bf8b7 148 z_velocity = 1;
bjornnijhuis 75:9995528bf8b7 149 } else if( velocity < 0) {
bjornnijhuis 75:9995528bf8b7 150 z_velocity = -1;
bjornnijhuis 75:9995528bf8b7 151 } else {
bjornnijhuis 75:9995528bf8b7 152 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 153 }
bjornnijhuis 75:9995528bf8b7 154 break;
bjornnijhuis 75:9995528bf8b7 155 }
bjornnijhuis 75:9995528bf8b7 156 }
bjornnijhuis 75:9995528bf8b7 157 }
bjornnijhuis 75:9995528bf8b7 158 } else {
bjornnijhuis 75:9995528bf8b7 159 if((emg_time > LST)&&(emg_time < UST)) {
bjornnijhuis 75:9995528bf8b7 160 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 161 // Switch channel -----------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 162 DOF = DOF + 1;
bjornnijhuis 75:9995528bf8b7 163 if (DOF == 4) {
bjornnijhuis 75:9995528bf8b7 164 DOF = 1;
bjornnijhuis 75:9995528bf8b7 165 }
bjornnijhuis 75:9995528bf8b7 166 } else {
bjornnijhuis 75:9995528bf8b7 167 // Switch pump ---------------------------------------------------------------------------
annesteenbeek 127:831f03471efb 168 enablePump = !enablePump;
bjornnijhuis 75:9995528bf8b7 169 }
bjornnijhuis 75:9995528bf8b7 170 }
bjornnijhuis 75:9995528bf8b7 171 // No input: set all value to zero ---------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 172 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 173 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 174 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 175 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 176 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 177 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 178 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 179 }
bjornnijhuis 75:9995528bf8b7 180 }
bjornnijhuis 75:9995528bf8b7 181
bjornnijhuis 75:9995528bf8b7 182 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 183 {
bjornnijhuis 75:9995528bf8b7 184 if (emg_filt_val1 > UPT) {
bjornnijhuis 75:9995528bf8b7 185 thr_pass1 = true;
bjornnijhuis 75:9995528bf8b7 186 }
bjornnijhuis 75:9995528bf8b7 187 if (emg_filt_val2 > UPT) {
bjornnijhuis 75:9995528bf8b7 188 thr_pass2 = true;
bjornnijhuis 75:9995528bf8b7 189 }
bjornnijhuis 75:9995528bf8b7 190
bjornnijhuis 75:9995528bf8b7 191 if ((thr_pass1 == true) && (thr_pass2 == true)) {
bjornnijhuis 75:9995528bf8b7 192 // If both true terminate
bjornnijhuis 75:9995528bf8b7 193 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 194 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 195 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 196 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 197 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 198 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 199 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 200
bjornnijhuis 75:9995528bf8b7 201 } else {
bjornnijhuis 75:9995528bf8b7 202 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 203 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val1, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 204 } else if(thr_pass2) {
bjornnijhuis 75:9995528bf8b7 205 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val2, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 206 }
bjornnijhuis 75:9995528bf8b7 207 }
bjornnijhuis 75:9995528bf8b7 208 }
bjornnijhuis 75:9995528bf8b7 209
bjornnijhuis 75:9995528bf8b7 210
annesteenbeek 78:0cc7c64ba94c 211 void readEMG(){
bjornnijhuis 75:9995528bf8b7 212 if(mode==normalize && normalizing_timer.read_ms() == 0) { // Start normalizing timer
bjornnijhuis 75:9995528bf8b7 213 normalizing_timer.reset();
bjornnijhuis 75:9995528bf8b7 214 normalizing_timer.start();
bjornnijhuis 75:9995528bf8b7 215 }
bjornnijhuis 75:9995528bf8b7 216
bjornnijhuis 75:9995528bf8b7 217 if(mode ==normalize) {
bjornnijhuis 75:9995528bf8b7 218 emg_val1 = emg1.read(); // Sample EMG value 1 from AnalogIn
bjornnijhuis 75:9995528bf8b7 219 emg_val2 = emg2.read(); // Sample EMG value 2 from AnalogIn
bjornnijhuis 75:9995528bf8b7 220
bjornnijhuis 75:9995528bf8b7 221 emg_filt_val1 = filtera(emg_val1); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 222 emg_filt_val2 = filterb(emg_val2); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 223
bjornnijhuis 75:9995528bf8b7 224
bjornnijhuis 75:9995528bf8b7 225 /* Determining normalizing constants
bjornnijhuis 75:9995528bf8b7 226 - Read value from EMG and average as above
bjornnijhuis 75:9995528bf8b7 227 - If mode "normalizing" and normalizing timer below ending time:
bjornnijhuis 75:9995528bf8b7 228 * store averaged EMG value 1 in max_vol_cont1 while overwriting previous value when current value > previous value
bjornnijhuis 75:9995528bf8b7 229 - If normalizing time exceeded, wait for given time
bjornnijhuis 75:9995528bf8b7 230 - Switch channels: redo above procedure for EMG value 2
bjornnijhuis 75:9995528bf8b7 231 - Switch to sampling mode
bjornnijhuis 75:9995528bf8b7 232 */
bjornnijhuis 75:9995528bf8b7 233
bjornnijhuis 75:9995528bf8b7 234 // First normalizing step: channel 1
bjornnijhuis 75:9995528bf8b7 235 if (normalizing_timer.read_ms() <= normalize_time && channel == 1) {
annesteenbeek 80:8f030bd5dd15 236 if (ledsEnable){
annesteenbeek 80:8f030bd5dd15 237 redLed.write(off);
annesteenbeek 80:8f030bd5dd15 238 greenLed.write(on);
annesteenbeek 80:8f030bd5dd15 239 }
bjornnijhuis 75:9995528bf8b7 240 if (emg_filt_val1 > max_vol_cont1) {
bjornnijhuis 75:9995528bf8b7 241 max_vol_cont1 = emg_filt_val1;
bjornnijhuis 75:9995528bf8b7 242 }
bjornnijhuis 75:9995528bf8b7 243 // Second normalizing step: wait time, switch channel
bjornnijhuis 75:9995528bf8b7 244 } else if (normalizing_timer.read_ms() > normalize_time && channel == 1) {
bjornnijhuis 75:9995528bf8b7 245 channel = 2;
annesteenbeek 80:8f030bd5dd15 246 if (ledsEnable){
annesteenbeek 80:8f030bd5dd15 247 greenLed.write(off);
annesteenbeek 80:8f030bd5dd15 248 redLed.write(on);
annesteenbeek 80:8f030bd5dd15 249 }
bjornnijhuis 75:9995528bf8b7 250 // Third normalizing step: channel 2
bjornnijhuis 75:9995528bf8b7 251 } else if (normalizing_timer.read_ms() >= (normalize_time + normalize_wait) && normalizing_timer.read_ms() <= (2*normalize_time + normalize_wait) && channel == 2) {
annesteenbeek 80:8f030bd5dd15 252 if (ledsEnable){
annesteenbeek 80:8f030bd5dd15 253 redLed.write(off);
annesteenbeek 80:8f030bd5dd15 254 greenLed.write(on);
annesteenbeek 80:8f030bd5dd15 255 }
bjornnijhuis 75:9995528bf8b7 256 if (emg_filt_val2 > max_vol_cont2) {
bjornnijhuis 75:9995528bf8b7 257 max_vol_cont2 = emg_filt_val2;
bjornnijhuis 75:9995528bf8b7 258 }
bjornnijhuis 75:9995528bf8b7 259 // Final normalizing step: stop normalizing process, start outputting velocities
bjornnijhuis 75:9995528bf8b7 260 } else if (normalizing_timer.read_ms() > (2*normalize_time + normalize_wait)) {
bjornnijhuis 75:9995528bf8b7 261 normalizing_timer.stop();
bjornnijhuis 75:9995528bf8b7 262 normalizing_timer.reset();
annesteenbeek 80:8f030bd5dd15 263 if (ledsEnable){
annesteenbeek 80:8f030bd5dd15 264 greenLed.write(off);
annesteenbeek 80:8f030bd5dd15 265 redLed.write(off);
annesteenbeek 80:8f030bd5dd15 266 blueLed.write(on);
annesteenbeek 80:8f030bd5dd15 267 }
bjornnijhuis 75:9995528bf8b7 268 mode = sample;
bjornnijhuis 75:9995528bf8b7 269 }
bjornnijhuis 75:9995528bf8b7 270 }
bjornnijhuis 75:9995528bf8b7 271
bjornnijhuis 75:9995528bf8b7 272
bjornnijhuis 75:9995528bf8b7 273 if(mode ==sample) {
bjornnijhuis 75:9995528bf8b7 274 emg_val1 = emg1.read(); // Sample EMG value 1 from AnalogIn
bjornnijhuis 75:9995528bf8b7 275 emg_val2 = emg2.read(); // Sample EMG value 2 from AnalogIn
bjornnijhuis 75:9995528bf8b7 276
bjornnijhuis 75:9995528bf8b7 277 // Normalize EMG values using pre-determined coefficients
bjornnijhuis 75:9995528bf8b7 278 if(max_vol_cont1 != 0 && max_vol_cont2 != 0) { // Safety check: normalizing coefficients have to be set first
bjornnijhuis 75:9995528bf8b7 279 emg_val1 = emg_val1 / max_vol_cont1; // Normalize EMG-value 1
bjornnijhuis 75:9995528bf8b7 280 emg_val2 = emg_val2 / max_vol_cont2; // Normalize EMG-value 2
bjornnijhuis 75:9995528bf8b7 281
bjornnijhuis 75:9995528bf8b7 282 emg_filt_val1 = filtera(emg_val1); // Filter and average signal 1
bjornnijhuis 75:9995528bf8b7 283 emg_filt_val2 = filterb(emg_val2); // Filter and average signal 2
bjornnijhuis 75:9995528bf8b7 284
bjornnijhuis 75:9995528bf8b7 285 if (emg_filt_val1 > 1) { // Safety-function: set max. output to 1, even if muscle contraction exceeds max. voluntary contraction
bjornnijhuis 75:9995528bf8b7 286 emg_filt_val1 = 1;
bjornnijhuis 75:9995528bf8b7 287 }
bjornnijhuis 75:9995528bf8b7 288 if (emg_filt_val2 > 1) { // Safety-function: set max. output to 1, even if muscle contraction exceeds max. voluntary contraction
bjornnijhuis 75:9995528bf8b7 289 emg_filt_val2 = 1;
bjornnijhuis 75:9995528bf8b7 290 }
bjornnijhuis 75:9995528bf8b7 291
bjornnijhuis 75:9995528bf8b7 292 /* Checking EMG input:
bjornnijhuis 75:9995528bf8b7 293 - Make sure only one DOF is actuated at a time
bjornnijhuis 75:9995528bf8b7 294 - Distinct between switching function and motion from one EMG-signal
bjornnijhuis 75:9995528bf8b7 295 */
bjornnijhuis 75:9995528bf8b7 296
bjornnijhuis 75:9995528bf8b7 297 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 298
bjornnijhuis 75:9995528bf8b7 299 } else {
annesteenbeek 80:8f030bd5dd15 300 if (ledsEnable){
annesteenbeek 80:8f030bd5dd15 301 greenLed.write(off);
annesteenbeek 80:8f030bd5dd15 302 redLed.write(on);
annesteenbeek 80:8f030bd5dd15 303 blueLed.write(off);
annesteenbeek 80:8f030bd5dd15 304 }
bjornnijhuis 75:9995528bf8b7 305 }
bjornnijhuis 75:9995528bf8b7 306 }
bjornnijhuis 75:9995528bf8b7 307
bjornnijhuis 75:9995528bf8b7 308 // Graphical output to HIDScope for debugging/ program check
bjornnijhuis 75:9995528bf8b7 309 }
bjornnijhuis 75:9995528bf8b7 310