Guest User

Slave_acc

a guest
Apr 9th, 2015
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.25 KB | None | 0 0
  1.  
  2. #include <Wire.h>
  3. #include "Kalman.h" // Source: https://github.com/TKJElectronics/KalmanFilter
  4. #define RESTRICT_PITCH // Comment out to restrict roll to ±90deg instead - please read: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf
  5.  
  6. Kalman kalmanX; // Create the Kalman instances
  7. Kalman kalmanY;
  8.  
  9. /* IMU Data */
  10. double accX, accY, accZ;
  11. double gyroX, gyroY, gyroZ;
  12. int16_t tempRaw;
  13.  
  14. /* со старого акселерометра */
  15. volatile boolean flag = 0;
  16. unsigned long time;
  17. unsigned long total_time;
  18. boolean is_first = 1;
  19. /* конец */
  20.  
  21. double gyroXangle, gyroYangle; // Angle calculate using the gyro only
  22. double compAngleX, compAngleY; // Calculated angle using a complementary filter
  23. double kalAngleX, kalAngleY; // Calculated angle using a Kalman filter
  24.  
  25. uint32_t timer;
  26. uint8_t i2cData[14]; // Buffer for I2C data
  27.  
  28. void setup() {
  29.   Serial.begin(115200);
  30.   Wire.begin();
  31.  
  32.   /* со старого акселерометра */
  33.   attachInterrupt(0, accel, RISING);
  34.   /* конец */
  35.  
  36.   TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz
  37.  
  38.   i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
  39.   i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
  40.   i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
  41.   i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
  42.   while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
  43.   while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode
  44.   while (i2cRead(0x75, i2cData, 1));
  45.   if (i2cData[0] != 0x68)
  46.   { // Read "WHO_AM_I" register
  47.     Serial.print(F("Error reading sensor"));
  48.     while (1);
  49.   }
  50.   /* Set kalman and gyro starting angle */
  51.   while (i2cRead(0x3B, i2cData, 6));
  52.   accX = (i2cData[0] << 8) | i2cData[1];
  53.   accY = (i2cData[2] << 8) | i2cData[3];
  54.   accZ = (i2cData[4] << 8) | i2cData[5];
  55.  
  56.   // Source: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf eq. 25 and eq. 26
  57.   // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
  58.   // It is then converted from radians to degrees
  59. #ifdef RESTRICT_PITCH // Eq. 25 and 26
  60.   double roll  = atan2(accY, accZ) * RAD_TO_DEG;
  61.   double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
  62. #else // Eq. 28 and 29
  63.   double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
  64.   double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
  65. #endif
  66.  
  67.   kalmanX.setAngle(roll); // Set starting angle
  68.   kalmanY.setAngle(pitch);
  69.   gyroXangle = roll;
  70.   gyroYangle = pitch;
  71.   compAngleX = roll;
  72.   compAngleY = pitch;
  73.   timer = micros();
  74. }
  75.  
  76. void loop() {
  77.    /* со старого акселерометра */
  78.   if(flag)
  79.   {
  80.    /* конец */
  81.    /* Update all the values */
  82.   while (i2cRead(0x3B, i2cData, 14));
  83.   accX = ((i2cData[0] << 8) | i2cData[1]) + 2000.0; // You might need to adjust these zeroes values depending on your accelerometer
  84.   accY = ((i2cData[2] << 8) | i2cData[3]) + 3319.84;
  85.   accZ = ((i2cData[4] << 8) | i2cData[5]) + 664.48;
  86.   tempRaw = (i2cData[6] << 8) | i2cData[7];
  87.   gyroX = (i2cData[8] << 8) | i2cData[9];
  88.   gyroY = (i2cData[10] << 8) | i2cData[11];
  89.   gyroZ = (i2cData[12] << 8) | i2cData[13];
  90.  
  91.   double dt = (double)(micros() - timer) / 1000000; // Calculate delta time
  92.   timer = micros();
  93.  
  94.   // Source: http://www.freescale.com/files/sensors/doc/app_note/AN3461.pdf eq. 25 and eq. 26
  95.   // atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
  96.   // It is then converted from radians to degrees
  97. #ifdef RESTRICT_PITCH // Eq. 25 and 26
  98.   double roll  = atan2(accY, accZ) * RAD_TO_DEG;
  99.   double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
  100. #else // Eq. 28 and 29
  101.   double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
  102.   double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
  103. #endif
  104.  
  105.   double gyroXrate = gyroX / 131.0; // Convert to deg/s
  106.   double gyroYrate = gyroY / 131.0; // Convert to deg/s
  107.  
  108. #ifdef RESTRICT_PITCH
  109.   // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
  110.   if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {
  111.     kalmanX.setAngle(roll);
  112.     compAngleX = roll;
  113.     kalAngleX = roll;
  114.     gyroXangle = roll;
  115.   } else
  116.     kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter
  117.  
  118.   if (abs(kalAngleX) > 90)
  119.     gyroYrate = -gyroYrate; // Invert rate, so it fits the restriced accelerometer reading
  120.   kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);
  121. #else
  122.   // This fixes the transition problem when the accelerometer angle jumps between -180 and 180 degrees
  123.   if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90))
  124.   {
  125.     kalmanY.setAngle(pitch);
  126.     compAngleY = pitch;
  127.     kalAngleY = pitch;
  128.     gyroYangle = pitch;
  129.   }
  130.   else
  131.     kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt); // Calculate the angle using a Kalman filter
  132.  
  133.   if (abs(kalAngleY) > 90)
  134.     gyroXrate = -gyroXrate; // Invert rate, so it fits the restriced accelerometer reading
  135.   kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt); // Calculate the angle using a Kalman filter
  136. #endif
  137.  
  138.   gyroXangle += gyroXrate * dt; // Calculate gyro angle without any filter
  139.   gyroYangle += gyroYrate * dt;
  140.   //gyroXangle += kalmanX.getRate() * dt; // Calculate gyro angle using the unbiased rate
  141.   //gyroYangle += kalmanY.getRate() * dt;
  142.  
  143.   compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll; // Calculate the angle using a Complimentary filter
  144.   compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;
  145.  
  146.   // Reset the gyro angle when it has drifted too much
  147.   if (gyroXangle < -180 || gyroXangle > 180)
  148.     gyroXangle = kalAngleX;
  149.   if (gyroYangle < -180 || gyroYangle > 180)
  150.     gyroYangle = kalAngleY;
  151.  
  152.   /* Print Data */
  153. #if 1 // Set to 1 to activate
  154.   Serial.print(accX); Serial.print("\t");
  155. //  total_time +=(micros()-time);
  156. //  time=micros();
  157. Serial.println(micros()-time); Serial.print("\t");
  158. Serial.print("\t");
  159. #endif
  160.  
  161.    flag=0;
  162.   }
  163. }
  164.   void accel()
  165.   {
  166.   flag=1;
  167.   if (is_first == 1)
  168.     {
  169.     is_first = 0;
  170.     time = micros();
  171.     }  
  172.   }
Advertisement
Add Comment
Please, Sign In to add comment