@ -190,9 +190,9 @@ void GYRO::calculate_imu_error(void) {
GyZ = read_register ( GYRO_ZOUT_H ) < < 8 | read_register ( GYRO_ZOUT_L ) ;
// Sum all readings
GyroErrorX = GyroErrorX + ( GyX / 131.0 ) ;
GyroErrorY = GyroErrorY + ( GyY / 131.0 ) ;
GyroErrorZ = GyroErrorZ + ( GyZ / 131.0 ) ;
GyroErrorX = GyroErrorX + ( GyX / 16.4 ) ;
GyroErrorY = GyroErrorY + ( GyY / 16.4 ) ;
GyroErrorZ = GyroErrorZ + ( GyZ / 16.4 ) ;
c + + ;
}
@ -211,6 +211,43 @@ void GYRO::calculate_imu_error(void) {
}
void GYRO : : read_accelerometer ( void ) {
AcX = read_register ( ACCEL_XOUT_H ) < < 8 | read_register ( ACCEL_XOUT_L ) ;
AcY = read_register ( ACCEL_YOUT_H ) < < 8 | read_register ( ACCEL_YOUT_L ) ;
AcZ = read_register ( ACCEL_ZOUT_H ) < < 8 | read_register ( ACCEL_ZOUT_L ) ;
// Calculating Roll and Pitch from the accelerometer data
accAngleX = ( atan ( AcY / sqrt ( pow ( AcX , 2 ) + pow ( AcZ , 2 ) ) ) * 180 / PI ) - 0.58 ; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
accAngleY = ( atan ( - 1 * AcX / sqrt ( pow ( AcY , 2 ) + pow ( AcZ , 2 ) ) ) * 180 / PI ) + 1.58 ; // AccErrorY ~(-1.58)
}
void GYRO : : read_gyro ( void ) {
// Read Gyro data
previousTime = currentTime ; // Previous time is stored before the actual time read
currentTime = millis ( ) ; // Current time actual time read
elapsedTime = ( currentTime - previousTime ) / 1000 ; // Divide by 1000 to get seconds
GyX = ( read_register ( GYRO_XOUT_H ) < < 8 | read_register ( GYRO_XOUT_L ) ) / 16.4 ; // For a 2000deg/s range we have to divide first the raw value by 16.4, according to the datasheet
GyY = ( read_register ( GYRO_YOUT_H ) < < 8 | read_register ( GYRO_YOUT_L ) ) / 16.4 ;
GyZ = ( read_register ( GYRO_ZOUT_H ) < < 8 | read_register ( GYRO_ZOUT_L ) ) / 16.4 ;
// Correct the outputs with the calculated error values
// GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
// GyroY = GyroY - 2; // GyroErrorY ~(2)
// GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
// Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
gyroAngleX = GyX * elapsedTime ; // deg/s * s = deg
gyroAngleY = GyY * elapsedTime ;
yaw = GyZ * elapsedTime ;
// Complementary filter - combine acceleromter and gyro angle values
roll = 0.96 * gyroAngleX + 0.04 * accAngleX ;
pitch = 0.96 * gyroAngleY + 0.04 * accAngleY ;
}
void GYRO : : read_all ( void ) {
AcX = read_register ( ACCEL_XOUT_H ) < < 8 | read_register ( ACCEL_XOUT_L ) ;
AcY = read_register ( ACCEL_YOUT_H ) < < 8 | read_register ( ACCEL_YOUT_L ) ;
@ -225,7 +262,6 @@ void GYRO::read_all(void) {
GyZ = read_register ( GYRO_ZOUT_H ) < < 8 | read_register ( GYRO_ZOUT_L ) ;
temperatureG = read_register ( TEMP_OUT_L ) ;
}
@ -315,7 +351,7 @@ void GYRO::calculate_angles(void) {
// Initialization
for ( axis = 0 ; axis < 3 ; axis + + ) {
// valid as long as LPF_FACTOR is less than 15
imu . accSmooth [ axis ] = LPFAcc [ axis ] > > ACC_LPF_FACTOR ;
imu . accSmooth [ axis ] = LPFAcc [ axis ] > > ACC_LPF_FACTOR ;
LPFAcc [ axis ] + = imu . accADC [ axis ] - imu . accSmooth [ axis ] ;
// used to calculate later the magnitude of acc vector