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:
bjornnijhuis
Date:
Tue Oct 20 10:24:01 2015 +0000
Revision:
75:9995528bf8b7
Child:
78:0cc7c64ba94c
New EMG-processing files included

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bjornnijhuis 75:9995528bf8b7 1 #include "filter_constants.h" // All constants for EMG processing
bjornnijhuis 75:9995528bf8b7 2 #include "emg.h"
bjornnijhuis 75:9995528bf8b7 3
bjornnijhuis 75:9995528bf8b7 4 #include "mbed.h"
bjornnijhuis 75:9995528bf8b7 5 #include "HIDScope.h"
bjornnijhuis 75:9995528bf8b7 6
bjornnijhuis 75:9995528bf8b7 7
bjornnijhuis 75:9995528bf8b7 8
bjornnijhuis 75:9995528bf8b7 9 // Define objects
bjornnijhuis 75:9995528bf8b7 10 AnalogIn emg1(A0); // Analog input 1
bjornnijhuis 75:9995528bf8b7 11 AnalogIn emg2(A1); // Analog input 2
bjornnijhuis 75:9995528bf8b7 12 DigitalOut ledred(LED_RED); // Red led
bjornnijhuis 75:9995528bf8b7 13 DigitalOut ledgreen(LED_GREEN); // Green led
bjornnijhuis 75:9995528bf8b7 14 DigitalOut ledblue(LED_BLUE); // Blue led
bjornnijhuis 75:9995528bf8b7 15 Ticker sample_tick; // Ticker for sampling
bjornnijhuis 75:9995528bf8b7 16 Ticker output; // Ticker for PC output
bjornnijhuis 75:9995528bf8b7 17 HIDScope scope(6); // Number of scopes
bjornnijhuis 75:9995528bf8b7 18 Timer normalizing_timer; // Timer for normalizing
bjornnijhuis 75:9995528bf8b7 19 Timer EMG_timer; // Timer for switch statement
bjornnijhuis 75:9995528bf8b7 20
bjornnijhuis 75:9995528bf8b7 21 // Define program constants
bjornnijhuis 75:9995528bf8b7 22 const int on = 0; // On-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 23 const int off = 1; // Off-constant for LEDs for program readability
bjornnijhuis 75:9995528bf8b7 24 const int sample = 0; // Constant for mode switching for program readability
bjornnijhuis 75:9995528bf8b7 25 const int normalize = 1; // Constant for mode switching for program readability
bjornnijhuis 75:9995528bf8b7 26
bjornnijhuis 75:9995528bf8b7 27
bjornnijhuis 75:9995528bf8b7 28 //**********************************************************************************************
bjornnijhuis 75:9995528bf8b7 29 bool mode = normalize; // Set program mode
bjornnijhuis 75:9995528bf8b7 30 //**********************************************************************************************
bjornnijhuis 75:9995528bf8b7 31
bjornnijhuis 75:9995528bf8b7 32 // Initialize sampling constants
bjornnijhuis 75:9995528bf8b7 33 double emg_val1 = 0, emg_val2 = 0, emg_filt_val1 = 0, emg_filt_val2 = 0;
bjornnijhuis 75:9995528bf8b7 34
bjornnijhuis 75:9995528bf8b7 35 // Initialize normalizing parameters
bjornnijhuis 75:9995528bf8b7 36 double max_vol_cont1 = 0; // Maximum voluntary contraction for scaling EMG1
bjornnijhuis 75:9995528bf8b7 37 double max_vol_cont2 = 0; // Maximum voluntary contraction for scaling EMG2
bjornnijhuis 75:9995528bf8b7 38 int channel = 1; // Channel for normalizing (EMG1 or EMG2)
bjornnijhuis 75:9995528bf8b7 39
bjornnijhuis 75:9995528bf8b7 40 // Initialize movement parameters
bjornnijhuis 75:9995528bf8b7 41 int DOF = 1; // Switch variable for controlled DOF: 1=x 2=y 3=z
bjornnijhuis 75:9995528bf8b7 42 bool pump = false; // Pump switch
bjornnijhuis 75:9995528bf8b7 43 bool thr_pass1 = false; // Processing threshold passed for signal 1?
bjornnijhuis 75:9995528bf8b7 44 bool thr_pass2 = false; // Processing threshold passed for signal 2?
bjornnijhuis 75:9995528bf8b7 45 double velocity = 0; // Forward velocity
bjornnijhuis 75:9995528bf8b7 46 double x_velocity = 0; // x component for velocity
bjornnijhuis 75:9995528bf8b7 47 double y_velocity = 0; // y component for velocity
bjornnijhuis 75:9995528bf8b7 48 double z_velocity = 0; // z component for velocity
bjornnijhuis 75:9995528bf8b7 49
bjornnijhuis 75:9995528bf8b7 50
bjornnijhuis 75:9995528bf8b7 51 // Reusable BiQuad filter
bjornnijhuis 75:9995528bf8b7 52 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 53 {
bjornnijhuis 75:9995528bf8b7 54 double v = u - a1*v1-a2*v2;
bjornnijhuis 75:9995528bf8b7 55 double y = gain*(b0*v+b1*v1+b2*v2);
bjornnijhuis 75:9995528bf8b7 56 v2 = v1;
bjornnijhuis 75:9995528bf8b7 57 v1=v;
bjornnijhuis 75:9995528bf8b7 58 return y;
bjornnijhuis 75:9995528bf8b7 59 }
bjornnijhuis 75:9995528bf8b7 60
bjornnijhuis 75:9995528bf8b7 61
bjornnijhuis 75:9995528bf8b7 62 // Apply filters: applies all necesary filters and averaging methods to input signal value
bjornnijhuis 75:9995528bf8b7 63 double filtera(double emg_val)
bjornnijhuis 75:9995528bf8b7 64 {
bjornnijhuis 75:9995528bf8b7 65 // Filtering signal
bjornnijhuis 75:9995528bf8b7 66 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 67 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 68 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 69 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 70 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 71 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 72 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 73 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 74 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 75 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 76
bjornnijhuis 75:9995528bf8b7 77 // Rectify signal
bjornnijhuis 75:9995528bf8b7 78 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 79
bjornnijhuis 75:9995528bf8b7 80 // Averaging signal
bjornnijhuis 75:9995528bf8b7 81 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 82 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 83 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 84
bjornnijhuis 75:9995528bf8b7 85 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 86 }
bjornnijhuis 75:9995528bf8b7 87 double filterb(double emg_val)
bjornnijhuis 75:9995528bf8b7 88 {
bjornnijhuis 75:9995528bf8b7 89 // Filtering signal
bjornnijhuis 75:9995528bf8b7 90 double emg_filt_val;
bjornnijhuis 75:9995528bf8b7 91 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 92 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 93 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 94 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 95 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 96 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 97 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 98 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 99 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 100
bjornnijhuis 75:9995528bf8b7 101 // Rectify signal
bjornnijhuis 75:9995528bf8b7 102 emg_filt_val = fabs(emg_filt_val);
bjornnijhuis 75:9995528bf8b7 103
bjornnijhuis 75:9995528bf8b7 104 // Averaging signal
bjornnijhuis 75:9995528bf8b7 105 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 106 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 107 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 108
bjornnijhuis 75:9995528bf8b7 109 return emg_filt_val;
bjornnijhuis 75:9995528bf8b7 110 }
bjornnijhuis 75:9995528bf8b7 111
bjornnijhuis 75:9995528bf8b7 112 // Create velocity steps: Converts continious velocity input signal to stepped output
bjornnijhuis 75:9995528bf8b7 113 double velocity_step(double velocity)
bjornnijhuis 75:9995528bf8b7 114 {
bjornnijhuis 75:9995528bf8b7 115 if (velocity <= 0.33) {
bjornnijhuis 75:9995528bf8b7 116 velocity=0.33;
bjornnijhuis 75:9995528bf8b7 117 } else if(velocity <= 0.66) {
bjornnijhuis 75:9995528bf8b7 118 velocity=0.66;
bjornnijhuis 75:9995528bf8b7 119 } else if(velocity > 0.66) {
bjornnijhuis 75:9995528bf8b7 120 velocity=1;
bjornnijhuis 75:9995528bf8b7 121 }
bjornnijhuis 75:9995528bf8b7 122 return velocity;
bjornnijhuis 75:9995528bf8b7 123 }
bjornnijhuis 75:9995528bf8b7 124
bjornnijhuis 75:9995528bf8b7 125 // Output velocity components
bjornnijhuis 75:9995528bf8b7 126 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 127 {
bjornnijhuis 75:9995528bf8b7 128 if (emg_time == 0) {
bjornnijhuis 75:9995528bf8b7 129 EMG_timer.start();
bjornnijhuis 75:9995528bf8b7 130 }
bjornnijhuis 75:9995528bf8b7 131
bjornnijhuis 75:9995528bf8b7 132 if (emg_val > LPT) {
bjornnijhuis 75:9995528bf8b7 133 if (emg_time > LST) {
bjornnijhuis 75:9995528bf8b7 134 if(emg_time > UST) {
bjornnijhuis 75:9995528bf8b7 135 // Output velocities -------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 136 velocity = (emg_val - LPT)*(1/(1-LPT));
bjornnijhuis 75:9995528bf8b7 137
bjornnijhuis 75:9995528bf8b7 138 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 139 velocity = velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 140 } else {
bjornnijhuis 75:9995528bf8b7 141 velocity = - velocity_step(velocity);
bjornnijhuis 75:9995528bf8b7 142 }
bjornnijhuis 75:9995528bf8b7 143
bjornnijhuis 75:9995528bf8b7 144 switch(DOF) {
bjornnijhuis 75:9995528bf8b7 145 case 1 :
bjornnijhuis 75:9995528bf8b7 146 x_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 147 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 148 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 149 break;
bjornnijhuis 75:9995528bf8b7 150 case 2 :
bjornnijhuis 75:9995528bf8b7 151 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 152 y_velocity = velocity;
bjornnijhuis 75:9995528bf8b7 153 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 154 break;
bjornnijhuis 75:9995528bf8b7 155 case 3 :
bjornnijhuis 75:9995528bf8b7 156 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 157 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 158
bjornnijhuis 75:9995528bf8b7 159 // z-velocity is not controlled continiously, but set to fixed value +/- 1
bjornnijhuis 75:9995528bf8b7 160 if(velocity > 0) {
bjornnijhuis 75:9995528bf8b7 161 z_velocity = 1;
bjornnijhuis 75:9995528bf8b7 162 } else if( velocity < 0) {
bjornnijhuis 75:9995528bf8b7 163 z_velocity = -1;
bjornnijhuis 75:9995528bf8b7 164 } else {
bjornnijhuis 75:9995528bf8b7 165 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 166 }
bjornnijhuis 75:9995528bf8b7 167 break;
bjornnijhuis 75:9995528bf8b7 168 }
bjornnijhuis 75:9995528bf8b7 169 }
bjornnijhuis 75:9995528bf8b7 170 }
bjornnijhuis 75:9995528bf8b7 171 } else {
bjornnijhuis 75:9995528bf8b7 172 if((emg_time > LST)&&(emg_time < UST)) {
bjornnijhuis 75:9995528bf8b7 173 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 174 // Switch channel -----------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 175 DOF = DOF + 1;
bjornnijhuis 75:9995528bf8b7 176 if (DOF == 4) {
bjornnijhuis 75:9995528bf8b7 177 DOF = 1;
bjornnijhuis 75:9995528bf8b7 178 }
bjornnijhuis 75:9995528bf8b7 179 } else {
bjornnijhuis 75:9995528bf8b7 180 // Switch pump ---------------------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 181 pump = !pump;
bjornnijhuis 75:9995528bf8b7 182 }
bjornnijhuis 75:9995528bf8b7 183 }
bjornnijhuis 75:9995528bf8b7 184 // No input: set all value to zero ---------------------------------------------------------------
bjornnijhuis 75:9995528bf8b7 185 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 186 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 187 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 188 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 189 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 190 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 191 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 192 }
bjornnijhuis 75:9995528bf8b7 193 }
bjornnijhuis 75:9995528bf8b7 194
bjornnijhuis 75:9995528bf8b7 195 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 196 {
bjornnijhuis 75:9995528bf8b7 197 if (emg_filt_val1 > UPT) {
bjornnijhuis 75:9995528bf8b7 198 thr_pass1 = true;
bjornnijhuis 75:9995528bf8b7 199 }
bjornnijhuis 75:9995528bf8b7 200 if (emg_filt_val2 > UPT) {
bjornnijhuis 75:9995528bf8b7 201 thr_pass2 = true;
bjornnijhuis 75:9995528bf8b7 202 }
bjornnijhuis 75:9995528bf8b7 203
bjornnijhuis 75:9995528bf8b7 204 if ((thr_pass1 == true) && (thr_pass2 == true)) {
bjornnijhuis 75:9995528bf8b7 205 // If both true terminate
bjornnijhuis 75:9995528bf8b7 206 thr_pass1 = false;
bjornnijhuis 75:9995528bf8b7 207 thr_pass2 = false;
bjornnijhuis 75:9995528bf8b7 208 EMG_timer.stop();
bjornnijhuis 75:9995528bf8b7 209 EMG_timer.reset();
bjornnijhuis 75:9995528bf8b7 210 x_velocity = 0;
bjornnijhuis 75:9995528bf8b7 211 y_velocity = 0;
bjornnijhuis 75:9995528bf8b7 212 z_velocity = 0;
bjornnijhuis 75:9995528bf8b7 213
bjornnijhuis 75:9995528bf8b7 214 } else {
bjornnijhuis 75:9995528bf8b7 215 if(thr_pass1) {
bjornnijhuis 75:9995528bf8b7 216 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val1, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 217 } else if(thr_pass2) {
bjornnijhuis 75:9995528bf8b7 218 EMG_velocity(x_velocity, y_velocity, z_velocity, emg_filt_val2, thr_pass1, DOF, emg_time);
bjornnijhuis 75:9995528bf8b7 219 }
bjornnijhuis 75:9995528bf8b7 220 }
bjornnijhuis 75:9995528bf8b7 221 }
bjornnijhuis 75:9995528bf8b7 222
bjornnijhuis 75:9995528bf8b7 223
bjornnijhuis 75:9995528bf8b7 224 void readEMG()
bjornnijhuis 75:9995528bf8b7 225 {
bjornnijhuis 75:9995528bf8b7 226 if(mode==normalize && normalizing_timer.read_ms() == 0) { // Start normalizing timer
bjornnijhuis 75:9995528bf8b7 227 normalizing_timer.reset();
bjornnijhuis 75:9995528bf8b7 228 normalizing_timer.start();
bjornnijhuis 75:9995528bf8b7 229 }
bjornnijhuis 75:9995528bf8b7 230
bjornnijhuis 75:9995528bf8b7 231 if(mode ==normalize) {
bjornnijhuis 75:9995528bf8b7 232 emg_val1 = emg1.read(); // Sample EMG value 1 from AnalogIn
bjornnijhuis 75:9995528bf8b7 233 emg_val2 = emg2.read(); // Sample EMG value 2 from AnalogIn
bjornnijhuis 75:9995528bf8b7 234
bjornnijhuis 75:9995528bf8b7 235 emg_filt_val1 = filtera(emg_val1); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 236 emg_filt_val2 = filterb(emg_val2); // Filter and average signal
bjornnijhuis 75:9995528bf8b7 237
bjornnijhuis 75:9995528bf8b7 238
bjornnijhuis 75:9995528bf8b7 239 /* Determining normalizing constants
bjornnijhuis 75:9995528bf8b7 240 - Read value from EMG and average as above
bjornnijhuis 75:9995528bf8b7 241 - If mode "normalizing" and normalizing timer below ending time:
bjornnijhuis 75:9995528bf8b7 242 * store averaged EMG value 1 in max_vol_cont1 while overwriting previous value when current value > previous value
bjornnijhuis 75:9995528bf8b7 243 - If normalizing time exceeded, wait for given time
bjornnijhuis 75:9995528bf8b7 244 - Switch channels: redo above procedure for EMG value 2
bjornnijhuis 75:9995528bf8b7 245 - Switch to sampling mode
bjornnijhuis 75:9995528bf8b7 246 */
bjornnijhuis 75:9995528bf8b7 247
bjornnijhuis 75:9995528bf8b7 248 // First normalizing step: channel 1
bjornnijhuis 75:9995528bf8b7 249 if (normalizing_timer.read_ms() <= normalize_time && channel == 1) {
bjornnijhuis 75:9995528bf8b7 250 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 251 ledgreen.write(on);
bjornnijhuis 75:9995528bf8b7 252 if (emg_filt_val1 > max_vol_cont1) {
bjornnijhuis 75:9995528bf8b7 253 max_vol_cont1 = emg_filt_val1;
bjornnijhuis 75:9995528bf8b7 254 }
bjornnijhuis 75:9995528bf8b7 255 // Second normalizing step: wait time, switch channel
bjornnijhuis 75:9995528bf8b7 256 } else if (normalizing_timer.read_ms() > normalize_time && channel == 1) {
bjornnijhuis 75:9995528bf8b7 257 channel = 2;
bjornnijhuis 75:9995528bf8b7 258 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 259 ledred.write(on);
bjornnijhuis 75:9995528bf8b7 260 // Third normalizing step: channel 2
bjornnijhuis 75:9995528bf8b7 261 } else if (normalizing_timer.read_ms() >= (normalize_time + normalize_wait) && normalizing_timer.read_ms() <= (2*normalize_time + normalize_wait) && channel == 2) {
bjornnijhuis 75:9995528bf8b7 262 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 263 ledgreen.write(on);
bjornnijhuis 75:9995528bf8b7 264 if (emg_filt_val2 > max_vol_cont2) {
bjornnijhuis 75:9995528bf8b7 265 max_vol_cont2 = emg_filt_val2;
bjornnijhuis 75:9995528bf8b7 266 }
bjornnijhuis 75:9995528bf8b7 267 // Final normalizing step: stop normalizing process, start outputting velocities
bjornnijhuis 75:9995528bf8b7 268 } else if (normalizing_timer.read_ms() > (2*normalize_time + normalize_wait)) {
bjornnijhuis 75:9995528bf8b7 269 normalizing_timer.stop();
bjornnijhuis 75:9995528bf8b7 270 normalizing_timer.reset();
bjornnijhuis 75:9995528bf8b7 271 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 272 ledred.write(off);
bjornnijhuis 75:9995528bf8b7 273 ledblue.write(on);
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 {
bjornnijhuis 75:9995528bf8b7 306 ledgreen.write(off);
bjornnijhuis 75:9995528bf8b7 307 ledred.write(on);
bjornnijhuis 75:9995528bf8b7 308 ledblue.write(off);
bjornnijhuis 75:9995528bf8b7 309 }
bjornnijhuis 75:9995528bf8b7 310 }
bjornnijhuis 75:9995528bf8b7 311
bjornnijhuis 75:9995528bf8b7 312 // Graphical output to HIDScope for debugging/ program check
bjornnijhuis 75:9995528bf8b7 313 scope.set(0,emg_filt_val2);
bjornnijhuis 75:9995528bf8b7 314 scope.set(1,x_velocity);
bjornnijhuis 75:9995528bf8b7 315 scope.set(2,y_velocity);
bjornnijhuis 75:9995528bf8b7 316 scope.set(3,pump);
bjornnijhuis 75:9995528bf8b7 317 scope.set(4,DOF);
bjornnijhuis 75:9995528bf8b7 318 scope.set(5,DOF);
bjornnijhuis 75:9995528bf8b7 319 scope.send();
bjornnijhuis 75:9995528bf8b7 320
bjornnijhuis 75:9995528bf8b7 321
bjornnijhuis 75:9995528bf8b7 322 }
bjornnijhuis 75:9995528bf8b7 323