Problem with accelerometer value read via C API

Hello,

I’m currently working with module DWM1001 and I faced some problems with reading the accelerometer values via C code Api. To read from i2c I use the following code within the thread loop:

	rv = dwm_i2c_read(0x33 >> 1, i2cbyte, 2);
	if (rv == DWM_OK) {
		printf("Accelerometer: %u , %u\n", *i2cbyte , *(i2cbyte + 1));			
	} else {
		printf("i2c: read failed (%d)\n", rv);
	}

I have already figured out that I need to disable stationary detection to make it work.

The problem is I always read 0s unless I issue “av” command after which I start getting some values at address i2cbyte and i2cbyte + 1 but they seem to be random and independent of module’s orientation.

I have the following questions:

  1. Why do I need to use “av” shell comand to start reading some non 0 values from i2c and how to avoid it ?
  2. How to understand those two 8-bit integers as acceleration values ?

Thanks in advance,
Filip

Hi Filip,

  1. When stationary detection is disabled the Accelerometer is unconfigured after the reset. The sensor is inactive and you will need to configure it. The “av” command configures it so that explains your observation.

Please refer to the sensor documentation for more details:

This is an example:

write_reg8(LIS2DX_CTRL_REG1, 0);
write_reg8(LIS2DX_CTRL_REG5, LIS2DX_BOOT);
write_reg8(LIS2DX_CTRL_REG1, LIS2DX_ODR_50 | LIS2DX_ZEN | LIS2DX_YEN | LIS2DX_XEN);
write_reg8(LIS2DX_CTRL_REG2, 0);
write_reg8(LIS2DX_CTRL_REG3, LIS2DX_I1_ZYXDA);
write_reg8(LIS2DX_CTRL_REG4, LIS2DX_HR | LIS2DX_FS_2G);
write_reg8(LIS2DX_CTRL_REG6, 0);

  1. The raw values are 16-bit so you should read 2 bytes for each axis, e.g.

x = read_reg16(LIS2DX_OUT_X_L);
y = read_reg16(LIS2DX_OUT_Y_L);
z = read_reg16(LIS2DX_OUT_Z_L);

Cheers,
TDK

2 Likes

Thank You, that was very helpfull.

Cheers,
Filip

Dear Filip
Have you solved your problem? I am working on it in dwm-simple project but it seems that works unstably. With the pointer *i2cbyte I printf some random outputs when my tag unit stay still. I understand that i need to read 6 consecutive bytes for 3 axis but none of them keeps stable. Could you pls share your code snipset with me?

Here is the code now I am using

uint8_t data[6];
data[0] = 0; data[1] = 0; data[2] = 0; data[3] = 0; data[4] = 0; data[5] = 0;
const uint8_t addr = 0x33;
dwm_i2c_read(addr >> 1, data, 6);
printf(“Accelerometer: %u, %u, %u, %u, %u, %u\n”, data[0], data[1], data[2], data[3], data[4], data[5]);

BTW, I want to know how did you define i2cbyte?
I tried uint8_t to define i2cbyte but failed at compiling and SES shows that “invalid type argument of unary ‘*’ (have ‘int’)” at line

printf(“Accelerometer: %u , %u\n”, *i2cbyte , *(i2cbyte + 1));

I have tried also with

uint8_t* i2cbyte;

but the result is i2c read failed with rv = -1.

Dear leapslabs
Thanks your explanation! I understand that 16-bits digit represent one axis accleration raw data. I read the API guide and I know that dwm_i2c_read returns pointers to register (e.g i2cbyte in this post).

So for example, I have pointer i2cbyte which contains data 00111100 and i2cbyte+1 contains 10110000.I must connect them to a 16-bits data 0011110010110000 and then convert it to decimal 15536, which stands for X axis. Similarly, for Y(Z) axis I should use pointer i2cbyte+2 and i2cbyte+3 (i2cbyte+4 and i2cbyte+5 ) to obtain correct data.

Is my understanding correct?

Great thanks to you!