pot controller voor positie, kp handmatig instellen, werkt met motor 1 en 2
Dependencies: MODSERIAL QEI mbed-dsp mbed
Fork of PI_moter1and2_ticker by
main.cpp@12:505e5ea9f639, 2018-10-25 (annotated)
- Committer:
- Florianhs
- Date:
- Thu Oct 25 13:01:31 2018 +0000
- Revision:
- 12:505e5ea9f639
- Parent:
- 11:4b0dbbdc56fb
andere toetsenbordaansturing;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vsluiter | 0:c8f15874531b | 1 | #include "mbed.h" |
vsluiter | 0:c8f15874531b | 2 | #include "MODSERIAL.h" |
SimonRez | 6:1ee8795b7578 | 3 | #include "QEI.h" |
rachieldb | 9:466dff9ae128 | 4 | #include "math.h" |
rachieldb | 9:466dff9ae128 | 5 | #define _USE_MATH_DEFINES |
rachieldb | 9:466dff9ae128 | 6 | # define M_PI 3.14159265358979323846 /* pi */ |
Florianhs | 11:4b0dbbdc56fb | 7 | //motor 1 |
Florianhs | 12:505e5ea9f639 | 8 | double Kp = 10; |
Florianhs | 10:61a7cb3b3aa3 | 9 | double Ki = 1; |
Florianhs | 10:61a7cb3b3aa3 | 10 | double u_k = 1; |
Florianhs | 10:61a7cb3b3aa3 | 11 | double u_i = 1; |
Florianhs | 10:61a7cb3b3aa3 | 12 | double Kswitch; |
Florianhs | 10:61a7cb3b3aa3 | 13 | double kp_scalar = 1; |
Florianhs | 10:61a7cb3b3aa3 | 14 | double ki_scalar = 1; |
Florianhs | 11:4b0dbbdc56fb | 15 | double m1_scalar; |
Florianhs | 10:61a7cb3b3aa3 | 16 | double motor1_ang=0; |
Florianhs | 11:4b0dbbdc56fb | 17 | double m1=0; |
Florianhs | 10:61a7cb3b3aa3 | 18 | double input_motor; |
Florianhs | 11:4b0dbbdc56fb | 19 | //motor 2 |
Florianhs | 12:505e5ea9f639 | 20 | double Kp2 = 12; |
Florianhs | 11:4b0dbbdc56fb | 21 | double Ki2 = 1; |
Florianhs | 11:4b0dbbdc56fb | 22 | double u_k2 = 1; |
Florianhs | 11:4b0dbbdc56fb | 23 | double u_i2 = 1; |
Florianhs | 11:4b0dbbdc56fb | 24 | double Kswitch2; |
Florianhs | 11:4b0dbbdc56fb | 25 | double kp_scalar2 = 1; |
Florianhs | 11:4b0dbbdc56fb | 26 | double ki_scalar2 = 1; |
Florianhs | 11:4b0dbbdc56fb | 27 | double m2_scalar; |
Florianhs | 11:4b0dbbdc56fb | 28 | double motor2_ang=0; |
Florianhs | 11:4b0dbbdc56fb | 29 | double m2=0; |
Florianhs | 11:4b0dbbdc56fb | 30 | double input_motor2; |
Florianhs | 11:4b0dbbdc56fb | 31 | |
Florianhs | 11:4b0dbbdc56fb | 32 | //rest |
Florianhs | 10:61a7cb3b3aa3 | 33 | bool input_switch = true; |
Florianhs | 10:61a7cb3b3aa3 | 34 | const double Ts = 0.01f; |
Florianhs | 11:4b0dbbdc56fb | 35 | volatile char input; |
Florianhs | 10:61a7cb3b3aa3 | 36 | |
Florianhs | 10:61a7cb3b3aa3 | 37 | Ticker Control; |
Florianhs | 12:505e5ea9f639 | 38 | Ticker serialEvent; |
Florianhs | 12:505e5ea9f639 | 39 | |
SimonRez | 4:651d06e860e7 | 40 | |
rachieldb | 9:466dff9ae128 | 41 | PwmOut motor1_pwm(D5); |
rachieldb | 9:466dff9ae128 | 42 | PwmOut motor2_pwm(D6); |
rachieldb | 9:466dff9ae128 | 43 | DigitalOut motor1_dir(D4); |
rachieldb | 9:466dff9ae128 | 44 | DigitalOut motor2_dir(D7); |
SimonRez | 6:1ee8795b7578 | 45 | AnalogIn pot1(A0); |
rachieldb | 9:466dff9ae128 | 46 | AnalogIn pot2(A1); |
SimonRez | 6:1ee8795b7578 | 47 | |
rachieldb | 9:466dff9ae128 | 48 | QEI motor1_enc(D12,D13,NC,8400,QEI::X4_ENCODING); |
rachieldb | 9:466dff9ae128 | 49 | QEI motor2_enc(D10,D11,NC,8400,QEI::X4_ENCODING); |
SimonRez | 5:f07bafaf11d7 | 50 | |
SimonRez | 4:651d06e860e7 | 51 | InterruptIn sw2(SW2); |
SimonRez | 4:651d06e860e7 | 52 | InterruptIn sw3(SW3); |
SimonRez | 2:52b3c0b95388 | 53 | |
vsluiter | 0:c8f15874531b | 54 | MODSERIAL pc(USBTX, USBRX); |
vsluiter | 0:c8f15874531b | 55 | |
Florianhs | 10:61a7cb3b3aa3 | 56 | //hoek uitrekenen van de motor |
rachieldb | 9:466dff9ae128 | 57 | double countstoangle(int counts){ |
rachieldb | 9:466dff9ae128 | 58 | double angle; |
Florianhs | 10:61a7cb3b3aa3 | 59 | int counts_abs =(counts); |
Florianhs | 10:61a7cb3b3aa3 | 60 | angle = (2 * M_PI * counts_abs)/8400; |
Florianhs | 10:61a7cb3b3aa3 | 61 | return angle; |
Florianhs | 10:61a7cb3b3aa3 | 62 | |
Florianhs | 10:61a7cb3b3aa3 | 63 | } |
Florianhs | 10:61a7cb3b3aa3 | 64 | void buttonpress() |
Florianhs | 10:61a7cb3b3aa3 | 65 | { |
Florianhs | 10:61a7cb3b3aa3 | 66 | input_switch=!input_switch; //verander de potmeter input tussen kp en ki |
Florianhs | 10:61a7cb3b3aa3 | 67 | } |
Florianhs | 10:61a7cb3b3aa3 | 68 | |
Florianhs | 11:4b0dbbdc56fb | 69 | double PID_controller1(double error) //bereken de input die naar de motor wordt gestuurd aan de hand van kp en ki en de error op elk moment |
Florianhs | 10:61a7cb3b3aa3 | 70 | { |
Florianhs | 10:61a7cb3b3aa3 | 71 | //Proportional part |
Florianhs | 10:61a7cb3b3aa3 | 72 | u_k = Kp*error; |
Florianhs | 10:61a7cb3b3aa3 | 73 | |
Florianhs | 10:61a7cb3b3aa3 | 74 | //Integral part |
Florianhs | 11:4b0dbbdc56fb | 75 | //static double error_integral = 0; |
Florianhs | 11:4b0dbbdc56fb | 76 | //error_integral = error_integral + error * Ts; |
Florianhs | 11:4b0dbbdc56fb | 77 | //u_i = Ki * error_integral; |
Florianhs | 11:4b0dbbdc56fb | 78 | return u_k; //+ u_i; |
Florianhs | 10:61a7cb3b3aa3 | 79 | } |
Florianhs | 10:61a7cb3b3aa3 | 80 | |
Florianhs | 11:4b0dbbdc56fb | 81 | double PID_controller2(double error2) //bereken de input die naar de motor wordt gestuurd aan de hand van kp en ki en de error op elk moment |
Florianhs | 11:4b0dbbdc56fb | 82 | { |
Florianhs | 11:4b0dbbdc56fb | 83 | //Proportional part |
Florianhs | 11:4b0dbbdc56fb | 84 | u_k2 = Kp2*error2; |
Florianhs | 11:4b0dbbdc56fb | 85 | |
Florianhs | 11:4b0dbbdc56fb | 86 | //Integral part |
Florianhs | 11:4b0dbbdc56fb | 87 | //static double error_integral2 = 0; |
Florianhs | 11:4b0dbbdc56fb | 88 | //error_integral2 = error_integral2 + error2 * Ts; |
Florianhs | 11:4b0dbbdc56fb | 89 | //u_i2 = Ki2 * error_integral2; |
Florianhs | 11:4b0dbbdc56fb | 90 | return u_k2; //+ u_i2; |
Florianhs | 11:4b0dbbdc56fb | 91 | } |
Florianhs | 10:61a7cb3b3aa3 | 92 | |
Florianhs | 11:4b0dbbdc56fb | 93 | void aansturing() |
Florianhs | 11:4b0dbbdc56fb | 94 | { //posities voor de motoren bepalen |
Florianhs | 12:505e5ea9f639 | 95 | |
Florianhs | 12:505e5ea9f639 | 96 | if(input=='a') |
Florianhs | 12:505e5ea9f639 | 97 | {if(m1>0) |
Florianhs | 12:505e5ea9f639 | 98 | {m1 = m1-0.01f;}} |
Florianhs | 12:505e5ea9f639 | 99 | else if(input=='s') |
Florianhs | 12:505e5ea9f639 | 100 | {if(m1<1.5f) |
Florianhs | 12:505e5ea9f639 | 101 | {m1 = m1+0.01f;}} |
Florianhs | 12:505e5ea9f639 | 102 | else if(input=='q') |
Florianhs | 12:505e5ea9f639 | 103 | {if(m2>0) |
Florianhs | 12:505e5ea9f639 | 104 | {m2 = m2-0.01f;}} |
Florianhs | 12:505e5ea9f639 | 105 | else if(input=='w') |
Florianhs | 12:505e5ea9f639 | 106 | {if(m2<4.0f) |
Florianhs | 12:505e5ea9f639 | 107 | {m2 = m2+0.01f;}} |
Florianhs | 12:505e5ea9f639 | 108 | |
Florianhs | 12:505e5ea9f639 | 109 | input= NULL; |
Florianhs | 12:505e5ea9f639 | 110 | //m1_scalar=pot1.read(); |
Florianhs | 12:505e5ea9f639 | 111 | //m2_scalar=pot2.read(); |
Florianhs | 12:505e5ea9f639 | 112 | //m1=m1_scalar*1.5f; |
Florianhs | 12:505e5ea9f639 | 113 | //m2=m2_scalar*1.5f; |
Florianhs | 12:505e5ea9f639 | 114 | Kswitch = pot1.read(); //kp en ki bepalen voor motor 1 |
Florianhs | 12:505e5ea9f639 | 115 | Kswitch2 = pot2.read(); //kp en ki bepalen voor motor 2 |
Florianhs | 11:4b0dbbdc56fb | 116 | |
Florianhs | 12:505e5ea9f639 | 117 | kp_scalar=Kswitch; |
Florianhs | 12:505e5ea9f639 | 118 | kp_scalar2=Kswitch2; |
Florianhs | 11:4b0dbbdc56fb | 119 | // //kijken of er gekozen is voor het uitlezen van de kp of ki van de potmeter |
Florianhs | 12:505e5ea9f639 | 120 | if(input_switch==true) |
Florianhs | 12:505e5ea9f639 | 121 | {kp_scalar = Kswitch;} |
Florianhs | 12:505e5ea9f639 | 122 | else |
Florianhs | 12:505e5ea9f639 | 123 | {ki_scalar = Kswitch;} |
Florianhs | 12:505e5ea9f639 | 124 | |
Florianhs | 12:505e5ea9f639 | 125 | if(input_switch==true) |
Florianhs | 12:505e5ea9f639 | 126 | {kp_scalar2 = Kswitch2;} |
Florianhs | 12:505e5ea9f639 | 127 | else |
Florianhs | 12:505e5ea9f639 | 128 | {ki_scalar2 = Kswitch2;} |
Florianhs | 11:4b0dbbdc56fb | 129 | |
Florianhs | 11:4b0dbbdc56fb | 130 | //waarde voor de inputcontrol value instellen aan de hand van potmeter |
Florianhs | 12:505e5ea9f639 | 131 | Kp = kp_scalar*5.0f; |
Florianhs | 12:505e5ea9f639 | 132 | Ki = ki_scalar*5.0f; |
Florianhs | 12:505e5ea9f639 | 133 | Kp2 = kp_scalar2*5.0f; |
Florianhs | 12:505e5ea9f639 | 134 | Ki2 = ki_scalar2*5.0f; |
Florianhs | 10:61a7cb3b3aa3 | 135 | |
Florianhs | 10:61a7cb3b3aa3 | 136 | |
Florianhs | 11:4b0dbbdc56fb | 137 | |
Florianhs | 10:61a7cb3b3aa3 | 138 | motor1_ang = countstoangle(motor1_enc.getPulses()); // de hoek van de motor uit bovenstaande formule halen, om de error te kunnen berekenen |
Florianhs | 11:4b0dbbdc56fb | 139 | double error = motor1_ang -m1; |
Florianhs | 10:61a7cb3b3aa3 | 140 | |
Florianhs | 11:4b0dbbdc56fb | 141 | motor2_ang = countstoangle(motor2_enc.getPulses()); // de hoek van de motor uit bovenstaande formule halen, om de error te kunnen berekenen |
Florianhs | 11:4b0dbbdc56fb | 142 | double error2 = motor2_ang -m2; |
Florianhs | 10:61a7cb3b3aa3 | 143 | |
Florianhs | 11:4b0dbbdc56fb | 144 | //input voor de motor met de PID controllers bepalen |
Florianhs | 11:4b0dbbdc56fb | 145 | double input_motor = PID_controller1(error); |
Florianhs | 11:4b0dbbdc56fb | 146 | double input_motor2 = PID_controller2(error2); |
Florianhs | 10:61a7cb3b3aa3 | 147 | |
Florianhs | 11:4b0dbbdc56fb | 148 | //signaal naar motor 1 sturen |
Florianhs | 10:61a7cb3b3aa3 | 149 | if(input_motor>1.0) //pwm signaal kan niet groter zijn dan 1, dus moet gelimiteerd worden |
Florianhs | 10:61a7cb3b3aa3 | 150 | {input_motor = 1.0;} |
Florianhs | 10:61a7cb3b3aa3 | 151 | else if(input_motor<-1.0) //absolute waarde wordt ingevuld, maar de negatieve kant is belangrijk voor de richting van de motor |
Florianhs | 10:61a7cb3b3aa3 | 152 | {input_motor = -1.0;} |
Florianhs | 10:61a7cb3b3aa3 | 153 | |
Florianhs | 10:61a7cb3b3aa3 | 154 | |
Florianhs | 10:61a7cb3b3aa3 | 155 | if(input_motor<0.0) //bepaal de richting aan de hand van het teken van het pwm signaal. |
Florianhs | 10:61a7cb3b3aa3 | 156 | {motor1_dir = 0;} |
Florianhs | 10:61a7cb3b3aa3 | 157 | else |
Florianhs | 10:61a7cb3b3aa3 | 158 | {motor1_dir = 1;} |
Florianhs | 10:61a7cb3b3aa3 | 159 | motor1_pwm.write(fabs(input_motor)); // de uiteindelijke input aan de motor geven |
Florianhs | 11:4b0dbbdc56fb | 160 | |
Florianhs | 11:4b0dbbdc56fb | 161 | //signaal naar motor 12 sturen |
Florianhs | 11:4b0dbbdc56fb | 162 | if(input_motor2>1.0) //pwm signaal kan niet groter zijn dan 1, dus moet gelimiteerd worden |
Florianhs | 11:4b0dbbdc56fb | 163 | {input_motor2 = 1.0;} |
Florianhs | 11:4b0dbbdc56fb | 164 | else if(input_motor2<-1.0) //absolute waarde wordt ingevuld, maar de negatieve kant is belangrijk voor de richting van de motor |
Florianhs | 11:4b0dbbdc56fb | 165 | {input_motor2 = -1.0;} |
Florianhs | 11:4b0dbbdc56fb | 166 | |
Florianhs | 11:4b0dbbdc56fb | 167 | |
Florianhs | 11:4b0dbbdc56fb | 168 | if(input_motor2<0.0) //bepaal de richting aan de hand van het teken van het pwm signaal. |
Florianhs | 11:4b0dbbdc56fb | 169 | {motor2_dir = 0;} |
Florianhs | 11:4b0dbbdc56fb | 170 | else |
Florianhs | 11:4b0dbbdc56fb | 171 | {motor2_dir = 1;} |
Florianhs | 11:4b0dbbdc56fb | 172 | motor2_pwm.write(fabs(input_motor2)); // de uiteindelijke input aan de motor geven |
Florianhs | 10:61a7cb3b3aa3 | 173 | // pc.printf("ki: %f kp: %f yref: %f error: %f u_k: %f angle: %f\r\n",Ki, Kp, y_ref,error,u_k,motor1_ang); |
rachieldb | 9:466dff9ae128 | 174 | } |
SimonRez | 4:651d06e860e7 | 175 | |
Florianhs | 12:505e5ea9f639 | 176 | void serialSampler(){ |
Florianhs | 12:505e5ea9f639 | 177 | if(pc.readable()){ |
Florianhs | 12:505e5ea9f639 | 178 | input = pc.getc(); |
Florianhs | 12:505e5ea9f639 | 179 | pc.printf("Input = %c\r\n",input); |
Florianhs | 12:505e5ea9f639 | 180 | }else if(input_switch==true){ |
Florianhs | 12:505e5ea9f639 | 181 | pc.printf("Kp ingeschakeld\r\n"); |
Florianhs | 12:505e5ea9f639 | 182 | }else{ |
Florianhs | 12:505e5ea9f639 | 183 | pc.printf("Ki ingeschakeld\r\n"); |
Florianhs | 12:505e5ea9f639 | 184 | } |
Florianhs | 12:505e5ea9f639 | 185 | } |
Florianhs | 12:505e5ea9f639 | 186 | |
vsluiter | 0:c8f15874531b | 187 | int main() |
vsluiter | 0:c8f15874531b | 188 | { |
SimonRez | 2:52b3c0b95388 | 189 | |
Florianhs | 10:61a7cb3b3aa3 | 190 | sw2.fall(buttonpress); |
Florianhs | 10:61a7cb3b3aa3 | 191 | pc.baud(115200); |
SimonRez | 2:52b3c0b95388 | 192 | |
rachieldb | 9:466dff9ae128 | 193 | motor1_pwm.period_us(60); |
rachieldb | 9:466dff9ae128 | 194 | motor1_pwm = 0; |
rachieldb | 9:466dff9ae128 | 195 | motor2_pwm.period_us(60); |
rachieldb | 9:466dff9ae128 | 196 | motor2_pwm = 0; |
Florianhs | 10:61a7cb3b3aa3 | 197 | |
Florianhs | 10:61a7cb3b3aa3 | 198 | Control.attach(aansturing, Ts); //de aansturing regelen met een sampletime |
Florianhs | 12:505e5ea9f639 | 199 | serialEvent.attach(&serialSampler, 0.05); |
SimonRez | 2:52b3c0b95388 | 200 | while (true) |
Florianhs | 12:505e5ea9f639 | 201 | { |
Florianhs | 11:4b0dbbdc56fb | 202 | double errorprint = motor1_ang-m1; |
Florianhs | 11:4b0dbbdc56fb | 203 | double errorprint2 = motor2_ang-m2; |
Florianhs | 12:505e5ea9f639 | 204 | pc.printf("ki1: %.2f kp1: %.2f m1: %.2f u_k1: %.2f angle1: %.2f error1: %.2f\r\n",Ki, Kp, m1,u_k,motor1_ang,errorprint); |
Florianhs | 12:505e5ea9f639 | 205 | pc.printf("ki2: %.2f kp2: %.2f m2: %.2f u_k2: %.2f angle2: %.2f error2: %.2f\r\n\n",Ki2, Kp2, m2,u_k2,motor2_ang,errorprint2); |
Florianhs | 11:4b0dbbdc56fb | 206 | pc.printf("toets=%c\r\n",input); |
Florianhs | 10:61a7cb3b3aa3 | 207 | wait(0.5); |
vsluiter | 0:c8f15874531b | 208 | } |
vsluiter | 0:c8f15874531b | 209 | } |
SimonRez | 2:52b3c0b95388 | 210 | |
SimonRez | 2:52b3c0b95388 | 211 |