First trial
Dependencies: MPU6050 Motor ledControl2 mbed
Fork of BalancingRobotPS3 by
BalancingRobot.cpp@1:01295228342f, 2012-02-14 (annotated)
- Committer:
- Lauszus
- Date:
- Tue Feb 14 18:31:05 2012 +0000
- Revision:
- 1:01295228342f
- Parent:
- 0:f5c02b620688
- Child:
- 2:caec5534774d
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Lauszus | 1:01295228342f | 1 | /* |
Lauszus | 1:01295228342f | 2 | * The code is released under the GNU General Public License. |
Lauszus | 1:01295228342f | 3 | * Developed by Kristian Lauszus |
Lauszus | 1:01295228342f | 4 | * This is the algorithm for my balancing robot/segway. |
Lauszus | 1:01295228342f | 5 | * It is controlled by a PS3 Controller via bluetooth. |
Lauszus | 1:01295228342f | 6 | * The remote control code can be found at my other github repository: https://github.com/TKJElectronics/BalancingRobot |
Lauszus | 1:01295228342f | 7 | * For details, see http://blog.tkjelectronics.dk |
Lauszus | 1:01295228342f | 8 | */ |
Lauszus | 1:01295228342f | 9 | |
Lauszus | 0:f5c02b620688 | 10 | #include "BalancingRobot.h" |
Lauszus | 0:f5c02b620688 | 11 | |
Lauszus | 0:f5c02b620688 | 12 | /* Serial communication */ |
Lauszus | 0:f5c02b620688 | 13 | Serial xbee(p13,p14); // For wireless debugging |
Lauszus | 0:f5c02b620688 | 14 | Serial ps3(p9,p10); // For remote control |
Lauszus | 0:f5c02b620688 | 15 | Serial debug(USBTX, USBRX); // USB |
Lauszus | 0:f5c02b620688 | 16 | |
Lauszus | 0:f5c02b620688 | 17 | /* Timer instance */ |
Lauszus | 0:f5c02b620688 | 18 | Timer t; |
Lauszus | 0:f5c02b620688 | 19 | |
Lauszus | 0:f5c02b620688 | 20 | int main() { |
Lauszus | 0:f5c02b620688 | 21 | xbee.baud(115200); |
Lauszus | 0:f5c02b620688 | 22 | ps3.baud(115200); |
Lauszus | 0:f5c02b620688 | 23 | debug.baud(115200); |
Lauszus | 0:f5c02b620688 | 24 | |
Lauszus | 0:f5c02b620688 | 25 | leftPWM.period(0.00005); //The motor driver can handle pwm values up to 20kHz (1/20000=0.00005) |
Lauszus | 0:f5c02b620688 | 26 | rightPWM.period(0.00005); |
Lauszus | 0:f5c02b620688 | 27 | |
Lauszus | 0:f5c02b620688 | 28 | calibrateSensors(); // Calibrate the gyro and accelerometer relative to ground |
Lauszus | 0:f5c02b620688 | 29 | |
Lauszus | 0:f5c02b620688 | 30 | xbee.printf("Initialized\n"); |
Lauszus | 0:f5c02b620688 | 31 | |
Lauszus | 0:f5c02b620688 | 32 | // Start timing |
Lauszus | 0:f5c02b620688 | 33 | t.start(); |
Lauszus | 0:f5c02b620688 | 34 | loopStartTime = t.read_us(); |
Lauszus | 0:f5c02b620688 | 35 | timer = loopStartTime; |
Lauszus | 0:f5c02b620688 | 36 | |
Lauszus | 0:f5c02b620688 | 37 | while (1) { |
Lauszus | 0:f5c02b620688 | 38 | // See my guide for more info about calculation the angles and the Kalman filter: http://arduino.cc/forum/index.php/topic,58048.0.html |
Lauszus | 0:f5c02b620688 | 39 | accYangle = getAccY(); |
Lauszus | 0:f5c02b620688 | 40 | gyroYrate = getGyroYrate(); |
Lauszus | 0:f5c02b620688 | 41 | |
Lauszus | 0:f5c02b620688 | 42 | pitch = kalman(accYangle, gyroYrate, t.read_us() - timer); // calculate the angle using a Kalman filter |
Lauszus | 0:f5c02b620688 | 43 | timer = t.read_us(); |
Lauszus | 0:f5c02b620688 | 44 | |
Lauszus | 0:f5c02b620688 | 45 | if (ps3.readable()) // Check if there's any incoming data |
Lauszus | 0:f5c02b620688 | 46 | receiveSerial(); |
Lauszus | 0:f5c02b620688 | 47 | |
Lauszus | 0:f5c02b620688 | 48 | //debug.printf("Pitch: %f, accYangle: %f\n",pitch,accYangle); |
Lauszus | 0:f5c02b620688 | 49 | |
Lauszus | 1:01295228342f | 50 | if (pitch < 75 || pitch > 105) // Stop if falling or laying down |
Lauszus | 0:f5c02b620688 | 51 | stopAndReset(); |
Lauszus | 0:f5c02b620688 | 52 | else |
Lauszus | 0:f5c02b620688 | 53 | PID(targetAngle); |
Lauszus | 0:f5c02b620688 | 54 | |
Lauszus | 0:f5c02b620688 | 55 | /* Used a time fixed loop */ |
Lauszus | 0:f5c02b620688 | 56 | lastLoopUsefulTime = t.read_us() - loopStartTime; |
Lauszus | 0:f5c02b620688 | 57 | if (lastLoopUsefulTime < STD_LOOP_TIME) |
Lauszus | 0:f5c02b620688 | 58 | wait_us(STD_LOOP_TIME - lastLoopUsefulTime); |
Lauszus | 0:f5c02b620688 | 59 | lastLoopTime = t.read_us() - loopStartTime; // only used for debugging |
Lauszus | 0:f5c02b620688 | 60 | loopStartTime = t.read_us(); |
Lauszus | 0:f5c02b620688 | 61 | |
Lauszus | 0:f5c02b620688 | 62 | //debug.printf("%i,%i\n",lastLoopUsefulTime,lastLoopTime); |
Lauszus | 0:f5c02b620688 | 63 | } |
Lauszus | 0:f5c02b620688 | 64 | } |
Lauszus | 0:f5c02b620688 | 65 | void stopAndReset() { |
Lauszus | 0:f5c02b620688 | 66 | stop(both); |
Lauszus | 0:f5c02b620688 | 67 | lastError = 0; |
Lauszus | 0:f5c02b620688 | 68 | iTerm = 0; |
Lauszus | 0:f5c02b620688 | 69 | } |
Lauszus | 0:f5c02b620688 | 70 | void receiveSerial() { |
Lauszus | 0:f5c02b620688 | 71 | char input[16]; // The serial buffer is only 16 characters, so the data has to be split up |
Lauszus | 1:01295228342f | 72 | int i = 0; |
Lauszus | 0:f5c02b620688 | 73 | while (ps3.readable()) { |
Lauszus | 1:01295228342f | 74 | input[i] = ps3.getc(); |
Lauszus | 1:01295228342f | 75 | if(input[i] == ';') |
Lauszus | 1:01295228342f | 76 | break; |
Lauszus | 1:01295228342f | 77 | i++; |
Lauszus | 1:01295228342f | 78 | } |
Lauszus | 0:f5c02b620688 | 79 | //debug.printf("Input: %s\n",input); |
Lauszus | 0:f5c02b620688 | 80 | |
Lauszus | 0:f5c02b620688 | 81 | /* For remote control */ |
Lauszus | 0:f5c02b620688 | 82 | if (input[0] == 'F') { // Forward |
Lauszus | 0:f5c02b620688 | 83 | steerForward = true; |
Lauszus | 0:f5c02b620688 | 84 | steerBackward = false; |
Lauszus | 0:f5c02b620688 | 85 | steerLeft = false; |
Lauszus | 0:f5c02b620688 | 86 | steerRotateLeft = false; |
Lauszus | 0:f5c02b620688 | 87 | steerRight = false; |
Lauszus | 0:f5c02b620688 | 88 | steerRotateRight = false; |
Lauszus | 0:f5c02b620688 | 89 | } else if (input[0] == 'B') { // Backward |
Lauszus | 0:f5c02b620688 | 90 | steerForward = false; |
Lauszus | 0:f5c02b620688 | 91 | steerBackward = true; |
Lauszus | 0:f5c02b620688 | 92 | steerLeft = false; |
Lauszus | 0:f5c02b620688 | 93 | steerRotateLeft = false; |
Lauszus | 0:f5c02b620688 | 94 | steerRight = false; |
Lauszus | 0:f5c02b620688 | 95 | steerRotateRight = false; |
Lauszus | 0:f5c02b620688 | 96 | } else if (input[0] == 'L') { // Left |
Lauszus | 0:f5c02b620688 | 97 | if (input[1] == 'R') { // Left Rotate |
Lauszus | 0:f5c02b620688 | 98 | steerLeft = false; |
Lauszus | 0:f5c02b620688 | 99 | steerRotateLeft = true; |
Lauszus | 0:f5c02b620688 | 100 | } else { |
Lauszus | 0:f5c02b620688 | 101 | steerLeft = true; |
Lauszus | 0:f5c02b620688 | 102 | steerRotateLeft = false; |
Lauszus | 0:f5c02b620688 | 103 | } |
Lauszus | 0:f5c02b620688 | 104 | steerForward = false; |
Lauszus | 0:f5c02b620688 | 105 | steerBackward = false; |
Lauszus | 0:f5c02b620688 | 106 | steerRight = false; |
Lauszus | 0:f5c02b620688 | 107 | steerRotateRight = false; |
Lauszus | 0:f5c02b620688 | 108 | } else if (input[0] == 'R') { // Right |
Lauszus | 0:f5c02b620688 | 109 | if (input[1] == 'R') { // Right Rotate |
Lauszus | 0:f5c02b620688 | 110 | steerRight = false; |
Lauszus | 0:f5c02b620688 | 111 | steerRotateRight = true; |
Lauszus | 0:f5c02b620688 | 112 | } else { |
Lauszus | 0:f5c02b620688 | 113 | steerRight = true; |
Lauszus | 0:f5c02b620688 | 114 | steerRotateRight = false; |
Lauszus | 0:f5c02b620688 | 115 | } |
Lauszus | 0:f5c02b620688 | 116 | steerForward = false; |
Lauszus | 0:f5c02b620688 | 117 | steerBackward = false; |
Lauszus | 0:f5c02b620688 | 118 | steerLeft = false; |
Lauszus | 0:f5c02b620688 | 119 | steerRotateLeft = false; |
Lauszus | 0:f5c02b620688 | 120 | } else if (input[0] == 'S') { // Stop |
Lauszus | 0:f5c02b620688 | 121 | steerForward = false; |
Lauszus | 0:f5c02b620688 | 122 | steerBackward = false; |
Lauszus | 0:f5c02b620688 | 123 | steerLeft = false; |
Lauszus | 0:f5c02b620688 | 124 | steerRotateLeft = false; |
Lauszus | 0:f5c02b620688 | 125 | steerRight = false; |
Lauszus | 0:f5c02b620688 | 126 | steerRotateRight = false; |
Lauszus | 0:f5c02b620688 | 127 | } |
Lauszus | 0:f5c02b620688 | 128 | |
Lauszus | 0:f5c02b620688 | 129 | else if (input[0] == 'T') { // Set the target angle |
Lauszus | 0:f5c02b620688 | 130 | strtok(input, ","); // Ignore 'T' |
Lauszus | 1:01295228342f | 131 | targetAngle = atof(strtok(NULL, ";")); // read until the end and then convert from string to double |
Lauszus | 0:f5c02b620688 | 132 | if (targetAngle < 75 || targetAngle > 105) // The serial communication sometimes behaves weird |
Lauszus | 1:01295228342f | 133 | targetAngle = lastTargetAngle; |
Lauszus | 1:01295228342f | 134 | lastTargetAngle = targetAngle; |
Lauszus | 0:f5c02b620688 | 135 | xbee.printf("%f\n",targetAngle); // Print targetAngle for debugging |
Lauszus | 0:f5c02b620688 | 136 | } else if (input[0] == 'A') { // Abort |
Lauszus | 0:f5c02b620688 | 137 | stopAndReset(); |
Lauszus | 0:f5c02b620688 | 138 | while (ps3.getc() != 'C'); // Wait until continue is send |
Lauszus | 0:f5c02b620688 | 139 | } |
Lauszus | 0:f5c02b620688 | 140 | } |
Lauszus | 0:f5c02b620688 | 141 | void PID(double restAngle) { |
Lauszus | 0:f5c02b620688 | 142 | if (steerForward) |
Lauszus | 1:01295228342f | 143 | restAngle -= 1.5; |
Lauszus | 0:f5c02b620688 | 144 | else if (steerBackward) |
Lauszus | 1:01295228342f | 145 | restAngle += 1.5; |
Lauszus | 0:f5c02b620688 | 146 | |
Lauszus | 0:f5c02b620688 | 147 | double error = (restAngle - pitch)/100; |
Lauszus | 0:f5c02b620688 | 148 | double pTerm = Kp * error; |
Lauszus | 0:f5c02b620688 | 149 | iTerm += Ki * error; |
Lauszus | 0:f5c02b620688 | 150 | double dTerm = Kd * (error - lastError); |
Lauszus | 0:f5c02b620688 | 151 | lastError = error; |
Lauszus | 0:f5c02b620688 | 152 | |
Lauszus | 0:f5c02b620688 | 153 | double PIDValue = pTerm + iTerm + dTerm; |
Lauszus | 0:f5c02b620688 | 154 | |
Lauszus | 0:f5c02b620688 | 155 | //debug.printf("Pitch: %5.2f\tPIDValue: %5.2f\tpTerm: %5.2f\tiTerm: %5.2f\tdTerm: %5.2f\tKp: %5.2f\tKi: %5.2f\tKd: %5.2f\n",pitch,PIDValue,pTerm,iTerm,dTerm,Kp,Ki,Kd); |
Lauszus | 0:f5c02b620688 | 156 | |
Lauszus | 0:f5c02b620688 | 157 | double PIDLeft; |
Lauszus | 0:f5c02b620688 | 158 | double PIDRight; |
Lauszus | 0:f5c02b620688 | 159 | if (steerLeft) { |
Lauszus | 0:f5c02b620688 | 160 | PIDLeft = PIDValue-(0.1); |
Lauszus | 0:f5c02b620688 | 161 | PIDRight = PIDValue+(0.1); |
Lauszus | 0:f5c02b620688 | 162 | } else if (steerRotateLeft) { |
Lauszus | 0:f5c02b620688 | 163 | PIDLeft = PIDValue-(0.2); |
Lauszus | 0:f5c02b620688 | 164 | PIDRight = PIDValue+(0.2); |
Lauszus | 0:f5c02b620688 | 165 | } else if (steerRight) { |
Lauszus | 0:f5c02b620688 | 166 | PIDLeft = PIDValue-(-0.1); |
Lauszus | 0:f5c02b620688 | 167 | PIDRight = PIDValue+(-0.1); |
Lauszus | 0:f5c02b620688 | 168 | } else if (steerRotateRight) { |
Lauszus | 0:f5c02b620688 | 169 | PIDLeft = PIDValue-(-0.2); |
Lauszus | 0:f5c02b620688 | 170 | PIDRight = PIDValue+(-0.2); |
Lauszus | 0:f5c02b620688 | 171 | } else { |
Lauszus | 0:f5c02b620688 | 172 | PIDLeft = PIDValue; |
Lauszus | 0:f5c02b620688 | 173 | PIDRight = PIDValue; |
Lauszus | 0:f5c02b620688 | 174 | } |
Lauszus | 0:f5c02b620688 | 175 | PIDLeft *= 0.9; // compensate for difference in the motors |
Lauszus | 0:f5c02b620688 | 176 | |
Lauszus | 0:f5c02b620688 | 177 | //Set PWM Values |
Lauszus | 0:f5c02b620688 | 178 | if (PIDLeft >= 0) |
Lauszus | 0:f5c02b620688 | 179 | move(left, forward, PIDLeft); |
Lauszus | 0:f5c02b620688 | 180 | else |
Lauszus | 0:f5c02b620688 | 181 | move(left, backward, PIDLeft * -1); |
Lauszus | 0:f5c02b620688 | 182 | if (PIDRight >= 0) |
Lauszus | 0:f5c02b620688 | 183 | move(right, forward, PIDRight); |
Lauszus | 0:f5c02b620688 | 184 | else |
Lauszus | 0:f5c02b620688 | 185 | move(right, backward, PIDRight * -1); |
Lauszus | 0:f5c02b620688 | 186 | } |
Lauszus | 0:f5c02b620688 | 187 | double kalman(double newAngle, double newRate, double dtime) { |
Lauszus | 0:f5c02b620688 | 188 | // KasBot V2 - Kalman filter module - http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1284738418 - http://www.x-firm.com/?page_id=145 |
Lauszus | 0:f5c02b620688 | 189 | // with slightly modifications by Kristian Lauszus |
Lauszus | 0:f5c02b620688 | 190 | dt = dtime / 1000000; // Convert from microseconds to seconds |
Lauszus | 0:f5c02b620688 | 191 | |
Lauszus | 0:f5c02b620688 | 192 | // Discrete Kalman filter time update equations - Time Update ("Predict") |
Lauszus | 0:f5c02b620688 | 193 | // Update xhat - Project the state ahead |
Lauszus | 0:f5c02b620688 | 194 | angle += dt * (newRate - bias); |
Lauszus | 0:f5c02b620688 | 195 | |
Lauszus | 0:f5c02b620688 | 196 | // Update estimation error covariance - Project the error covariance ahead |
Lauszus | 0:f5c02b620688 | 197 | P_00 += -dt * (P_10 + P_01) + Q_angle * dt; |
Lauszus | 0:f5c02b620688 | 198 | P_01 += -dt * P_11; |
Lauszus | 0:f5c02b620688 | 199 | P_10 += -dt * P_11; |
Lauszus | 0:f5c02b620688 | 200 | P_11 += +Q_gyro * dt; |
Lauszus | 0:f5c02b620688 | 201 | |
Lauszus | 0:f5c02b620688 | 202 | // Discrete Kalman filter measurement update equations - Measurement Update ("Correct") |
Lauszus | 0:f5c02b620688 | 203 | // Calculate Kalman gain - Compute the Kalman gain |
Lauszus | 0:f5c02b620688 | 204 | S = P_00 + R_angle; |
Lauszus | 0:f5c02b620688 | 205 | K_0 = P_00 / S; |
Lauszus | 0:f5c02b620688 | 206 | K_1 = P_10 / S; |
Lauszus | 0:f5c02b620688 | 207 | |
Lauszus | 0:f5c02b620688 | 208 | // Calculate angle and resting rate - Update estimate with measurement zk |
Lauszus | 0:f5c02b620688 | 209 | y = newAngle - angle; |
Lauszus | 0:f5c02b620688 | 210 | angle += K_0 * y; |
Lauszus | 0:f5c02b620688 | 211 | bias += K_1 * y; |
Lauszus | 0:f5c02b620688 | 212 | |
Lauszus | 0:f5c02b620688 | 213 | // Calculate estimation error covariance - Update the error covariance |
Lauszus | 0:f5c02b620688 | 214 | P_00 -= K_0 * P_00; |
Lauszus | 0:f5c02b620688 | 215 | P_01 -= K_0 * P_01; |
Lauszus | 0:f5c02b620688 | 216 | P_10 -= K_1 * P_00; |
Lauszus | 0:f5c02b620688 | 217 | P_11 -= K_1 * P_01; |
Lauszus | 0:f5c02b620688 | 218 | |
Lauszus | 0:f5c02b620688 | 219 | return angle; |
Lauszus | 0:f5c02b620688 | 220 | } |
Lauszus | 0:f5c02b620688 | 221 | double getGyroYrate() { |
Lauszus | 0:f5c02b620688 | 222 | // (gyroAdc-gyroZero)/Sensitivity (In quids) - Sensitivity = 0.00333/3.3*4095=4.132227273 |
Lauszus | 0:f5c02b620688 | 223 | double gyroRate = -(((gyroY.read()*4095) - zeroValues[0]) / 4.132227273); |
Lauszus | 0:f5c02b620688 | 224 | return gyroRate; |
Lauszus | 0:f5c02b620688 | 225 | } |
Lauszus | 0:f5c02b620688 | 226 | double getAccY() { |
Lauszus | 0:f5c02b620688 | 227 | // (accAdc-accZero)/Sensitivity (In quids) - Sensitivity = 0.33/3.3*4095=409.5 |
Lauszus | 0:f5c02b620688 | 228 | double accXval = ((accX.read()*4095) - zeroValues[1]) / 409.5; |
Lauszus | 0:f5c02b620688 | 229 | double accYval = ((accY.read()*4095) - zeroValues[2]) / 409.5; |
Lauszus | 0:f5c02b620688 | 230 | accYval--;//-1g when lying down |
Lauszus | 0:f5c02b620688 | 231 | double accZval = ((accZ.read()*4095) - zeroValues[3]) / 409.5; |
Lauszus | 0:f5c02b620688 | 232 | |
Lauszus | 0:f5c02b620688 | 233 | double R = sqrt(pow(accXval, 2) + pow(accYval, 2) + pow(accZval, 2)); // Calculate the force vector |
Lauszus | 0:f5c02b620688 | 234 | double angleY = acos(accYval / R) * RAD_TO_DEG; |
Lauszus | 0:f5c02b620688 | 235 | |
Lauszus | 0:f5c02b620688 | 236 | return angleY; |
Lauszus | 0:f5c02b620688 | 237 | } |
Lauszus | 0:f5c02b620688 | 238 | void calibrateSensors() { |
Lauszus | 0:f5c02b620688 | 239 | onboardLED1 = 1; |
Lauszus | 0:f5c02b620688 | 240 | onboardLED2 = 1; |
Lauszus | 0:f5c02b620688 | 241 | onboardLED3 = 1; |
Lauszus | 0:f5c02b620688 | 242 | onboardLED4 = 1; |
Lauszus | 0:f5c02b620688 | 243 | |
Lauszus | 0:f5c02b620688 | 244 | double adc[4]; |
Lauszus | 0:f5c02b620688 | 245 | for (uint8_t i = 0; i < 100; i++) { // Take the average of 100 readings |
Lauszus | 0:f5c02b620688 | 246 | adc[0] += gyroY.read()*4095; |
Lauszus | 0:f5c02b620688 | 247 | adc[1] += accX.read()*4095; |
Lauszus | 0:f5c02b620688 | 248 | adc[2] += accY.read()*4095; |
Lauszus | 0:f5c02b620688 | 249 | adc[3] += accZ.read()*4095; |
Lauszus | 0:f5c02b620688 | 250 | wait_ms(10); |
Lauszus | 0:f5c02b620688 | 251 | } |
Lauszus | 0:f5c02b620688 | 252 | zeroValues[0] = adc[0] / 100; // Gyro X-axis |
Lauszus | 0:f5c02b620688 | 253 | zeroValues[1] = adc[1] / 100; // Accelerometer X-axis |
Lauszus | 0:f5c02b620688 | 254 | zeroValues[2] = adc[2] / 100; // Accelerometer Y-axis |
Lauszus | 0:f5c02b620688 | 255 | zeroValues[3] = adc[3] / 100; // Accelerometer Z-axis |
Lauszus | 0:f5c02b620688 | 256 | |
Lauszus | 0:f5c02b620688 | 257 | onboardLED1 = 0; |
Lauszus | 0:f5c02b620688 | 258 | onboardLED2 = 0; |
Lauszus | 0:f5c02b620688 | 259 | onboardLED3 = 0; |
Lauszus | 0:f5c02b620688 | 260 | onboardLED4 = 0; |
Lauszus | 0:f5c02b620688 | 261 | } |
Lauszus | 0:f5c02b620688 | 262 | void move(Motor motor, Direction direction, float speed) { // speed is a value in percentage (0.0f to 1.0f) |
Lauszus | 0:f5c02b620688 | 263 | if (motor == right) { |
Lauszus | 0:f5c02b620688 | 264 | leftPWM = speed; |
Lauszus | 0:f5c02b620688 | 265 | if (direction == forward) { |
Lauszus | 0:f5c02b620688 | 266 | leftA = 0; |
Lauszus | 0:f5c02b620688 | 267 | leftB = 1; |
Lauszus | 0:f5c02b620688 | 268 | } else if (direction == backward) { |
Lauszus | 0:f5c02b620688 | 269 | leftA = 1; |
Lauszus | 0:f5c02b620688 | 270 | leftB = 0; |
Lauszus | 0:f5c02b620688 | 271 | } |
Lauszus | 0:f5c02b620688 | 272 | } else if (motor == left) { |
Lauszus | 0:f5c02b620688 | 273 | rightPWM = speed; |
Lauszus | 0:f5c02b620688 | 274 | if (direction == forward) { |
Lauszus | 0:f5c02b620688 | 275 | rightA = 0; |
Lauszus | 0:f5c02b620688 | 276 | rightB = 1; |
Lauszus | 0:f5c02b620688 | 277 | } else if (direction == backward) { |
Lauszus | 0:f5c02b620688 | 278 | rightA = 1; |
Lauszus | 0:f5c02b620688 | 279 | rightB = 0; |
Lauszus | 0:f5c02b620688 | 280 | } |
Lauszus | 0:f5c02b620688 | 281 | } else if (motor == both) { |
Lauszus | 0:f5c02b620688 | 282 | leftPWM = speed; |
Lauszus | 0:f5c02b620688 | 283 | rightPWM = speed; |
Lauszus | 0:f5c02b620688 | 284 | if (direction == forward) { |
Lauszus | 0:f5c02b620688 | 285 | leftA = 0; |
Lauszus | 0:f5c02b620688 | 286 | leftB = 1; |
Lauszus | 0:f5c02b620688 | 287 | |
Lauszus | 0:f5c02b620688 | 288 | rightA = 0; |
Lauszus | 0:f5c02b620688 | 289 | rightB = 1; |
Lauszus | 0:f5c02b620688 | 290 | } else if (direction == backward) { |
Lauszus | 0:f5c02b620688 | 291 | leftA = 1; |
Lauszus | 0:f5c02b620688 | 292 | leftB = 0; |
Lauszus | 0:f5c02b620688 | 293 | |
Lauszus | 0:f5c02b620688 | 294 | rightA = 1; |
Lauszus | 0:f5c02b620688 | 295 | rightB = 0; |
Lauszus | 0:f5c02b620688 | 296 | } |
Lauszus | 0:f5c02b620688 | 297 | } |
Lauszus | 0:f5c02b620688 | 298 | } |
Lauszus | 0:f5c02b620688 | 299 | void stop(Motor motor) { |
Lauszus | 0:f5c02b620688 | 300 | if (motor == left) { |
Lauszus | 0:f5c02b620688 | 301 | leftPWM = 1; |
Lauszus | 0:f5c02b620688 | 302 | leftA = 1; |
Lauszus | 0:f5c02b620688 | 303 | leftB = 1; |
Lauszus | 0:f5c02b620688 | 304 | } else if (motor == right) { |
Lauszus | 0:f5c02b620688 | 305 | rightPWM = 1; |
Lauszus | 0:f5c02b620688 | 306 | rightA = 1; |
Lauszus | 0:f5c02b620688 | 307 | rightB = 1; |
Lauszus | 0:f5c02b620688 | 308 | } else if (motor == both) { |
Lauszus | 0:f5c02b620688 | 309 | leftPWM = 1; |
Lauszus | 0:f5c02b620688 | 310 | leftA = 1; |
Lauszus | 0:f5c02b620688 | 311 | leftB = 1; |
Lauszus | 0:f5c02b620688 | 312 | |
Lauszus | 0:f5c02b620688 | 313 | rightPWM = 1; |
Lauszus | 0:f5c02b620688 | 314 | rightA = 1; |
Lauszus | 0:f5c02b620688 | 315 | rightB = 1; |
Lauszus | 0:f5c02b620688 | 316 | } |
Lauszus | 0:f5c02b620688 | 317 | } |