MPU6050 Arduino High-Frequency Accelerometer and Gyroscope Data Saver
“As an Amazon Associates Program member, clicking on links may result in Maker Portal receiving a small commission that helps support future projects.”
The MPU6050 is a 6-DoF (degree of freedom) accelerometer and gyroscope that is designed for inexpensive, small-scale, and efficient approximation of motion. Accelerometers and gyroscopes are used in smart phones for orientation detection, vibration analysis in vehicles and machines, and even camera stabilization and motion tracking. There are countless applications for accelerometers and gyroscopes, and with devices as accessible as the MPU6050, we can really test the limits of the technology.
The MPU6050 features three 16-bit analog-to-digital converters (ADCs) for digitizing the gyroscope outputs and three 16-bit ADCs for digitizing the accelerometer outputs. For this specific tutorial, the gyroscope range spans ±250°/sec, and the accelerometer range spans ±2g. The MPU6050 uses the I2C serial communication, which can be interfaced using pins A4/A5 (SDA/SCL) on the Arduino Uno board. The sensor also uses 3.3V as the supply voltage. The gyroscope and accelerometer can be sampled between 1-8kHz, but the limitations of the SD module will restrict the sample rate down to 500 Hz - which suffices for many applications (full datasheet for MPU6050 here).
The Arduino Uno board will be used as the controller for acquiring data from the MPU6050 at high speeds. An SD module will also be used to save the data in real time for analysis and post processing. This will more flexibility of the analysis while also allowing for portable applications such as tracking and vibration analysis (which would be very difficult with an Arduino board). The parts needed to replicate the experiments in this tutorial are listed below:
Arduino Uno - $11.00 [Our Store]
MPU6050 Accelerometer + Gyroscope - $8.99 (3 pcs) [Amazon]
SD Module - $7.99 (2 pcs) [Amazon]
USB SD Card Reader - $4.70 [Amazon]
Micro SD Card - $3.49 [Amazon]
3.7V LiPo Battery - $18.99 (4 pcs + charger) [Amazon]
3.7V to 5V Boost Converter - $7.99 (2 pcs) [Amazon]
Mini Breadboard - $3.00 [Our Store]
Jumper Wires - $5.99 (120 pcs) [Amazon]
Raspberry Pi 3B+ Kit - $48.99 [Amazon]
The wiring for the experiments conducted in this tutorial is very minimal and uses I2C wiring for the accelerometer and gyroscope, and SPI wiring for the SD card module. The wiring diagram is given below:
The wiring table is also given below:
One note regarding the wiring: the Arduino-to-Arduino wiring from 5V to pin D3 is used for letting the program know when to start (HIGH) and stop (LOW) recording. This is important because we will have no other way to notify the program to start and stop. A pullup resistor will be used on pin D3 to limit the power input onto that pin. The rest of the wiring is traditional and expected for the MPU6050 (I2C) and the SD module (SPI). The SD module requires 5V, which is why we’re using a 3.7V to 5V LiPo boost converter. The LED is wired for notifications regarding acquisition of data and processing - this will be discussed in the next section.
The Arduino Uno will be used to acquire acceleration and gyroscopic data from the MPU6050. An Arduino program is given below which automatically acquires data from the MPU6050 at a sample rate of 500Hz and saves it to the SD card. The data acquisition code is based on the SDFat library and its MPU6050 low-latency logger code, except I have cut out the user interface section, which allows us to use the code in a portable manner. In order to use the code, the SDFat library must be downloaded to the Arduino IDE:
The full code (over 500 lines!) is given below:
There isn’t much to say about the code without creating an entire post about the methods used in it. Therefore, I leave the code analysis to the user. Most of it is not mine, rather it was developed by the SDFat folks, so this is the extent to which I will explore it. I will, however, continue to discuss the notifications and outputs of the code, which will be necessary for acquiring and analyzing the data.
The general process flow followed by the code is as follows:
HIGH -> Acquire Data (LED HIGH)
While PIN 3 is HIGH data is acquired and stored in binary format for efficiency (500 Hz sample rate)
PIN 3 goes LOW, data enters conversion mode to .csv format
LED blinks during this process - DO NOT eject SD card or power off Arduino
LED will stop blinking and go LOW - Now, we go back to the beginning of this tree flow
LOW -> Do Nothing
The following should be the sequence for acquiring data:
Put PIN 3 LOW
Power on Arduino with LiPo battery
PIN 3 HIGH (acquire data)
PIN 3 LOW (convert data to .csv)
Wait for LED to stop blinking and go LOW
Power off Arduino
Eject SD card
The LED may blink for the same amount of time as the acquisition. The Arduino works at the highest frequency possible during acquisition, so the conversion can be lengthy due to the high sample rate (500Hz). If the MPU6050 is acquiring data for ten minutes, it may take just as long to convert - so patience is key.
Now we’re ready to analyze the data!
The output file should be named as follows:
where the last two digits of the file name iterate up as more files are created on one SD card. Once the SD card is inserted into a desktop computer via the USB drive, we can open one of the files with a Python program. An example Python scripe to do this is given below:
If the MPU6050 is not moved and it remains on its horizontal axis (with the z-axis pointed toward the ground - in the direction of gravity), we should see an output similar to the one shown below (plotted using the code given above):
We can see in the figure how the z-direction shows 1 (indicating that it is constantly experiencing the effect of gravity). The other accelerations are near zero. All gyroscope x,y,z values are zero, because we have not rotated the device at all. Toward the 13 second mark in the plot, we see some disturbance, which is a result of switching the acquisition pin from LOW to HIGH, and slightly disturbing the module. Below, the MPU6050 will be rotated to test and identify each axis of the accelerometer and gyroscope, which will give us a better idea of how the given axes function.
Once the acclerometer and gyroscope data is acquired, we must create an offset or calibration method for ensuring that accelerations and gyroscopic movements are tracked properly and with reference to the physical world. The best method for offsetting MPU6050 data is to assume the device starts at rest (which is a fine assumption for users who are aware of this). Therefore, using the data above, we can offset the data by subtracting the motionless data (I average over a few points) from the rest of the data. We also must take note of the gravitational influence and direction of gravity (z-direction in our case, assuming it adds to 1).
We now expect all the points in the beginning of the data plot to be centered about zero:
The offset code is incorporated in the Python code below:
And now we can start our analysis of accelerometer and gyroscope data. Better methods for offsetting and calibrating the accelerometer data will be explored, but at this time we need to acquire more meaningful data and analyze the acceleration and rotation using relevant algorithms and more advanced mathematics.
We can start by carrying out the following experiment:
Briefly rotate and hold the MPU6050 on each of its axes (x,y, and z) - this will ensure better calculation of offset with respect to gravity
Rotate the MPU6050 clockwise and then couter-clockwise on each axis - this will allow us to determine the degree of rotation for the gyroscope
The resulting data output should look as follows:
Now this might look like a bit of a mess, but the rotations and resulting accelerations and angles endow us with the information needed for complete calibration of the sensor.
First, we can see that the accelerations due to gravity are not quite 1 in each direction, meaning that our sensor is likely slightly angled. This is not an issue - as we can correct for it under the assumption of a uniform field of gravitation (accurate on earth in a stationary position). We can do this by selecting a steady section during each axis’s rotation in the direction of gravity, then finding the deficit in gravitational acceleration for each axis.
The MPU6050 6-Dof accelerometer and gyroscope was introduced and explored using Arduino as a high-speed data acquisition system. An SD module was used to save acceleration and gyroscopic information at a rate of 500 Hz (with the Arduino Uno board). I introduced a simple wiring method to acquire the 6-DoF inertial measurements, which were later analyzed using a Python program. With Python, we were able to read the accelerometer and gyroscope information using the csv reader library. The inertial data was then plotted for visualization and offset using a calibration technique harnessing the acceleration due to gravity (for the accelerometer offset values). This tutorial merely introduced the 6-DoF MPU6050 sensor, which will be further elaborated-upon in the next entry in the analysis using Python.
See More in Sensors and Python: