4 directional EMG control of the XY table. Made during my bachelor end assignment.

Dependencies:   C12832_lcd HIDScope mbed-dsp mbed

Committer:
jessekaiser
Date:
Fri Jun 05 12:33:13 2015 +0000
Revision:
46:7a7cb589579a
Parent:
45:f5d74c7f8fbf
Child:
47:150924ff4b2c
Code voor controle met 2 motoren en 4 emg signalen.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jessekaiser 46:7a7cb589579a 1 /*Code by Jesse Kaiser, s1355783 for control of the 2DOF Planar Table
jessekaiser 46:7a7cb589579a 2 Some variables are also numbered at the end. The numbers stands for the muscle that controls it.
jessekaiser 46:7a7cb589579a 3 Biceps = 1
jessekaiser 46:7a7cb589579a 4 Triceps = 2
jessekaiser 46:7a7cb589579a 5 Pectoralis Major = 3
jessekaiser 46:7a7cb589579a 6 Deltoid = 4
jessekaiser 46:7a7cb589579a 7 The "x" and "y" at the end of variables stand for the X-Spindle or Y-Spindle respectivly.
jessekaiser 46:7a7cb589579a 8 */
jessekaiser 46:7a7cb589579a 9
jessekaiser 0:3acdd563582f 10 #include "mbed.h"
jessekaiser 10:7f94cd65c910 11 #include "C12832_lcd.h"
jessekaiser 45:f5d74c7f8fbf 12 #include "arm_math.h"
jessekaiser 45:f5d74c7f8fbf 13 #include "HIDScope.h"
jessekaiser 0:3acdd563582f 14
jessekaiser 45:f5d74c7f8fbf 15 #define K_Gain 14 //Gain of the filtered EMG signal
jessekaiser 45:f5d74c7f8fbf 16 #define Damp 5 //Deceleration of the motor
jessekaiser 45:f5d74c7f8fbf 17 #define Mass 1 // Mass value
jessekaiser 45:f5d74c7f8fbf 18 #define dt 0.002 //Sample frequency
jessekaiser 45:f5d74c7f8fbf 19 #define MAX_bi 0.09 //Can be used for normalisation of the EMG signal of the biceps
jessekaiser 45:f5d74c7f8fbf 20 #define MAX_tri 0.09
jessekaiser 46:7a7cb589579a 21 #define MAX_pect 0.09
jessekaiser 46:7a7cb589579a 22 #define MAX_delt 0.09
jessekaiser 45:f5d74c7f8fbf 23 #define MIN_freq 500 //The motor turns off below this frequency
jessekaiser 45:f5d74c7f8fbf 24 #define EMG_tresh 0.02
jessekaiser 31:372ff8d49430 25
jessekaiser 45:f5d74c7f8fbf 26 //Motor control
jessekaiser 46:7a7cb589579a 27 DigitalOut Dirx(p12);
jessekaiser 46:7a7cb589579a 28 DigitalOut Diry(p13);
jessekaiser 46:7a7cb589579a 29 PwmOut Stepx(p21);
jessekaiser 46:7a7cb589579a 30 PwmOut Stepy(p22);
jessekaiser 45:f5d74c7f8fbf 31
jessekaiser 45:f5d74c7f8fbf 32 //Signal to and from computer
jessekaiser 45:f5d74c7f8fbf 33 Serial pc(USBTX, USBRX);
jessekaiser 45:f5d74c7f8fbf 34
jessekaiser 46:7a7cb589579a 35 DigitalOut Enablex(p24); //Connected to green led
jessekaiser 46:7a7cb589579a 36 DigitalOut Enabley(p25); //Connected to blue led
jessekaiser 45:f5d74c7f8fbf 37
jessekaiser 45:f5d74c7f8fbf 38 //Microstepping
jessekaiser 0:3acdd563582f 39 DigitalOut MS1(p27);
jessekaiser 0:3acdd563582f 40 DigitalOut MS2(p28);
jessekaiser 0:3acdd563582f 41 DigitalOut MS3(p29);
jessekaiser 45:f5d74c7f8fbf 42
jessekaiser 45:f5d74c7f8fbf 43 //Potmeter and EMG
jessekaiser 10:7f94cd65c910 44 AnalogIn Pot1(p19);
jessekaiser 31:372ff8d49430 45 AnalogIn Pot2(p20);
jessekaiser 45:f5d74c7f8fbf 46
jessekaiser 46:7a7cb589579a 47 AnalogIn emg1(p15); //EMG bordje bovenop, biceps
jessekaiser 46:7a7cb589579a 48 AnalogIn emg2(p16); //triceps
jessekaiser 46:7a7cb589579a 49 AnalogIn emg3(p17);
jessekaiser 46:7a7cb589579a 50 AnalogIn emg4(p18);
jessekaiser 46:7a7cb589579a 51
jessekaiser 46:7a7cb589579a 52 HIDScope scope(4);
jessekaiser 45:f5d74c7f8fbf 53 Ticker scopeTimer;
jessekaiser 45:f5d74c7f8fbf 54
jessekaiser 45:f5d74c7f8fbf 55 //lcd
jessekaiser 30:0a8f849e0292 56 C12832_LCD lcd;
jessekaiser 0:3acdd563582f 57
jessekaiser 45:f5d74c7f8fbf 58 //Variables for motor control
jessekaiser 45:f5d74c7f8fbf 59 float setpoint = 4400; //Frequentie setpint
jessekaiser 45:f5d74c7f8fbf 60 float step_freq1 = 1;
jessekaiser 45:f5d74c7f8fbf 61 float step_freq2 = 1;
jessekaiser 46:7a7cb589579a 62 float step_freq3 = 1;
jessekaiser 46:7a7cb589579a 63 float step_freq4 = 1;
jessekaiser 45:f5d74c7f8fbf 64
jessekaiser 45:f5d74c7f8fbf 65 //EMG filter
jessekaiser 45:f5d74c7f8fbf 66 arm_biquad_casd_df1_inst_f32 lowpass_biceps;
jessekaiser 45:f5d74c7f8fbf 67 arm_biquad_casd_df1_inst_f32 lowpass_triceps;
jessekaiser 46:7a7cb589579a 68 arm_biquad_casd_df1_inst_f32 lowpass_pect;
jessekaiser 46:7a7cb589579a 69 arm_biquad_casd_df1_inst_f32 lowpass_deltoid;
jessekaiser 45:f5d74c7f8fbf 70 //lowpass filter settings: Fc = 2 Hz, Fs = 500 Hz, Gain = -3 dB
jessekaiser 45:f5d74c7f8fbf 71 float lowpass_const[] = {0.00015514839749793376, 0.00031029679499586753, 0.00015514839749793376, 1.9644602512795832, -0.9650808448695751};
jessekaiser 45:f5d74c7f8fbf 72 arm_biquad_casd_df1_inst_f32 highnotch_biceps;
jessekaiser 45:f5d74c7f8fbf 73 arm_biquad_casd_df1_inst_f32 highnotch_triceps;
jessekaiser 46:7a7cb589579a 74 arm_biquad_casd_df1_inst_f32 highnotch_pect;
jessekaiser 46:7a7cb589579a 75 arm_biquad_casd_df1_inst_f32 highnotch_deltoid;
jessekaiser 45:f5d74c7f8fbf 76 //highpass filter settings: Fc = 20 Hz, Fs = 500 Hz, notch Fc = 50, Fs = 500 Hz
jessekaiser 45:f5d74c7f8fbf 77 float highnotch_const[] = {0.8370879899975344, -1.6741759799950688, 0.8370879899975344, 1.6474576182593796, -0.7008943417307579, 0.7063988100714527, -1.1429772843080923, 0.7063988100714527, 1.1429772843080923, -0.41279762014290533};
jessekaiser 45:f5d74c7f8fbf 78
jessekaiser 45:f5d74c7f8fbf 79 //state values
jessekaiser 45:f5d74c7f8fbf 80 float lowpass_biceps_states[4];
jessekaiser 45:f5d74c7f8fbf 81 float highnotch_biceps_states[8];
jessekaiser 45:f5d74c7f8fbf 82 float lowpass_triceps_states[4];
jessekaiser 45:f5d74c7f8fbf 83 float highnotch_triceps_states[8];
jessekaiser 46:7a7cb589579a 84 float lowpass_pect_states[4];
jessekaiser 46:7a7cb589579a 85 float highnotch_pect_states[8];
jessekaiser 46:7a7cb589579a 86 float lowpass_deltoid_states[4];
jessekaiser 46:7a7cb589579a 87 float highnotch_deltoid_states[8];
jessekaiser 45:f5d74c7f8fbf 88
jessekaiser 45:f5d74c7f8fbf 89 //global variabels
jessekaiser 46:7a7cb589579a 90 float filtered_biceps, filtered_triceps, filtered_pect, filtered_deltoid;
jessekaiser 46:7a7cb589579a 91 float speed_old1, speed_old2, speed_old3, speed_old4;
jessekaiser 46:7a7cb589579a 92 float acc1, acc2, acc3, acc4;
jessekaiser 46:7a7cb589579a 93 float force1, force2, force3, force4;
jessekaiser 46:7a7cb589579a 94 float speed1, speed2, speed3, speed4;
jessekaiser 46:7a7cb589579a 95 float damping1, damping2, damping3, damping4;
jessekaiser 45:f5d74c7f8fbf 96
jessekaiser 45:f5d74c7f8fbf 97 void looper_emg()
jessekaiser 45:f5d74c7f8fbf 98 {
jessekaiser 46:7a7cb589579a 99 float emg_value1_f32, emg_value2_f32, emg_value3_f32, emg_value4_f32;
jessekaiser 45:f5d74c7f8fbf 100 emg_value1_f32 = emg1.read();
jessekaiser 45:f5d74c7f8fbf 101 emg_value2_f32 = emg2.read();
jessekaiser 46:7a7cb589579a 102 emg_value3_f32 = emg3.read();
jessekaiser 46:7a7cb589579a 103 emg_value4_f32 = emg4.read();
jessekaiser 45:f5d74c7f8fbf 104
jessekaiser 45:f5d74c7f8fbf 105 //process emg biceps
jessekaiser 46:7a7cb589579a 106 arm_biquad_cascade_df1_f32(&highnotch_biceps, &emg_value1_f32, &filtered_biceps, 1 ); //High pass and notch filter
jessekaiser 46:7a7cb589579a 107 filtered_biceps = fabs(filtered_biceps); //Rectifier
jessekaiser 46:7a7cb589579a 108 arm_biquad_cascade_df1_f32(&lowpass_biceps, &filtered_biceps, &filtered_biceps, 1 ); //low pass filter
jessekaiser 45:f5d74c7f8fbf 109
jessekaiser 45:f5d74c7f8fbf 110 //process emg triceps
jessekaiser 45:f5d74c7f8fbf 111 arm_biquad_cascade_df1_f32(&highnotch_triceps, &emg_value2_f32, &filtered_triceps, 1 );
jessekaiser 45:f5d74c7f8fbf 112 filtered_triceps = fabs(filtered_triceps);
jessekaiser 45:f5d74c7f8fbf 113 arm_biquad_cascade_df1_f32(&lowpass_triceps, &filtered_triceps, &filtered_triceps, 1 );
jessekaiser 45:f5d74c7f8fbf 114
jessekaiser 46:7a7cb589579a 115 //process emg triceps
jessekaiser 46:7a7cb589579a 116 arm_biquad_cascade_df1_f32(&highnotch_pect, &emg_value3_f32, &filtered_pect, 1 );
jessekaiser 46:7a7cb589579a 117 filtered_pect = fabs(filtered_pect);
jessekaiser 46:7a7cb589579a 118 arm_biquad_cascade_df1_f32(&lowpass_pect, &filtered_pect, &filtered_pect, 1 );
jessekaiser 46:7a7cb589579a 119
jessekaiser 46:7a7cb589579a 120 //process emg triceps
jessekaiser 46:7a7cb589579a 121 arm_biquad_cascade_df1_f32(&highnotch_deltoid, &emg_value4_f32, &filtered_deltoid, 1 );
jessekaiser 46:7a7cb589579a 122 filtered_deltoid = fabs(filtered_deltoid);
jessekaiser 46:7a7cb589579a 123 arm_biquad_cascade_df1_f32(&lowpass_deltoid, &filtered_deltoid, &filtered_deltoid, 1 );
jessekaiser 46:7a7cb589579a 124
jessekaiser 45:f5d74c7f8fbf 125 /*send value to PC. */
jessekaiser 45:f5d74c7f8fbf 126 scope.set(0,filtered_biceps); //Filtered EMG signal
jessekaiser 45:f5d74c7f8fbf 127 scope.set(1,filtered_triceps);
jessekaiser 46:7a7cb589579a 128 scope.set(2,filtered_pect);
jessekaiser 46:7a7cb589579a 129 scope.set(3,filtered_deltoid);
jessekaiser 45:f5d74c7f8fbf 130 }
jessekaiser 45:f5d74c7f8fbf 131
jessekaiser 46:7a7cb589579a 132 void looper_motory()
jessekaiser 45:f5d74c7f8fbf 133 {
jessekaiser 45:f5d74c7f8fbf 134 //Vooruit
jessekaiser 45:f5d74c7f8fbf 135 force1 = K_Gain*(filtered_biceps/MAX_bi);
jessekaiser 45:f5d74c7f8fbf 136 force1 = force1 - damping1;
jessekaiser 45:f5d74c7f8fbf 137 acc1 = force1/Mass;
jessekaiser 45:f5d74c7f8fbf 138 speed1 = speed_old1 + (acc1 * dt);
jessekaiser 45:f5d74c7f8fbf 139 damping1 = speed1 * Damp;
jessekaiser 45:f5d74c7f8fbf 140 step_freq1 = (setpoint*speed1);
jessekaiser 45:f5d74c7f8fbf 141 speed_old1 = speed1;
jessekaiser 45:f5d74c7f8fbf 142
jessekaiser 45:f5d74c7f8fbf 143 //Achteruit triceps
jessekaiser 45:f5d74c7f8fbf 144 force2 = K_Gain*(filtered_triceps/MAX_tri);
jessekaiser 45:f5d74c7f8fbf 145 force2 = force2 - damping2;
jessekaiser 45:f5d74c7f8fbf 146 acc2 = force2/Mass;
jessekaiser 45:f5d74c7f8fbf 147 speed2 = speed_old2 + (acc2 * dt);
jessekaiser 45:f5d74c7f8fbf 148 damping2 = speed2 * Damp;
jessekaiser 45:f5d74c7f8fbf 149 step_freq2 = (setpoint*speed2);
jessekaiser 45:f5d74c7f8fbf 150 speed_old2 = speed2;
jessekaiser 45:f5d74c7f8fbf 151 if (filtered_biceps > filtered_triceps) {
jessekaiser 46:7a7cb589579a 152 Diry = 0;
jessekaiser 45:f5d74c7f8fbf 153 speed2 = 0.01;
jessekaiser 45:f5d74c7f8fbf 154 speed_old2 = 0.01;
jessekaiser 46:7a7cb589579a 155 Stepy.period(1.0/step_freq1);
jessekaiser 45:f5d74c7f8fbf 156 } if (filtered_triceps > filtered_biceps) {
jessekaiser 46:7a7cb589579a 157 Diry = 1;
jessekaiser 45:f5d74c7f8fbf 158 speed1 = 0.01;
jessekaiser 45:f5d74c7f8fbf 159 speed_old1 = 0.01;
jessekaiser 46:7a7cb589579a 160 Stepy.period(1.0/step_freq2);
jessekaiser 45:f5d74c7f8fbf 161 }
jessekaiser 45:f5d74c7f8fbf 162 //Speed limit
jessekaiser 45:f5d74c7f8fbf 163 if (speed1 > 1) {
jessekaiser 45:f5d74c7f8fbf 164 speed1 = 1;
jessekaiser 45:f5d74c7f8fbf 165 step_freq1 = setpoint;
jessekaiser 45:f5d74c7f8fbf 166 }
jessekaiser 45:f5d74c7f8fbf 167 if (speed2 > 1) {
jessekaiser 45:f5d74c7f8fbf 168 speed2 = 1;
jessekaiser 45:f5d74c7f8fbf 169 step_freq2 = setpoint;
jessekaiser 45:f5d74c7f8fbf 170 }
jessekaiser 45:f5d74c7f8fbf 171 //EMG treshold
jessekaiser 45:f5d74c7f8fbf 172 if (filtered_biceps < EMG_tresh && filtered_triceps < EMG_tresh) {
jessekaiser 46:7a7cb589579a 173 Enabley = 1; //Enable = 1 turns the motor off.
jessekaiser 45:f5d74c7f8fbf 174 speed1 = 0.01;
jessekaiser 45:f5d74c7f8fbf 175 speed_old1 = 0.01;
jessekaiser 45:f5d74c7f8fbf 176 speed2 = 0.01;
jessekaiser 45:f5d74c7f8fbf 177 speed_old2 = 0.01;
jessekaiser 45:f5d74c7f8fbf 178 } else {
jessekaiser 46:7a7cb589579a 179 Enabley = 0;
jessekaiser 45:f5d74c7f8fbf 180 }
jessekaiser 45:f5d74c7f8fbf 181
jessekaiser 45:f5d74c7f8fbf 182 }
jessekaiser 45:f5d74c7f8fbf 183
jessekaiser 46:7a7cb589579a 184 void looper_motorx()
jessekaiser 46:7a7cb589579a 185 {
jessekaiser 46:7a7cb589579a 186 //To the left
jessekaiser 46:7a7cb589579a 187 force3 = K_Gain*(filtered_pect/MAX_pect);
jessekaiser 46:7a7cb589579a 188 force3 = force3 - damping3;
jessekaiser 46:7a7cb589579a 189 acc3 = force3/Mass;
jessekaiser 46:7a7cb589579a 190 speed3 = speed_old3 + (acc3 * dt);
jessekaiser 46:7a7cb589579a 191 damping3 = speed3 * Damp;
jessekaiser 46:7a7cb589579a 192 step_freq3 = (setpoint*speed3);
jessekaiser 46:7a7cb589579a 193 speed_old3 = speed3;
jessekaiser 46:7a7cb589579a 194
jessekaiser 46:7a7cb589579a 195 //To the right
jessekaiser 46:7a7cb589579a 196 force4 = K_Gain*(filtered_deltoid/MAX_delt);
jessekaiser 46:7a7cb589579a 197 force4 = force4 - damping4;
jessekaiser 46:7a7cb589579a 198 acc4 = force4/Mass;
jessekaiser 46:7a7cb589579a 199 speed4 = speed_old4 + (acc4 * dt);
jessekaiser 46:7a7cb589579a 200 damping4 = speed4 * Damp;
jessekaiser 46:7a7cb589579a 201 step_freq4 = (setpoint*speed4);
jessekaiser 46:7a7cb589579a 202 speed_old4 = speed4;
jessekaiser 46:7a7cb589579a 203 if (filtered_pect > filtered_deltoid) {
jessekaiser 46:7a7cb589579a 204 Dirx = 0;
jessekaiser 46:7a7cb589579a 205 speed4 = 0.01;
jessekaiser 46:7a7cb589579a 206 speed_old4 = 0.01;
jessekaiser 46:7a7cb589579a 207 Stepy.period(1.0/step_freq3);
jessekaiser 46:7a7cb589579a 208 } if (filtered_triceps > filtered_biceps) {
jessekaiser 46:7a7cb589579a 209 Dirx = 1;
jessekaiser 46:7a7cb589579a 210 speed3 = 0.01;
jessekaiser 46:7a7cb589579a 211 speed_old3 = 0.01;
jessekaiser 46:7a7cb589579a 212 Stepy.period(1.0/step_freq4);
jessekaiser 46:7a7cb589579a 213 }
jessekaiser 46:7a7cb589579a 214 //Speed limit
jessekaiser 46:7a7cb589579a 215 if (speed3 > 1) {
jessekaiser 46:7a7cb589579a 216 speed3 = 1;
jessekaiser 46:7a7cb589579a 217 step_freq3 = setpoint;
jessekaiser 46:7a7cb589579a 218 }
jessekaiser 46:7a7cb589579a 219 if (speed4 > 1) {
jessekaiser 46:7a7cb589579a 220 speed4 = 1;
jessekaiser 46:7a7cb589579a 221 step_freq4 = setpoint;
jessekaiser 46:7a7cb589579a 222 }
jessekaiser 46:7a7cb589579a 223 //EMG treshold
jessekaiser 46:7a7cb589579a 224 if (filtered_pect < EMG_tresh && filtered_deltoid < EMG_tresh) {
jessekaiser 46:7a7cb589579a 225 Enablex = 1; //Enable = 1 turns the motor off.
jessekaiser 46:7a7cb589579a 226 speed3 = 0.01;
jessekaiser 46:7a7cb589579a 227 speed_old3 = 0.01;
jessekaiser 46:7a7cb589579a 228 speed4 = 0.01;
jessekaiser 46:7a7cb589579a 229 speed_old4 = 0.01;
jessekaiser 46:7a7cb589579a 230 } else {
jessekaiser 46:7a7cb589579a 231 Enablex = 0;
jessekaiser 46:7a7cb589579a 232 }
jessekaiser 46:7a7cb589579a 233
jessekaiser 46:7a7cb589579a 234 }
jessekaiser 41:a666a531d52e 235 int main()
jessekaiser 41:a666a531d52e 236 {
jessekaiser 45:f5d74c7f8fbf 237 // Attach the HIDScope::send method from the scope object to the timer at 500Hz. Hier wordt de sample freq aangegeven.
jessekaiser 45:f5d74c7f8fbf 238 scopeTimer.attach_us(&scope, &HIDScope::send, 2e3);
jessekaiser 45:f5d74c7f8fbf 239
jessekaiser 46:7a7cb589579a 240 Ticker emgtimer; //biceps
jessekaiser 45:f5d74c7f8fbf 241 arm_biquad_cascade_df1_init_f32(&lowpass_biceps, 1 , lowpass_const, lowpass_biceps_states);
jessekaiser 45:f5d74c7f8fbf 242 arm_biquad_cascade_df1_init_f32(&highnotch_biceps, 2 , highnotch_const, highnotch_biceps_states);
jessekaiser 46:7a7cb589579a 243 //triceps
jessekaiser 45:f5d74c7f8fbf 244 arm_biquad_cascade_df1_init_f32(&lowpass_triceps, 1 , lowpass_const, lowpass_triceps_states);
jessekaiser 45:f5d74c7f8fbf 245 arm_biquad_cascade_df1_init_f32(&highnotch_triceps, 2 , highnotch_const, highnotch_triceps_states);
jessekaiser 46:7a7cb589579a 246 //pectoralis major
jessekaiser 46:7a7cb589579a 247 arm_biquad_cascade_df1_init_f32(&lowpass_pect, 1 , lowpass_const, lowpass_pect_states);
jessekaiser 46:7a7cb589579a 248 arm_biquad_cascade_df1_init_f32(&highnotch_pect, 2 , highnotch_const, highnotch_pect_states);
jessekaiser 46:7a7cb589579a 249 //deltoid
jessekaiser 46:7a7cb589579a 250 arm_biquad_cascade_df1_init_f32(&lowpass_deltoid, 1 , lowpass_const, lowpass_deltoid_states);
jessekaiser 46:7a7cb589579a 251 arm_biquad_cascade_df1_init_f32(&highnotch_deltoid, 2 , highnotch_const, highnotch_deltoid_states);
jessekaiser 45:f5d74c7f8fbf 252 emgtimer.attach(looper_emg, 0.002);
jessekaiser 45:f5d74c7f8fbf 253
jessekaiser 45:f5d74c7f8fbf 254 Ticker looptimer;
jessekaiser 46:7a7cb589579a 255 looptimer.attach(looper_motorx, 0.01); //X-Spindle motor, why this freq?
jessekaiser 46:7a7cb589579a 256 looptimer.attach(looper_motory, 0.01); //Y-Spindle motor
jessekaiser 46:7a7cb589579a 257
jessekaiser 46:7a7cb589579a 258 //Microstepping control, now configured as half stepping (MS1=1,MS2=0,MS3=0)
jessekaiser 44:d5aa53e4778c 259 MS1 = 1;
jessekaiser 45:f5d74c7f8fbf 260 MS2 = 0;
jessekaiser 44:d5aa53e4778c 261 MS3 = 0;
jessekaiser 46:7a7cb589579a 262 Stepx.write(0.5); // Duty cycle of 50%
jessekaiser 46:7a7cb589579a 263 Stepy.write(0.5);
jessekaiser 45:f5d74c7f8fbf 264
jessekaiser 44:d5aa53e4778c 265 while (1) {
jessekaiser 23:4d050e85e863 266
jessekaiser 46:7a7cb589579a 267 //lcd.printf("Bi %.2f ,Tri %.2f \n", filtered_biceps, filtered_triceps); Filtered EMG values
jessekaiser 46:7a7cb589579a 268 lcd.printf("1 %.0f, 2 %.0f, 3 %.0f, 4 %.0f \n", step_freq1, step_freq2, step_freq3, step_freq4); //step_freq value of every EMG sensor
jessekaiser 45:f5d74c7f8fbf 269 wait(0.01);
jessekaiser 0:3acdd563582f 270 }
jessekaiser 45:f5d74c7f8fbf 271 }