MPU 9250

I am testing two different methods to read raw acceleration data.

  1. a function reads individual register and the returned value gets saved in a buffer in main loop.
    #define MPU_REG_ACCEL_XOUT_H 0x3B
    #define MPU_REG_ACCEL_XOUT_L 0x3C
    #define MPU_REG_ACCEL_YOUT_H 0x3D
    #define MPU_REG_ACCEL_YOUT_L 0x3E
    #define MPU_REG_ACCEL_ZOUT_H 0x3F
    #define MPU_REG_ACCEL_ZOUT_L 0x40

void loop() {
buf[0] = mpu_read(MPU_REG_ACCEL_XOUT_H);
buf[1] = mpu_read(MPU_REG_ACCEL_XOUT_L);
buf[2] = mpu_read(MPU_REG_ACCEL_YOUT_H);
buf[3] = mpu_read(MPU_REG_ACCEL_YOUT_L);
buf[4] = mpu_read(MPU_REG_ACCEL_ZOUT_H);
buf[5] = mpu_read(MPU_REG_ACCEL_ZOUT_L);

accel_temp[0] = (buf[0]<<8|buf[1]);
accel_temp[1] = (buf[2]<<8|buf[3]);
accel_temp[2] = (buf[4]<<8|buf[5]);
}

char mpu_read(char addr)
{
digitalWrite(MPU_CS,LOW);
MPU_SPI.transfer(0x80|addr);
char ret = MPU_SPI.transfer(0X00);
digitalWrite(MPU_CS,HIGH);
return ret;
}

  1. a function reads all the accelerometer registers and save the values in a buffer. The function returns the buffer to the main function.
    void loop() {
    mpu_read_bytes(MPU_REG_ACCEL_XOUT_H, &buf[0], 6);

int16_t accel_temp[3];
accel_temp[0] = (buf[0]<<8|buf[1]);
accel_temp[1] = (buf[2]<<8|buf[3]);
accel_temp[2] = (buf[4]<<8|buf[5]);
}
void mpu_read_bytes(char addr, uint8_t *buf, unsigned n)
{
digitalWrite(MPU_CS, LOW);
for(int i = 0; i< n; i++)
{
char reg = addr+i;
MPU_SPI.transfer(0x80|reg);
char ret = MPU_SPI.transfer(0x00);
buf = ret;

  • }*
  • digitalWrite(MPU_CS, HIGH);*
  • }*
    I believe accel_temp[] values for both methods should be the same.
    However, they are not.
    accel_temp[0] are the same.
    accel_temp[1] of the first method is the same as accel_temp[2] of the second method.
    accel_temp[2] of the first method is the same as accel_temp[1] of the second method.
    Can you suggest why it happens and how to fix the problem?
    Thanks

accel_temp[1] of the first method is the same as accel_temp[2] of the second method.
accel_temp[2] of the first method is the same as accel_temp[1] of the second method.

I suspect it has to do with the SlaveSelect line not going high between register reads.

It is possible that the device will allow you to read multiple registers without sending an address for each one. I'd check the datasheet.

If it doesn't support multiple reads, change the code to pulse the SS pin HIGH between addresses.

Thanks johnwasser,

I moved the chipselect functions into the loop and it worked.