Interfacing GY-91 (9-axis MPU9250 + BMP280) Module with Arduino

MPU9250 + BMP280 Module Features

This IMU module is a small board which all the sensors required for 10 degrees of freedom are placed in. This module communicates with the Arduino or microcontrollers via the I2C interface. Using the existing FreeIMU functions and source code, you can easily use this IMU as an AHRS system in flight controls. You can use this module in VTOLs, model airplanes, UAVS, and also industrial and medical devices.

GY-91 Module Pinout

This sensor has 8 pins:

  • VIN: Module power supply – 5 V
  • GND: Ground
  • 3V3: Module power supply – 3.3 V
  • SLC: I2C Clock / SPI Clock
  • SDA: I2C data / MOSI pin for SPI
  • SAO/SDO: Address adjust pin for I2C / MISO pin for SPI
  • NCS: Chip Select pin only for MPU-9250 sensor
  • CSB: Chip Select pin only for BMP280 sensor

You can see pinout of this module in the image below.

You can download the datasheet of this module here.

Required Materials

Hardware Components

Arduino UNO R3 × 1
MPU9250 + BMP280 Module × 1
Male to Female jumper wire × 1

Software Apps

Arduino IDE

Interfacing GY-91 Module with Arduino

Step 1: Circuit

The following circuit shows how you should connect Arduino to this module. Connect wires accordingly.

Step 2: Code


If you need more help with installing a library on Arduino, read this tutorial: How to Install an Arduino Library

Upload the following code to your Arduino.

After uploading the code, by moving the module, you can see the output in the serial monitor.

  by MohammedDamirchi
*/ #include <MPU9250_asukiaaa.h> #include <Adafruit_BMP280.h> #ifdef _ESP32_HAL_I2C_H_ #define SDA_PIN 21 #define SCL_PIN 22 #endif Adafruit_BMP280 bme; // I2C MPU9250_asukiaaa mySensor; float aX, aY, aZ, aSqrt, gX, gY, gZ, mDirection, mX, mY, mZ; void setup() { Serial.begin(115200); while (!Serial); #ifdef _ESP32_HAL_I2C_H_ // For ESP32 Wire.begin(SDA_PIN, SCL_PIN); mySensor.setWire(&Wire); #else Wire.begin(); mySensor.setWire(&Wire); #endif bme.begin(); mySensor.beginAccel(); mySensor.beginGyro(); mySensor.beginMag(); // You can set your own offset for mag values // mySensor.magXOffset = -50; // mySensor.magYOffset = -55; // mySensor.magZOffset = -10; } void loop() { if (mySensor.accelUpdate() == 0) { aX = mySensor.accelX(); aY = mySensor.accelY(); aZ = mySensor.accelZ(); aSqrt = mySensor.accelSqrt(); Serial.print("accelX: " + String(aX)); Serial.print("\taccelY: " + String(aY)); Serial.print("\taccelZ: " + String(aZ)); Serial.print("\taccelSqrt: " + String(aSqrt)); } if (mySensor.gyroUpdate() == 0) { gX = mySensor.gyroX(); gY = mySensor.gyroY(); gZ = mySensor.gyroZ(); Serial.print("\tgyroX: " + String(gX)); Serial.print("\tgyroY: " + String(gY)); Serial.print("\tgyroZ: " + String(gZ)); } if (mySensor.magUpdate() == 0) { mX = mySensor.magX(); mY = mySensor.magY(); mZ = mySensor.magZ(); mDirection = mySensor.magHorizDirection(); Serial.print("\tmagX: " + String(mX)); Serial.print("\tmaxY: " + String(mY)); Serial.print("\tmagZ: " + String(mZ)); Serial.print("\thorizontalDirection: " + String(mDirection)); } Serial.print("\tTemperature(*C): "); Serial.print(bme.readTemperature()); Serial.print("\tPressure(Inches(Hg)): "); Serial.print(bme.readPressure()/3377); Serial.print("\tApproxAltitude(m): "); Serial.print(bme.readAltitude(1013.25)); // this should be adjusted to your local forcase Serial.println(""); // Add an empty line }
Liked What You See?​
Get Updates And Learn From The Best​

