SparkFun Forums 

Where electronics enthusiasts find answers.

Have questions about a SparkFun product or board? This is the place to be.
By Nainara
#192757
I'm writing a bit of driver code in java using pi4j to poll the LSM9DS1 orientation data for use with my raspberry pi 3. As far as I'm aware, there is no existing open source code base to perform this task on the LSM9DS1 in Java. This is pretty far afield from my area, and a lot of the terminology and acronyms in the device datasheet are greek to me, so I apologize if this is a silly question.

According to the datasheet section 7.31-7.33, the accelerometer registers are arranged in pairs representing two's complement 16-bit values for the X, Y, Z axes. According to section 2.1, the accelerometer unit is measured in g's. When reading the accelerometer registers (on a flat surface), one would expect to get approximately: x=0, y=0, z=1

Instead my outputs are are as follows:
Acc (x): -119
Acc (y): -1433
Acc (z): 15862

If I hold the device sideways, then the registers read out:
Acc (x): 15121
Acc (y): 695
Acc (z): 4174

It seems as though the device is working correctly but I'm misunderstanding something about the byte conversion to two's complement?
Here's a sample of the actual binary outputs from the registers from a different polling:
Acc z High (OUT_Z_H_XL): 00111110
Acc z Low (OUT_Z_L_XL): 00010000

Assembled, they are: 0011111000010000 => 15,888 in decimal

Can anybody offer insight on what the problem might be?
By Nainara
#192937
In case anyone stumbles on this thread in the future looking for an answer to the same problem, here's what I've found.
I believe that the LSM9DS1 is converting the analog signal from the accelerometer on a linear scale distributed between the min and max values of the signed 16-bit word, e.g. -32767 and +32767. The formula to resolve the 16-bit word to a meaningful float in gs is as follows: (value / 32767 ) * scale. In the above post, I was using the default scale (plus or minus 2g), so the polling evaluates to (15,888 / 32767) * 2 = 0.97g, which is pretty reasonable considering that the breakout board wasn't precisely level at the time of the polling. I've tested this on all four available scales via CTRL_REG6_XL, and it appears to be producing consistent results.

Java code:
byteArr[0] = hb;
byteArr[1] = lb;
bb = ByteBuffer.wrap(byteArr);
return ((float) bb.getShort() / Short.MAX_VALUE) * scale;
By Nainara
#193212
In the event that it's useful to others, I've placed my Pi4j java driver out on github. It's far from feature-complete and probably never will be, considering how many esoteric features that the LSM9DS1 has, but it should cover most basic scenarios that involve efficiently reading sensor data via a reasonable java API.