做机械臂或者云台,最憋屈的一件事是关节"不知道自己在哪"。电位器有磨损、量程不够一圈,普通增量编码器断电就丢位置。AS5600这颗磁编码器是个很干净的答案:非接触式霍尔方案,I2C直接读出0到360度的绝对角度,断电也不丢。这篇把它接到ESP32上,从引脚、接线、寄存器代码到关节上装磁铁的校准,一次讲完。

先认识这颗芯片:12位角度,地址0x36
AS5600是ams出品的接触式磁角度传感器,说非接触更准确——转轴上贴一颗径向充磁的小磁铁,芯片内的霍尔阵列感应磁场方向,内部走AFE、12位ADC、CORDIC反正切这一条链路,算出磁铁相对芯片的绝对角度,I2C接口直出。量程是完整一圈,12位也就是0到4095对应0到360度,一格约0.088度。芯片内部还有AGC自动增益,磁铁装得稍偏一点它会自动补信号强度。

它还能当输出用:OUT脚可以输出模拟电压或PWM角度信号,不跑I2C也能读,只是精度和灵活性不如直接读寄存器。我们这篇走I2C,这才是它的主力用法。
两套引脚:裸芯片SOIC-8和模块丝印
裸芯片是SOIC-8封装:1脚VDD5V、2脚VDD3V3、3脚OUT、4脚GND、5脚PGO、6脚SDA、7脚SCL、8脚DIR。两个电源脚是5V和3.3V两路供电入口,用其一即可;PGO是编程输入,正常使用悬空。

买模块的话丝印更直白:VCC、OUT、GND一组,DIR、SCL、SDA、GPO一组。GPO对应芯片的PGO。模块供电范围3.0到5.5V,I2C上拉电阻板载,接3.3V供电时总线电平正好和ESP32一致,不用另接上拉。
接线:四根线搞定,DIR别悬空
ESP32 DevKit默认I2C是GPIO21(SDA)和GPIO22(SCL),AS5600直接挂上去:
| AS5600模块 | ESP32 DevKit | 说明 |
|---|---|---|
| VCC | 3V3 | 模块支持3.0-5.5V,取3.3V让总线电平一致 |
| GND | GND | 必须共地 |
| SDA | GPIO21 | 默认I2C数据线 |
| SCL | GPIO22 | 默认I2C时钟线 |
| DIR | GND | 固定计数方向:接地则角度顺时针递增 |
| OUT / GPO | 悬空 | I2C读取用不到 |
DIR这个脚要专门提一句:接GND角度顺时针增加,接VDD则逆时针,悬空读数会飘。很多"读数乱跳"的求助帖,最后查出来是DIR悬空或者没共地。
顺带提醒ESP32这边的坑:GPIO6到11接了内部Flash别碰;GPIO34到39只能输入且没有上下拉,不适合做I2C;ESP32是3.3V系统,IO不耐5V,别图省事拿5V给模块供电又直连。另外如果你的程序要开Wi-Fi,ADC2那组引脚会和Wi-Fi冲突,但I2C的21/22不受影响,放心用。
代码:读0x0C寄存器,两字节拼出角度
AS5600的I2C地址固定0x36。角度寄存器有两个:0x0C是RAW ANGLE(原始角度,不带你烧录的零位偏移),0x0E是ANGLE(带烧录零位)。上手先用0x0C。下面的示例代码取自器件商Orwintech的AS5600技术页,机械搬运,只有头文件按平台习惯写成了引号包含:
#include "Wire.h"
#define I2C_SDA 21
#define I2C_SCL 22
const uint8_t AS5600_ADDRESS = 0x36;
const uint8_t RAW_ANGLE_REG = 0x0C;
void setup() {
Serial.begin(115200);
Wire.begin(I2C_SDA, I2C_SCL, 400000);
}
void loop() {
Wire.beginTransmission(AS5600_ADDRESS);
Wire.write(RAW_ANGLE_REG);
if (Wire.endTransmission(false) == 0) {
if (Wire.requestFrom(
AS5600_ADDRESS, (uint8_t)2) == 2) {
uint16_t highByte = Wire.read();
uint16_t lowByte = Wire.read();
uint16_t rawAngle =
((highByte << 8) | lowByte) & 0x0FFF;
float degrees = rawAngle * 360.0 / 4096.0;
Serial.printf(
"ESP32 Read -> Angle: %.2f degrees\n",
degrees
);
}
}
delay(50);
}逻辑不复杂:先写寄存器地址0x0C,repeated start后读两字节,高字节左移8位或上低字节,再把12位以外的位掩掉,乘360除4096就是度数。示例把I2C总线跑在400kHz,如果线长或者上拉偏弱通信不稳,把400000改成100000降速即可。烧进去打开串口监视器,115200波特率,转动磁铁就能看到角度跟着走。
装到关节上:磁铁和校准才是真正的功夫
电气部分很简单,机械安装才是AS5600好不好用的分水岭。要点三条:磁铁必须是径向充磁的圆片磁铁(常见6mm钕磁铁);磁铁圆心对准芯片中心;磁铁表面到芯片表面的气隙控制在0.5到3mm之间。贴偏了某个角度区间读数会跳,离太远信号弱,太近可能饱和。
装到机械臂关节或舵机输出轴上,还有一步归零校准:AS5600的0度方向和你机械结构的零位几乎肯定不重合,程序里把关节转到你定义的零位,读一次当前值存成偏移量,之后每次读数减去偏移就是关节真实角度。方向不一致就用DIR脚翻转,不用改代码。
如果你的关节只需要一段角度(比如云台0到270度),还可以往ZPOS、MPOS寄存器烧录自定义量程,把不用的角度段剔除,有效分辨率更集中。这属于进阶玩法,上手阶段先跑通0x0C再说。
很多玩家拿这套组合做"伪闭环舵机":普通舵机拆限位改连续转,AS5600读输出轴真实角度,PID闭环纠正,花几块钱就把开环舵机升级成能精确定位的360度关节。对桌面机械臂和云台来说,这大概是性价比最高的角度反馈方案了。烧录环节有报错的,先查端口和驱动,再回来查I2C地址扫不扫得到0x36,顺序别乱。


照着接了GPIO21和22,串口里角度跟着转,一次点亮,爽
正好在给云台做闭环,之前用电位器死区大得没法看,看了这篇想把AS5600换成磁编码器方案。DIR接地的那个坑我踩过,悬空的时候读数完全是随机的,接了地才稳定。
气隙0.5到3mm这个提醒很实在,上回磁铁离芯片远了直接扫不到地址。
问一下ZPOS和MPOS烧录是要走OTP一次性的吗,写错了还能改不
0.088度一格,这精度对桌面上摆弄小机械臂来说很够了