Arduino通过Wire库读取AS5600编码器数据
- 📌AS5600资料:
https://pan.baidu.com/s/15UMUH5_ppb2FTju7AJgFyw
- 🌿磁场Bz和典型的间隙
典型的间隙在0.5 mm到3 mm之间,这取决于所选的磁铁。一个更大和更强的磁铁允许一个更大的间隙。使用AGC值作为导轨,通过调整磁体与AS5600之间的距离,使AGC值在其范围的中心,可以找到最佳的间隙。当使用直径为6mm的磁铁时,参考磁铁的旋转轴从包装中心的最大允许位移为0.25 mm。
- 🔖AS5600输出精度:12位 DAC 输出分辨率
📘 硬件电路部分
- 🌿在3.3V供电情况下,原理图部分:
- 🔰5.0V 和 3.3V 电源供应电路选择参考:
- ✨有关I2C总线是否需要接外部上拉电阻问题,如果没有接外部上拉电阻,那么通过硬件I2C时,需要配置开启内部上拉电阻,才可以检测到设备。如果使用软件I2C,将通讯引脚配置为推挽输出模式,外部不接上拉电阻情况下,实测也是可以的。在使用RP2040测试过程中,发现不接上拉电阻,也可以检测到设备。推荐还是接上上拉电阻。
- 🌿PCB电路布线:芯片底部范围不要走线,也不要铺铜,让芯片光秃秃的趴在中间,把引脚线路一出一定的范围。
⛳📒 I2C引脚说明
- 🌿如果使用的是ESP32,I2C默认引脚:SDA:21 ,SCL:22
- 🌿如果使用的是ESP8266,I2C默认引脚:SDA:4 ,SCL:5
- 🌿如果使用的是Ateml328p,,I2C默认引脚:SDA:A4 ,SCL:A5
- 📑引脚任意指定:
Wire.setSDA(8);
Wire.setSCL(9);
或者
Wire.setPins(int sda, int scl);
以及
Wire.begin(sda,scl);
- 👉针对不同开发板,wire库接口函数存在差异,以上提供参考的接口函数可能不通用。
📙测试代码
- 🔖首先扫描I2C设备,在loop循环中读取。
#include "Wire.h"
#define Address_IN 0x0c
word readTwoBytesTogether(byte addr_in );
void setup() {
Serial.begin(115200);
Wire.begin();
byte error, address;
int nDevices = 0;
delay(3000);
Serial.println("Scanning for I2C devices ...");
for(address = 0x01; address < 0x7f; address++){
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0){
Serial.printf("I2C device found at address 0x%02X\n", address);
nDevices++;
} else if(error != 2){
Serial.printf("Error %d at address 0x%02X\n", error, address);
}
}
if (nDevices == 0){
Serial.println("No I2C devices found");
}
}
void loop() {
int Raw_num = readTwoBytesTogether(Address_IN);//读取当前值
// 处理角度数据...
float Real_angle = (Raw_num * 360.0)/4096.0;//换算成角度
Serial.println(Real_angle,2);// 打印保留2位小数
delay(1000); // 延迟一段时间再读取下一次数据
}
word readTwoBytesTogether(byte addr_in )
{
Wire.beginTransmission(0x36); // AS5600的I2C地址为0x36
Wire.write(0x0C); //发送要读取的寄存器地址,此处为0x0C
Wire.endTransmission(false); // 发送重复启动信号,保持总线连接
//Wire.endTransmission();
Wire.requestFrom((int)0x36, (int)2); // 从AS5600读取2个字节的数据
while (Wire.available() < 2)// 等待数据接收完毕
{
} ;
int highByte = Wire.read(); // 读取高字节
int lowByte = Wire.read(); // 读取低字节
return (highByte << 8) | lowByte; // 将高字节和低字节组合成16位的角度数据
}
- 📜测试数据串口输出:
📗使用第三方库驱动AS5600
- 🥕AS5600驱动库:
https://github.com/RobTillaart/AS5600
//
// FILE: AS5600_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/AS5600
//
// Examples may use AS5600 or AS5600L devices.
// Check if your sensor matches the one used in the example.
// Optionally adjust the code.
#include "AS5600.h"
//AS5600L as5600; // use default Wire
AS5600 as5600; // use default Wire
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("AS5600_LIB_VERSION: ");
Serial.println(AS5600_LIB_VERSION);
Wire.setSDA(14);
Wire.setSCL(15);
Wire.begin();
as5600.begin(5); // set direction pin.AS5600 DIR引脚
as5600.setDirection(AS5600_CLOCK_WISE); // default, just be explicit.
int b = as5600.isConnected();
Serial.print("Connect: ");
Serial.println(b);
delay(1000);
}
void loop()
{
// Serial.print(millis());
// Serial.print("\t");
Serial.print(as5600.readAngle());
Serial.print("\t");
Serial.println(as5600.rawAngle());
// Serial.println(as5600.rawAngle() * AS5600_RAW_TO_DEGREES);
delay(1000);
}
// -- END OF FILE --
⛳注意事项:
- ✨有些硬件I2C在配置开漏输出模式下(STM32F103),引脚不能同时开启内部上拉,有些硬件是支持在开启开漏输出模式下,引脚同时可以开启内部上拉电阻,这一点需要注意。
- STM32G431:
- STM32F103在STM32CubeMX配置界面,I2C外设引脚选项里面没有上下拉选项:
配置完后,需要在HAL_I2C_MspInit
函数中手动添加:
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;//stm32f103,补充,插入这一行
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
- ✨软件I2C方式没有I2C没有上拉电阻的情况下,需要将IO口配置为推挽输出模式才行,没有上拉情况下,开漏模式可能访问不到。