How to Use GY511 module with Arduino [And Make a Digital Compass]

Table of Contents


In some electronics projects, we need to know the geographic location at any moment and do a specific operation accordingly. In this tutorial, you’ll learn how to use the LSM303DLHC GY-511 compass module with Arduino to make a digital compass. First, you’ll learn about this module and how it works, and then you’ll see how to interface the LSM303DLHC GY-511 module with Arduino.

What You Will Learn

General Information about Compass Module

GY-511 module includes a 3-axis accelerometer and a 3-axis magnetometer. This sensor can measure the linear acceleration at full scales of ± 2 g / ± 4 g / ± 8 g / ± 16 g and magnetic fields at full scales of  ± 1.3 / ± 1.9 / ± 2.5 / ± 4.0 / ± 4.7 / ± 5.6 / ± 8.1 Gauss.  When this module is placed in a magnetic field, according to the Lorentz law an excitation current induces in its microscopic coil. The compass module converts this current to the differential voltage for each coordinate direction. Using these voltages, you can calculate the magnetic field in each direction and obtain the geographic position. 
QMC5883L is another commonly used compass module. This module, which has a similar structure and application as the LMS303 module, is slightly different in performance. So if you are doing the projects, be careful about your module type. If your module is QMC5882L, use the appropriate library and codes that are also included in the tutorial. 

Required Materials

Hardware Components

Arduino UNO R3 × 1
GY-511 3-Axis Accelerometer + Magnetometer × 1
Servo motor × 1
1602 LCD Module × 1
Jumpers × 1

Software Apps

Arduino IDE

Interfacing GY-511 Compass Module with Arduino

GY-511 compass module has 8 pins, but you need only 4 of them to interface with Arduino. This module communicates with Arduino using I2C protocol, so connect the SDA (I2C output) and SCK (I2C clock input) pins of the module to the I2C pins on the Arduino board.

As you can see, we have used the GY-511 module in this project. But you can use this instruction for setting up other LMS303 compass modules.

GY-511 Compass Module Calibration

In order to navigate, you first need to calibrate the module, which means to set the measuring range from 0 to 360 degrees. To do this, connect the module to Arduino as shown below and upload the following code on your board. After executing the code, you can see the minimum and maximum values of the measuring range for X, Y and Z axis in the serial monitor window. You will need these numbers in the next part, so write them down.



In this code, you need the Wire.h library for I2C communication, and LMS303.h library for the compass module. You can download these libraries from the following links.

LMS303.h Library

Wire.h Library

If you are using QMC5883, you’ll need the following library: MechaQMC5883L.h Here, we explain the code for LMS303, but you can download the codes for the QMC module as well.
Compass Calibration
by Hanie Kiani 
*/ #include <Wire.h> #include <LSM303.h> LSM303 compass; LSM303::vector<int16_t> running_min = {32767, 32767, 32767}, running_max = {-32768, -32768, -32768}; char report[80]; void setup() { Serial.begin(9600); Wire.begin(); compass.init(); compass.enableDefault(); } void loop() {; running_min.x = min(running_min.x, compass.m.x); running_min.y = min(running_min.y, compass.m.y); running_min.z = min(running_min.z, compass.m.z); running_max.x = max(running_max.x, compass.m.x); running_max.y = max(running_max.y, compass.m.y); running_max.z = max(running_max.z, compass.m.z); snprintf(report, sizeof(report), "min: {%+6d, %+6d, %+6d} max: {%+6d, %+6d, %+6d}", running_min.x, running_min.y, running_min.z, running_max.x, running_max.y, running_max.z); Serial.println(report); delay(100); }

Let’s see some of the new functions:


Module initialization;

Reading the output values of compass module

   running_min.z = min(running_min.z, compass.m.z);
  running_max.x = max(running_max.x, compass.m.x);

Determining the minimum and maximum values of measurement range by comparing the measured values.

Making a Digital Compass

After calibrating the module, we are going to build a compass by connecting a servo motor to the module. So that the servo indicator, always shows us the north direction, like the red arrow on the compass. To do this, first the compass module calculates the geographic direction first and send it to Arduino and Then, by applying an appropriate coefficient, you’ll calculate the angle that the servo motor should rotate so that its indicator points to the magnetic north. Eventually, we apply that angle to the servo motor.



For this part you also need the Servo.h library, that is installed on your Arduino software by default.

Compass Calibration
by Hanie Kiani 
*/ #include <Wire.h> #include <LSM303.h> #include <Servo.h> LSM303 compass; int servoPin = 3; Servo Servo1; void setup() { Serial.begin(9600); Wire.begin(); Servo1.attach(servoPin); compass.init(); compass.enableDefault(); compass.m_min = (LSM303::vector<int16_t>){-32767, -32767, -32767}; compass.m_max = (LSM303::vector<int16_t>){+32767, +32767, +32767}; } void loop() {; float heading =compass.heading((LSM303::vector<int>){0, 0, 1}); Serial.println(heading); Servo1.write(180-heading); delay(100); }

Let’s see some of the new functions:

 Servo Servo1;

Module initialization;

Introducing the servo motor object

Initialization the compass module and servo motor The Servo1.attach() argument is the number of the pin connected to the servo motor.
 compass.m_min = (LSM303::vector){-32767, -32767, -32767};
  compass.m_max = (LSM303::vector){+32767, +32767, +32767};

Using these lines you define the minimum and maximum values for measuring the range obtained in the previous part.

 float heading =compass.heading((LSM303::vector){0, 0, 1}); float heading =compass.heading((LSM303::vector){0, 0, 1});

The heading() function returns the angle between the coordinate axis and a fixed axis. You can define the fixed axis with a vector in the function argument. For example, here, by defining the (LSM303 :: vector ) {0, 0, 1}, the Z axis is considered as a constant axis.

The Servo1.write() function applies the read value by the compass module to the servo motor.
Note that the servo motor may have a magnetic field, so it is better to place the servo motor at a suitable distance from the compass module, that it does not cause the compass module to deviate.

What’s Next?

  • Add the ESP8266 module to the system to report your position to your mobile phone at any moment.

Liked What you see?

Get updates and learn from the best

More To Explore

Comments (2)

  • Kumail Reply

    Unable to calibrate. I get this error:
    ‘compass’ does not name a type

    November 23, 2021 at 10:10 pm
    • Mehran Maleki Reply

      I just compiled the code and there were no errors. So, the code seems fine. Your error might be related to the libraries that the code needs. Make sure you have LSM303 library installed on your Arduino IDE.

      November 27, 2021 at 8:50 am

Leave a Reply

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