Advertisement
Guest User

Untitled

a guest
May 2nd, 2014
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.68 KB | None | 0 0
  1. #include <Kalman.h>
  2. #include <Streaming.h>
  3. #include <Wire.h>
  4.  
  5. // Create the Kalman instances:
  6. Kalman kalmanX;
  7. Kalman kalmanY;
  8.  
  9. // IMU Raw Data:
  10. int16_t accX, accY, accZ;
  11. int16_t gyroX, gyroY, gyroZ;
  12. int16_t tempRaw;
  13.  
  14. // Serial Incoming Data
  15. int inByte = 0; // incoming serial byte
  16.  
  17. // Calculated Data
  18. double accXangle, accYangle; // Angle calculate using the accelerometer
  19. double gyroXangle, gyroYangle; // Angle calculate using the gyro
  20. double temp; // Temperature
  21. double compAngleX, compAngleY; // Calculate the angle using a complementary filter
  22. double kalAngleX, kalAngleY; // Calculate the angle using a Kalman filter
  23.  
  24. // Global Variables
  25. uint32_t timer;
  26. uint8_t i2cData[14]; // Buffer for I2C data
  27.  
  28. #define DEBUG
  29.  
  30. void setup()
  31. {
  32. Serial.begin(9600); // start serial port at 9600 bps
  33. Wire.begin();
  34. MPU6050_Init();
  35. establishContact(); // send a byte to establish contact until Processing responds
  36. }
  37.  
  38. void loop()
  39. {
  40. MPU6050_Update();
  41. // if we get a valid byte, read analog ins:
  42. if (Serial.available() > 0) {
  43. SendData();
  44. }
  45. }
  46.  
  47. void SendData(){
  48. float data[10] = {
  49. (float)accX, (float)accY, (float)accZ, (float)gyroX, (float)gyroY, (float)gyroZ, (float)tempRaw, (float)temp, (float)compAngleX, (float)compAngleY };
  50.  
  51. // send sensor values:
  52. for(int i = 0; i < 10; i++){
  53. Serial.println(data[i],2);
  54. }
  55. }
  56.  
  57. void establishContact() {
  58. while (Serial.available() <= 0) {
  59. Serial.write('A'); // send a capital A
  60. delay(300);
  61. }
  62. }
  63.  
  64. void MPU6050_Update()
  65. {
  66. while (i2cRead(0x3B, i2cData, 14));
  67. accX = ((i2cData[0] << 8) | i2cData[1]);
  68. accY = ((i2cData[2] << 8) | i2cData[3]);
  69. accZ = ((i2cData[4] << 8) | i2cData[5]);
  70. tempRaw = ((i2cData[6] << 8) | i2cData[7]);
  71. gyroX = ((i2cData[8] << 8) | i2cData[9]);
  72. gyroY = ((i2cData[10] << 8) | i2cData[11]);
  73. gyroZ = ((i2cData[12] << 8) | i2cData[13]);
  74.  
  75. // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
  76. // We then convert it to 0 to 2π and then from radians to degrees
  77. accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
  78. accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
  79.  
  80. double gyroXrate = (double)gyroX / 131.0;
  81. double gyroYrate = -((double)gyroY / 131.0);
  82. gyroXangle += gyroXrate * ((double)(micros() - timer) / 1000000); // Calculate gyro angle without any filter
  83. gyroYangle += gyroYrate * ((double)(micros() - timer) / 1000000);
  84. //gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
  85. //gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
  86.  
  87. compAngleX = (0.93 * (compAngleX + (gyroXrate * (double)(micros() - timer) / 1000000))) + (0.07 * accXangle); // Calculate the angle using a Complimentary filter
  88. compAngleY = (0.93 * (compAngleY + (gyroYrate * (double)(micros() - timer) / 1000000))) + (0.07 * accYangle);
  89.  
  90. kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
  91. kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 1000000);
  92. timer = micros();
  93.  
  94. temp = ((double)tempRaw + 12412.0) / 340.0;
  95. delay(1);
  96. }
  97.  
  98. void MPU6050_Init()
  99. {
  100. TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz
  101.  
  102. i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
  103. i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
  104. i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
  105. i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
  106. while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
  107. while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode
  108.  
  109. while (i2cRead(0x75, i2cData, 1));
  110. if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
  111. Serial.print(F("Error reading sensor"));
  112. while (1);
  113. }
  114.  
  115. delay(100); // Wait for sensor to stabilize
  116.  
  117. /* Set kalman and gyro starting angle */
  118. while (i2cRead(0x3B, i2cData, 6));
  119. accX = ((i2cData[0] << 8) | i2cData[1]);
  120. accY = ((i2cData[2] << 8) | i2cData[3]);
  121. accZ = ((i2cData[4] << 8) | i2cData[5]);
  122. // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
  123. // We then convert it to 0 to 2π and then from radians to degrees
  124. accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
  125. accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
  126.  
  127. kalmanX.setAngle(accXangle); // Set starting angle
  128. kalmanY.setAngle(accYangle);
  129. gyroXangle = accXangle;
  130. gyroYangle = accYangle;
  131. compAngleX = accXangle;
  132. compAngleY = accYangle;
  133.  
  134. timer = micros();
  135. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement