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);
I'm not sure if that will work the way you want it to. Try this instead:
Wire.write(0x78);
Wire.write(0x66);
If that doesn't work, flip the byte order and see if it fixes things.
Let us concentrate on the Pressure Sensor of the inertial device.
1. Pressure sensor has a separate 7-bit I2C Bus address: 0x63 (1100011).
2. Within the pressure sensor there is an embedded temperatures sensor; the data of this sensor comes along with the pressure sensor; ths temperature data is used in the correction of pressure data.
3. Pressure sensor becomes active along with inertial device when --
(1) HIGH is stored at bit-1 position of INT_PIN_CFG Register (address: 0x37) which is within the inertial device.
(2) LOW is stored at I2C_MST_EN bit of USER_CTRL (address: 0x6A) Register (Fig-1) which is within the inertial device. Unfortunately, this bit is not found in the register map. Anyway, we will take Bit-4 for it.
Figure-1:
4. The Sketch (not tested but compiled)
#include<Wire.h>
byte myData[9]; //to hold P and T data
byte busStatus = 0x00; //to detect data reday status
void setup()
{
Serial.begin(9600);
Wire.begin();
Wire.setClock(400000);
//----put HIGH at Bit-1 of register with addr: 0x37------------------
Wire.beginTransmission(0x68); //addressing inertial device to put HIGH at Bit-1 of REg. at 0x37
Wire.write(0x37); //poiting INT_PIN_CFG reg.
Wire.endTransmission();
Wire.requestFrom(0x68, 1);
byte x = Wire.read(); //readin content of INT_PIN_CFG regs
bitSet(x, 1);
Wire.beginTransmission(0x68); //addressing inertial device to put HIGH at Bit-1 of REg. at 0x37
Wire.write(0x37); //poiting INT_PIN_CFG reg.
Wire.write(x); //
Wire.endTransmission();
//------put LOW at Bit-4 of register with addr: 0x6A----------------
Wire.beginTransmission(0x68); //addressing inertial device to put LOW at I2C_MST_EN bit at reg. 0x6A
Wire.write(0x6A); //pointing USER_CRTL reg.
Wire.endTransmission();
Wire.requestFrom(0x68, 1);
x = Wire.read(); //reading content of USER_CRTL regs
bitClear(x, 4);
Wire.beginTransmission(0x68); //addressing inertial device
Wire.write(0x6A); //
Wire.write(x); //
Wire.endTransmission();
//--------------------------------------------------
}
void loop()
{
//---giving measurement commands for Normal measurement----------------------
Wire.beginTransmission(0x63); //addressing presure sensor
Wire.write(0x68); //high byte of temperature sensor
Wire.write(0x25); //low byte of T sensor
Wire.write(0x48); //high byte of P sensor
Wire.write(0xA3); //low byte of P sensor
Wire.endTransmission();
//-- wait until measurement is complete--------------------
do
{
Wire.beginTransmission(0x63);
busStatus = Wire.endTransmission();
}
while (busStatus != 0x00);
//---read P (MMSB, MLSB, CRC, LMSB, LLSB, CRC) and T (MSB, LSB, CRC) data from Pressur sensor
Wire.requestFrom(0x63, 9); //9-byte to read
//---read P data from FIFO Buffer
for(int i = 0; i<9; i++)
{
myData[i] = Wire.read();
}
//-- form RAW Pressure; disreagard CRC and discard LLSB 9as per data sheet)
long int rawPressure = (long)myData[0]<16 | myData[1]<<8 | myData[3];
Serial.print("Showing Raw Pressure: ");
Serial.println(rawPressure, HEX); //should show uncalibared pressur; consult data sheet for calibration
//---form rRAW Temperature; ---------------
int rawTemp = myData[6]<<8 | myData[7];
Serial.print("Showing Raw Temperature: ");
Serial.println(rawTemp, HEX); //should show uncalibrated tempe; consult data sheet for calibration
//------------------------------
delay(1000); //test interval
}