I am currently trying to get an Adafruit ISM330DHCX working using the I2C bus using an Arduino Nano Every. However, when I plug in the wires using the QT wires alongside the Adafruit example code, it simply does not detect the sensor. I already ran an I2C address checker, and it found no addresses on 0x6A or 0x6B, which are the addresses for the ISM330DHCX. Instead, it found addresses on 0x02 and 0x03.
I suspect the issue might be that I am not using pull up resistors, although I am almost entirely new to pull up resistors and am unsure if they would actually make much of a difference.
No pullup resistors for SDA and SCL are shown in the official schematic for the Nano Every. They are absolutely required. Try adding 4.7K from each line to 5V.
Instead, [I2C Scanner] found addresses on 0x02 and 0x03.
Tried it and it worked, thank you so much.
I began coding the ISM330DHCX using the Adafruit driver, however, I found that the gyro readings are the rate of change of the angles, not the angles themselves. I attempted to integrate the angle rate values but got mixed results. Is there a better way to do this? My code is below.
#include <Adafruit_ISM330DHCX.h>
Adafruit_ISM330DHCX ism330dhcx;
double gyroY = 0.0; //angle of y axis of gyro, in radians
double gyroYvel = 0.0; //rate of change of angle of y axis of gyro, in radians/sec
double gyroZ = 0.0; //angle of z axis of gyro, in radians
double gyroZvel = 0.0; //rate of change of angle of z axis of gyro, in radians/sec
double time = 0.0;
double prevTime = 0.0;
double deltaTime = 0.0; // time and prevTime are in milliseconds, but deltaTime (change in time) is converted to seconds
void setup() {
Serial.begin(460800);
if (!ism330dhcx.begin_I2C()) {
// if (!ism330dhcx.begin_SPI(LSM_CS)) {
// if (!ism330dhcx.begin_SPI(LSM_CS, LSM_SCK, LSM_MISO, LSM_MOSI)) {
Serial.println("Failed to find ISM330DHCX chip");
while (1) {
delay(10);
}
}
ism330dhcx.setAccelRange(LSM6DS_ACCEL_RANGE_16_G);
ism330dhcx.setGyroRange(ISM330DHCX_GYRO_RANGE_4000_DPS);
ism330dhcx.setAccelDataRate(LSM6DS_RATE_416_HZ);
ism330dhcx.setGyroDataRate(LSM6DS_RATE_416_HZ);
ism330dhcx.configInt1(false, false, true); // accelerometer DRDY on INT1
ism330dhcx.configInt2(false, true, false); // gyro DRDY on INT2
}
void loop() {
time = millis();
if ((time - prevTime) > 50) { //Generally use this instead of delay() as this is more accurate
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
ism330dhcx.getEvent(&accel, &gyro, &temp);
deltaTime = (time - prevTime)/1000.0;
gyroYvel = gyro.gyro.y;
gyroZvel = gyro.gyro.z;
Serial.print(millis());
Serial.print(" ");
Serial.print(deltaTime);
Serial.println(" ");
Serial.print(gyroYvel);
Serial.print(" ");
Serial.print(gyroZvel);
//only do integration for each axis if the change in angle is large enough, avoids drift
if(gyroYvel < -0.01 || gyroYvel > 0.01) {
gyroY = gyroY + (gyroYvel * deltaTime);
}
if(gyroZvel < -0.01 || gyroZvel > 0.01) {
gyroZ = gyroZ + (gyroZvel * deltaTime);
}
Serial.print(" ");
Serial.print(gyroY*180.0/3.14159); //printed in degrees
Serial.print(" ");
Serial.println(gyroZ*180.0/3.14159);
prevTime = time;
}
}
For rate integration to work at all requires that you subtract the gyro offsets, which you can determine by averaging a few hundred readings at startup with the sensor held still. Since the offsets are temperature dependent, drift is inevitable.
Most people use the quaternion approach to determine 3D orientations from IMUs, as it is not easy to extract useful Earth-frame orientation angles from direct integration. Here are some examples for the ISM330DHCX, one of which includes gyro-only integration.