The IMU was wired to the Artemis with the QWIIC connector cable, according to the diagram below.
I then ran the example program Example1_Basics, which came with the ICM 20948 library, on the Artemis successfully.
The AD0 pin’s value is defined with the variable AD0_VAL, which represents the value of the last bit of its I2C address. I stuck with the default value, 1, which indicates that we are reading data from the IMU. When the ADR jumper is closed, this value becomes 0, indicating that we are writing data to the IMU.
The accelerometer value changed when the IMU was rotated, flipped, or accelerated, with the changing component being dependent on the axis of the movement. The gyroscope value changed when the IMU was rotated or flipped, with the changing component being dependent on the axis of the movement.
I also added code that would make the Artemis blink its built-in LED three times on startup.
The accelerometer’s pitch and roll were calculated using the equations below, taken from the lecture slides, where θ is roll and ϕ is pitch. I converted these values to degrees in my code.
I plotted the output at {-90,0,90} degrees using the Serial Plotter, where pink is pitch and gray is roll.
I found, using a protractor, that the output was off by about 5 degrees from the measured value, on average, which is pretty accurate.
I then tapped the IMU to generate noise, recorded the pitch and roll data, and performed FFTs on them using Python.
There do not seem to be any spikes in the FFT outputs due to the noise from tapping on the IMU. This is because the IMU already has an internal low-pass filter that filters out noise. There does not seem to be a need to implement an addition low-pass filter.
Using the equations given in class, I created functions to calculate the pitch, roll, and yaw, as seen below.
The following images show the Serial Plotter output for the pitch (red), roll (pink), and yaw (blue) for zero degrees, 90 degrees, and -90 degrees, with respect to the x-axis, respectively.
When looking at these plots, it is clear that these measurements are susceptible to drift. I also tried decreasing the sampling rate by increasing the delay in the loop, which decreased the accuracy of the estimated angles.
I then implemented complementary filters, with α = 0.5, for both the pitch and the roll, combining the gyroscope and accelerometer measurements as shown below. I chose an α of 0.5 after testing different values to see the accuracy they provided.
The accuracy and working range are demonstrated in the video below. The accuracy seems to be higher than the accelerometer measurements alone and much higher than the gyroscope measurements alone.
They were also not very susceptible to drift and quick vibrations, shown by the first and second image below, respectively.
After removing extra delays and Serial.print statements, and checking if the data is ready rather than waiting for it to be ready, I was able to sample new data every 133 ms.
I was also able to collect and store timestamped IMU data in arrays of size 500 using the code below.
By integrating my IMU code into the existing code to transmit 5 seconds of TOF data via Bluetooth from the Artemis to the Python end, and creating a new command called GET_TOF_IMU, I was able to transmit 5 seconds of both TOF and IMU data.
On the Python end, I received the data using a notification handler.
The digital electronics were powered by a 3.7V 650mAh battery, while the motors were powered by a 3.7V 850mAh battery. The battery with more capacity is used to drive the motors so the motors can run faster.
When playing around with the car, before mounting the Artemis onto it, I noticed that the car moved at a high speed, accelerated quickly, and made fairly sharp turns.
Once I got a feel for the car, I mounted the Artemis, along with the battery and sensors, onto it and performed a stunt. Five seconds of the data collected during the stunt were transmitted via Bluetooth and plotted using Python, as seen below.
In this plot, blue represents one TOF sensor, green represents the other TOF sensor, red represents pitch, and black represents roll. The results were as expected, although there was some unintended movement of the sensors due to the tape used to mount them being flimsy. I plotted this data in two different plots because the optimal y-axis scaling to see the trends clearly was very different for the TOF sensor versus the IMU.