Comments (24)

  • Tamer Salmem Reply

    acelerometro:17:14: error: ‘SDA_PIN’ was not declared in this scope
    acelerometro:17:23: error: ‘SCL_PIN’ was not declared in this scope

    Just to improve your tutorial. Thank you for the post!

    March 24, 2021 at 4:37 pm
    • Mehran Maleki Reply

      The code was originally written for an Arduino Board. If you’re planning to use it for an ESP32 Board, then you need to define SDA and SCL pins on your own.

      March 30, 2021 at 8:58 am
  • Andy Reply

    Hallo, thanks for your code.
    I use mCore (ATmega328) with GY-91 wired to pin SDA and SCL of port 3.
    So I can read MPU9250 data but anything about BMP280.
    May be I have to wire it to another PINs (I tried with 11,12,A0,A1) but I don’t know which ones.
    Can you help me, please?
    Thank you!

    April 7, 2021 at 6:14 pm
    • Mehran Maleki Reply

      BMP280 and MPU9250 both use I2C communication protocols, but they have different I2C addresses and can use the same I2C bus for communication. So now that you have connected the GY-91 module to the I2C pins of your microcontroller, no more wiring is needed. You can access both BMP280 and MPU9250 through those pins. You just need to use the appropriate libraries for that.

      April 10, 2021 at 4:18 am
  • Pierre Reply

    Hello, great code, thank you for it.
    I am using arduino Mega and GY91 bought on aliexpress.
    However, only gyro’s data is changing on serial display. Do I have to modify something in libraries (adresses maybe ?) in order to access the full data ?
    Thank you

    May 15, 2021 at 9:15 am
    • Mehran Maleki Reply

      Hi. The tutorial here is based on Arduino Uno, but there shouldn’t be any difference in the code when using your module with Arduino Mega. Just keep in mind that the Arduino Mega I2C pin are A20 and A21. (SDA and SCL respectively) So that’s the only difference you should pay attention to when interfacing the module with Arduino Mega, and you should get the same results as here. If you don’t, there can be something wrong with the GY-91 module. To check the functionality of the sensor, you can use i2c_scanner code provided in Arduino IDE examples → Wire → i2c_scanner and see the i2c addresses it returns.

      May 17, 2021 at 5:14 am
  • Emre ERTEKİN Reply

    Hello, great code,
    I am using Arduino/Teensy and this module GY-91
    i am getting this values for AccelX and AccelY. Here is link:
    Can you help me?
    Thanks .

    June 13, 2021 at 1:56 pm
    • Mehran Maleki Reply

      Hello my friend,
      When the values of some particular parameters don’t change, it usually means that there is something wrong with the module. Try to find some other library and code and compare the results. If nothing changed and the problem still persisted, you’ll probably need to get a new module.
      Good luck.

      June 14, 2021 at 4:19 am
  • Joshua Kolby Reply

    Hello. Really nice tutorial and code.
    However, I am running into one problem.
    The mpu9250 is giving me good values for accel, gyro, and mag, but the bmp280 is giving me nothing. Temp reads 0.00, pressure reads 0.00 which causes the alt to read 44330.00. I have tried three different gy-91s and all three gave me the same result.
    I thought at first it might be the library, so I tried a different library but received the same result. Because a library change didn’t do anything and the wiring is obviously correct since the mpu9250 works, that leaves me to conclude that the problem is in the gy-91 itself. However, I could understand one of them being defective, but all three?!
    I am hoping I just missed something somewhere rather than buying 3 defective gy-91s.
    Thank you for your time.

    July 7, 2021 at 9:36 pm
    • Mehran Maleki Reply

      Hello. Thanks for your exhaustive explanation of your problem! According to what you have already done, there is little I can add to that. There is just one other thing you haven’t check. Use the “i2c_scanner” code to check what addresses it returns. To find this code, open the Arduino IDE. You can see the code in “File → Examples → Wire → i2c_scanner”. Using this code, you can find out what I2C devices are connected to your Arduino Board. The I2C address of the BMP280 sensor is 0x76 of 0x77. If the i2c_scanner doesn’t return an address like that, then the modules might be defective. Hope that helps! Good luck.

      July 10, 2021 at 5:31 am
    • J Reply

      Joshua, your problem is possibly that you need to set the address of the BMP 280 on line 21. Change line 21 in the code above from:

      bme.begin(0x76); // Assumes GY-91’s BMP 280 is at default address

      This worked for me with a GY-91 attached to a TeensyDuino 3.2 after reading and running Wire -> Scanner with Scanner set up for a Teensy’s I2C pins.

      My mag reading is stuck at zero but that is a separate problem.


      July 22, 2021 at 7:20 pm
      • Peter Mueller Reply

        thanks, now it is working

        April 13, 2022 at 12:19 pm
    • Kiven Reply

      Hello, I want to know how to get accel, gyro, and mag. The three infos are all 0 in my computer. After seeing Mr. Maleki’s method, I key in 0x76 and get correct infos of temperature, pressure and altitude. But there’s still a problem to accel, gyro, and mag. Thank you.

      May 7, 2022 at 11:30 am
  • Mehak Reply

    In file included from accel_WR.ino:4:0:
    C:\Users\Maheek Fatima\Documents\Arduino\libraries\Adafruit_BMP280_Library/Adafruit_BMP280.h:24:29: fatal error: Adafruit_Sensor.h: No such file or directory
    #include “Adafruit_Sensor.h”
    compilation terminated.
    Error compiling.

    if anyone can help!

    October 11, 2021 at 7:22 pm
    • Mehran Maleki Reply

      I just compiled the code to make sure there is no error, and there was none. Make sure you have installed the 2 libraries discussed in the tutorial. Also, make sure you have the “Adafruit Unified Sensor” library installed on your Arduino IDE. It’s a library that a lot of other libraries such as the 2 libraries in this article use. To install it, open your Arduino IDE. Go to “Tools → Manage Libraries”. Type “Adafruit Unified Sensor” in the search box, scroll down to find the “Adafruit Unified Sensor” library and install it. That must solve your problem.

      October 12, 2021 at 5:53 am
  • Marian Reply


    January 10, 2022 at 9:07 am
    • Mehran Maleki Reply

      Thank you for your generous comment! You’re most welcome.

      January 11, 2022 at 6:19 am
  • Julio Reply

    I just have included this code to my arduino IDE, did 100% the same things as the post said, and I’m having trouble showing the result on the serial monitor, it keeps showing me random letters. Can u pls help me? just don’t know what I did wrong.

    April 26, 2022 at 4:06 am
    • Mehran Maleki Reply

      This often happens when the baudrate of the Serial Monitor is not set to the right value. Make sure the baudrate is set to 115200.

      April 27, 2022 at 3:12 pm
      • Julio Reply

        Hello, thank you for the response, I changed the baudrate to 115200 and this especific problem was solved. But another one came up, the serial print of the accelerometer, gyroscope and magnetometer are not appearing on the serial monitor, only the pressure, temperature and alttitude are appearing, but with “nan” as a result, just like this print shows you: I’m sorry for bothering again but I hope you can help me.
        Thanks again.

        April 28, 2022 at 5:11 am
        • Mehran Maleki Reply

          You’re welcome! And about your new problem, you have either not connected the sensor to the Arduino properly, or there is something wrong with the sensor itselt. So, first, double check the wiring.

          April 30, 2022 at 5:52 pm
  • Wilhelm Kuckelsberg Reply

    I have a question about the GY-91 board. How are the CSB and NCS pins connected?
    Gyro delivers good results, the BME280 cannot be initialized.

    May 21, 2022 at 4:59 pm
  • Shiven Patel Reply

    Hi. Thank you for the tutorial you sent. I also had this issue where my sensor would print “NaN”. As you said to the other guy, I checked my wiring, and it looks fine, but it still prints “NaN’. Do you mind solving this issue? I am using an Arduino GIGA R1 and my SDA is connected to its SDA1 pin and SCL to SCL1 pin. Then I connected to 5V and GND pins. I even tried connecting the SDA and SCL to A4 and A5, but it still printed “NaN”. Do you mind helping me.

    March 11, 2024 at 1:57 am
    • Mohammad Damirchi Reply

      Hi Shivan,
      Start by utilizing the I2C Scanner available under “File → Examples → Wire → i2c_scanner” to verify the wiring.
      For the Arduino GIGA R1, note that it features 3 I2C ports, with the default pins being 20 (SDA) and 21 (SCL). To initialize I2C1, use Wire1.begin(), and for I2C2, utilize Wire2.begin().
      Once you receive the ID from the sensor, ensure to cross-check it in the code.

      March 12, 2024 at 5:05 am

Leave a Reply

Your email address will not be published. Required fields are marked *