MPU-9250 accel sensitivity register issue

Hello

I’m having an issue when trying to set the 0x1C accel. register sensitivity.

2g works fine with 0x00
When I set 4g with 0x01 i still get 2g raw values
8g works fine with 0x10
When I set 16g with 0x11 i still get 8g raw values

Do you think my sensor is bad or am I missing something?
Seems to me its ignoring the 3rd bit.

Here is my code with 16g config:

#include <Wire.h>

long X, Y, Z;
float gX, gY, gZ;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  setupsensor();
}

void loop() {
  recordG();
  printData();
  delay(100);
}

void setupsensor() {
  Wire.beginTransmission(0b1101001); // AD0 High
  Wire.write(0x6B); // power management
  Wire.write(0b00000000); //Setting sleep to 0
  Wire.endTransmission();
  Wire.beginTransmission(0b1101001); // AD0 High
  Wire.write(0x1C); // sensitivity configuration
  Wire.write(0x11); // 0x00 2g at 16384LSB/g, 0x01 4g at 8192LSB/g, 0x10 8g at 4,096LSB/g, 0x11 16g at 2048LSB/g
  Wire.endTransmission();
}

void recordG() {
  Wire.beginTransmission(0b1101001); // AD0 High
  Wire.write(0x3B); // Accel Read
  Wire.endTransmission();
  Wire.requestFrom(0b1101001,6);  //request Accel registers (3B - 40)
  while(Wire.available() < 6);
  X = Wire.read()<<8|Wire.read();
  Y = Wire.read()<<8|Wire.read();
  Z = Wire.read()<<8|Wire.read();
  CalcG(); 
}

void CalcG() {
  gX = X / 2048.0;
  gY = Y / 2048.0;
  gZ = Z / 2048.0;
}

void printData() {
  Serial.print ("X=");
  Serial.print (X);
  Serial.print (" Y=");
  Serial.print (Y);
  Serial.print (" Z=");
  Serial.println (Z);
  Serial.print ("gX=");
  Serial.print (gX);
  Serial.print (" gY=");
  Serial.print (gY);
  Serial.print (" gZ=");
  Serial.println (gZ);
}

And this is what I get:

16:14:40.278 -> X=497 Y=398 Z=3317
16:14:40.312 -> gX=0.24 gY=0.19 gZ=1.62

When you read and print out the register, after modifying the register, what value do you get vs value expected?

Here is the code I use to change the accel register:

int myMPU9250::setAccelRange( int range )
{
  SPI_Err = 0;
  if ( ACCEL_RANGE_2G == range )
  {
    // setting the accel range to 2G
    SPI_Err = _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_2G );
    vTaskDelay(1);
    _accelScaleFactor = (G * 2.0f) / AtoDscaleFactor; // setting the accel scale to 2G
    return SPI_Err;
  }
  if ( ACCEL_RANGE_4G == range )
  {
    // setting the accel range to 4G
    SPI_Err = _spi.fWriteSPIdata8bits(ACCEL_CONFIG, ACCEL_FS_SEL_4G);
    vTaskDelay(1);
    _accelScaleFactor = (G * 4.0f) / AtoDscaleFactor; // setting the accel scale to 4G
    return SPI_Err;
  }
  if ( ACCEL_RANGE_8G == range )
  {
    // setting the accel range to 8G
    SPI_Err = _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_8G );
    vTaskDelay(1);
    _accelScaleFactor = (G * 8.0f) / AtoDscaleFactor; // setting the accel scale to 8G
    return SPI_Err;
  }
  if ( ACCEL_RANGE_16G == range )
  {
    // setting the accel range to 16G
    SPI_Err = _spi.fWriteSPIdata8bits( ACCEL_CONFIG, ACCEL_FS_SEL_16G );
    vTaskDelay(1);
    _accelScaleFactor = (G * 16.0f) / AtoDscaleFactor; // setting the accel scale to 16G
    return SPI_Err;
  }
} //int myMPU9250::setAccelRange( int range )

Works fine for each setting.

Are you adjusting the scale factor with each setting change?

I have found that, for some unknown reason, when reading a group of registers of the MPU9250 that the first 16bits will, from time to time, not read out correctly. A, 100%, solution has been to read the register previous to the ones I want and, during data processing, ignore the first 16 bits.

int myMPU9250::getAdata()
{
  SPI_Err = 0;
  SPI_Err = _spi.fReadSPI( 8 , 0X3A | SPI_READ );
  if (  SPI_Err == 0 )
  {
    x_Araw.x = 0.0;
    x_Araw.y = 0.0;
    x_Araw.z = 0.0;
    // transform
    x_Araw.y = ((float)(int16_t)(((int16_t)_spi.get_rxData8bit(2) << 8) | _spi.get_rxData8bit(3)));
    x_Araw.x = ((float)(int16_t)(((int16_t)_spi.get_rxData8bit(4) << 8) | _spi.get_rxData8bit(5)));
    x_Araw.z = ((float)(int16_t)(((int16_t)_spi.get_rxData8bit(6) << 8) | _spi.get_rxData8bit(7)));
    x_Araw.z *= -1;
    // scale and bias
    x_Ascaled.x = ( (x_Araw.x * _accelScaleFactor) - x_Abias.x ) * x_ASF.x;
    x_Ascaled.y = ( (x_Araw.y * _accelScaleFactor) - x_Abias.y ) * x_ASF.y;
    x_Ascaled.z = ( (x_Araw.z * _accelScaleFactor) - x_Abias.z ) * x_ASF.z;
  }
  // reads one address previous to the accelerometer data
  // found that from time to time only positive values returned if
  // desired register was read directly
  return SPI_Err;
}

Hi Idahowalker

Thank you, You pointed me to the right direction, after reading the register I found that the values were not what they were supposed to be.

I found the error in my config, I was setting incorrect hex value.
Here are correct values

Binary:

2g = 0b00000000
4g = 0b00001000
8g = 0b00010000
16g = 0b00011000

Hex:

2g = 0x00
4g = 0x8
8g = 0x10
16g = 0x18

And here is the correct config for 16g sensitivity:

void setupsensor() {
  Wire.beginTransmission(0b1101001); // AD0 High
  Wire.write(0x6B); // power management
  Wire.write(0b00000000); //Setting sleep to 0
  Wire.endTransmission();
  Wire.beginTransmission(0b1101001); // AD0 High
  Wire.write(0x1C); // sensitivity configuration
  Wire.write(0b00011000); // 0x00 2g at 16384LSB/g, 0x8 4g at 8192LSB/g, 0x10 8g at 4,096LSB/g, 0x18 16g at 2048LSB/g
  Wire.endTransmission();
}

Anyways Thanks for the config, I haven't run into your issue but I'll look out for it..