コード例 #1
0
static void sensorsSetupSlaveRead(void)
{
  // Now begin to set up the slaves
#ifdef SENSORS_MPU6500_DLPF_256HZ
  // As noted in registersheet 4.4: "Data should be sampled at or above sample rate;
  // SMPLRT_DIV is only used for 1kHz internal sampling." Slowest update rate is then 500Hz.
  mpu6500SetSlave4MasterDelay(15); // read slaves at 500Hz = (8000Hz / (1 + 15))
#else
  mpu6500SetSlave4MasterDelay(9); // read slaves at 100Hz = (500Hz / (1 + 4))
#endif

  mpu6500SetI2CBypassEnabled(false);
  mpu6500SetWaitForExternalSensorEnabled(true); // 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
  mpu6500SetSlaveReadWriteTransitionEnabled(false); // Send a stop at the end of a slave read
  mpu6500SetMasterClockSpeed(13); // Set i2c speed to 400kHz

#ifdef SENSORS_ENABLE_MAG_AK8963
  if (isMagnetometerPresent)
  {
    // Set registers for MPU6500 master to read from
    mpu6500SetSlaveAddress(0, 0x80 | AK8963_ADDRESS_00); // set the magnetometer to Slave 0, enable read
    mpu6500SetSlaveRegister(0, AK8963_RA_ST1); // read the magnetometer heading register
    mpu6500SetSlaveDataLength(0, SENSORS_MAG_BUFF_LEN); // read 8 bytes (ST1, x, y, z heading, ST2 (overflow check))
    mpu6500SetSlaveDelayEnabled(0, true);
    mpu6500SetSlaveEnabled(0, true);
  }
#endif

#ifdef SENSORS_ENABLE_PRESSURE_LPS25H
  if (isBarometerPresent)
  {
    // Configure the LPS25H as a slave and enable read
    // Setting up two reads works for LPS25H fifo avg filter as well as the
    // auto inc wraps back to LPS25H_PRESS_OUT_L after LPS25H_PRESS_OUT_H is read.
    mpu6500SetSlaveAddress(1, 0x80 | LPS25H_I2C_ADDR);
    mpu6500SetSlaveRegister(1, LPS25H_STATUS_REG | LPS25H_ADDR_AUTO_INC);
    mpu6500SetSlaveDataLength(1, SENSORS_BARO_BUFF_S_P_LEN);
    mpu6500SetSlaveDelayEnabled(1, true);
    mpu6500SetSlaveEnabled(1, true);

    mpu6500SetSlaveAddress(2, 0x80 | LPS25H_I2C_ADDR);
    mpu6500SetSlaveRegister(2, LPS25H_TEMP_OUT_L | LPS25H_ADDR_AUTO_INC);
    mpu6500SetSlaveDataLength(2, SENSORS_BARO_BUFF_T_LEN);
    mpu6500SetSlaveDelayEnabled(2, true);
    mpu6500SetSlaveEnabled(2, true);
  }
#endif

  // Enable sensors after configuration
  mpu6500SetI2CMasterModeEnabled(true);

  mpu6500SetIntDataReadyEnabled(true);
}
コード例 #2
0
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);
}