APM 2.5 onboard MPU6000 sensors data reading using

Hello, i’m currently trying to read sensors data from the onboard MPU6000 of the APM 2.5 using Arduino IDE. For that, i have tried many options:

1.use the ArduIMU V3 code which uses SPI to get the datas from the sensors. However, i get wrong values (-1 for all values). Can i use the ArduIMU code to read sensors values?? I’ve set the MPU6000_CHIP_SELECT_PIN to 8 as it corresponds to port PB0 i think ( from what i understood from reading amp 2.5 board schematic)?? is this correct?

Code here:

// MPU6000 SENSOR RAW DATA READING BASED ON ArduIMU V3 CODE
#include <SPI.h>
#include <Wire.h>

#define MPU6000_CHIP_SELECT_PIN 8  // MPU6000 CHIP SELECT

// MPU 6000 registers
#define MPUREG_WHOAMI 0x75 //
........

// global variables
volatile uint8_t MPU6000_newdata;

//Sensor variables
int accelX;
int accelY;
int accelZ;

int gyroX;
int gyroY;
int gyroZ;

byte MPU6000_ADDRESS;

// MPU6000 SPI functions
byte MPU6000_SPI_read(byte reg)
{
  byte dump;
  byte return_value;
  byte addr = reg | 0x80; // Set most significant bit
  digitalWrite(MPU6000_CHIP_SELECT_PIN, LOW);
  dump = SPI.transfer(addr);
  return_value = SPI.transfer(0);
  digitalWrite(MPU6000_CHIP_SELECT_PIN, HIGH);
  return(return_value);
}

void MPU6000_SPI_write(byte reg, byte data)
{
  byte dump;
  digitalWrite(MPU6000_CHIP_SELECT_PIN, LOW);
  dump = SPI.transfer(reg);
  dump = SPI.transfer(data);
  digitalWrite(MPU6000_CHIP_SELECT_PIN, HIGH);
}

// MPU6000 INTERRUPT ON INT0
void MPU6000_data_int()
{
  MPU6000_newdata++;
}

