For 90% of embedded robotics, steering, and motor-control projects requiring absolute angular position without a homing sequence, the AMS AS5600 12-bit magnetic rotary position sensor is the definitive choice. Priced around $3.50 on breakout boards, it speaks I2C, SPI, or ratiometric analog, and survives over 100 million rotations without the mechanical wiper wear that destroys standard potentiometers. Below is the exact wiring, register math, and mechanical mounting protocol to integrate it with an ESP32.
The Physics of Magnetic Position Sensing
The AS5600 relies on the Hall effect, where a magnetic field perpendicular to a current-carrying semiconductor deflects charge carriers, creating a measurable transverse voltage. Instead of a single Hall element, the AS5600 integrates a circular array of Hall plates on a single CMOS die. As a diametrically magnetized rotor spins above the chip, the array detects the shifting magnetic flux vectors, allowing the internal DSP to calculate the exact angular position.
Unlike optical encoders that require precision slotted discs and LED alignment, or LVDTs that demand complex AC excitation circuits, this Hall-based architecture is entirely non-contact and immune to dust, oil, and moisture. The internal Automatic Gain Control (AGC) dynamically adjusts the amplifier gain to compensate for temperature-induced changes in the magnet's field strength, ensuring a stable 12-bit output across the -40°C to +125°C operating range.
Decision Tree: Selecting the Right Architecture
Do not default to a potentiometer just because it is cheap. Use this decision matrix to select the correct positions sensor architecture for your specific mechanical and electrical constraints.
| Criterion | 10k Potentiometer | Incremental Optical (e.g., CUI AMT102) | Absolute Magnetic (AS5600) |
|---|---|---|---|
| Cost | < $0.50 | $20 - $35 | $3.00 - $5.00 |
| Position on Boot | Yes (Absolute) | No (Requires homing switch) | Yes (Absolute) |
| Lifecycle | ~100k rotations | Infinite (non-contact) | Infinite (non-contact) |
| Resolution | ~8-bit (ADC noise limited) | 11-bit to 14-bit | 12-bit (4096 steps) |
| Best Use Case | Low-cost user knobs | High-speed BLDC commutation | Robot joints, steering, gimbals |
AS5600 ESP32 Wiring and Pinout
The AS5600 operates in two distinct voltage modes. For 3.3V logic microcontrollers like the ESP32, you must supply the VCC pin with 3.3V. Supplying 5V to a breakout board configured for 3.3V logic will back-feed the I2C pull-ups and potentially damage the ESP32's GPIO pins.
| AS5600 Pin | ESP32 DevKit V1 Pin | Function & Notes |
|---|---|---|
| VCC | 3V3 | Supply range: 3.0V to 3.6V. Do not use 5V. |
| GND | GND | Common ground reference. |
| SDA | GPIO 21 | I2C Data. Requires 4.7kΩ pull-up to 3.3V (often on breakout). |
| SCL | GPIO 22 | I2C Clock. Requires 4.7kΩ pull-up to 3.3V. |
| DIR | GND | Direction select. Tie to GND for Clockwise (CW) angle increase. |
| OUT | Not Connected | Analog/PWM output. Leave floating when using I2C. |
0x36. It cannot be changed via hardware pins. If you need multiple sensors on the same I2C bus, you must use an I2C multiplexer like the TCA9548A.
Raw-to-Degree Math and I2C Register Code
The sensor outputs a 12-bit integer representing the angular position. The raw value ranges from 0 to 4095, mapping to 0° to 359.9°. The mathematical scaling factor is exactly 0.087890625 degrees per step (360 / 4096).
To read this via I2C, you must request two consecutive bytes from the Angle Registers: 0x0E (MSB, containing bits 11-8) and 0x0F (LSB, containing bits 7-0). Note that registers 0x0C and 0x0D provide the raw unadjusted angle, while 0x0E and 0x0F apply any internal zero-offset or range mappings you have burned into the OTP memory.
#include <Wire.h>
#define AS5600_ADDRESS 0x36
#define ANGLE_REG_MSB 0x0E
#define ANGLE_REG_LSB 0x0F
#define STEPS_PER_REV 4096.0
void setup() {
Serial.begin(115200);
// Initialize I2C with explicit ESP32 pins and 400kHz fast mode
Wire.begin(21, 22, 400000);
}
void loop() {
float angleDeg = readAS5600Angle();
Serial.printf("Angle: %.2f deg\n", angleDeg);
delay(20); // 50Hz polling rate
}
float readAS5600Angle() {
Wire.beginTransmission(AS5600_ADDRESS);
Wire.write(ANGLE_REG_MSB);
Wire.endTransmission(false); // Repeated start condition
Wire.requestFrom(AS5600_ADDRESS, 2);
if (Wire.available() >= 2) {
uint8_t msb = Wire.read();
uint8_t lsb = Wire.read();
// Combine bytes and mask to 12 bits
uint16_t rawAngle = ((msb << 8) | lsb) & 0x0FFF;
// Raw-to-unit math
return (rawAngle / STEPS_PER_REV) * 360.0;
}
return -1.0; // Error state
}
Calibration Note: The AS5600 does not require software scaling for linearity; the internal DSP handles it. However, you must calibrate the mechanical zero-offset. Mount your magnet, read the raw angle at your desired mechanical "zero" point, and write that value to the ZPOS (Zero Position) registers (0x01 and 0x02) if you want the chip to handle the offset internally.
Defeating EMI and Mechanical Interference
Magnetic sensors are inherently susceptible to environmental noise. If your ESP32 serial monitor shows angle jitter exceeding ±0.2°, you are likely experiencing one of three failure modes. Address them in this order:
- Stray Magnetic Fields (EMI): Stepper motors and BLDC stators generate massive alternating magnetic fields. If the AS5600 is mounted directly against a motor casing, the stator flux will distort the rotor's field. Fix: Maintain at least a 10mm physical distance from the motor stator, or insert a mu-metal shielding plate between the motor and the sensor.
- Air Gap Variance: The AS5600 requires the diametric magnet to be positioned between 1.0mm and 2.5mm from the IC surface. If the gap exceeds 2.5mm, the magnetic flux drops below the 30mT minimum threshold, causing the internal AGC to max out and the output to quantize or drop out. If the gap is <1.0mm, the field saturates the Hall array. Fix: Use a precision 3D-printed spacer or a machined aluminum collar to lock the air gap at exactly 2.0mm.
- Incorrect Magnet Type: A standard axially magnetized disc (like a fridge magnet or standard neodymium button) will not work. The field lines must run horizontally across the face of the IC. Fix: You must source a diametrically magnetized cylinder (e.g., a 6x2.5mm NdFeB N35 grade magnet) where the North and South poles are on opposite sides of the cylinder's diameter, not the flat faces.
For deeper integration into ESP-IDF environments, refer to the official Espressif I2C API documentation to implement interrupt-driven reads using the AS5600's push-pull output pin, rather than blocking I2C polling loops. For a broader understanding of the underlying semiconductor physics, review the Hall Effect sensor principles on All About Circuits.






