Guest User

Untitled

a guest
Dec 14th, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.51 KB | None | 0 0
  1. #include<Wire.h>
  2. const int MPU_addr=0x68;
  3. double AccelX,AccelY,AccelZ,Tmp,GyroX,GyroY,GyroZ; //These will be the raw data from the MPU6050.
  4. uint32_t timer; //it's a timer, saved as a big-ass unsigned int. We use it to save times from the "micros()" command and subtract the present time in microseconds from the time stored in timer to calculate the time for each loop.
  5. double Angle_X, Angle_Y; //These are the angles in the complementary filter
  6. #define degconvert 57.29577951 //there are like 57 degrees in a radian.
  7.  
  8. #define m1_left 12
  9. #define m1_right 10
  10. #define m2_left 3
  11. #define m2_right 4
  12.  
  13.  
  14. #define Kp 210
  15. #define Kd 2
  16. #define Ki 90
  17. #define sampleTime 0.005
  18. #define targetAngle 0
  19. volatile int output = 0;
  20. volatile float currentAngle, prevAngle=0, error, prevError=0, errorSum=0;
  21. void setup() {
  22. pinMode(m1_left, OUTPUT);
  23. pinMode(m1_right, OUTPUT);
  24. pinMode(m2_left, OUTPUT);
  25. pinMode(m2_right, OUTPUT);
  26. Wire.begin();
  27. #if ARDUINO >= 157
  28. Wire.setClock(400000UL); // Set I2C frequency to 400kHz
  29. #else
  30. TWBR = ((F_CPU / 400000UL) - 16) / 2; // Set I2C frequency to 400kHz
  31. #endif
  32.  
  33.  
  34. Wire.beginTransmission(MPU_addr);
  35. Wire.write(0x6B); // PWR_MGMT_1 register
  36. Wire.write(0); // set to zero (wakes up the MPU-6050)
  37. Wire.endTransmission(true);
  38. Serial.begin(57600);
  39. delay(100);
  40.  
  41. //setup starting angle
  42. //1) collect the data
  43. Wire.beginTransmission(MPU_addr);
  44. Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
  45. Wire.endTransmission(false);
  46. Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers
  47. AccelX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  48. AccelY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  49. AccelZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  50. Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  51. GyroX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  52. GyroY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  53. GyroZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  54.  
  55. double roll = atan2(AccelY, AccelZ)*degconvert;
  56. double pitch = atan2(-AccelX, AccelZ)*degconvert;
  57.  
  58. double gyroXangle = roll;
  59. double gyroYangle = pitch;
  60. double Angle_X = roll;
  61. double Angle_Y = pitch;
  62.  
  63. //start a timer
  64. timer = micros();
  65. }
  66.  
  67. void command(int L_M_Speed, int R_M_Speed) {
  68. if(L_M_Speed >= 0) {
  69. analogWrite(m2_left, L_M_Speed);
  70. digitalWrite(m2_right, LOW);
  71. }
  72. else {
  73. analogWrite(m2_left, 255 + L_M_Speed);
  74. digitalWrite(m2_right, HIGH);
  75. }
  76. if(R_M_Speed >= 0) {
  77. analogWrite(m1_right, R_M_Speed);
  78. digitalWrite(m1_left, LOW);
  79. }
  80. else {
  81. analogWrite(m1_right, 255 + R_M_Speed);
  82. digitalWrite(m1_left, HIGH);
  83. }
  84. }
  85. void loop(){
  86. //Now begins the main loop.
  87. //Collect raw data from the sensor.
  88. Wire.beginTransmission(MPU_addr);
  89. Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
  90. Wire.endTransmission(false);
  91. Wire.requestFrom(MPU_addr,14,true); // request a total of 14 registers
  92. AccelX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  93. AccelY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  94. AccelZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  95. Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  96. GyroX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  97. GyroY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  98. GyroZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  99.  
  100. double dt = (double)(micros() - timer) / 1000000;
  101. timer = micros();
  102. double roll = atan2(AccelY, AccelZ)*degconvert;
  103. double pitch = atan2(-AccelX, AccelZ)*degconvert;
  104. double gyroXrate = GyroX/131.0;
  105. double gyroYrate = GyroY/131.0;
  106. Angle_X = 0.99 * (Angle_X + gyroXrate * dt) + 0.01 * roll;
  107. Angle_Y = 0.99 * (Angle_Y + gyroYrate * dt) + 0.01 * pitch;
  108. currentAngle = Angle_Y;
  109. if(currentAngle > 50 && currentAngle < -50){
  110. digitalWrite(m2_right, LOW);
  111. digitalWrite(m1_right, LOW);
  112. digitalWrite(m2_left, LOW);
  113. digitalWrite(m1_left, LOW);
  114. }
  115. else{
  116. error = currentAngle - targetAngle;
  117. errorSum = errorSum + error;
  118. errorSum = constrain(errorSum, -300, 300);
  119. //calculate output from P, I and D values
  120. output = Kp*(error) + Ki*(errorSum)*sampleTime - Kd*(currentAngle-prevAngle)/sampleTime;
  121. output = constrain(output, -255, 255);
  122. command(output, output);
  123. prevAngle = currentAngle;
  124. }
  125. }
Add Comment
Please, Sign In to add comment