// MPU6000 Initialization and configuration
void MPU6000_Init(void)
{
    // MPU6000 chip select setup
    pinMode(MPU6000_CHIP_SELECT_PIN, OUTPUT);
    digitalWrite(MPU6000_CHIP_SELECT_PIN, HIGH);
    
    // SPI initialization
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV16);      // SPI at 1Mhz (on 16Mhz clock)
    delay(10);
    
    // Chip reset
    MPU6000_SPI_write(MPUREG_PWR_MGMT_1, BIT_H_RESET);
    delay(100);
    // Wake up device and select GyroZ clock (better performance)
    MPU6000_SPI_write(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
    delay(1);
    // Disable I2C bus (recommended on datasheet)
    MPU6000_SPI_write(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
    delay(1);
    // SAMPLE RATE
    //MPU6000_SPI_write(MPUREG_SMPLRT_DIV,0x04);     // Sample rate = 200Hz    Fsample= 1Khz/(4+1) = 200Hz     
    MPU6000_SPI_write(MPUREG_SMPLRT_DIV,19);     // Sample rate = 50Hz    Fsample= 1Khz/(19+1) = 50Hz     
    delay(1);
    // FS & DLPF   FS=2000º/s, DLPF = 20Hz (low pass filter)
    MPU6000_SPI_write(MPUREG_CONFIG, BITS_DLPF_CFG_20HZ);  
    delay(1);
    MPU6000_SPI_write(MPUREG_GYRO_CONFIG,BITS_FS_2000DPS);  // Gyro scale 2000º/s
    delay(1);
    MPU6000_SPI_write(MPUREG_ACCEL_CONFIG,0x08);            // Accel scale 4g (4096LSB/g)
    delay(1);   
    // INT CFG => Interrupt on Data Ready
    MPU6000_SPI_write(MPUREG_INT_ENABLE,BIT_RAW_RDY_EN);         // INT: Raw data ready
    delay(1);
    MPU6000_SPI_write(MPUREG_INT_PIN_CFG,BIT_INT_ANYRD_2CLEAR);  // INT: Clear on any read
    delay(1);
    // Oscillator set
    // MPU6000_SPI_write(MPUREG_PWR_MGMT_1,MPU_CLK_SEL_PLLGYROZ);
    delay(1);
  
    // MPU_INT is connected to INT 0. Enable interrupt on INT0
    attachInterrupt(0,MPU6000_data_int,RISING);
}

// Read gyros and accel sensors on MPU6000
void MPU6000_Read()
{
  int byte_H;
  int byte_L;
  
  // Read AccelX
    byte_H = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_ACCEL_XOUT_L);
    accelX = (byte_H<<8)| byte_L;
    // Read AccelY
    byte_H = MPU6000_SPI_read(MPUREG_ACCEL_YOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_ACCEL_YOUT_L);
    accelY = (byte_H<<8)| byte_L;
    // Read AccelZ
    byte_H = MPU6000_SPI_read(MPUREG_ACCEL_ZOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_ACCEL_ZOUT_L);
    accelZ = (byte_H<<8)| byte_L;
     
    // Read GyroX
    byte_H = MPU6000_SPI_read(MPUREG_GYRO_XOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_GYRO_XOUT_L);
    gyroX = (byte_H<<8)| byte_L;
    // Read GyroY
    byte_H = MPU6000_SPI_read(MPUREG_GYRO_YOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_GYRO_YOUT_L);
    gyroY = (byte_H<<8)| byte_L;
    // Read GyroZ
    byte_H = MPU6000_SPI_read(MPUREG_GYRO_ZOUT_H);
    byte_L = MPU6000_SPI_read(MPUREG_GYRO_ZOUT_L);
    gyroZ = (byte_H<<8)| byte_L;
    
    
}

void setup()
{ 
  Serial.begin(38400);
  
  MPU6000_Init();       // MPU6000 initialization
  
  //READ who_Am_I register --ACD
  MPU6000_ADDRESS = MPU6000_SPI_read(MPUREG_WHOAMI);
  Serial.print("----WHO_AM_I----:");
  Serial.println(MPU6000_ADDRESS,HEX);
  delay(250);
}

void loop() //Main Loop
{
    MPU6000_Read();    // Read MPU6000 sensor values
                
		Serial.print("gyro_X:");
		Serial.print(gyroX,DEC); 
		Serial.print("  gyroY:");
		Serial.print(gyroY,DEC);
		Serial.print("  gyroZ:");
		Serial.println(gyroZ,DEC);  
		Serial.print("accelX:");
		Serial.print(accelX,DEC);
		Serial.print("  accelY:");
		Serial.print(accelY,DEC);
		Serial.print("  accelZ:");
		Serial.println(accelZ,DEC);  

  delay(2500);
}// MPU6000 support for ArduIMU V3
  1. I’ve also attempted to use I2C comm to get raw datas, but i haven’t succeeded to get anything reliable. what should be the I2C address of the MPU6000? I used 0x69 since its is explained in the MPU60X0 product specification that data sheet for MPU6000, AD0 is VDD, so AD0 is high, then I2C address thus becomes 0x69 instead of 0x68. Do i have to put the pin connect AD0 high by setting to output high??
    For my I2C code i’ve mainly based on this tutorial on MPU6050 : playground.arduino.cc/Main/MPU-6050#.UwuUUihibWE

I’m new to this, i might have done flagrant mistakes, so please help. I’d appreciate it a lot, been working on this for days :frowning: :confused:

Hi lodiaz,

I think this is more a software or code question than hardware. Maybe you can take a look to the ardupilot code to see how is the sensor readings.

You can get the code from here:
github.com/diydrones/ardupilot

Understanding the code, arducopter code overview here:
dev.ardupilot.com/wiki/apmcopter-code-overview/