Unsure in converting raw gyro data to deg/s ( ITG-3200 )
noellim
Posts: 10
Hi All,
I am using the sparkfun 9 DOF sensor stick(https://www.sparkfun.com/products/10724). I have written a basic i2c code to extract raw data from the gyros of the sensor stick. I went on to read the data sheet(https://www.sparkfun.com/datasheets/Sensors/Gyro/PS-ITG-3200-00-01.4.pdf) which tells me to divide the the raw data with gyro sensitivity which is 14.375 to get the result in degrees per second(LSB/s). I do not know if this is correct? I am getting values close to x=0,y=2,z=-1 when the sensor is stationary.
I am using the sparkfun 9 DOF sensor stick(https://www.sparkfun.com/products/10724). I have written a basic i2c code to extract raw data from the gyros of the sensor stick. I went on to read the data sheet(https://www.sparkfun.com/datasheets/Sensors/Gyro/PS-ITG-3200-00-01.4.pdf) which tells me to divide the the raw data with gyro sensitivity which is 14.375 to get the result in degrees per second(LSB/s). I do not know if this is correct? I am getting values close to x=0,y=2,z=-1 when the sensor is stationary.
#include "simpletools.h" // Include simple tools const char SCL = 3; //i2c pins const char SDA = 4; const char gyrosAddr = 0x68; int datReg_gyr = 0x1D; float GYRO_SENSITIVITY=14.375; //from data sheet i2c *ADCSbus; void Gyro_setup() { unsigned char Read_back[]={0}; unsigned char DLPF = 0x16; //Register 22- DLPF,FullScale i2c_in(ADCSbus,gyrosAddr,0x00,1,Read_back,1); //Test Device ID print("Gyros ID is : %x \n",Read_back[0]); Read_back[0]=0x19; i2c_out(ADCSbus,gyrosAddr,DLPF,1,&Read_back[0],1); //0x19 is written to set FS_SEL to proper operation // DLPF_CFG to a random mode(1 in this case-I dono about this) i2c_in(ADCSbus,gyrosAddr,DLPF,1,Read_back,1); print("Read from DLPF is : %x \n",Read_back[0]); } int main() { int16_t gx16, gy16, gz16; int8_t data_gyr[6]; ADCSbus = i2c_newbus(SCL, SDA, 0); Gyro_setup(); while(1) { memset(data_gyr, 0, 6); i2c_in(ADCSbus,gyrosAddr,datReg_gyr,1,data_gyr,6); gx16 = (data_gyr[0] << 8) | data_gyr[1]; gy16 = (data_gyr[2] << 8) | data_gyr[3]; gz16 = (data_gyr[4] << 8) | data_gyr[5]; float gfx16 = gx16/GYRO_SENSITIVITY; float gfy16 = gy16/GYRO_SENSITIVITY; float gfz16 = gz16/GYRO_SENSITIVITY; print("%c%d,%d,%d,%d%c\n",HOME,gfx16,gfy16,gfz16,timer,CLREOL); //gyr only }
Comments
My values when the sensor is stationary are as follows:
afx16=0,afy16=0,afz16=-22
The way to tell for sure if it's correct would be to put the gyro on a turntable or a servo where you have control of the rate of spin. Or you you could try integrating the numbers - IE, add up all the readings, but scaled by the amount of elapsed time (in seconds) between readings. Then you could rotate the board and see if the summation value tracks well. For example, if you rotate the board 90 degrees around the Z axis, the summed Z value should be very close to 90.
Your accelerometer readings don't look right. An accelerometer at rest should read very close to 1.0 G in the Z axis, zero in X and Y (assuming it's upright and level). Before scaling, the values should be close to 0x, 0y, and 256z.
For both the acceleromenter and gyroscope the readings are in 16bit format which is provided by the sensor stick. The raw accelerometer value that I get is therefore x=0(+-10) y=0(+-10) z=6000(+-50).
I will only get 0x,0y,256z only if the raw data is 8 bit . Am I correct?
What is the register 0x31 justify bit set as? If it's set to 1, then you'll need to shift with sign extension.
To clarify, the number is a 13 bit number with either sign extension or left justification, depending on that bit.
Second, do you have the read order correct? From the datasheet for register 0x31:
"The output data is twos complement, with DATAx0 as the least significant byte and DATAx1 as the most significant byte, where x represent X, Y, or Z."
So I think your code should be
I did the configuration for register 0x31 as 0x0D. Then the MSB and LSB is also swapped. The changes are as below.
At Acc_setup:
At main Function:
The values I get when the now when the sensor is stationary is as follows:
afx16=320, afy16=-670, afz16=7428
It still seems similar to my values that I got previously?
Second, when you give us example values, it's much more useful to get the a*16 type values, rather than the af*16 values. The float conversion and multiplication mangles the usefulness of the numbers for debugging.
The raw data is :
ax16= 5, ay16= -13, az16= -23
This values are when the sensor is stationary.
For both the acceleromenter and gyroscope the readings are in 16bit format which is provided by the sensor stick. The raw accelerometer value that I get is therefore x=0(+-10) y=0(+-10) z=6000(+-50). I will only get 0x,0y,256z only if the raw data is 8 bit . Am I correct?
Not quite. Like SLRM said, it's much easier for us to see what's going on if you report the data coming from the sensor first. Once you have that right, then worry about scaling it. In general, when working with a new device or system, you start very simple, verify it works, then add complexity a little at a time. If you start with 5 things that *might* not be working, you'll spend a long time guessing.
An accelerometer at rest will read a constant "acecleration" due to gravity. Assuming you have your sensor reasonably flat and level, you'll most likely see that reading on the Z axis. So if the accelerometer gives 3.9mg per LSB, that means 1g (1000mg) should be outputting (1000mg / 3.9mg), or 256.41 as a raw sensor reading. Since the sensor can't output fractions, it's 256. X and Y should be reading pretty close to zero.
That's going to depend on the other settings SLRM mentioned, which are justification and resolution. If you look on page 4 of the datasheet, one of the entries in the table is "sensitivity". That shows you how many LSB's per G you should see, minimum, typical, and maximum. So a 1G reading in Z should give you one of the numbers you see in the "typical" column of the table, depending on how you have the chip configured. In "full resolution" mode or +/-2g, the number is 256.
the raw values from the sensor when it is flat on the table are ax16= 5, ay16= -13, az16= -23
This values are without any scaling
Let me know if I am missing anything!
If that doesn't work, I usually start debugging with a logic analyzer. I use a Saleae Logic16, and it usually makes things very clear by seeing what's happening on the wire.
the raw data seems to be fluctuating even when I am not moving the sensor. It seems to be fluctuating in multiples of 32. Should I divide the data by 32 ? Is there some problem with the code?
This is the raw data from using the print as above:
-96,1,32,-1,32,29
-96,1,0,-1,32,29
-64,1,0,-1,64,29
-96,1,0,-1,64,29
-128,1,64,-1,64,29
-64,1,32,-1,64,29
-96,1,0,-1,64,29
-96,1,32,-1,64,29
-96,1,32,-1,64,29
-64,1,32,-1,64,29
-96,1,32,-1,32,29
-96,1,32,-1,32,29
-96,1,0,-1,64,29
-96,1,0,-1,64,29
-96,1,64,-1,64,29
-96,1,32,-1,32,29
-96,1,-32,-2,64,29
-128,1,0,-1,32,29
-96,1,32,-1,32,29
-96,1,32,-1,64,29
-128,1,32,-1,32,29
-96,1,32,-1,96,29
-64,1,32,-1,32,29
-96,1,32,-1,96,29
-96,1,32,-1,64,29
-96,1,64,-1,64,29
-64,1,0,-1,64,29
-128,1,32,-1,32,29
-96,1,32,-1,32,29
-96,1,32,-1,64,29
-96,1,32,-1,32,29
The value I got was ax16=-7 , ay16=5 , az16=234 when the sensor is stationary on the table. This value seems to be near/similar to x0, y0, z256 as said earlier.
I went on to multiply this value with 0.0039 and the I got results as follows:
afx16,afy16,afz16
0.06,-0.02,0.91
0.06,-0.02,0.91
0.07,-0.02,0.90
0.07,-0.02,0.91
0.07,-0.05,0.90
0.07,-0.05,0.90
0.07,-0.05,0.91
0.07,-0.01,0.91
0.07,-0.02,0.91
0.07,-0.05,0.91
0.07,-0.05,0.91
0.07,-0.05,0.91
0.07,-0.02,0.91
0.07,-0.02,0.91
0.07,-0.05,0.91
0.07,-0.05,0.90
0.07,-0.02,0.91
Am I doing it correctly?
This is the code that i used:
First off, the values look to be correct. Next up is to back out why they are correct.
Diving by 32 is equivalent to shift right by 5 (value >> 5), so that implies that the value is left justified instead of right justified. Secondly, shifting right by 5 puts the value at 11 bits, which is full resolution for the +- 4g range (see page 4 of the datasheet).
It seems that register 0x31 is being set incorrectly, with a value of 0bNNNN0101.
I now get data from ax16=13 , ay16=-12 , az16=-22 (raw data without any multiplication or division) when the sensor is stationary.
What should I do with this? It doesn't seem to be near x0 y0 z255. Is there anything else wrong?