void imu6Init(void) { if(isInit) return; isMagPresent = false; isBaroPresent = false; // Wait for sensors to startup while (xTaskGetTickCount() < M2T(IMU_STARTUP_TIME_MS)); i2cdevInit(I2C3_DEV); mpu6500Init(I2C3_DEV); if (mpu6500TestConnection() == true) { DEBUG_PRINT("MPU9250 I2C connection [OK].\n"); } else { DEBUG_PRINT("MPU9250 I2C connection [FAIL].\n"); } mpu6500Reset(); vTaskDelay(M2T(50)); // Activate MPU6500 mpu6500SetSleepEnabled(false); // Enable temp sensor mpu6500SetTempSensorEnabled(true); // Disable interrupts mpu6500SetIntEnabled(false); // Connect the HMC5883L to the main I2C bus mpu6500SetI2CBypassEnabled(true); // Set x-axis gyro as clock source mpu6500SetClockSource(MPU6500_CLOCK_PLL_XGYRO); // Set gyro full scale range mpu6500SetFullScaleGyroRange(IMU_GYRO_FS_CFG); // Set accelerometer full scale range mpu6500SetFullScaleAccelRange(IMU_ACCEL_FS_CFG); #ifdef IMU_MPU6500_DLPF_256HZ // 256Hz digital low-pass filter only works with little vibrations // Set output rate (15): 8000 / (1 + 15) = 500Hz mpu6500SetRate(15); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_256); #else // To low DLPF bandwidth might cause instability and decrease agility // but it works well for handling vibrations and unbalanced propellers // Set output rate (1): 1000 / (1 + 1) = 500Hz mpu6500SetRate(1); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_98); #endif #ifdef IMU_ENABLE_MAG_AK8963 ak8963Init(I2C3_DEV); if (ak8963TestConnection() == true) { isMagPresent = true; ak8963SetMode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz DEBUG_PRINT("AK8963 I2C connection [OK].\n"); } else { DEBUG_PRINT("AK8963 I2C connection [FAIL].\n"); } #endif #ifdef IMU_ENABLE_PRESSURE_LPS25H lps25hInit(I2C3_DEV); if (lps25hTestConnection() == true) { lps25hSetEnabled(true); isBaroPresent = true; DEBUG_PRINT("LPS25H I2C connection [OK].\n"); } else { //TODO: Should sensor test fail hard if no connection DEBUG_PRINT("LPS25H I2C connection [FAIL].\n"); } #endif imuBiasInit(&gyroBias); #ifdef IMU_TAKE_ACCEL_BIAS imuBiasInit(&accelBias); #endif varianceSampleTime = -GYRO_MIN_BIAS_TIMEOUT_MS + 1; imuAccLpfAttFactor = IMU_ACC_IIR_LPF_ATT_FACTOR; cosPitch = cosf(configblockGetCalibPitch() * (float) M_PI/180); sinPitch = sinf(configblockGetCalibPitch() * (float) M_PI/180); cosRoll = cosf(configblockGetCalibRoll() * (float) M_PI/180); sinRoll = sinf(configblockGetCalibRoll() * (float) M_PI/180); isInit = true; }
static void sensorsDeviceInit(void) { isMagnetometerPresent = false; isBarometerPresent = false; // Wait for sensors to startup while (xTaskGetTickCount() < 1000); i2cdevInit(I2C3_DEV); mpu6500Init(I2C3_DEV); if (mpu6500TestConnection() == true) { DEBUG_PRINT("MPU9250 I2C connection [OK].\n"); } else { DEBUG_PRINT("MPU9250 I2C connection [FAIL].\n"); } mpu6500Reset(); vTaskDelay(M2T(50)); // Activate MPU6500 mpu6500SetSleepEnabled(false); // Enable temp sensor mpu6500SetTempSensorEnabled(true); // Disable interrupts mpu6500SetIntEnabled(false); // Connect the HMC5883L to the main I2C bus mpu6500SetI2CBypassEnabled(true); // Set x-axis gyro as clock source mpu6500SetClockSource(MPU6500_CLOCK_PLL_XGYRO); // Set gyro full scale range mpu6500SetFullScaleGyroRange(IMU_GYRO_FS_CFG); // Set accelerometer full scale range mpu6500SetFullScaleAccelRange(IMU_ACCEL_FS_CFG); #ifdef IMU_MPU6500_DLPF_256HZ // 256Hz digital low-pass filter only works with little vibrations // Set output rate (15): 8000 / (1 + 15) = 500Hz mpu6500SetRate(15); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_256); #else // To low DLPF bandwidth might cause instability and decrease agility // but it works well for handling vibrations and unbalanced propellers // Set output rate (1): 1000 / (1 + 1) = 500Hz mpu6500SetRate(1); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_98); #endif // delay 3 seconds until the quad has stabilized enough to pass the test bool mpu6500SelfTestPassed = false; for (int i=0; i<300; i++) { if(mpu6500SelfTest() == true) { mpu6500SelfTestPassed = true; break; } else { vTaskDelay(M2T(10)); } } configASSERT(mpu6500SelfTestPassed); // Now begin to set up the slaves mpu6500SetSlave4MasterDelay(4); // read slaves at 100Hz = (500Hz / (1 + 4)) #ifdef IMU_ENABLE_MAG_AK8963 ak8963Init(I2C3_DEV); if (ak8963TestConnection() == true) { isMagnetometerPresent = true; ak8963SetMode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz configASSERT(ak8963SelfTest()); DEBUG_PRINT("AK8963 I2C connection [OK].\n"); mpu6500SetSlaveAddress(0, 0x80 | AK8963_ADDRESS_00); // set the magnetometer to Slave 0, enable read mpu6500SetSlaveRegister(0, AK8963_RA_HXL); // read the magnetometer heading register mpu6500SetSlaveDataLength(0, 6); // read 6 bytes (x, y, z heading) mpu6500SetSlaveDelayEnabled(0, true); mpu6500SetSlaveEnabled(0, true); } else { DEBUG_PRINT("AK8963 I2C connection [FAIL].\n"); } #endif #ifdef IMU_ENABLE_PRESSURE_LPS25H lps25hInit(I2C3_DEV); if (lps25hTestConnection() == true) { lps25hSetEnabled(true); isBarometerPresent = true; configASSERT(lps25hSelfTest()); DEBUG_PRINT("LPS25H I2C connection [OK].\n"); mpu6500SetSlaveAddress(1, 0x80 | LPS25H_I2C_ADDR); // set the barometer to Slave 1, enable read mpu6500SetSlaveRegister(1, LPS25H_PRESS_OUT_XL | LPS25H_ADDR_AUTO_INC); mpu6500SetSlaveDataLength(1, 5); mpu6500SetSlaveDelayEnabled(1, true); mpu6500SetSlaveEnabled(1, true); } else { //TODO: Should sensor test fail hard if no connection DEBUG_PRINT("LPS25H I2C connection [FAIL].\n"); } #endif mpu6500SetI2CBypassEnabled(false); mpu6500SetI2CMasterModeEnabled(true); mpu6500SetWaitForExternalSensorEnabled(false); // the slave data isn't so important for the state estimation mpu6500SetInterruptMode(0); // active high mpu6500SetInterruptDrive(0); // push pull mpu6500SetInterruptLatch(0); // latched until clear mpu6500SetInterruptLatchClear(1); // cleared on any register read mpu6500SetIntDataReadyEnabled(true); }
static void sensorsDeviceInit(void) { isMagnetometerPresent = false; isBarometerPresent = false; // Wait for sensors to startup while (xTaskGetTickCount() < 1000); i2cdevInit(I2C3_DEV); mpu6500Init(I2C3_DEV); if (mpu6500TestConnection() == true) { DEBUG_PRINT("MPU9250 I2C connection [OK].\n"); } else { DEBUG_PRINT("MPU9250 I2C connection [FAIL].\n"); } mpu6500Reset(); vTaskDelay(M2T(50)); // Activate MPU6500 mpu6500SetSleepEnabled(false); // Delay until registers are reset vTaskDelay(M2T(100)); // Set x-axis gyro as clock source mpu6500SetClockSource(MPU6500_CLOCK_PLL_XGYRO); // Delay until clock is set and stable vTaskDelay(M2T(200)); // Enable temp sensor mpu6500SetTempSensorEnabled(true); // Disable interrupts mpu6500SetIntEnabled(false); // Connect the MAG and BARO to the main I2C bus mpu6500SetI2CBypassEnabled(true); // Set gyro full scale range mpu6500SetFullScaleGyroRange(SENSORS_GYRO_FS_CFG); // Set accelerometer full scale range mpu6500SetFullScaleAccelRange(SENSORS_ACCEL_FS_CFG); // Set accelerometer digital low-pass bandwidth mpu6500SetAccelDLPF(MPU6500_ACCEL_DLPF_BW_41); #if SENSORS_MPU6500_DLPF_256HZ // 256Hz digital low-pass filter only works with little vibrations // Set output rate (15): 8000 / (1 + 7) = 1000Hz mpu6500SetRate(7); // Set digital low-pass bandwidth mpu6500SetDLPFMode(MPU6500_DLPF_BW_256); #else // To low DLPF bandwidth might cause instability and decrease agility // but it works well for handling vibrations and unbalanced propellers // Set output rate (1): 1000 / (1 + 0) = 1000Hz mpu6500SetRate(0); // Set digital low-pass bandwidth for gyro mpu6500SetDLPFMode(MPU6500_DLPF_BW_98); // Init second order filer for accelerometer for (uint8_t i = 0; i < 3; i++) { lpf2pInit(&gyroLpf[i], 1000, GYRO_LPF_CUTOFF_FREQ); lpf2pInit(&accLpf[i], 1000, ACCEL_LPF_CUTOFF_FREQ); } #endif #ifdef SENSORS_ENABLE_MAG_AK8963 ak8963Init(I2C3_DEV); if (ak8963TestConnection() == true) { isMagnetometerPresent = true; ak8963SetMode(AK8963_MODE_16BIT | AK8963_MODE_CONT2); // 16bit 100Hz DEBUG_PRINT("AK8963 I2C connection [OK].\n"); } else { DEBUG_PRINT("AK8963 I2C connection [FAIL].\n"); } #endif #ifdef SENSORS_ENABLE_PRESSURE_LPS25H lps25hInit(I2C3_DEV); if (lps25hTestConnection() == true) { lps25hSetEnabled(true); isBarometerPresent = true; DEBUG_PRINT("LPS25H I2C connection [OK].\n"); } else { //TODO: Should sensor test fail hard if no connection DEBUG_PRINT("LPS25H I2C connection [FAIL].\n"); } #endif cosPitch = cosf(configblockGetCalibPitch() * (float) M_PI/180); sinPitch = sinf(configblockGetCalibPitch() * (float) M_PI/180); cosRoll = cosf(configblockGetCalibRoll() * (float) M_PI/180); sinRoll = sinf(configblockGetCalibRoll() * (float) M_PI/180); }