Angle Output 6-Axis Accelorometer + Gyroscope Module With UART Interface

Introduction:

This is a low cost 3 Axis accelerometer + 3 Axis Gyro sensor chip. Its very popular for applications like flight controllers for multirotors, gimbals and general robotics applications. However the IMU chip works on I2C and to get the Roll, Pitch and Yaw angles calculated it requires complex code. To make it easier this sensor has a microcontroller onboard which calculates the Roll, Pitch and Yaw angles and gives the output on UART, so any mcu board like Arduino can take input on UART with minimal coding.

Specification:

  • Chip: MCU + MPU6050
  • Power supply: 3-5v (internal low dropout regulator)
  • Communication: serial communication (baud 9600,115200), IIC communication
  • Module Dimensions: 15.5mm x 11.5mm 2.54mm/0.1″ pin headers
  • Direct Data: YAW ROLL PITCH
  • Heading angle (YAW) ± 180°
  • Roll angle (ROLL) ± 180°
  • The pitch angle (PITCH) ± 180°
  • 0.01° angular resolution
  • measurement accuracy : 0.1°
  • Repeatability : 0.1°
  • Measurement frequency : 100 HZ (115200bps)
  • Working current : 15 mA
  • Operating temperature : -20°C to  +85°C
  • Storage temperature : -40°C to 100°C

Pin outs:

  • Pin 1 – VCC Power + (3v-5v)
  • Pin 2 – RX Receiving data from serial
  • Pin 3 – TX Serial data transmission
  • Pin 4 – GND Power Ground
  • Pin 5 – RST Internal use, no connection, vacant
  • Pin 6 – B0 Internal use, no connection, vacant
  • Pin 7 – SCL I2C clock
  • Pin 8 – SDA I2C data

Usage:

  • Angle data output on UART through the gyroscope and accelerometer data fusion algorithm.
  • Output baud rate: 9600bps and 115200bps
  • Continuous output and inquiry output modes
  • Can be connected to mcu or computer
  • Can be used in handheld instruments, meters, robot navigation and positioning, RC airrcrafts, balancing robot etc.

Communication protocol:

UART
Baud rate:        115200 bps     Parity bit: N      Data bits: 8       Stop bits: 1 (DEFAULT)
Baud rate:         9600 bps        Parity bit: N      Data bits: 8       Stop bits: 1

Note: The baud rate selection is operated by solder jumper, see below.

Output format :
    each frame contains 8 bytes (hex):

  1. Byte0: 0xAA Preamble Flags
  2. Byte1: 0x00-0xFF HIGH heading(yaw)
  3. Byte2: 0x00-0xFF LOW heading(yaw)
  4. Byte3: 0x00-0xFF HIGH pitch
  5. Byte4: 0x00-0xFF LOW pitch
  6. Byte5: 0x00-0xFF HIGH roll
  7. Byte6: 0x00-0xFF LOW roll
  8. Byte7: 0x55 Frame end flag

Calculation method:
Angle = ( (HIGH << 8) | LOW ) / 0X64

Example:
Given the following data [0xAA, 0x00, 0x64, 0x03, 0XE8, 0x27, 0x10, 0x55]
heading angle = 1.00 °
Pitch angle = 10.00 °
Roll Angle = 100.00 °

COMMANDS:

  • 0xA5 + 0x51: query mode, return directly to the angle value, to be sent each read
  • 0xA5 + 0x52: Automatic mode, send a direct return angle, only initialization
  • 0xA5 + 0x53: Automatic mode, ASCII code output, serial port for direct computer assistant View
  • 0xA5 + 0x54: correction mode, the pitch correction roll angle of 0 degrees, need to stay level when sending
  •  0xA5 + 0x55: correction mode, 0 degree course correction, heading cleared at any angle

(1) On startup the module goes to calibration mode for 3 seconds, during this time module should be stationary or results may not be accurate.
(2)  Module heading(Yaw) will drift after a while without magnetometer.
(3)  Due to the angle of the Euler angles universal lock problem, roll, pitch, have an impact on each other at 90 degrees.
(4)  The module IOs are 5.0V tolerant, the module can be used with 5.0 and 3.3V system and serial adapters without any risk

#include <Wire.h> 
int YPR[3];
unsigned char Re_buf[8],counter=0;
unsigned char sign=0;
int led = 13;

void setup()
{
  Serial.begin(115200);  //set the serial baud
  delay(2000);    
  Serial.write(0XA5); 
  Serial.write(0X52);    //Initialize GY25, continuous output mode
}

void loop() 
{
  if(sign)
  {  
     sign=0;
     if(Re_buf[0]==0xAA && Re_buf[7]==0x55)        //Check the header, end of the frame
     {  	       
            YPR[0]=(Re_buf[1]<<8|Re_buf[2])/100;   //Synthesize data, remove 2 decimal places
            YPR[1]=(Re_buf[3]<<8|Re_buf[4])/100;
            YPR[2]=(Re_buf[5]<<8|Re_buf[6])/100;
           Serial.print("YPR:\t");
           Serial.print(YPR[0], DEC); Serial.print("\t"); //Show course
           Serial.print(YPR[1], DEC); Serial.print("\t"); //Show pitch angle
           Serial.println(YPR[2], DEC);                   //Show roll angle             
           delay(10);           
   }
  } 
} 

void serialEvent() {
  while (Serial.available()) {   
    Re_buf[counter]=(unsigned char)Serial.read();
    if(counter==0&&Re_buf[0]!=0xAA) return;      //Check the header   
    counter++;       
    if(counter==8)                //Received data
    {    
       counter=0;                 //Reassigned, ready to receive the next frame of data
       sign=1;
    }      
  }
}