Advertisement
Shanmhel

Gyro-Cam-Gimbal-2

Jun 25th, 2017
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.77 KB | None | 0 0
  1. /*
  2. 2-AXES SERVO-BASED CAMERA GIMBAL
  3. BY SHANGLOR
  4.  
  5. */
  6.  
  7.  
  8. #include <Servo.h>
  9. Servo xservo,yservo;
  10.  
  11. #include <Wire.h>
  12. #include "Kalman.h"
  13. Kalman kalmanX;
  14. Kalman kalmanY;
  15.  
  16. uint8_t IMUAddress = 0x68; // MPU6050 Address
  17.  
  18. /* IMU Data */
  19. int16_t accX;
  20. int16_t accY;
  21. int16_t accZ;
  22. int16_t tempRaw;
  23. int16_t gyroX;
  24. int16_t gyroY;
  25. int16_t gyroZ;
  26.  
  27. int moveX,moveY;
  28. int mapX,mapY;
  29. int correctionX,correctionY;
  30.  
  31. double accXangle;
  32. double accYangle;
  33. double gyroXangle = 9;
  34. double gyroYangle = 9;
  35. double compAngleX = 90;
  36. double compAngleY = 90;
  37. double kalAngleX;
  38. double kalAngleY;
  39. uint32_t timer;
  40.  
  41.  
  42.  
  43.  
  44. // ---------- VOID SETUP START -------------- /
  45. void setup() {
  46. Serial.begin(115200);
  47. xservo.attach(10);
  48. yservo.attach(11);
  49.  
  50. Wire.begin();
  51. i2cWrite(0x6B,0x00); // Disable sleep mode
  52. if(i2cRead(0x75,1)[0] != 0x68) { // Read "WHO_AM_I" register
  53. Serial.print(F("MPU-6050 with address 0x"));
  54. Serial.print(IMUAddress,HEX);
  55. Serial.println(F(" is not connected"));
  56. while(1);
  57. }
  58. kalmanX.setAngle(90); // Set starting angle
  59. kalmanY.setAngle(90);
  60. timer = micros();
  61. }
  62.  
  63. // ---------- VOID SETUP END -------------- /
  64.  
  65.  
  66. // ---------------------- VOID LOOP START -------------- /
  67. void loop() {
  68. /* Update all the values */
  69. uint8_t* data = i2cRead(0x3B,14);
  70. accX = ((data[0] << 8) | data[1]);
  71. accY = ((data[2] << 8) | data[3]);
  72. accZ = ((data[4] << 8) | data[5]);
  73. tempRaw = ((data[6] << 8) | data[7]);
  74. gyroX = ((data[8] << 8) | data[9]);
  75. gyroY = ((data[10] << 8) | data[11]);
  76. gyroZ = ((data[12] << 8) | data[13]);
  77.  
  78. /* Calculate the angls based on the different sensors and algorithm */
  79.  
  80. accYangle = (atan2(accX,accZ)+PI)*RAD_TO_DEG;
  81. accXangle = (atan2(accY,accZ)+PI)*RAD_TO_DEG;
  82. double gyroXrate = (double)gyroX/131.0;
  83. double gyroYrate = -((double)gyroY/131.0);
  84.  
  85. gyroXangle += gyroXrate*((double)(micros()-timer)/1000000); // Calculate gyro angle without any filter
  86. gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  87. compAngleX = (0.93*(compAngleX+(gyroXrate*(double)(micros()-timer)/1000000)))+(0.07*accXangle); // Calculate the angle using a Complimentary filter
  88. kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  89.  
  90. gyroYangle += gyroYrate*((double)(micros()-timer)/1000000); // Calculate gyro angle without any filter
  91. gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  92. compAngleY = (0.93*(compAngleY+(gyroYrate*(double)(micros()-timer)/1000000)))+(0.07*accYangle); // Calculate the angle using a Complimentary filter
  93. kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros()-timer)/1000000); // Calculate the angle using a Kalman filter
  94. timer = micros();
  95. mapX = map(kalAngleX, 0, 200, 0, 179); //calculate limitation of servo mechanical
  96. mapY = map(kalAngleY, 0, 200, 0, 179); //calculate limitation of servo mechanical
  97.  
  98.  
  99. // /////////////////////////////
  100.  
  101. correctionX = 0; // EDIT THIS VALUE FOR SERVO CORRECTION ANGLE
  102. correctionY = 0; // EDIT THIS VALUE FOR SERVO CORRECTION ANGLE
  103.  
  104. // ////////////////////////////
  105.  
  106.  
  107. moveX = 270 - (kalAngleX) + correctionX;
  108. moveY = 270 - (kalAngleY) + correctionY;
  109.  
  110. // ------- SEND TO SERIAL PRINT START ----- /
  111.  
  112. // Serial.print(moveX);Serial.print("\t");
  113. // Serial.print("\n");
  114.  
  115. // Serial.print(moveY);Serial.print("\t");
  116. // Serial.print("\n");
  117.  
  118. // ------- SEND TO SERIAL PRINT END ----- /
  119.  
  120.  
  121.  
  122.  
  123. // ------- SEND TO SERVO START ----- /
  124.  
  125. xservo.write(moveX); // Send signal to servo
  126. Serial.print("moveX= ");
  127. Serial.println(moveX);
  128. yservo.write(moveY); // Send signal to servo
  129. Serial.print("moveY= ");
  130. Serial.println(moveY);
  131. delay(15); // delay to allow servos to move (ms)
  132.  
  133. // ------- SEND TO SERVO END ----- /
  134.  
  135. delay(1); // The accelerometer's maximum samples rate is 1kHz
  136. }
  137. // ---------------------- VOID LOOP END -------------- /
  138.  
  139.  
  140.  
  141. // -- FUNCTIONS START --
  142. void i2cWrite(uint8_t registerAddress, uint8_t data){
  143. Wire.beginTransmission(IMUAddress);
  144. Wire.write(registerAddress);
  145. Wire.write(data);
  146. Wire.endTransmission(); // Send stop
  147. }
  148.  
  149. uint8_t* i2cRead(uint8_t registerAddress, uint8_t nbytes) {
  150. uint8_t data[nbytes];
  151. Wire.beginTransmission(IMUAddress);
  152. Wire.write(registerAddress);
  153. Wire.endTransmission(false); // Don't release the bus
  154. Wire.requestFrom(IMUAddress, nbytes); // Send a repeated start and then release the bus after reading
  155. for(uint8_t i = 0; i < nbytes; i++)
  156. data[i] = Wire.read();
  157. return data;
  158. }
  159. // -- FUNCTIONS END --
  160. // END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement