Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FastPWM mbed QEI biquadFilter HIDScope MODSERIAL
main.cpp@34:30100c1901d4, 2018-10-31 (annotated)
- Committer:
- efvanmarrewijk
- Date:
- Wed Oct 31 09:56:35 2018 +0000
- Revision:
- 34:30100c1901d4
- Parent:
- 32:a5b411833d1e
Motor movement in ticker, names of variables for motors changed to 1st motor = l (left), 2nd motor = r (right), 3nd motor = f (flip)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
efvanmarrewijk | 16:720365110953 | 1 | // Inclusion of libraries |
efvanmarrewijk | 31:91ad5b188bd9 | 2 | #include "mbed.h" |
efvanmarrewijk | 31:91ad5b188bd9 | 3 | #include "FastPWM.h" |
efvanmarrewijk | 31:91ad5b188bd9 | 4 | #include "QEI.h" // Includes library for encoder |
efvanmarrewijk | 31:91ad5b188bd9 | 5 | #include "MODSERIAL.h" |
efvanmarrewijk | 31:91ad5b188bd9 | 6 | #include "HIDScope.h" |
efvanmarrewijk | 31:91ad5b188bd9 | 7 | #include "BiQuad.h" |
Ramonwaninge | 0:3ea1bbfbeaae | 8 | |
efvanmarrewijk | 14:e21cb701ccb8 | 9 | // Input |
efvanmarrewijk | 27:3430dfb4c9fb | 10 | AnalogIn pot1(A1); |
efvanmarrewijk | 27:3430dfb4c9fb | 11 | AnalogIn pot2(A2); |
efvanmarrewijk | 34:30100c1901d4 | 12 | InterruptIn buttonbio1(D0); |
efvanmarrewijk | 34:30100c1901d4 | 13 | InterruptIn buttonbio2(D1); |
efvanmarrewijk | 34:30100c1901d4 | 14 | InterruptIn buttonK64F(SW3); |
efvanmarrewijk | 31:91ad5b188bd9 | 15 | InterruptIn emergencybutton(SW2); //The button SW2 on the K64F is the emergency button: if you press this, everything will abort as soon as possible |
efvanmarrewijk | 21:363271dcfe1f | 16 | |
efvanmarrewijk | 32:a5b411833d1e | 17 | DigitalIn pin8(D8); // Encoder 1 B |
efvanmarrewijk | 32:a5b411833d1e | 18 | DigitalIn pin9(D9); // Encoder 1 A |
efvanmarrewijk | 32:a5b411833d1e | 19 | DigitalIn pin10(D10); // Encoder 2 B |
efvanmarrewijk | 32:a5b411833d1e | 20 | DigitalIn pin11(D11); // Encoder 2 A |
efvanmarrewijk | 32:a5b411833d1e | 21 | DigitalIn pin12(D12); // Encoder 3 B |
efvanmarrewijk | 32:a5b411833d1e | 22 | DigitalIn pin13(D13); // Encoder 3 A |
efvanmarrewijk | 9:65c52c1f4a57 | 23 | |
efvanmarrewijk | 14:e21cb701ccb8 | 24 | // Output |
efvanmarrewijk | 34:30100c1901d4 | 25 | DigitalOut pin2(D2); // Motor 3 direction = motor flip |
efvanmarrewijk | 34:30100c1901d4 | 26 | FastPWM pin3(D3); // Motor 3 pwm = motor flip |
efvanmarrewijk | 34:30100c1901d4 | 27 | DigitalOut pin4(D4); // Motor 2 direction = motor right |
efvanmarrewijk | 34:30100c1901d4 | 28 | FastPWM pin5(D5); // Motor 2 pwm = motor right |
efvanmarrewijk | 34:30100c1901d4 | 29 | FastPWM pin6(D6); // Motor 1 pwm = motor left |
efvanmarrewijk | 34:30100c1901d4 | 30 | DigitalOut pin7(D7); // Motor 1 direction = motor left |
efvanmarrewijk | 26:b48708ed51ff | 31 | |
efvanmarrewijk | 26:b48708ed51ff | 32 | DigitalOut greenled(LED_GREEN,1); |
efvanmarrewijk | 26:b48708ed51ff | 33 | DigitalOut redled(LED_RED,1); |
efvanmarrewijk | 26:b48708ed51ff | 34 | DigitalOut blueled(LED_BLUE,1); |
Ramonwaninge | 2:d8a552d1d33a | 35 | |
efvanmarrewijk | 16:720365110953 | 36 | // Utilisation of libraries |
efvanmarrewijk | 16:720365110953 | 37 | MODSERIAL pc(USBTX, USBRX); |
efvanmarrewijk | 34:30100c1901d4 | 38 | QEI Encoderl(D9,D8,NC,4200); // Counterclockwise motor rotation is the positive direction |
efvanmarrewijk | 34:30100c1901d4 | 39 | QEI Encoderr(D11,D10,NC,4200); // Counterclockwise motor rotation is the positive direction |
efvanmarrewijk | 34:30100c1901d4 | 40 | QEI Encoderf(D13,D12,NC,4200); // Counterclockwise motor rotation is the positive direction |
efvanmarrewijk | 20:695140b8db2f | 41 | Ticker motor; |
efvanmarrewijk | 24:d255752065d1 | 42 | Ticker encoders; |
efvanmarrewijk | 9:65c52c1f4a57 | 43 | |
efvanmarrewijk | 16:720365110953 | 44 | // Global variables |
efvanmarrewijk | 32:a5b411833d1e | 45 | const float pi = 3.14159265358979f; |
efvanmarrewijk | 32:a5b411833d1e | 46 | float u3 = 0.0f; // Normalised variable for the movement of motor 3 |
efvanmarrewijk | 32:a5b411833d1e | 47 | const float fCountsRad = 4200.0f; |
efvanmarrewijk | 32:a5b411833d1e | 48 | const float dt = 0.001f; |
efvanmarrewijk | 16:720365110953 | 49 | |
efvanmarrewijk | 16:720365110953 | 50 | // Functions |
efvanmarrewijk | 32:a5b411833d1e | 51 | void Emergency() // Emgergency, if SW2 on biorobotics is pressed, everything will instantly abort and a red light goes on |
efvanmarrewijk | 32:a5b411833d1e | 52 | { greenled = 1; // Red light on |
efvanmarrewijk | 30:c4a3e868ef04 | 53 | blueled = 1; |
efvanmarrewijk | 30:c4a3e868ef04 | 54 | redled = 0; |
efvanmarrewijk | 32:a5b411833d1e | 55 | pin3 = 0; // All motor forces to zero |
efvanmarrewijk | 30:c4a3e868ef04 | 56 | pin5 = 0; |
efvanmarrewijk | 30:c4a3e868ef04 | 57 | pin6 = 0; |
efvanmarrewijk | 32:a5b411833d1e | 58 | exit (0); // Abort mission!! |
efvanmarrewijk | 30:c4a3e868ef04 | 59 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 60 | |
efvanmarrewijk | 31:91ad5b188bd9 | 61 | // Subfunctions |
efvanmarrewijk | 34:30100c1901d4 | 62 | int Countslinput() // Gets the counts from encoder 1 |
efvanmarrewijk | 34:30100c1901d4 | 63 | { int countsl; |
efvanmarrewijk | 34:30100c1901d4 | 64 | countsl = Encoderl.getPulses(); |
efvanmarrewijk | 34:30100c1901d4 | 65 | return countsl; |
efvanmarrewijk | 27:3430dfb4c9fb | 66 | } |
efvanmarrewijk | 34:30100c1901d4 | 67 | int Countsrinput() // Gets the counts from encoder 2 |
efvanmarrewijk | 34:30100c1901d4 | 68 | { int countsr; |
efvanmarrewijk | 34:30100c1901d4 | 69 | countsr = Encoderr.getPulses(); |
efvanmarrewijk | 34:30100c1901d4 | 70 | return countsr; |
efvanmarrewijk | 27:3430dfb4c9fb | 71 | } |
efvanmarrewijk | 34:30100c1901d4 | 72 | int Countsfinput() // Gets the counts from encoder3 |
efvanmarrewijk | 34:30100c1901d4 | 73 | { int countsf; |
efvanmarrewijk | 34:30100c1901d4 | 74 | countsf = Encoderf.getPulses(); |
efvanmarrewijk | 34:30100c1901d4 | 75 | return countsf; |
efvanmarrewijk | 27:3430dfb4c9fb | 76 | } |
efvanmarrewijk | 27:3430dfb4c9fb | 77 | |
efvanmarrewijk | 32:a5b411833d1e | 78 | float CurrentAngle(float counts) // Calculates the current angle of the motor (between -2*pi to 2*pi) based on the counts from the encoder |
efvanmarrewijk | 32:a5b411833d1e | 79 | { float angle = ((float)counts*2.0f*pi)/fCountsRad; |
efvanmarrewijk | 32:a5b411833d1e | 80 | while (angle > 2.0f*pi) |
efvanmarrewijk | 32:a5b411833d1e | 81 | { angle = angle-2.0f*pi; |
efvanmarrewijk | 27:3430dfb4c9fb | 82 | } |
efvanmarrewijk | 32:a5b411833d1e | 83 | while (angle < -2.0f*pi) |
efvanmarrewijk | 32:a5b411833d1e | 84 | { angle = angle+2.0f*pi; |
efvanmarrewijk | 30:c4a3e868ef04 | 85 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 86 | return angle; |
efvanmarrewijk | 27:3430dfb4c9fb | 87 | } |
efvanmarrewijk | 27:3430dfb4c9fb | 88 | |
efvanmarrewijk | 32:a5b411833d1e | 89 | float ErrorCalc(float refvalue,float CurAngle) // Calculates the error of the system, based on the current angle and the reference value |
efvanmarrewijk | 32:a5b411833d1e | 90 | { float error = refvalue - CurAngle; |
efvanmarrewijk | 30:c4a3e868ef04 | 91 | return error; |
efvanmarrewijk | 30:c4a3e868ef04 | 92 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 93 | |
efvanmarrewijk | 32:a5b411833d1e | 94 | float Kpcontr() // Sets the Kp value for the controller dependent on the scaled angle of potmeter 2 |
efvanmarrewijk | 32:a5b411833d1e | 95 | { float Kp = 20.0f*pot2; |
efvanmarrewijk | 30:c4a3e868ef04 | 96 | return Kp; |
efvanmarrewijk | 30:c4a3e868ef04 | 97 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 98 | |
efvanmarrewijk | 32:a5b411833d1e | 99 | float Kdcontr() // Sets the Kd value for the controller dependent on the scaled angle of potmeter 1 |
efvanmarrewijk | 32:a5b411833d1e | 100 | { float Kd = 0.25f*pot1; |
efvanmarrewijk | 30:c4a3e868ef04 | 101 | return Kd; |
efvanmarrewijk | 30:c4a3e868ef04 | 102 | } |
efvanmarrewijk | 31:91ad5b188bd9 | 103 | |
efvanmarrewijk | 32:a5b411833d1e | 104 | float PIDcontroller(float refvalue,float CurAngle) // PID controller for the motors, based on the reference value and the current angle of the motor |
efvanmarrewijk | 30:c4a3e868ef04 | 105 | { //float Kp = Kpcontr(); |
efvanmarrewijk | 32:a5b411833d1e | 106 | float Kp = 10.42f; |
efvanmarrewijk | 32:a5b411833d1e | 107 | float Ki = 1.02f; |
efvanmarrewijk | 32:a5b411833d1e | 108 | float Kd = 0.0493f; |
efvanmarrewijk | 30:c4a3e868ef04 | 109 | //float Kd = Kdcontr(); |
efvanmarrewijk | 32:a5b411833d1e | 110 | float error = ErrorCalc(refvalue,CurAngle); |
efvanmarrewijk | 30:c4a3e868ef04 | 111 | static float error_integral = 0.0; |
efvanmarrewijk | 30:c4a3e868ef04 | 112 | static float error_prev = error; // initialization with this value only done once! |
efvanmarrewijk | 31:91ad5b188bd9 | 113 | static BiQuad PIDfilter(0.0640, 0.1279, 0.0640, -1.1683, 0.4241); |
efvanmarrewijk | 27:3430dfb4c9fb | 114 | // Proportional part: |
efvanmarrewijk | 30:c4a3e868ef04 | 115 | float u_k = Kp * error; |
efvanmarrewijk | 27:3430dfb4c9fb | 116 | // Integral part |
efvanmarrewijk | 27:3430dfb4c9fb | 117 | error_integral = error_integral + error * dt; |
efvanmarrewijk | 30:c4a3e868ef04 | 118 | float u_i = Ki * error_integral; |
efvanmarrewijk | 30:c4a3e868ef04 | 119 | // Derivative part |
efvanmarrewijk | 30:c4a3e868ef04 | 120 | float error_derivative = (error - error_prev)/dt; |
efvanmarrewijk | 31:91ad5b188bd9 | 121 | float filtered_error_derivative = PIDfilter.step(error_derivative); |
efvanmarrewijk | 30:c4a3e868ef04 | 122 | float u_d = Kd * filtered_error_derivative; |
efvanmarrewijk | 30:c4a3e868ef04 | 123 | error_prev = error; |
efvanmarrewijk | 27:3430dfb4c9fb | 124 | // Sum all parts and return it |
efvanmarrewijk | 34:30100c1901d4 | 125 | //pc.printf ("Kp = %f Kd = %f",Kp,Kd); |
efvanmarrewijk | 30:c4a3e868ef04 | 126 | return u_k + u_i + u_d; |
efvanmarrewijk | 27:3430dfb4c9fb | 127 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 128 | |
efvanmarrewijk | 32:a5b411833d1e | 129 | float DesiredAngle() // Sets the desired angle for the controller dependent on the scaled angle of potmeter 1 |
efvanmarrewijk | 32:a5b411833d1e | 130 | { float angle = (pot1*2.0f*pi)-pi; |
efvanmarrewijk | 30:c4a3e868ef04 | 131 | return angle; |
efvanmarrewijk | 30:c4a3e868ef04 | 132 | } |
efvanmarrewijk | 27:3430dfb4c9fb | 133 | |
efvanmarrewijk | 34:30100c1901d4 | 134 | void turnl() // main function for movement of motor 1, all above functions with an extra tab are called |
efvanmarrewijk | 26:b48708ed51ff | 135 | { |
efvanmarrewijk | 31:91ad5b188bd9 | 136 | //float refvalue1 = pi/4.0; |
efvanmarrewijk | 34:30100c1901d4 | 137 | float refvalue = DesiredAngle(); |
efvanmarrewijk | 34:30100c1901d4 | 138 | int counts = Counts1input(); |
efvanmarrewijk | 34:30100c1901d4 | 139 | float currentangle = CurrentAngle(counts); |
efvanmarrewijk | 34:30100c1901d4 | 140 | float PIDcontrol = PIDcontroller(refvalue,currentangle); |
efvanmarrewijk | 34:30100c1901d4 | 141 | float error = ErrorCalc(refvalue,currentangle); |
efvanmarrewijk | 30:c4a3e868ef04 | 142 | |
efvanmarrewijk | 34:30100c1901d4 | 143 | pin6 = fabs(PIDcontrol); |
efvanmarrewijk | 34:30100c1901d4 | 144 | pin7 = PIDcontrol > 0.0f; |
efvanmarrewijk | 31:91ad5b188bd9 | 145 | //pin6 = 0.4+0.6*fabs(PIDcontr); //geschaald |
efvanmarrewijk | 31:91ad5b188bd9 | 146 | //pin6 = fabs(PIDcontr)/pi; |
efvanmarrewijk | 34:30100c1901d4 | 147 | //pc.printf(" error: %f ref: %f angle: %f \r\n",error,refvalue,currentangle); |
efvanmarrewijk | 18:ca084c362855 | 148 | } |
efvanmarrewijk | 25:76e9e5597416 | 149 | |
efvanmarrewijk | 32:a5b411833d1e | 150 | float ActualPosition(int counts, int offsetcounts) // After calibration, this function is used to return the counts (and thus the angle of the system) to 0 |
efvanmarrewijk | 32:a5b411833d1e | 151 | { float MotorPosition = - (counts - offsetcounts) / fCountsRad; |
efvanmarrewijk | 25:76e9e5597416 | 152 | // minus sign to correct for direction convention |
efvanmarrewijk | 32:a5b411833d1e | 153 | return MotorPosition; |
efvanmarrewijk | 25:76e9e5597416 | 154 | } |
efvanmarrewijk | 11:3efd6a324f16 | 155 | |
efvanmarrewijk | 16:720365110953 | 156 | // Main program |
efvanmarrewijk | 11:3efd6a324f16 | 157 | int main() |
efvanmarrewijk | 18:ca084c362855 | 158 | { |
efvanmarrewijk | 26:b48708ed51ff | 159 | pc.baud(115200); |
efvanmarrewijk | 32:a5b411833d1e | 160 | pin3.period_us(15); // If you give a period on one pin, c++ gives all pins this period |
efvanmarrewijk | 31:91ad5b188bd9 | 161 | |
efvanmarrewijk | 34:30100c1901d4 | 162 | motor.attach(turnl,dt); |
efvanmarrewijk | 28:aec0d9bdb949 | 163 | |
efvanmarrewijk | 26:b48708ed51ff | 164 | emergencybutton.rise(Emergency); //If the button is pressed, stop program |
efvanmarrewijk | 30:c4a3e868ef04 | 165 | //pin6 = 0.01; |
efvanmarrewijk | 17:0ae9e8c958f8 | 166 | |
efvanmarrewijk | 16:720365110953 | 167 | while (true) |
efvanmarrewijk | 25:76e9e5597416 | 168 | { |
efvanmarrewijk | 34:30100c1901d4 | 169 | //turnl(); |
efvanmarrewijk | 34:30100c1901d4 | 170 | //wait(dt); |
Ramonwaninge | 3:d39285fdd103 | 171 | } |
efvanmarrewijk | 30:c4a3e868ef04 | 172 | } |