0

I am trying to interface with the ICM-20789 over I2C. DataSheet

I have been successfully able to get all three gyroscope readings and all three accelerometer readings. I am now trying to get the pressure readings from the device, since it has a built-in pressure sensor, but cannot seem to get it working.

In the datasheet, it says to enable Bypass Mode.

Bypass Mode: Set register INT_PIN_CFG (Address: 55 (Decimal); 37 (Hex)) bit 1 to value 1 and I2C_MST_EN bit is ‘0’ (Address: 106 (Decimal); 6A (Hex). Pressure sensor data can then be accessed using the procedure described in Section 10

In the setup I use this code:

  Wire.beginTransmission(gyro_address);                                  
  Wire.write(0x37);      //INT_PIN_CFG                                                    
  Wire.write(0x02);      //00000010                                                    
  Wire.endTransmission(); 

I am having trouble finding I2C_MST_EN in the datasheet as well, as I cannot find it in the 6A Address.

Once I have the bypass bit enabled, I try to request the pressure and temperature data from the sensor using this code:

Wire.beginTransmission(0x63);      
Wire.write(0x7866);     
Wire.endTransmission();
Wire.requestFrom(0x63, 16);

while (Wire.available() < 16);
pressure = Wire.read() << 16 | Wire.read() << 8 | Wire.read();
temp_2   = Wire.read() << 16 | Wire.read() << 8 | Wire.read();

Unfortunately, the device freezes when I try to run this code. I know I am obviously doing something wrong here, just don't know exactly what yet.

  • Wire.write(0x7866); will truncate your value to just 0x66. You can only write 8 bits at a time. – Majenko Sep 29 '19 at 22:37
1

There are four things wrong with your code.

  1. You are not sending the "start measurement" command properly. The Wire.write() function can only send 8 bits, but you are passing it a 16-bit value. Instead you should break it apart into 2 separate 8-bit values:

    Wire.beginTransmission(0x63);
    Wire.write(0x78);
    Wire.write(0x66);
    Wire.endTransmission();

  2. The data returned is spread over 9 bytes, not 16. According to the datasheet:

Temperature data is transmitted in two 8-bit words and pressure data is transmitted in four 8-bit words.

and:

Two bytes of data are always followed by one byte CRC checksum

That's 2 + 4 = 6 + (6/2) = 9

  1. You aren't waiting for the conversion to complete. According to the datasheet, in "ultra low noise" mode (0x7866) it takes up to 94.5ms to perform the measurement. So you should add a delay of slightly more than that to allow it to do what it needs to do.

  2. The command you are sending responds with temperature first, not pressure, but you are reading pressure first (and reading the wrong bytes anyway).

In all, your code should look more like:

Wire.beginTransmission(0x63);      
Wire.write(0x78);     
Wire.write(0x66);     
Wire.endTransmission();

delay(100);

Wire.requestFrom(0x63, 9);
uint8_t tmsb = Wire.read(); // Temperature highest byte
uint8_t tlsb = Wire.read(); // Temperature lowest byte
Wire.read();

uint8_t pmmsb = Wire.read(); // Highest pressure byte
uint8_t pmlsb = Wire.read(); // Next highest pressure byte
Wire.read(); // Discard checksum
uint8_t plmsb = Wire.read(); // Next lowest pressure byte
uint8_t pllsb = Wire.read(); // Lowest pressure byte
Wire.read(); // Discard checksum

pressure = (pmmsb << 24) | (pmlsb << 16) | (plmsb << 8) | pllsb;
temp_2   = (tmsb << 8) | (plsb << 8);
| improve this answer | |
  • Thank you Majenko! That makes more sense. I have added that code to my loop. My code is still freezing though. It happens when I add this code in the setup to enter bypass mode: Wire.beginTransmission(0x63); Wire.write(0x78); Wire.write(0x66); Wire.endTransmission(); – M.Schindler Sep 29 '19 at 23:36
  • That's not the code to enter bypass mode - that's the code to start a pressure conversion. – Majenko Sep 29 '19 at 23:43
  • My apologies, I copied over the wrong code. When I have these lines of code on my setup, the code freezes. Wire.beginTransmission(gyro_address); Wire.write(0x37); //INT_PIN_CFG Wire.write(0x02); //00000010 Wire.endTransmission(); – M.Schindler Sep 29 '19 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.