MPU6050 – Using MPU6050 6-axis MotionTracking Device

Preparation
  • Ameba x 1
  • MPU6050 x 1

Example

MPU6050 is a common 6-axis motion tracking sensor (3-axis gyro + 3-axis accelerometer). It is connected through I2C interface to deliver data. There are a number of open source library can be found to control MPU6050 sensor via I2C.
I2CDev is one of the famous libraries to control the I2C interface. You can find the original source code here.
We need 2 libraries to use MPU6050: I2CDev and MPU6050. Please download from following links:
  • I2CDev
    We use the original I2CDev source code without modification.
  • MPU6050
    We only modify the example to fit our use case.

Follow the tutorial to install the libraries to Ameba:
https://www.arduino.cc/en/Guide/Libraries#toc4

Open the sample code in “Files” -> “Example” -> “AmebaMPU6050” -> “MPU6050_raw” (The sample code is the same as the example on the I2CDev official website).

In this example, we show how to read the value of the 3-axis gyro and the 3-axis accelerometer.
First follow the wiring diagram:
1

RTL8710 Wiring Diagram:
1

Compile and upload the code to Ameba, press the reset button. Then you can see the messages printed in serial monitor:
2

The six values are:
1. x-axis acceleration
2. y-axis acceleration
3. z-axis acceleration
4. x-axis angular velocity
5. y-axis angular velocity
6. z-axis angular velocity

Each value ranges in -16383 ~ 16384. Notice that due to the gravity acceleration, the value of z-axis acceleration tends to be close to 16384. These values could be changeable because of the interference.

Code Reference

To initialize: initialize()
After initializaion, we can get the value by getMotion6(int16_t* ax, int16_t* ay, int16_t* az, int16_t* gx, int16_t* gy, int16_t* gz)
 
Using Digital Motion Processor
MPU6050 is equipped with a DMP(Digital Motion Processor) to handle the calculation of some motion algorithms, such as conversion to the 3-axis yaw/pitch/roll of planes, conversion to quaternion, or conversion to Euler angle.
DMP performs high speed calculation, and sends GPIO interrupt to INT pin on complete. The calculation result is stored in FIFO. If Ameba does not read the result and the result is left in the FIFO for a long time, it could lead to FIFO overflow, and the result of the next read operation might be incorrect. In this case, please reset the FIFO.
Another noteworthy situation is that when MPU6050 sends GPIO interrupt as it is handling I2C data transmission, this would cause MPU6050 to stop responding. Since there is no reset or enable pin on MPU6050, we have to cut and replug the power to get it back to work again. Therefore, it is recommended that to handle calculation that requires some time, always wait until next GPIO interruption to perform I2C data transmission.Open the example in “File” -> “Examples” -> “AmebaMPU6050” -> “MPU6050_DMP6” (The sample code is similar to the example on the I2CDev official website, but we have modified some code in setting part)

To enable DMP, we have to connect one additional wire:
3Compile and upload to Ameba, press the reset button.
Open the serial monitor, then you can see the message notifies to send character to begin DMP.
4

After you send a character, the serial monitor prints the YPR value.
5

YPR represents Yaw/Pitch/Roll, which is a common representation in the flight of planes.
6

Code Reference

To use DMP, we should first do the initialization: mpu.dmpInitialize()
Use the following API to adjust the initialized value:
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
To enable DMP: mpu.setDMPEnabled(true);Specify the Ameba GPIO pin to wait for interrupt (here we set to D3 pin), and when the interrupt occurs, call function dmpDataReady():
attachInterrupt(3, dmpDataReady, RISING);

To get the packet size of the calculation result of DMP:
packetSize = mpu.dmpGetFIFOPacketSize();

Set the calculation speed of DMP (default to be 4, i.e., 1k/(1+4) = 200Hz). However, since printing log requires a lot of time, the interrupt may occur when the I2C transmission is still in progress. If this happens, the MPU6050 would stop responding. Therefore, it is important to select the appropriate rate. If we select the rate too high (sample rate too low), it cause the DMP to respond slowly.
mpu.setRate(5); // 1khz / (1 + 5) = 166 Hz

Then, use a loop() to wait for an interrupt, and when an interrupt occurs, get the result.
fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);

In the example we use OUTPUT_READABLE_YAWPITCHROLL, and then do the conversion to get related value.
mpu.dmpGetQuaternion(&q, fifoBuffer); // quaternion
mpu.dmpGetGravity(&gravity, &q); // gravity value
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); // convert to yaw/pitch/roll

Please confirm that QQ communication software is installed