🔧 MPU 9250 and Arduino - wiring diagram

🔧 MPU 9250 and Arduino - wiring diagram

Daniil Zhuk

In this article, we will introduce the MPU 9250 9-axis 3D position sensor. This module can be used in aircraft (various drones and quadrocopters) and smartphones as a compass and navigation, as well as in robotics, various manipulators and devices associated with 3D control and gesture recognition.

To implement the project from this article, we need the following components:

  • Arduino Uno R3
  • MPU-9250 (GY-85) - 9-axis IMU sensor
  • Breadboard
  • Wires

    MPU 9250 and Arduino - wiring diagram
    The MPU 9250 performs the functions of several sensors at once: this is both a gyroscope, and an accelerometer, and a magnetometer — all three devices in one, which is very convenient.

    Let us dwell a little more on each of them.

    A gyroscope is a sensor that responds to changes in orientation angles in space. In the same quadcopter, it is used to stabilize the position of the device in the air and protect it from the wind.

    For example, during fishing, we throw fishing rods into the pond and only the float is visible on the surface of the water. If the weather is windy enough, then the float will always go in different directions and bend at a random angle, which may prevent us from seeing the fish bite in time. The same thing will happen in the air. So that your quadcopter is not constantly in an inclined position, the gyroscope will be engaged in its alignment.

    As an illustration, below you can visually see the tests of the DIY drone along with the gyroscope installed in its hardware.

     The accelerometer compares the projection of the acceleration of an object with gravitational acceleration and is capable of measuring the linear velocity of the object, and, together with the gyroscope, its position in space.

    A magnetometer is a device for measuring the intensity of the nearest magnetic field acting on an object (however, the sensor name speaks for itself).

    And according to some sources, our MPU 9250 module is the world's smallest nine-axis sensor. This indicates the high performance of the chip (the name of which is called our “hero”), which was provided by the use of CMOS MEMS technology.

    The module case consists of two smallest crystals, one of which is responsible for the gyroscope and accelerometer, and the other for the magnetometer. Data from them is processed by the embedded DMP signal processor using Motion Fusion algorithms and transmitted via I2C or SPI interfaces.

    In addition to high performance, the module is quite popular among electrical engineers and those who are fond of devices for remote control, and also has low power consumption and cost.


    As mentioned earlier, the sensor can be connected to the Arduino via the I2C or SPI bus. The module can be powered from 5 V, since the sensor board has a linear stabilizer for this type of power, but it can also be supplied with a value of 3.3 V.

    You can connect the module to your microcontroller by four pins via the I2C interface (5V, Gnd, SCL, SDA) or via SPI, using 5 pins on the module board (5V, Gnd, SCL, SDA, CS, SDO).

    The picture shows the connection through the I2C interface.

    As examples for working with the MPU 9250 module, you can use the sketch below.

    This code using a pair of libraries will allow you to read information (data) from all three sensors and output to the port. Here you will need the Wire 0 library. It is already built into the Arduino IDE, which means that you do not need to install it separately.

    The TimerOne.h library simplifies the use of temporary functions. It can be downloaded from the link below:


    #include <Wire.h>
    #include <TimerOne.h>

    #define MPU9250_ADDRESS 0x68
    #define MAG_ADDRESS 0x0C

    #define GYRO_FULL_SCALE_250_DPS 0x00
    #define GYRO_FULL_SCALE_500_DPS 0x08
    #define GYRO_FULL_SCALE_1000_DPS 0x10
    #define GYRO_FULL_SCALE_2000_DPS 0x18

    #define ACC_FULL_SCALE_2_G 0x00
    #define ACC_FULL_SCALE_4_G 0x08
    #define ACC_FULL_SCALE_8_G 0x10
    #define ACC_FULL_SCALE_16_G 0x18

    // This function read Nbytes bytes from I2C device at address Address.
    // Put read bytes starting at register Register in the Data array.
    void I2Cread(uint8_t Address, uint8_t Register, uint8_t Nbytes, uint8_t* Data)
    // Set register address

    // Read Nbytes
    Wire.requestFrom(Address, Nbytes);
    uint8_t index=0;
    while (Wire.available())

    // Write a byte (Data) in device (Address) at register (Register)
    void I2CwriteByte(uint8_t Address, uint8_t Register, uint8_t Data)
    // Set register address

    // Initial time
    long int ti;
    volatile bool intFlag=false;

    // Initializations
    void setup()
    // Arduino initializations

    // Set accelerometers low pass filter at 5Hz
    // Set gyroscope low pass filter at 5Hz

    // Configure gyroscope range
    // Configure accelerometers range
    // Set by pass mode for the magnetometers

    // Request continuous magnetometer measurements in 16 bits

    pinMode(13, OUTPUT);
    Timer1.initialize(10000); // initialize timer1, and set a 1/2 second period
    Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt

    // Store initial time

    // Counter
    long int cpt=0;

    void callback()
    digitalWrite(13, digitalRead(13) ^ 1);

    // Main loop, read and display data
    void loop()
    while (!intFlag);

    // Display time
    Serial.print (millis()-ti,DEC);
    Serial.print ("t");

    // _______________
    // ::: Counter :::

    // Display data counter
    // Serial.print (cpt++,DEC);
    // Serial.print ("t");

    // ____________________________________
    // ::: accelerometer and gyroscope :::

    // Read accelerometer and gyroscope
    uint8_t Buf[14];

    // Create 16 bits values from 8 bits data

    // Accelerometer
    int16_t ax=-(Buf[0]<<8 | Buf[1]);
    int16_t ay=-(Buf[2]<<8 | Buf[3]);
    int16_t az=Buf[4]<<8 | Buf[5];

    // Gyroscope
    int16_t gx=-(Buf[8]<<8 | Buf[9]);
    int16_t gy=-(Buf[10]<<8 | Buf[11]);
    int16_t gz=Buf[12]<<8 | Buf[13];

    // Display values

    // Accelerometer
    Serial.print (ax,DEC);
    Serial.print ("t");
    Serial.print (ay,DEC);
    Serial.print ("t");
    Serial.print (az,DEC);
    Serial.print ("t");

    // Gyroscope
    Serial.print (gx,DEC);
    Serial.print ("t");
    Serial.print (gy,DEC);
    Serial.print ("t");
    Serial.print (gz,DEC);
    Serial.print ("t");

    // _____________________
    // ::: Magnetometer :::

    // Read register Status 1 and wait for the DRDY: Data Ready

    uint8_t ST1;
    while (!(ST1&0x01));

    // Read magnetometer data
    uint8_t Mag[7];

    // Create 16 bits values from 8 bits data

    // Magnetometer
    int16_t mx=-(Mag[3]<<8 | Mag[2]);
    int16_t my=-(Mag[1]<<8 | Mag[0]);
    int16_t mz=-(Mag[5]<<8 | Mag[4]);

    // Magnetometer
    Serial.print (mx+200,DEC);
    Serial.print ("t");
    Serial.print (my-70,DEC);
    Serial.print ("t");
    Serial.print (mz-700,DEC);
    Serial.print ("t");

    // End of line
    // delay(100);

    Add a comment

    * Comments must be approved before being displayed.