Cleaner version
Dependencies: HIDScope MODSERIAL Motordriver QEI Servo mbed
Fork of The_Claw_with_EMG_Control_PID by
main.cpp@18:cbe3fe6d89a7, 2016-11-07 (annotated)
- Committer:
- Nickname
- Date:
- Mon Nov 07 11:40:27 2016 +0000
- Revision:
- 18:cbe3fe6d89a7
- Parent:
- 17:18e9df406502
Clean
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
megrootens | 0:048fbd80203e | 1 | #include "mbed.h" |
meikefrok | 5:3d88f7506cd9 | 2 | #include "MODSERIAL.h" |
meikefrok | 5:3d88f7506cd9 | 3 | #define SERIAL_BAUD 115200 |
meikefrok | 3:3a671d01bcb8 | 4 | #include "motordriver.h" |
meikefrok | 5:3d88f7506cd9 | 5 | #include "QEI.h" |
meikefrok | 5:3d88f7506cd9 | 6 | #include "Servo.h" |
meikefrok | 10:31e4c3d71ee6 | 7 | #include "HIDScope.h" |
megrootens | 0:048fbd80203e | 8 | |
meikefrok | 5:3d88f7506cd9 | 9 | //======== Serial Communication ================================================ |
megrootens | 0:048fbd80203e | 10 | MODSERIAL pc(USBTX,USBRX); |
megrootens | 0:048fbd80203e | 11 | |
meikefrok | 5:3d88f7506cd9 | 12 | //======== Motor and QEI ======================================================= |
meikefrok | 5:3d88f7506cd9 | 13 | int Brakeable; |
meikefrok | 5:3d88f7506cd9 | 14 | int sign; |
meikefrok | 5:3d88f7506cd9 | 15 | |
meikefrok | 5:3d88f7506cd9 | 16 | // motor |
Nickname | 18:cbe3fe6d89a7 | 17 | Motor Cart(D5, D4, D4, Brakeable); //right motor |
Nickname | 18:cbe3fe6d89a7 | 18 | Motor Arm(D6,D7, D7, Brakeable); //left motor |
meikefrok | 5:3d88f7506cd9 | 19 | |
Nickname | 18:cbe3fe6d89a7 | 20 | // QEI |
meikefrok | 6:23b1ed826b59 | 21 | QEI Encoder_Cart(D10, D11, NC, 6400); |
meikefrok | 6:23b1ed826b59 | 22 | QEI Encoder_Arm(D12, D13, NC, 6400); |
megrootens | 0:048fbd80203e | 23 | |
meikefrok | 5:3d88f7506cd9 | 24 | // servo |
meikefrok | 5:3d88f7506cd9 | 25 | Servo servo(D9); |
megrootens | 0:048fbd80203e | 26 | |
meikefrok | 5:3d88f7506cd9 | 27 | //======== Miscellaneous ======================================================= |
meikefrok | 5:3d88f7506cd9 | 28 | // button |
meikefrok | 5:3d88f7506cd9 | 29 | InterruptIn btn(SW2); |
meikefrok | 5:3d88f7506cd9 | 30 | InterruptIn btn2(SW3); |
meikefrok | 5:3d88f7506cd9 | 31 | |
meikefrok | 5:3d88f7506cd9 | 32 | InterruptIn btn_cart(D1); |
meikefrok | 5:3d88f7506cd9 | 33 | InterruptIn btn_arm(D2); |
meikefrok | 5:3d88f7506cd9 | 34 | InterruptIn btn_claw(D3); |
meikefrok | 5:3d88f7506cd9 | 35 | |
meikefrok | 5:3d88f7506cd9 | 36 | // led |
meikefrok | 2:ad4b181a6422 | 37 | DigitalOut led_r(LED_RED); |
meikefrok | 2:ad4b181a6422 | 38 | DigitalOut led_g(LED_GREEN); |
meikefrok | 2:ad4b181a6422 | 39 | DigitalOut led_b(LED_BLUE); |
megrootens | 0:048fbd80203e | 40 | |
meikefrok | 5:3d88f7506cd9 | 41 | // potmeter |
meikefrok | 5:3d88f7506cd9 | 42 | AnalogIn pot_cart(A2); |
meikefrok | 5:3d88f7506cd9 | 43 | AnalogIn pot_arm(A3); |
megrootens | 0:048fbd80203e | 44 | |
Nickname | 18:cbe3fe6d89a7 | 45 | AnalogIn emgl(A1); //labels are attached to the olimex shields the left tricep |
Nickname | 18:cbe3fe6d89a7 | 46 | AnalogIn emgr(A0); //should obviously be connected to the shield with an L label |
meikefrok | 7:9715323b20ac | 47 | |
meikefrok | 5:3d88f7506cd9 | 48 | // ticker |
Nickname | 18:cbe3fe6d89a7 | 49 | Ticker tick_part_cart; //ticker to switch to cart part |
Nickname | 18:cbe3fe6d89a7 | 50 | Ticker tick_part_arm; //ticker to switch to arm part |
Nickname | 18:cbe3fe6d89a7 | 51 | Ticker tick_part_claw; //ticker to switch to claw part |
Nickname | 18:cbe3fe6d89a7 | 52 | Ticker sampleTicker; //ticker to sample the EMG signal |
Nickname | 18:cbe3fe6d89a7 | 53 | Ticker measureTicker; //ticker to read out encoder |
Nickname | 18:cbe3fe6d89a7 | 54 | |
Nickname | 18:cbe3fe6d89a7 | 55 | HIDScope scope(2); //scope has two ports for the two EMG signals |
meikefrok | 5:3d88f7506cd9 | 56 | |
meikefrok | 5:3d88f7506cd9 | 57 | //======== Variables =========================================================== |
meikefrok | 5:3d88f7506cd9 | 58 | // speed |
meikefrok | 16:3c9a3ff09765 | 59 | double cart_speed = 0.2; |
meikefrok | 6:23b1ed826b59 | 60 | double arm_speed = 0.1; |
megrootens | 0:048fbd80203e | 61 | |
meikefrok | 5:3d88f7506cd9 | 62 | // position |
meikefrok | 12:b31df384b170 | 63 | float factor_cart = 0.05802; |
meikefrok | 5:3d88f7506cd9 | 64 | float factor_arm = 0.1539; |
meikefrok | 5:3d88f7506cd9 | 65 | int position_cart; |
meikefrok | 5:3d88f7506cd9 | 66 | int position_arm; |
Nickname | 18:cbe3fe6d89a7 | 67 | int position_claw; |
meikefrok | 5:3d88f7506cd9 | 68 | float ain_cart; //Variable to store the analog input of the cart |
meikefrok | 5:3d88f7506cd9 | 69 | float ain_arm; //Variable to store the analog input of the arm |
megrootens | 0:048fbd80203e | 70 | |
Nickname | 18:cbe3fe6d89a7 | 71 | //calibrate |
meikefrok | 17:18e9df406502 | 72 | int t = 0; |
meikefrok | 17:18e9df406502 | 73 | double value_right = 0; |
meikefrok | 17:18e9df406502 | 74 | double value_left = 0; |
meikefrok | 17:18e9df406502 | 75 | |
Nickname | 18:cbe3fe6d89a7 | 76 | //P Controller |
Nickname | 18:cbe3fe6d89a7 | 77 | const double Setpoint_Cart = 0; |
Nickname | 18:cbe3fe6d89a7 | 78 | const double Setpoint_Arm = 0; |
Nickname | 18:cbe3fe6d89a7 | 79 | double Arm_ControlSpeed = 0; |
Nickname | 18:cbe3fe6d89a7 | 80 | double Cart_ControlSpeed = 0; |
Nickname | 18:cbe3fe6d89a7 | 81 | double SetpointError_Cart = 0; |
Nickname | 18:cbe3fe6d89a7 | 82 | double SetpointError_Arm = 0; |
Nickname | 18:cbe3fe6d89a7 | 83 | double setpoint; |
Nickname | 18:cbe3fe6d89a7 | 84 | //Cart |
Nickname | 18:cbe3fe6d89a7 | 85 | const double Ts = 0.002; //Ts=1/fs (sample frequency) |
Nickname | 18:cbe3fe6d89a7 | 86 | const double Cart_Kp = 0.1, Cart_Ki = 0.0, Cart_Kd = 0.0; |
Nickname | 18:cbe3fe6d89a7 | 87 | double Cart_error = 0; |
Nickname | 18:cbe3fe6d89a7 | 88 | double Cart_e_prev = 0; |
Nickname | 18:cbe3fe6d89a7 | 89 | //Arm |
Nickname | 18:cbe3fe6d89a7 | 90 | const double Arm_Kp = 0.1, Arm_Ki = 0.0, Arm_Kd = 0.0; |
Nickname | 18:cbe3fe6d89a7 | 91 | double Arm_error = 0; |
Nickname | 18:cbe3fe6d89a7 | 92 | double Arm_e_prev = 0; |
Nickname | 18:cbe3fe6d89a7 | 93 | |
Nickname | 18:cbe3fe6d89a7 | 94 | |
Nickname | 18:cbe3fe6d89a7 | 95 | // miscellaneous |
Nickname | 18:cbe3fe6d89a7 | 96 | const float kTimeToggle = 0.05f; //period with which to toggle the parts |
Nickname | 18:cbe3fe6d89a7 | 97 | const int LedOn = 0; //LED on if 0 |
Nickname | 18:cbe3fe6d89a7 | 98 | volatile int part_id = 1; //ID of what part should move, begins with cart |
Nickname | 18:cbe3fe6d89a7 | 99 | volatile int servo_id = 1; //ID to the side the servo moves, begins in center |
Nickname | 18:cbe3fe6d89a7 | 100 | int waiting_claw = 1000; //Servo delay to make claw control easier |
Nickname | 18:cbe3fe6d89a7 | 101 | |
Nickname | 18:cbe3fe6d89a7 | 102 | //======== Variables Filter ==================================================== |
Nickname | 18:cbe3fe6d89a7 | 103 | /*coefficients of each filter |
Nickname | 18:cbe3fe6d89a7 | 104 | lno = left tricep notch filter at 50 Hz |
Nickname | 18:cbe3fe6d89a7 | 105 | lno2 = left tricep notch filter at 100 Hz |
Nickname | 18:cbe3fe6d89a7 | 106 | lhf = left tricep high pass filter |
Nickname | 18:cbe3fe6d89a7 | 107 | llf = left tricep lowpass filter |
Nickname | 18:cbe3fe6d89a7 | 108 | same goes for rno etc. |
Nickname | 18:cbe3fe6d89a7 | 109 | */ |
Nickname | 18:cbe3fe6d89a7 | 110 | double lno_b0 = 0.9911; double rno_b0 = 0.9911; |
Nickname | 18:cbe3fe6d89a7 | 111 | double lno_b1 = -1.6036; double rno_b1 = -1.6036; |
Nickname | 18:cbe3fe6d89a7 | 112 | double lno_b2 = 0.9911; double rno_b2 = 0.9911; |
Nickname | 18:cbe3fe6d89a7 | 113 | double lno_a1 = -1.603; double rno_a1 = -1.603; |
Nickname | 18:cbe3fe6d89a7 | 114 | double lno_a2 = 0.9822; double rno_a2 = 0.9822; |
Nickname | 18:cbe3fe6d89a7 | 115 | |
Nickname | 18:cbe3fe6d89a7 | 116 | double lno2_b0 = 0.9824; double rno2_b0 = 0.9824; |
Nickname | 18:cbe3fe6d89a7 | 117 | double lno2_b1 = -0.6071; double rno2_b1 = -0.6071; |
Nickname | 18:cbe3fe6d89a7 | 118 | double lno2_b2 = 0.9824; double rno2_b2 = 0.9824; |
Nickname | 18:cbe3fe6d89a7 | 119 | double lno2_a1 = -0.6071; double rno2_a1 = -0.6071; |
Nickname | 18:cbe3fe6d89a7 | 120 | double lno2_a2 = 0.9647; double rno2_a2 = 0.9647; |
Nickname | 18:cbe3fe6d89a7 | 121 | |
Nickname | 18:cbe3fe6d89a7 | 122 | double lhf_b0 = 0.9355; double rhf_b0 = 0.9355; |
Nickname | 18:cbe3fe6d89a7 | 123 | double lhf_b1 = -1.8711; double rhf_b1 = -1.8711; |
Nickname | 18:cbe3fe6d89a7 | 124 | double lhf_b2 = 0.9355; double rhf_b2 = 0.9355; |
Nickname | 18:cbe3fe6d89a7 | 125 | double lhf_a1 = -1.8669; double rhf_a1 = -1.8669; |
Nickname | 18:cbe3fe6d89a7 | 126 | double lhf_a2 = 0.8752; double rhf_a2 = 0.8752; |
Nickname | 18:cbe3fe6d89a7 | 127 | |
Nickname | 18:cbe3fe6d89a7 | 128 | double llf_b0 = 8.7656e-5; double rlf_b0 = 8.7656e-5; |
Nickname | 18:cbe3fe6d89a7 | 129 | double llf_b1 = 1.17531e-4; double rlf_b1 = 1.17531e-4; |
Nickname | 18:cbe3fe6d89a7 | 130 | double llf_b2 = 8.7656e-5; double rlf_b2 = 8.7656e-5; |
Nickname | 18:cbe3fe6d89a7 | 131 | double llf_a1 = -1.9733; double rlf_a1 = -1.9733; |
Nickname | 18:cbe3fe6d89a7 | 132 | double llf_a2 = 0.9737; double rlf_a2 = 0.9737; |
Nickname | 18:cbe3fe6d89a7 | 133 | |
Nickname | 18:cbe3fe6d89a7 | 134 | //starting values of the biquads of the corresponding filters |
Nickname | 18:cbe3fe6d89a7 | 135 | double lno_v1 = 0, lno_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 136 | double lno2_v1 = 0, lno2_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 137 | double lhf_v1 = 0, lhf_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 138 | double llf_v1 = 0, llf_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 139 | |
Nickname | 18:cbe3fe6d89a7 | 140 | double rno_v1 = 0, rno_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 141 | double rno2_v1 = 0, rno2_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 142 | double rhf_v1 = 0, rhf_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 143 | double rlf_v1 = 0, rlf_v2 = 0; |
Nickname | 18:cbe3fe6d89a7 | 144 | |
Nickname | 18:cbe3fe6d89a7 | 145 | //declaration of the outputs of each biquad. The output of the previous biquad |
Nickname | 18:cbe3fe6d89a7 | 146 | //is the input for the next biquad. So lno_y goes into lhf_y etc. |
Nickname | 18:cbe3fe6d89a7 | 147 | double lno_y; double rno_y; |
Nickname | 18:cbe3fe6d89a7 | 148 | double lno2_y; double rno2_y; |
Nickname | 18:cbe3fe6d89a7 | 149 | double lhf_y; double rhf_y; |
Nickname | 18:cbe3fe6d89a7 | 150 | double llf_y; double rlf_y; |
Nickname | 18:cbe3fe6d89a7 | 151 | double lrect_y; double rrect_y; |
Nickname | 18:cbe3fe6d89a7 | 152 | |
Nickname | 18:cbe3fe6d89a7 | 153 | //set the threshold value for the filtered signal |
Nickname | 18:cbe3fe6d89a7 | 154 | //if the signal exceeds this value the motors will start to rotate |
Nickname | 18:cbe3fe6d89a7 | 155 | const double threshold_value = 0.1; |
Nickname | 18:cbe3fe6d89a7 | 156 | const double threshold_value_claw = 0.08; |
Nickname | 18:cbe3fe6d89a7 | 157 | const double threshold_value_cart = 0.08; |
Nickname | 18:cbe3fe6d89a7 | 158 | |
Nickname | 18:cbe3fe6d89a7 | 159 | /* declaration of each biquad |
Nickname | 18:cbe3fe6d89a7 | 160 | The coefficients will be filled in later on in void scopeSend |
Nickname | 18:cbe3fe6d89a7 | 161 | The input of the first biquad is the raw EMG signal and the output of the last |
Nickname | 18:cbe3fe6d89a7 | 162 | biquad is the filtered signal. This is done for both left and right so this |
Nickname | 18:cbe3fe6d89a7 | 163 | makes two chains of 4 biquads */ |
Nickname | 18:cbe3fe6d89a7 | 164 | double biquad_lno(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 165 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 166 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 167 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 168 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 169 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 170 | return y; |
Nickname | 18:cbe3fe6d89a7 | 171 | } |
Nickname | 18:cbe3fe6d89a7 | 172 | double biquad_lno2(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 173 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 174 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 175 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 176 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 177 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 178 | return y; |
Nickname | 18:cbe3fe6d89a7 | 179 | } |
Nickname | 18:cbe3fe6d89a7 | 180 | double biquad_lhf(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 181 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 182 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 183 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 184 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 185 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 186 | return y; |
Nickname | 18:cbe3fe6d89a7 | 187 | } |
Nickname | 18:cbe3fe6d89a7 | 188 | double biquad_llf(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 189 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 190 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 191 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 192 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 193 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 194 | return y; |
Nickname | 18:cbe3fe6d89a7 | 195 | } |
Nickname | 18:cbe3fe6d89a7 | 196 | double biquad_rno(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 197 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 198 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 199 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 200 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 201 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 202 | return y; |
Nickname | 18:cbe3fe6d89a7 | 203 | } |
Nickname | 18:cbe3fe6d89a7 | 204 | double biquad_rno2(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 205 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 206 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 207 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 208 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 209 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 210 | return y; |
Nickname | 18:cbe3fe6d89a7 | 211 | } |
Nickname | 18:cbe3fe6d89a7 | 212 | double biquad_rhf(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 213 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 214 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 215 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 216 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 217 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 218 | return y; |
Nickname | 18:cbe3fe6d89a7 | 219 | } |
Nickname | 18:cbe3fe6d89a7 | 220 | double biquad_rlf(double u, double&v1, double&v2, const double a1, const double a2, |
Nickname | 18:cbe3fe6d89a7 | 221 | const double b0, const double b1, const double b2){ |
Nickname | 18:cbe3fe6d89a7 | 222 | double v = u - a1*v1 - a2*v2; |
Nickname | 18:cbe3fe6d89a7 | 223 | double y = b0*v + b1*v1 + b2*v2; |
Nickname | 18:cbe3fe6d89a7 | 224 | v2 = v1; |
Nickname | 18:cbe3fe6d89a7 | 225 | v1 = v; |
Nickname | 18:cbe3fe6d89a7 | 226 | return y; |
Nickname | 18:cbe3fe6d89a7 | 227 | } |
Nickname | 18:cbe3fe6d89a7 | 228 | |
Nickname | 18:cbe3fe6d89a7 | 229 | //calibration to determine maximum EMG value |
meikefrok | 17:18e9df406502 | 230 | double calibrate_right(){ |
meikefrok | 17:18e9df406502 | 231 | for(t=0; t<200; t++){ |
meikefrok | 17:18e9df406502 | 232 | if(value_right <= rlf_y){ |
Nickname | 18:cbe3fe6d89a7 | 233 | value_right = rlf_y; |
meikefrok | 17:18e9df406502 | 234 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 235 | value_right = value_right +0.0; |
Nickname | 18:cbe3fe6d89a7 | 236 | }} |
meikefrok | 17:18e9df406502 | 237 | return value_right; |
meikefrok | 17:18e9df406502 | 238 | } |
meikefrok | 17:18e9df406502 | 239 | double calibrate_left(){ |
meikefrok | 17:18e9df406502 | 240 | for(t=0; t<200; t++){ |
meikefrok | 17:18e9df406502 | 241 | if(value_left <= llf_y){ |
meikefrok | 17:18e9df406502 | 242 | value_left = llf_y; |
meikefrok | 17:18e9df406502 | 243 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 244 | value_left = value_left +0.0; |
Nickname | 18:cbe3fe6d89a7 | 245 | }} |
meikefrok | 17:18e9df406502 | 246 | return value_left; |
meikefrok | 17:18e9df406502 | 247 | } |
meikefrok | 17:18e9df406502 | 248 | |
Nickname | 18:cbe3fe6d89a7 | 249 | //======== P Controller ======================================================== |
Nickname | 18:cbe3fe6d89a7 | 250 | double p_control(double error, const double kp, const double ki, const double kd, |
Nickname | 18:cbe3fe6d89a7 | 251 | double &e_int, double &e_prev){ |
Nickname | 18:cbe3fe6d89a7 | 252 | double e_der = (error - e_prev) / Ts; |
Nickname | 18:cbe3fe6d89a7 | 253 | e_prev = error; |
Nickname | 18:cbe3fe6d89a7 | 254 | e_int = e_int + (Ts * error); |
meikefrok | 17:18e9df406502 | 255 | |
Nickname | 18:cbe3fe6d89a7 | 256 | return kp*error + ki + e_int + kd + e_der; |
meikefrok | 17:18e9df406502 | 257 | } |
meikefrok | 17:18e9df406502 | 258 | |
meikefrok | 7:9715323b20ac | 259 | //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
meikefrok | 7:9715323b20ac | 260 | //======== Functions and main ============================================================== |
meikefrok | 7:9715323b20ac | 261 | /* function that calculates the filtered EMG signal from the raw EMG signal. |
Nickname | 18:cbe3fe6d89a7 | 262 | So 2 chains of 4 biquads each are calculating the left and the right filtered EMG signal. |
meikefrok | 7:9715323b20ac | 263 | After this is calculated, the signals are sent to HIDscope (scope.send) to see what they look like. |
Nickname | 18:cbe3fe6d89a7 | 264 | The filtered signals (rlf_y and llf_y) are shown in channel 0 and 1 (scope.set)*/ |
Nickname | 18:cbe3fe6d89a7 | 265 | void scopeSend(){ |
meikefrok | 7:9715323b20ac | 266 | lno_y = biquad_lno(emgl.read(), lno_v1, lno_v2, lno_a1, lno_a2, lno_b0, lno_b1, lno_b2); |
meikefrok | 7:9715323b20ac | 267 | lno2_y = biquad_lno2(lno_y, lno2_v1, lno2_v2, lno2_a1, lno2_a2, lno2_b0, lno2_b1, lno2_b2); |
meikefrok | 7:9715323b20ac | 268 | lhf_y = biquad_lhf(lno2_y, lhf_v1, lhf_v2, lhf_a1, lhf_a2, lhf_b0, lhf_b1, lhf_b2); |
meikefrok | 7:9715323b20ac | 269 | lrect_y = fabs(lhf_y); |
meikefrok | 17:18e9df406502 | 270 | llf_y = biquad_llf(lrect_y, llf_v1, llf_v2, llf_a1, llf_a2, llf_b0, llf_b1, llf_b2)/value_left; |
meikefrok | 17:18e9df406502 | 271 | |
meikefrok | 7:9715323b20ac | 272 | rno_y = biquad_rno(emgr.read(), rno_v1, rno_v2, rno_a1, rno_a2, rno_b0, rno_b1, rno_b2); |
meikefrok | 7:9715323b20ac | 273 | rno2_y = biquad_rno2(rno_y, rno2_v1, rno2_v2, rno2_a1, rno2_a2, rno2_b0, rno2_b1, rno2_b2); |
meikefrok | 7:9715323b20ac | 274 | rhf_y = biquad_rhf(rno2_y, rhf_v1, rhf_v2, rhf_a1, rhf_a2, rhf_b0, rhf_b1, rhf_b2); |
meikefrok | 7:9715323b20ac | 275 | rrect_y = fabs(rhf_y); |
meikefrok | 17:18e9df406502 | 276 | rlf_y = biquad_rlf(rrect_y, rlf_v1, rlf_v2, rlf_a1, rlf_a2, rlf_b0, rlf_b1, rlf_b2)/value_right; |
meikefrok | 17:18e9df406502 | 277 | |
meikefrok | 16:3c9a3ff09765 | 278 | scope.set(1, llf_y); |
meikefrok | 16:3c9a3ff09765 | 279 | scope.set(0, rlf_y); |
meikefrok | 16:3c9a3ff09765 | 280 | scope.send(); |
meikefrok | 7:9715323b20ac | 281 | } |
meikefrok | 7:9715323b20ac | 282 | |
meikefrok | 10:31e4c3d71ee6 | 283 | void Measure(){ |
Nickname | 18:cbe3fe6d89a7 | 284 | // encoder Cart |
Nickname | 18:cbe3fe6d89a7 | 285 | position_cart = (Encoder_Cart.getPulses()*factor_cart); |
meikefrok | 10:31e4c3d71ee6 | 286 | ain_cart = pot_cart.read(); |
meikefrok | 12:b31df384b170 | 287 | |
Nickname | 18:cbe3fe6d89a7 | 288 | // encoder Arm |
Nickname | 18:cbe3fe6d89a7 | 289 | position_arm = (Encoder_Arm.getPulses()*factor_arm); |
meikefrok | 13:dd7b41766f5f | 290 | ain_arm = pot_arm.read(); |
meikefrok | 13:dd7b41766f5f | 291 | |
meikefrok | 16:3c9a3ff09765 | 292 | if (ain_arm == 0){ |
meikefrok | 16:3c9a3ff09765 | 293 | Encoder_Arm.reset(); |
meikefrok | 16:3c9a3ff09765 | 294 | }else {} |
meikefrok | 10:31e4c3d71ee6 | 295 | } |
meikefrok | 10:31e4c3d71ee6 | 296 | |
meikefrok | 5:3d88f7506cd9 | 297 | // Switch between Cart, Arm and Claw |
meikefrok | 8:ac4e5afbdbcd | 298 | void SwitchCart(){ |
meikefrok | 2:ad4b181a6422 | 299 | switch (part_id) { |
Nickname | 18:cbe3fe6d89a7 | 300 | //Cart |
Nickname | 18:cbe3fe6d89a7 | 301 | case 2: { |
Nickname | 18:cbe3fe6d89a7 | 302 | led_r = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 303 | if (rlf_y > threshold_value_cart){ |
Nickname | 18:cbe3fe6d89a7 | 304 | if(position_cart <= -170){ |
Nickname | 18:cbe3fe6d89a7 | 305 | Cart.stop(1)==1; //If the cart is at the right side, it stops |
Nickname | 18:cbe3fe6d89a7 | 306 | |
Nickname | 18:cbe3fe6d89a7 | 307 | }else if(position_cart >= 170 && position_arm <=-100){ |
Nickname | 18:cbe3fe6d89a7 | 308 | Cart.stop(1) == 1; //If the cart is at the left side and the arm is |
Nickname | 18:cbe3fe6d89a7 | 309 | //rotated 60 degrees to the left, the cart can't move to the right. |
Nickname | 18:cbe3fe6d89a7 | 310 | |
Nickname | 18:cbe3fe6d89a7 | 311 | }else if(position_cart >= 170 && position_arm <=-160 && position_claw == -18){ |
Nickname | 18:cbe3fe6d89a7 | 312 | Cart.stop(1) == 1; |
Nickname | 18:cbe3fe6d89a7 | 313 | |
Nickname | 18:cbe3fe6d89a7 | 314 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 315 | Cart.speed(cart_speed)==cart_speed; |
Nickname | 18:cbe3fe6d89a7 | 316 | } |
Nickname | 18:cbe3fe6d89a7 | 317 | if (llf_y > threshold_value_cart){ |
Nickname | 18:cbe3fe6d89a7 | 318 | Cart.stop(1)==1; |
meikefrok | 5:3d88f7506cd9 | 319 | } |
Nickname | 18:cbe3fe6d89a7 | 320 | }else if (llf_y > threshold_value_cart){ |
Nickname | 18:cbe3fe6d89a7 | 321 | if(position_cart >= 170){ |
Nickname | 18:cbe3fe6d89a7 | 322 | Cart.stop(1)==1; ////If the cart is at the left side, it stops |
meikefrok | 16:3c9a3ff09765 | 323 | |
Nickname | 18:cbe3fe6d89a7 | 324 | }else if(position_cart <= -170 && position_arm >=100){ |
Nickname | 18:cbe3fe6d89a7 | 325 | Cart.stop(1) == 1; //similar with the left side |
Nickname | 18:cbe3fe6d89a7 | 326 | |
Nickname | 18:cbe3fe6d89a7 | 327 | }else if(position_cart <= -170 && position_arm >=160 && position_claw == 27){ |
Nickname | 18:cbe3fe6d89a7 | 328 | Cart.stop(1)==1; |
Nickname | 18:cbe3fe6d89a7 | 329 | |
Nickname | 18:cbe3fe6d89a7 | 330 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 331 | Cart.speed(-cart_speed)==-cart_speed; |
meikefrok | 5:3d88f7506cd9 | 332 | } |
Nickname | 18:cbe3fe6d89a7 | 333 | if (rlf_y > threshold_value_cart){ |
Nickname | 18:cbe3fe6d89a7 | 334 | Cart.stop(1)==1; |
meikefrok | 12:b31df384b170 | 335 | } |
Nickname | 18:cbe3fe6d89a7 | 336 | }else { |
Nickname | 18:cbe3fe6d89a7 | 337 | Cart.stop(1)==1; |
Nickname | 18:cbe3fe6d89a7 | 338 | }} |
Nickname | 18:cbe3fe6d89a7 | 339 | if(!btn && !btn2) { |
Nickname | 18:cbe3fe6d89a7 | 340 | Arm.speed(0) == 0; |
Nickname | 18:cbe3fe6d89a7 | 341 | if(position_cart<0){ |
Nickname | 18:cbe3fe6d89a7 | 342 | Cart.speed(-0.1)== -0.1; |
Nickname | 18:cbe3fe6d89a7 | 343 | }else if(position_cart>0){ |
Nickname | 18:cbe3fe6d89a7 | 344 | Cart.speed(0.1)==0.1; |
Nickname | 18:cbe3fe6d89a7 | 345 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 346 | Cart.stop(0)==0; |
Nickname | 18:cbe3fe6d89a7 | 347 | }} |
Nickname | 18:cbe3fe6d89a7 | 348 | //Controller |
Nickname | 18:cbe3fe6d89a7 | 349 | SetpointError_Cart = setpoint - position_cart; |
Nickname | 18:cbe3fe6d89a7 | 350 | //set direction |
Nickname | 18:cbe3fe6d89a7 | 351 | if (SetpointError_Cart < 0) { |
meikefrok | 17:18e9df406502 | 352 | cart_speed = 0; |
Nickname | 18:cbe3fe6d89a7 | 353 | }else{} |
Nickname | 18:cbe3fe6d89a7 | 354 | |
Nickname | 18:cbe3fe6d89a7 | 355 | Cart_ControlSpeed = Ts * fabs( p_control(SetpointError_Cart, Cart_Kp, Cart_Ki, Cart_Kd, Cart_error, Cart_e_prev)); |
Nickname | 18:cbe3fe6d89a7 | 356 | if (fabs(SetpointError_Cart) < fabs(Setpoint_Cart*0.05)) { |
meikefrok | 17:18e9df406502 | 357 | cart_speed = 0; |
Nickname | 18:cbe3fe6d89a7 | 358 | }else{ |
meikefrok | 17:18e9df406502 | 359 | cart_speed = Cart_ControlSpeed; |
meikefrok | 17:18e9df406502 | 360 | } |
meikefrok | 5:3d88f7506cd9 | 361 | // controle LED |
meikefrok | 3:3a671d01bcb8 | 362 | led_g = not LedOn; |
meikefrok | 5:3d88f7506cd9 | 363 | led_b = not LedOn; |
meikefrok | 12:b31df384b170 | 364 | |
meikefrok | 5:3d88f7506cd9 | 365 | pc.baud(115200); |
meikefrok | 5:3d88f7506cd9 | 366 | pc.printf("Distance in mm: %i\n", position_cart); |
megrootens | 0:048fbd80203e | 367 | break; |
Nickname | 18:cbe3fe6d89a7 | 368 | }} |
meikefrok | 8:ac4e5afbdbcd | 369 | |
meikefrok | 8:ac4e5afbdbcd | 370 | void SwitchArm(){ |
meikefrok | 8:ac4e5afbdbcd | 371 | switch (part_id) { |
Nickname | 18:cbe3fe6d89a7 | 372 | //Cart |
Nickname | 18:cbe3fe6d89a7 | 373 | case 3: { |
Nickname | 18:cbe3fe6d89a7 | 374 | led_g = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 375 | if (rlf_y > threshold_value_claw) { |
Nickname | 18:cbe3fe6d89a7 | 376 | if(position_cart > -170 && position_arm >= 90){ //If the cart is not at |
Nickname | 18:cbe3fe6d89a7 | 377 | Arm.stop(1)==1; //the end, the arm can't move any further than 45 degrees |
Nickname | 18:cbe3fe6d89a7 | 378 | |
Nickname | 18:cbe3fe6d89a7 | 379 | }else if(position_cart > -200 && position_arm >= 60 && position_claw == 27){ |
meikefrok | 13:dd7b41766f5f | 380 | Arm.stop(1)==1; |
meikefrok | 16:3c9a3ff09765 | 381 | |
Nickname | 18:cbe3fe6d89a7 | 382 | }else if(position_cart<= -170 && position_arm>=160){ //If the cart is at |
Nickname | 18:cbe3fe6d89a7 | 383 | Arm.stop(1)==1; //the right end, the arm can't move any further than 70 degrees |
Nickname | 18:cbe3fe6d89a7 | 384 | |
Nickname | 18:cbe3fe6d89a7 | 385 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 386 | Arm.speed(arm_speed)==arm_speed; |
Nickname | 18:cbe3fe6d89a7 | 387 | } |
Nickname | 18:cbe3fe6d89a7 | 388 | |
Nickname | 18:cbe3fe6d89a7 | 389 | if (llf_y > threshold_value){ |
meikefrok | 13:dd7b41766f5f | 390 | Cart.stop(1)==1; |
Nickname | 18:cbe3fe6d89a7 | 391 | } |
Nickname | 18:cbe3fe6d89a7 | 392 | |
Nickname | 18:cbe3fe6d89a7 | 393 | }else if (llf_y > threshold_value_claw) { |
Nickname | 18:cbe3fe6d89a7 | 394 | if(position_cart < 170 && position_arm <= -90){ |
Nickname | 18:cbe3fe6d89a7 | 395 | Arm.stop(1)==1; //similar with the right side |
Nickname | 18:cbe3fe6d89a7 | 396 | |
Nickname | 18:cbe3fe6d89a7 | 397 | }else if(position_cart < 170 && position_arm <= -60 && position_claw == -18){ |
Nickname | 18:cbe3fe6d89a7 | 398 | Arm.stop(1)==1; |
Nickname | 18:cbe3fe6d89a7 | 399 | |
Nickname | 18:cbe3fe6d89a7 | 400 | }else if(position_cart>=170 && position_arm<=-160){ |
Nickname | 18:cbe3fe6d89a7 | 401 | Arm.stop(1)==1; //similar with the right side |
meikefrok | 13:dd7b41766f5f | 402 | |
meikefrok | 8:ac4e5afbdbcd | 403 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 404 | Arm.speed(-arm_speed)==-arm_speed; |
Nickname | 18:cbe3fe6d89a7 | 405 | } |
Nickname | 18:cbe3fe6d89a7 | 406 | if (rlf_y > threshold_value){ |
Nickname | 18:cbe3fe6d89a7 | 407 | Cart.stop(1)==1; |
meikefrok | 13:dd7b41766f5f | 408 | } |
Nickname | 18:cbe3fe6d89a7 | 409 | |
Nickname | 18:cbe3fe6d89a7 | 410 | }else { |
Nickname | 18:cbe3fe6d89a7 | 411 | Arm.stop(1)==1; |
Nickname | 18:cbe3fe6d89a7 | 412 | } |
meikefrok | 17:18e9df406502 | 413 | |
Nickname | 18:cbe3fe6d89a7 | 414 | if(!btn&&!btn2){ |
Nickname | 18:cbe3fe6d89a7 | 415 | Cart.speed(0) == 0; |
Nickname | 18:cbe3fe6d89a7 | 416 | if(position_arm>0){ |
Nickname | 18:cbe3fe6d89a7 | 417 | Arm.speed(-0.1)== -0.1; |
Nickname | 18:cbe3fe6d89a7 | 418 | }else if(position_arm<0){ |
Nickname | 18:cbe3fe6d89a7 | 419 | Arm.speed(0.1)==0.1; |
Nickname | 18:cbe3fe6d89a7 | 420 | }else{ |
Nickname | 18:cbe3fe6d89a7 | 421 | Arm.stop(0)==0; |
Nickname | 18:cbe3fe6d89a7 | 422 | }} |
Nickname | 18:cbe3fe6d89a7 | 423 | //Controller |
Nickname | 18:cbe3fe6d89a7 | 424 | SetpointError_Arm = setpoint - position_arm; |
Nickname | 18:cbe3fe6d89a7 | 425 | //set direction |
Nickname | 18:cbe3fe6d89a7 | 426 | if (SetpointError_Arm > 0) { |
meikefrok | 17:18e9df406502 | 427 | arm_speed = 0; |
Nickname | 18:cbe3fe6d89a7 | 428 | }else {} |
meikefrok | 17:18e9df406502 | 429 | |
Nickname | 18:cbe3fe6d89a7 | 430 | Arm_ControlSpeed = Ts * fabs( p_control(SetpointError_Arm, Arm_Kp, Arm_Ki, Arm_Kd, Arm_error, Arm_e_prev)); |
Nickname | 18:cbe3fe6d89a7 | 431 | if (fabs(SetpointError_Arm) < fabs(Setpoint_Arm*0.05)) { |
meikefrok | 17:18e9df406502 | 432 | Arm_ControlSpeed = 0; |
meikefrok | 17:18e9df406502 | 433 | }else{ |
meikefrok | 17:18e9df406502 | 434 | arm_speed = Arm_ControlSpeed; |
Nickname | 18:cbe3fe6d89a7 | 435 | }} |
meikefrok | 8:ac4e5afbdbcd | 436 | // controle LED |
meikefrok | 8:ac4e5afbdbcd | 437 | led_r = not LedOn; |
meikefrok | 8:ac4e5afbdbcd | 438 | led_b = not LedOn; |
meikefrok | 8:ac4e5afbdbcd | 439 | |
meikefrok | 13:dd7b41766f5f | 440 | pc.baud(115200); |
meikefrok | 13:dd7b41766f5f | 441 | pc.printf("Degrees: %i\n", position_arm); |
meikefrok | 8:ac4e5afbdbcd | 442 | break; |
megrootens | 0:048fbd80203e | 443 | } |
meikefrok | 8:ac4e5afbdbcd | 444 | } |
Nickname | 18:cbe3fe6d89a7 | 445 | |
meikefrok | 8:ac4e5afbdbcd | 446 | |
meikefrok | 15:caf29b6f5261 | 447 | void SwitchClaw(){ |
Nickname | 18:cbe3fe6d89a7 | 448 | switch (part_id) { |
meikefrok | 15:caf29b6f5261 | 449 | case 4: { |
meikefrok | 15:caf29b6f5261 | 450 | led_b = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 451 | if(rlf_y > threshold_value_claw){ |
Nickname | 18:cbe3fe6d89a7 | 452 | servo_id ++; |
meikefrok | 15:caf29b6f5261 | 453 | switch (servo_id) { |
Nickname | 18:cbe3fe6d89a7 | 454 | case 0: { |
Nickname | 18:cbe3fe6d89a7 | 455 | led_r = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 456 | led_b = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 457 | led_g = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 458 | servo.position(-18); |
Nickname | 18:cbe3fe6d89a7 | 459 | break; |
Nickname | 18:cbe3fe6d89a7 | 460 | } |
Nickname | 18:cbe3fe6d89a7 | 461 | case 1: { |
Nickname | 18:cbe3fe6d89a7 | 462 | led_b = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 463 | led_r = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 464 | led_g = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 465 | servo.position(3); |
Nickname | 18:cbe3fe6d89a7 | 466 | wait_ms(waiting_claw); |
Nickname | 18:cbe3fe6d89a7 | 467 | break; |
Nickname | 18:cbe3fe6d89a7 | 468 | } |
Nickname | 18:cbe3fe6d89a7 | 469 | case 2: { |
Nickname | 18:cbe3fe6d89a7 | 470 | led_g = LedOn; |
Nickname | 18:cbe3fe6d89a7 | 471 | led_r = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 472 | led_b = not LedOn; |
Nickname | 18:cbe3fe6d89a7 | 473 | servo.position(27); |
Nickname | 18:cbe3fe6d89a7 | 474 | break; |
Nickname | 18:cbe3fe6d89a7 | 475 | }} |
meikefrok | 15:caf29b6f5261 | 476 | }else if(llf_y > threshold_value_claw){ |
meikefrok | 15:caf29b6f5261 | 477 | servo_id --; |
meikefrok | 15:caf29b6f5261 | 478 | |
meikefrok | 15:caf29b6f5261 | 479 | switch (servo_id) { |
meikefrok | 15:caf29b6f5261 | 480 | case 0: { |
meikefrok | 15:caf29b6f5261 | 481 | led_r = LedOn; |
meikefrok | 15:caf29b6f5261 | 482 | led_b = not LedOn; |
meikefrok | 15:caf29b6f5261 | 483 | led_g = not LedOn; |
meikefrok | 15:caf29b6f5261 | 484 | servo.position(-18); |
meikefrok | 15:caf29b6f5261 | 485 | break; |
meikefrok | 15:caf29b6f5261 | 486 | } |
meikefrok | 15:caf29b6f5261 | 487 | case 1: { |
meikefrok | 15:caf29b6f5261 | 488 | led_b = LedOn; |
meikefrok | 15:caf29b6f5261 | 489 | led_r = not LedOn; |
meikefrok | 15:caf29b6f5261 | 490 | led_g = not LedOn; |
meikefrok | 15:caf29b6f5261 | 491 | servo.position(3); |
meikefrok | 15:caf29b6f5261 | 492 | wait_ms(waiting_claw); |
meikefrok | 15:caf29b6f5261 | 493 | break; |
meikefrok | 15:caf29b6f5261 | 494 | } |
meikefrok | 15:caf29b6f5261 | 495 | case 2: { |
meikefrok | 15:caf29b6f5261 | 496 | led_g = LedOn; |
meikefrok | 15:caf29b6f5261 | 497 | led_r = not LedOn; |
meikefrok | 15:caf29b6f5261 | 498 | led_b = not LedOn; |
meikefrok | 15:caf29b6f5261 | 499 | servo.position(27); |
meikefrok | 15:caf29b6f5261 | 500 | break; |
meikefrok | 15:caf29b6f5261 | 501 | } |
meikefrok | 15:caf29b6f5261 | 502 | } |
meikefrok | 15:caf29b6f5261 | 503 | }else{} |
Nickname | 18:cbe3fe6d89a7 | 504 | } |
meikefrok | 15:caf29b6f5261 | 505 | led_r = not LedOn; |
meikefrok | 15:caf29b6f5261 | 506 | led_g = not LedOn; |
meikefrok | 15:caf29b6f5261 | 507 | position_claw = servo.read(); |
meikefrok | 15:caf29b6f5261 | 508 | break; |
meikefrok | 15:caf29b6f5261 | 509 | } |
meikefrok | 15:caf29b6f5261 | 510 | } |
megrootens | 0:048fbd80203e | 511 | |
meikefrok | 5:3d88f7506cd9 | 512 | // Switch the part |
Nickname | 18:cbe3fe6d89a7 | 513 | void SetValue2(){ |
meikefrok | 3:3a671d01bcb8 | 514 | part_id = 2; |
meikefrok | 6:23b1ed826b59 | 515 | } |
Nickname | 18:cbe3fe6d89a7 | 516 | void SetValue3(){ |
meikefrok | 3:3a671d01bcb8 | 517 | part_id = 3; |
meikefrok | 6:23b1ed826b59 | 518 | } |
Nickname | 18:cbe3fe6d89a7 | 519 | void SetValue4(){ |
meikefrok | 3:3a671d01bcb8 | 520 | part_id = 4; |
megrootens | 0:048fbd80203e | 521 | } |
megrootens | 0:048fbd80203e | 522 | |
meikefrok | 5:3d88f7506cd9 | 523 | // Main |
megrootens | 0:048fbd80203e | 524 | int main() |
megrootens | 0:048fbd80203e | 525 | { |
meikefrok | 3:3a671d01bcb8 | 526 | led_r = not LedOn; |
meikefrok | 3:3a671d01bcb8 | 527 | led_g = not LedOn; |
meikefrok | 3:3a671d01bcb8 | 528 | led_b = not LedOn; |
megrootens | 0:048fbd80203e | 529 | |
Nickname | 18:cbe3fe6d89a7 | 530 | tick_part_cart.attach(&SwitchCart,kTimeToggle); |
meikefrok | 15:caf29b6f5261 | 531 | tick_part_arm.attach(&SwitchArm,kTimeToggle); |
meikefrok | 15:caf29b6f5261 | 532 | tick_part_claw.attach(&SwitchClaw,0.1f); |
meikefrok | 11:97f824629da5 | 533 | measureTicker.attach(Measure, 0.005); |
meikefrok | 15:caf29b6f5261 | 534 | sampleTicker.attach(scopeSend,0.01); |
meikefrok | 15:caf29b6f5261 | 535 | |
meikefrok | 3:3a671d01bcb8 | 536 | btn_cart.fall(&SetValue2); |
meikefrok | 3:3a671d01bcb8 | 537 | btn_arm.fall(&SetValue3); |
Nickname | 18:cbe3fe6d89a7 | 538 | btn_claw.fall(&SetValue4); |
Nickname | 18:cbe3fe6d89a7 | 539 | } |