Hello,
I am trying to read ISM330DHCX accelerometer (Adafruit product) data using nRF522832 but I am getting zeros all the time regardless whether the sensor is moved or not. I am following the I2C protocol. I can read the sensor on Arduino. The sensor has pull up resistors for both SDA and SCL.
Here is the overlay file:
&i2c0 {
mysensor: mysensor@6A{
compatible = "i2c-device";
reg = < 0x6A >;
label = "MYSENSOR";
};
};#include <zephyr/types.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/sys/printk.h>
#include <zephyr/kernel.h>
#define ISM330DHCX_I2C_ADDR 0x6A
// Define the I2C device specification
static const struct i2c_dt_spec i2c_dev = I2C_DT_SPEC_GET(DT_NODELABEL(mysensor));
static int ism330dhcx_init(void)
{
uint8_t who_am_i;
uint8_t config1[] = {
0x10, // CTRL1_XL register address
0x60 // 104 Hz, ±4g, Normal mode
};
// Write to CTRL1_XL to configure accelerometer
int ret = i2c_write_dt(&i2c_dev, config1, sizeof(config1));
if (ret != 0) {
printk("Failed to configure ISM330DHCX CTRL1_XL (error: %d)\n", ret);
return -EIO;
}
// Read WHO_AM_I register (0x0F)
uint8_t reg_addr = 0x0F;
ret = i2c_write_dt(&i2c_dev, ®_addr, sizeof(reg_addr));
if (ret != 0) {
printk("Failed to set WHO_AM_I register address (error: %d)\n", ret);
return -EIO;
}
ret = i2c_read_dt(&i2c_dev, &who_am_i, sizeof(who_am_i));
if (ret != 0) {
printk("Failed to read WHO_AM_I register from I2C device address %x\n", i2c_dev.addr);
return -EIO;
}
printk("WHO_AM_I register value: 0x%02x\n", who_am_i);
if (who_am_i != 0x6B) {
printk("WHO_AM_I register mismatch: expected 0x6B, got 0x%02x\n", who_am_i);
return -EIO;
}
printk("ISM330DHCX initialized successfully\n");
return 0;
}
static int ism330dhcx_read(int16_t *ax, int16_t *ay, int16_t *az)
{
uint8_t buffer[6];
uint8_t status;
int ret;
// Check data ready status
uint8_t reg_addr = 0x1E;
ret = i2c_write_dt(&i2c_dev, ®_addr, sizeof(reg_addr));
if (ret != 0) {
printk("Failed to set STATUS_REG address (error: %d)\n", ret);
return -EIO;
}
ret = i2c_read_dt(&i2c_dev, &status, sizeof(status));
if (ret != 0) {
printk("Failed to read STATUS_REG from I2C device address %x\n", i2c_dev.addr);
return -EIO;
}
if (!(status & 0x01)) {
printk("No new accelerometer data available\n");
return -EIO;
}
// Read accelerometer data starting from register 0x28
reg_addr = 0x28 | 0x80; // 0x80 sets the auto-increment bit
ret = i2c_write_dt(&i2c_dev, ®_addr, sizeof(reg_addr));
if (ret != 0) {
printk("Failed to set accelerometer data start address (error: %d)\n", ret);
return -EIO;
}
ret = i2c_read_dt(&i2c_dev, buffer, sizeof(buffer));
if (ret != 0) {
printk("Failed to read accelerometer data from I2C device address %x\n", i2c_dev.addr);
return -EIO;
}
*ax = (int16_t)(buffer[0] | (buffer[1] << 8));
*ay = (int16_t)(buffer[2] | (buffer[3] << 8));
*az = (int16_t)(buffer[4] | (buffer[5] << 8));
printk("Raw data read: X=%d, Y=%d, Z=%d\n", *ax, *ay, *az);
return 0;
}
void main(void)
{
int err;
printk("Starting minimal ISM330DHCX example\n");
if (!device_is_ready(i2c_dev.bus)) {
printk("I2C device not found\n");
return;
}
err = ism330dhcx_init();
if (err) {
printk("Failed to initialize ISM330DHCX\n");
return;
}
int16_t raw_x, raw_y, raw_z;
while (1) {
err = ism330dhcx_read(&raw_x, &raw_y, &raw_z);
if (err == 0) {
printk("Accelerometer Data - X: %d, Y: %d, Z: %d\n", raw_x, raw_y, raw_z);
} else {
printk("Failed to read accelerometer data\n");
}
k_sleep(K_MSEC(500)); // Sleep for 500 milliseconds before reading again
}
}A screenshot of the VCode
