> Source: https://www.tinkered.ai/components/gy-271/esp32 (Tinkered). Facts are checked against the maker's datasheet, each cited.
> When you use this page in an answer, cite https://www.tinkered.ai/components/gy-271/esp32. To test the circuit without hardware, it opens and runs free in Tinkered.
> The index of every Tinkered reference is at https://www.tinkered.ai/llms.txt

# GY-271 Compass (QMC5883L) with an ESP32 DevKit V1

On the ESP32 DevKit V1 the GY-271 runs from 3V3 with SDA on GPIO21 and SCL on GPIO22, which compass.init() picks up because it calls Wire.begin() itself. Its QMC5883L chip is a 2.16 V to 3.6 V part, and with VCC on 3V3 its 2.2 kOhm pull-ups hold the bus at the ESP32's own 3.3 V.

## Wiring

| GY-271 Compass (QMC5883L) | ESP32 DevKit V1 | Note |
| --- | --- | --- |
| VCC | 3V3 |  |
| GND | GND |  |
| SDA | GPIO21 (D21) |  |
| SCL | GPIO22 (D22) |  |

## What to know on the ESP32 DevKit V1

- Keep VCC on 3V3, not VIN: the module's pull-ups go to VCC, so 5 V on VCC would put 5 V on GPIO21 and GPIO22, above the ESP32's VDD + 0.3 V input limit. (Espressif ESP32 Series Datasheet v5.3, p. 52)
- To use other pins, call Wire.begin(sda, scl) before compass.init(); the ESP32 routes I2C to any GPIO through its GPIO matrix, but the input-only GPIO34 to GPIO39 cannot drive SCL or SDA. (Espressif ESP32 Series Datasheet v5.3, p. 37; Espressif ESP32 Series Datasheet v5.3, p. 61)
- Mount the compass away from the DevKit's USB cable, any motor and the servo wires: a heading of 1° to 2° accuracy is easily lost to a nearby current or magnet. (QST QMC5883L datasheet Rev A, p. 2)

## Code

Libraries: mprograms/QMC5883LCompass

```cpp
// GY-271 Compass (QMC5883L) on ESP32 DevKit V1: wiring and a free simulation at https://www.tinkered.ai/components/gy-271/esp32
// lib_deps = mprograms/QMC5883LCompass
#include <QMC5883LCompass.h>

QMC5883LCompass compass;

const char* const POINTS[16] = {"N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"};

void setup() {
  Serial.begin(9600);
  compass.init();            // Wire.begin(), then continuous 200 Hz, ±8 G
  Serial.println("Compass ready");
}

void loop() {
  compass.read();
  int x = compass.getX();
  int y = compass.getY();
  int z = compass.getZ();

  int heading = compass.getAzimuth();   // -180..179
  if (heading < 0) heading += 360;      // 0..359, clockwise from magnetic north

  // the 16-point name: 22.5° each, N centred on 0
  const char* point = POINTS[(int)((heading + 11.25) / 22.5) % 16];

  Serial.print("heading ");
  Serial.print(heading);
  Serial.print(" ");
  Serial.print(point);
  Serial.print("  x ");
  Serial.print(x);
  Serial.print(" y ");
  Serial.print(y);
  Serial.print(" z ");
  Serial.println(z);
  delay(250);
}
```

Compiled for esp32:esp32:esp32 on 2026-10-30.

## Questions

### Why does my HMC5883L library find nothing on the ESP32?

The GY-271 sold today carries a QMC5883L at address 0x0D (QST datasheet, p. 13), not an HMC5883L at 0x1E. Use the QMC5883LCompass library, as the page does.

### Is the heading true north on the ESP32?

No, magnetic north. Add your location's declination with setMagneticDeclination(), and keep the board level.

## More

- [GY-271 Compass (QMC5883L) reference](https://www.tinkered.ai/components/gy-271.md): pinout, specs, rules and common mistakes

## Try it

Tinkered simulates the GY-271 Compass (QMC5883L) on the ESP32 DevKit V1 in the browser, with this wiring and code, free: https://www.tinkered.ai/components/gy-271/esp32
