Arduino通过Wire库读取AS5600编码器数据

本文介绍如何使用Arduino及Wire库读取AS5600磁性旋转位置传感器的数据,包括硬件电路设计要点、I2C配置及上拉电阻的选择,并提供了测试代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Arduino通过Wire库读取AS5600编码器数据


  • 📌AS5600资料:https://pan.baidu.com/s/15UMUH5_ppb2FTju7AJgFyw
  • ✨在实际测试中,测试AS5600除了使用径向磁铁之外,球型的或者正四方体的强磁铁,也是可以进行测量。测试高度的话,从板子(芯片引脚底部)到磁铁底部15毫米内,都可以检测到角度。除去芯片从板子底部到顶部的高度2,保守检测空间高度可以达到12毫米。测试使用的是巴克球磁力球,5毫米直径的球体状和正四方体状的强磁体。
  • 🌿磁场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口配置为推挽输出模式才行,没有上拉情况下,开漏模式可能访问不到。
### 如何读取AS5600编码器 为了实现对AS5600编码器数据读取,可以采用I2C通信协议。该传感器支持通过I2C接口与微控制器进行交互,从而能够方便地获取角度位置和其他相关信息。 下面是一个简单的Arduino代码示例,展示了如何初始化并读取来自AS5600的角度值: ```cpp #include <Wire.h> #define AS5600_ADDRESS 0x36 // 默认地址为0x36 (7 bit) void setup() { Serial.begin(9600); Wire.begin(); // 初始化 I2C 总线 } uint16_t readRegister(uint8_t reg) { uint16_t value; Wire.beginTransmission(AS5600_ADDRESS); Wire.write(reg); // 发送寄存器地址 Wire.endTransmission(); Wire.requestFrom((int)AS5600_ADDRESS, 2); // 请求两个字节的数据 if(Wire.available()) { uint8_t highByte = Wire.read(); // 高位先传输 uint8_t lowByte = Wire.read(); // 接收低位 value = ((highByte & 0xFF) << 8) | (lowByte & 0xFF); } return value; } void loop() { uint16_t angleRaw = readRegister(0x0E); // 角度寄存器位于0x0E处 float angleDeg = map(angleRaw, 0, 4096, 0, 360); Serial.print("Angle: "); Serial.println(angleDeg); delay(500); // 延迟半秒以便观察变化 } ``` 此代码片段定义了一个`readRegister()`函数用来从指定的寄存器中读取数据,并将其应用于读取角度测量值。注意这里假设默认硬件连接方式下的设备地址是固定的;如果实际使用的模块有不同的配置,则可能需要调整相应的参数设置[^1]。 对于更复杂的项目来说,建议考虑使用官方提供的文件来简化编程工作量以及提高稳定性。此外,考虑到长时间运行可能导致数值溢出的情况,应该定期重置计数或将大范围内的增量传递给主机处理以防止潜在的问题发生[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值