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