L3GD20 data interpretation

Hi community,

I am new here and I have a problem to be sold :).
I bought L3GD20 board from pololu (https://www.pololu.com/product/2125) , connected it to RaspberryPi linux computer and I am programming with C. The connection over SPI is succesfull and I can read data from the sensor. So far so good. My problem is the interpretation of the axis-data. I am calculating degrees by integrating the raw data. For tests I am using only x-axis data. The programm writes x-axis degree on the screen in a looooong list as you can see in the endless loop. It starts from the value about -1.2 or so and increases (or decreases in negative way) to -23643.56 and still continues. I know the gyro drifts over time but how can I “normalize” this data? I want the data not to exceed over +/- 359.99 degree. How can I do that?

The configuration and code are below:

		...
		#define SENSITIVITY   (0.017500f) // 500 dps
		#define INT_TIME	(0.010526f) // 1/95Hz
		struct vector {
			double x_deg;
			double y_deg;
			double z_deg;
		};
		...
		int16_t raw_data[3];  // x,y,z
		struct vector angles;
		...
		wrtie8(CTRL_REG1, 0x0F); // ODR=95Hz, normal mode, Zen, Yen, Xen
		wrtie8(CTRL_REG2, 0x00); // HPM = normal
		wrtie8(CTRL_REG3, 0x00); // interrupts disabled
		wrtie8(CTRL_REG4, 0x10); // FS = 500dps
		wrtie8(CTRL_REG5, 0x00); // FIFO disabled
		...
		angles.x_deg = 0.0;
		angles.y_deg = 0.0;
		angles.z_deg = 0.0;

		while(1)
		{

			raw_data[0] = (read8(L3GD20_OUT_X_H) << 8) | read8(L3GD20_OUT_X_L);
			raw_data[1] = (read8(L3GD20_OUT_Y_H) << 8) | read8(L3GD20_OUT_Y_L);
			raw_data[2] = (read8(L3GD20_OUT_Z_H) << 8) | read8(L3GD20_OUT_Z_L);
			
			angles.x_deg += raw_data[0] * SENSITIVITY * INT_TIME;
			angles.y_deg += raw_data[1] * SENSITIVITY * INT_TIME;
			angles.z_deg += raw_data[2] * SENSITIVITY * INT_TIME;

			printf("%7.2f\n", angles.x_deg);

			usleep(500); // pause 500 µs
		}

Hello.

I am glad you were able to get the SPI connection working between the Raspberry Pi and the L3GD20. Could you post about how you did that in case anyone else wants to do the same thing?

Integrating the gyro’s three axes separately is not going to help you know what orientation the gyro is in. One way to see why that won’t work is to consider rotating the gyro about its X axis 90 degrees and then rotating it about its Y axis by 90 degrees. That will put the gyro board in one orientation, but if you did the two rotations in the other order then it will put the gyro board into a different orientation.

To integrate the gyro readings correctly, you need to store some representation of the current rotation and use frequent gyro readings to update it. I would recommend storing the current rotation as a quaternion.

Here is some code I wrote (also for the Raspberry Pi and L3GD20) that demonstrates how to do that: github.com/DavidEGrayson/minimu9-ahrs . In particular you should look at “fuse_gyro_only” in minimu9-ahrs.cpp which modifies the current rotation quaternion to account for the latest angular velocity reading from the gyro. The “dt” variable is the time period since the last reading. The actual quaternion math is done by a third-party library called Eigen, but this blog post by forum user Camel might be helpful if you want to understand some of the math:
camelsoftware.com/firetail/blog/c/imu-maths/

Another useful thing you can do to the raw data is hold the gyro perfectly still and take some readings to determine what the offset is on each axis. The offset for a given axis would just be the average reading you got on that axis while holding the gyro still. You can later subtract these offsets from your raw data to get more accurate results.

–David

Hello,
Thank you for your quick reply and sorry for my late answer :slight_smile:
I used Gordon’s Library for RPi SPI communication (projects.drogon.net/raspberry-p … i-library/), I was schocked :open_mouth: that it worked at the very first trying, normally one should spend a lot of days in order to get a working communication.
It is very good that you also made something similar, I looked your code and looks good. I have to study deeply because I have really no idea about quaternion.

I found something usefull on the ST site, a technical article TA0343 : (st.com/st-web-ui/static/acti … 034730.pdf)

But indeed it gives only some basic information.

I will try your code as soon as possible.
By the way, in my project I can only use gyroscope, I can not use accelerometer or magnetometer which are required as a reference for some other filtering technics such as kalman or whatever. Even If I have an acceloremeter, I can not use kalman because it is really very complicated for me.

Thanks.