IMU Lab Report

Objective

This lab focuses on setting up and analyzing IMU data from the SparkFun Artemis board.

IMU Setup

IMU Connection

To set up the IMU, I plugged it into the Artemis and then ran the example code provided to ensure it was working as intended.

Hardware Connection:

Screenshot showing virtual environment setup in command prompt

AD0_VAL Definition

In the example code, AD0_VAL is assigned a value of 1, signifying that the ADR jumper on the IMU has not been bridged. This setting designates the IMU’s address as 0x69, making SPI communication possible. If the jumper were soldered, SPI communication would be disabled.

IMU Basic Testing & Observations

Using the example code, I tested the IMU by applying different types of movement. When the IMU accelerates in a particular direction, only the corresponding accelerometer values change, while the gyroscope shows minimal variation. During rotation, the accelerometer readings fluctuate continuously, whereas the gyroscope detects changes only while the motion is happening. When flipped, the accelerometer readings adjust as different axes align with gravity. Once the IMU remains at a fixed angle, the gyroscope records small values since it measures angular velocity rather than absolute position. The video below illustrates these behaviors as the IMU is flipped, rotated, and accelerated.

LED Startup Indicator

I added code to make the Artemis blue light blink, indicating that the IMU is properly connected.

Blink Code:

Screenshot showing virtual environment setup in command prompt

Accelerometer

Pitch & Roll Equations

Accelerometer Output

Pitch & Roll at -90°, 0°, 90°

Readings seen in video:

Accelerometer Accuracy

The accelerometer accuracy seems to be alright if it is held steady at an angle. Even then, the sensor readings will keep changing. A fourier transform will assist with filtering out the noise from the sensor readings.

Fourier Transform Analysis

I sent data from arduino to python, and then did a fourier transform to better see what area of signal the noise was located. The graph of my fourier transform lead me to select a cutoff frequency of 5 hertz, as below this level is where the noise is. Here are graphs of my raw data of pitch and roll vs time along with the FFT plots. Note: the Frequency axis here should be scaled by 10,000.

Raw Roll:

.

Raw Pitch:

.

FFT Roll:

.

FFT Pitch:

.

Low-Pass Filter Implementation

I implemented a low pass filter to clean the noise out of the raw pich and roll data. I used .1 as my alpha, which is calculate from dt = 1/(sampling rate), RC = 1/(2*pi*cutoff freq), and alpha=dt/(dt+RC) using a sampling rate of about 270 message/min and a cutoff frequency of 5 Hz. Note: the Frequency axis here should be scaled by 10,000.

LPF Code:

.

LPF Roll:

.

LPF Pitch:

.

LPF Roll:

.

LPF Pitch:

.

Gyroscope

Pitch, Roll, and Yaw Computation

Gyroscope Code:

.

Gyroscope readings vs. Accelerometer:

Pitch:

.

Roll:

.

Yaw:

.

Discussion

The data indicates that the gyroscope exhibits significantly less noise than the accelerometer, but tends to drift over time. The accelerometer provides more accurate readings when the IMU remains in a fixed position. Increasing the sampling frequency enhances the gyroscope’s accuracy by allowing for more frequent updates. To achieve a more reliable signal, I implemented a complementary filter that combines both accelerometer and gyroscope measurements using weighting factor of 0.8 to give more emphasis to the accelerometer's readings, as they proved to be more accurate. The filter removes noise and drift from the input signal.

Complementary Filter

CF Code:

.

CF Pitch:

.

CF Roll:

.

Sample Data

IMU Sampling Speed: I rewrote my main Arduin loop, removing all prints and built-in delays. The resulting Arduino loop runs faster (362Hz) than the IMU can process data (48Mhz). Each data set (time, raw roll & pitch, filtered roll & pitch, guroscope readings, and the combined signals) are stored in their own individual arrays for easy access later.

Final Loop Code, storing data in arrays:

.

Bluetooth Data Transmission Analysis

The Artemis has 384 kiB of memory. My loop had 10 arrays to communicate all the data types from this lab. This number can be reduced depending on the desired data being transfered. With 10 arrays and 4 bits per float in the array, each array can store up to 9600 elements in each array. Since the IMU processes data at 362hz, the Artemis can store about 26.5 seconds of IMU data if stored in 10 separate float arrays.

5 seconds of data

Plotted:

.

Recording a Stunt

Here's the car doing a flip!

Observations from Playing with the Car

The car was very reactive and accelerated quickly. It turned well and quickly changing speed from front to back causes it to flip.

Conclusion

This lab taught me a lot about the nuances of working with this code. As a MechE, I am unfamiliar with the coding languages we are using. While troubleshooting, I was able to gain more confidence in defining arrays, float vs int, and the importance of the setup vs main body vs end code in the ble arduino file. Hopefully, with these larnings, next lab goes quicker!

Back to Main Page