回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【花雕学编程】Arduino动手做(225)---AS5600磁编码器 磁感应角度测量传感器 12bit高精度模块 简单

头像 驴友花雕 2024.08.20 718 0

37款传感器与执行器的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手尝试系列实验,不管成功(程序走通)与否,都会记录下来———小小的进步或是搞不掂的问题,希望能够抛砖引玉。

 

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百二十五:AS5600磁编码器 磁感应角度测量传感器 12bit高精度模块

 

00 (2).jpg

00 (1).jpg
00.jpg

核心芯片:AS5600 
是一款易于编程的磁性旋转位置传感器,具有高分辨率 12 位模拟或 PWM 输出。这种非接触式系统测量径向磁化同轴磁体的绝对角度。这款 AS5600 专为非接触式电位计应用而设计,其坚固的设计消除了任何均匀的外部杂散磁场的影响。行业标准的I²C接口支持用户对非易失性参数进行简单编程,无需专门的编程器。此外,该器件还实现了在所谓的“3线模式”中轻松进行启动和停止位置编程,无需编程器或数字接口。输出的默认范围是 0 到 360 度。AS5600 可以通过编程零角度(开始位置)和最大角度(停止位置)来应用于较小的范围。AS5600 还配备了智能低功耗模式功能,可自动降低功耗。

 

0-1.jpg

【花雕学编程】Arduino动手做(224)---AS5600磁编码传感器

AS5600框架与实物图

 

0--.jpg
02 (1).jpg
02 (2).jpg

该芯片包含四个呈圆圈排列的霍尔传感器。 内部霍尔元件放置在封装的中心,位于半径为 1 mm 的圆圈上。

 

0----.jpg

典型的径向磁铁感应气隙在 0.5 mm 到 3 mm 之间,这取决于所选的磁体。更大、更强的磁铁允许更大的气隙。以 AGC 值为指导,通过调整磁体和 AS5600 之间的距离,使 AGC 值位于其范围的中心,可以找到最佳气隙。当使用直径为 0.25mm 的磁体时,参考磁体的旋转轴从封装中心的最大允许位移为 6 mm。

 

0-1-.jpg

AS5600 允许使用 DIR 引脚控制磁铁旋转方向。如果 DIR 连接到 GND (DIR = 0),则从顶部顺时针旋转将产生计算角度的增量。如果 DIR 引脚连接到 VDD (DIR = 1),则计算的角度将逆时针旋转。

 

0-2.jpg

AS5600磁编码器 磁感应角度测量传感器 12bit高精度模块

 

0.jpg

非接触式磁感应角度测量模块。
精度高,多种输出方式:IIC,PWM和电压。
采用优质材料制成的高品质AS5600模块坚固耐用,不易损坏。
广泛支持,完美匹配。
电路板尺寸:23.3 × 22.8 毫米
套件重量:2.6 克
包括一个 AS5600 磁编码器模块、一个 7 针针头和一块小磁铁。

 

05.jpg

0-0-.jpg

电气参数: 
VCC:3.3V
GND:电源地
Out:PWM /模拟电压输出
DIR:旋转方向(接地=顺时针值增加;接 VCC=顺时针值减小)
SCL:IIC 通信时钟线
SDA:IIC 数据通信线
GPO:模式选择(内部上拉接地=编程模式 B)

 

0-9.jpg

相关的径向磁铁也收集了不少

 

0-8 (1).jpg
0-8 (2).jpg

为做好这个系列实验,特意打印了实验架子

 

0-80 (3).jpg

0-80 (1).jpg
0-80 (2).jpg
0-80 (4).jpg

Arduino实验接线示意图

 

04.jpg
04-.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之一:从AS5600读取角度值

实验开源代码

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之一:从AS5600读取角度值
*/

#include <Wire.h>
#define AS5600_I2C_ADDRESS 0x36

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println("AS5600准备就绪!开始测量");
}

void loop() {
  //向AS5600请求2字节的数据
  Wire.beginTransmission(AS5600_I2C_ADDRESS);
  //角度值的注册地址
  Wire.write(0x0E);
  Wire.endTransmission();
  Wire.requestFrom(AS5600_I2C_ADDRESS, 2);

  //从AS5600读取角度值
  int angleValue = (Wire.read() << 8) | Wire.read();
  //将寄存器值转换为度数
  float angle = (float)angleValue * 0.08789;

  //打印角度到串行监视器
  Serial.print("角度:");
  Serial.print(angle);
  Serial.println("度");

  delay(2000);
}

实验串口返回情况

 

08.jpg

这个项目实验一演示了如何通过I2C通信协议读取AS5600磁编码器的角度值。在setup()函数中,初始化了串口通信和Wire库(用于I2C通信)。在loop()函数中,通过向AS5600发送请求,并读取2个字节的数据。然后,将读取的数据转换为角度值,并打印到串口监视器中。通过调整延迟时间,可以控制采样频率。

 

 

实验场景图

 

10.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之二:将AS5600角度传感器集成到电机项目中

实验开源代码

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之二:将AS5600角度传感器集成到电机项目中
*/

#include "AS5600.h"
#include "Wire.h"

AS5600 as5600;  //默认情况下使用Wire

//不同变量的声明

int positionZero;
const int buttonPin = 2;  //按钮的引脚号
int buttonState = 0;      //用于读取按钮状态的变量


void setup() {
  //初始化串行端口并设置串行通信的波特率
  Serial.begin(115200);

  Wire.begin();

  //使用内部上拉将按钮初始化为输入
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.println("文件路径信息:");

  Serial.println(__FILE__);
  Serial.println(" ");


  //显示AS5600库的版本
  Serial.print("AS5600库的版本: ");
  Serial.println(AS5600_LIB_VERSION);


  as5600.begin(4);                         //这条线初始化AS5600传感器
  as5600.setDirection(AS5600_CLOCK_WISE);  //确定传感器的旋转方向

  //检查连接
  int b = as5600.isConnected();
  Serial.print("已连接: ");
  Serial.println(b);
  delay(5000);

  //设置零位置
  positionZero = as5600.rawAngle();
}

void loop() {
  //读取按钮状态
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW) {
    positionZero = as5600.rawAngle();
  }

  //显示相对于零点和定义方向的角度值
  Serial.print("点角值:");
  Serial.print("\t");

  //该代码行从AS5600传感器读取调整后的角度并将其显示在监视器上,
  //这可能有助于跟踪或调试。
  Serial.println(as5600.readAngle());


  //显示零的值
  Serial.print("零->位置的总值");
  //命令serial.print(“\t”);在代码中,Arduino在串行端口上发送一个制表符(由\t表示)
  Serial.print("\t");
  Serial.println(positionZero);


  //使用AS5600传感器测量角位置
  //并以度为单位显示角度值
  conversion_de_angle();

  Serial.println("  ");
  Serial.println("  ");
  delay(3000);
}

conversion_de_angle函数:

 

代码
void conversion_de_angle() {

  //这行代码允许通过减去参考位置来计算相对角度
  //测量的原始角度,这提供了更显著的角度测量
  //在预定义的参考位置。
  int angleBrut = as5600.rawAngle() - positionZero;  //减去零位置
  if (angleBrut < 0) angleBrut += 4096;  //管理溢出
  float angleBrutEnDegres = angleBrut * 0.088;  //转换为度
  Serial.print("读取角度值为: ");
  Serial.println(angleBrutEnDegres);
}

实验串口返回情况

 

11.jpg
12.jpg

适配42步进电机,用3D打印了二种AS5600磁编码器模块的安装部件

 

13.jpg

14.jpg

在42步进电机底部,用胶水黏住一个径向磁铁

 

15.jpg
16.jpg

效果是这样的

 

17.jpg
18.jpg

可以开始做实验了

 

19.jpg
20.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之三:转动42步进电机主轴从AS5600读取实时角度值

实验开源代码

 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之三:转动42步进电机主轴从AS5600读取实时角度值
*/

#include <Wire.h>
#define AS5600_I2C_ADDRESS 0x36

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Serial.println("42步进电机准备就绪!AS5600开始测量角度");
}

void loop() {
  //向AS5600请求2字节的数据
  Wire.beginTransmission(AS5600_I2C_ADDRESS);
  //角度值的注册地址
  Wire.write(0x0E);
  Wire.endTransmission();
  Wire.requestFrom(AS5600_I2C_ADDRESS, 2);

  //从AS5600读取角度值
  int angleValue = (Wire.read() << 8) | Wire.read();
  //将寄存器值转换为度数
  float angle = (float)angleValue * 0.08789;

  //打印角度到串行监视器
  Serial.print("角度=");
  Serial.print(angle);
  Serial.println("度");

  delay(2000);
}

实验串口返回情况

 

21.jpg

实验场景图

 

22.jpg

 搜索安装SimpleFOC库
 1、打开 https://github.com/
 2、搜索:SimpleFOC
 3、下载:https://github.com/simplefoc/Arduino-FOC-drivers
 4、安装:SimpleFOC库

 

24.jpg
25.jpg
26.jpg

 

 

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之四:通过循环扫描I2C总线上的设备地址,找到连接的AS5600设备

实验开源代码
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之四:通过循环扫描I2C总线上的设备地址,找到连接的AS5600设备
*/

#include <SimpleFOC.h>
#include <Wire.h>

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  for (int i = 0; i < 127; i++) {
    Wire.beginTransmission(i);
    if (Wire.endTransmission() == 0) {
      Serial.print("AS5600的IIC设备地址为");
      Serial.print("0x");
      Serial.println(i, HEX);
    }
  }
}

void loop() {}

实验串口返回情况

 

23.jpg

要点解读

库的正确安装:确保SimpleFOC库和Wire库已正确安装。包含路径:确保代码中包含了正确的库路径。I2C初始化:正确初始化I2C通信,设置SDA和SCL引脚以及通信速率。设备连接:确保I2C设备正确连接到Arduino板。调试通信:通过扫描I2C设备地址,调试和验证I2C通信是否正常。

 

 

27.jpg
28.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十四:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之五:手动旋转步进电机轴,实时读取AS5600原始数据

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之五:手动旋转步进电机轴,实时读取AS5600原始数据
*/

#include <SimpleFOC.h>
#include <Wire.h>

uint16_t readValue = 0;
byte readArray[2];

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);
  Serial.println("42步进电机准备就绪!手动旋转电机轴,准备读取数据");
}

void loop() {
  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  for (byte i = 0; i < 2; i++) {
    readArray[i] = Wire.read();
  }

  // 根据传感器架构组合LSB和MSB寄存器的使用位
  readValue = readArray[0] * 256 + readArray[1];
  Serial.print("实时读取AS5600原始数据为");
  Serial.println(readValue);
  delay(1000);
}

实验串口返回情况

 

29.jpg

调到了0位置

 

30.jpg

方案之二,主要删掉了setup函数中的begintransmission()等函数。

这个函数主要用于开启传输,但是requestFrom函数本身就会向从机发送数据请求信号。

 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之六:无begintransmission()函数,简化读取AS5600原始数据

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之六:无begintransmission()函数,简化读取AS5600原始数据
*/

#include <SimpleFOC.h>
#include <Wire.h>

uint16_t readValue = 0;
byte readArray[2];

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("完成初始化I2C,手动旋转电机轴,开始读取数据");
}

void loop() {
  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  for (byte i = 0; i < 2; i++) {
    readArray[i] = Wire.read();
  }

  // 根据传感器架构组合LSB和MSB寄存器的使用位
  readValue = readArray[0] * 256 + readArray[1];
  Serial.print("方案之二读取原始数据=");
  Serial.println(readValue);
  delay(1000);
}

实验串口返回情况

 

31.jpg

要点解读
1、库的正确使用:确保使用正确的库和函数。Arduino Uno的Wire库不支持传入多个参数来初始化I2C。
2、I2C初始化:使用Wire.begin()初始化I2C总线。
3、数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
4、数据读取:使用Wire.read()获取传感器数据。
5、数据处理:将读取的MSB和LSB数据组合成一个16位的值,并通过串口输出,便于调试和验证。

 

 

 

 

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之七:对读取到的AS5600原始数据进行低通滤波

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之七:对读取到的AS5600原始数据进行低通滤波
*/

#include <Wire.h>
#include <SimpleFOC.h>

LowPassFilter as5600_filter(0.01); // 使用SimpleFOC库中的低通滤波器

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("完成初始化I2C,准备就绪,对数据进行低通滤波");
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float filteredValue = as5600_filter(readValue);
    Serial.print("低通滤波后的数据=");
    Serial.println(filteredValue);
  } else {
    Serial.println("读取数据时出错!");
  }
  delay(1000);
}

实验串口返回情况

 

32.jpg

要点解读
避免类重定义:确保自定义类名称与库中的类名称不冲突。
使用库中的类:如果库中已有合适的类,可以直接使用,避免重复定义。
I2C初始化:使用Wire.begin()初始化I2C总线。
数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
数据处理:将读取的MSB和LSB数据组合成一个16位的值,并通过低通滤波器进行处理,最后通过串口输出,便于调试和验证。
 

一阶滤波算法的原理 
一阶滤波,又叫一阶惯性滤波,或一阶低通滤波。是使用软件编程实现普通硬件RC低通滤波器的功能。

一阶低通滤波的算法公式为:

                        Y(n)=αX(n) + (1-α)Y(n-1)

 式中:α=滤波系数;X(n)=本次采样值;Y(n-1)=上次滤波输出值;Y(n)=本次滤波输出值。

一阶低通滤波法采用本次采样值与上次滤波输出值进行加权,得到有效滤波值,使得输出对输入有反馈作用。

滤波系数越大,则更快达到目标开度,灵敏度越高,但曲线平滑性较差,滤波结果越不稳定;同样的滤波系数越小,则更慢达到目标开度,但曲线更加平滑,且稳定,但灵敏度较低。

因此在实际标定过程中,我们需要根据实际情况,平衡灵敏度和稳定性,来确定最终的滤波系数。

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之八:使用Baize_FOC代码的示例,确保正确读取AS5600传感器的数据,
 并进行低通滤波处理,是一个用于无刷电机驱动的开源项目

实验开源代码

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之八:使用Baize_FOC代码的示例,确保正确读取AS5600传感器的数据,
  并进行低通滤波处理,是一个用于无刷电机驱动的开源项目
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("已完成初始化I2C,Baize_FOC准备就绪");
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float filteredValue = as5600_filter(readValue);
    Serial.print("AS5600原始数据=");
    Serial.println(filteredValue);
  } else {
    Serial.println("Error reading data");
  }
  delay(1000);
}

实验串口返回情况

 

33.jpg

要点解读
I2C初始化:使用Wire.begin()初始化I2C总线。
数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
数据读取:使用Wire.read()获取传感器数据。
数据处理:将读取的MSB和LSB数据组合成一个16位的值,并通过低通滤波器进行处理。
串口输出:将处理后的数据通过串口输出,便于调试和验证。
 

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之九:使用SimpleFOC库中的低通滤波器,通过串口绘图监视器
 查看手动电机轴形成的数据波形

实验开源代码

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之九:使用SimpleFOC库中的低通滤波器,通过串口绘图监视器
  查看手动电机轴形成的数据波形
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float filteredValue = as5600_filter(readValue);
    Serial.println(filteredValue); // 输出到串口监视器
  } else {
    Serial.println("Error reading data");
  }
  delay(100);
}

实验串口返回情况

 

34.jpg

要点解读
I2C初始化:使用Wire.begin()初始化I2C总线。
数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
数据读取:使用Wire.read()获取传感器数据。
数据处理:将读取的MSB和LSB数据组合成一个16位的值,并通过低通滤波器进行处理。
串口输出:将处理后的数据通过串口输出,便于在串口绘图监视器中查看。

 

使用串口绘图监视器
打开Arduino IDE。
选择工具菜单中的“串口监视器”。
在串口监视器窗口中,选择右下角的“绘图”模式。
你将看到传感器数据的实时图形显示。

 

35.jpg
36.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十:将原始数据转换为度数并在串口绘图监视器中显示

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十:将原始数据转换为度数并在串口绘图监视器中显示
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float angle = (readValue / 4096.0) * 360.0; // 将原始数据转换为度数
    float filteredAngle = as5600_filter(angle);
    Serial.println(filteredAngle); // 输出到串口监视器
  } else {
    Serial.println("Error reading data");
  }
  delay(10);
}

实验串口返回情况

 

37.jpg

要将AS5600传感器的原始数据转换为度数,可以使用以下公式:

角度(度)=(原始数据 / 4096​)×360

AS5600传感器的输出范围是0到4095,对应0到360度。

要点解读
1、数据转换:将原始数据除以4096,再乘以360,得到角度值。
2、低通滤波:对转换后的角度值进行低通滤波处理。
3、串口输出:将处理后的角度值通过串口输出,便于在串口绘图监视器中查看。

使用串口绘图监视器
1、打开Arduino IDE。
2、选择工具菜单中的“串口监视器”。
3、在串口监视器窗口中,选择右下角的“绘图”模式。
4、你将看到传感器数据的实时图形显示。

 

38.jpg
39.jpg

 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十一:动态测试步进电机旋转时角度变化的波形,并在串口绘图监视器中显示

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十一:动态测试步进电机旋转时角度变化的波形,并在串口绘图监视器中显示
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float angle = (readValue / 4096.0) * 360.0; // 将原始数据转换为度数
    float filteredAngle = as5600_filter(angle);
    Serial.println(filteredAngle); // 输出到串口监视器
  } else {
    Serial.println("Error reading data");
  }
  delay(20);
}

要点解读
I2C初始化:使用Wire.begin()初始化I2C总线。
数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
数据读取:使用Wire.read()获取传感器数据。
数据转换:将原始数据除以4096,再乘以360,得到角度值。
低通滤波:对转换后的角度值进行低通滤波处理。
串口输出:将处理后的角度值通过串口输出,便于在串口绘图监视器中查看。

使用串口绘图监视器
打开Arduino IDE。
选择工具菜单中的“串口监视器”。
在串口监视器窗口中,选择右下角的“绘图”模式。
你将看到传感器数据的实时图形显示。

 

40.jpg

实验场景图  

 

41.jpg

 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十二:使用AS5600传感器读取角度数据,并计算步进电机的实时转速

实验开源代码
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十二:使用AS5600传感器读取角度数据,并计算步进电机的实时转速
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

unsigned long lastTime = 0;
float lastAngle = 0;
float rpm = 0;

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float angle = (readValue / 4096.0) * 360.0; // 将原始数据转换为度数
    float filteredAngle = as5600_filter(angle);

    // 计算转速
    unsigned long currentTime = millis();
    float deltaTime = (currentTime - lastTime) / 1000.0; // 转换为秒
    float deltaAngle = filteredAngle - lastAngle;
    if (deltaAngle < 0) deltaAngle += 360.0; // 处理角度回绕
    rpm = (deltaAngle / 360.0) / deltaTime * 60.0; // 计算RPM

    // 更新上次的时间和角度
    lastTime = currentTime;
    lastAngle = filteredAngle;

    // 输出到串口监视器
    Serial.println(rpm);
  } else {
    Serial.println("Error reading data");
  }
  delay(20);
}

要测量步进电机的实时转速,可以通过计算单位时间内的步数来实现。以上是一个示例代码,使用AS5600传感器读取角度数据,并计算步进电机的实时转速。这个代码会将实时转速显示在Arduino IDE的串口绘图监视器中。

要点解读
数据转换:将原始数据除以4096,再乘以360,得到角度值。
低通滤波:对转换后的角度值进行低通滤波处理。
转速计算:通过计算单位时间内的角度变化量来计算转速(RPM)。
串口输出:将实时转速通过串口输出,便于在串口绘图监视器中查看。

使用串口绘图监视器
打开Arduino IDE。
选择工具菜单中的“串口监视器”。
在串口监视器窗口中,选择右下角的“绘图”模式。
你将看到实时转速的图形显示。

 

 

42.jpg
43.jpg
44.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十三:测量步进电机的实时位置并在Arduino IDE的串口绘图监视器中显示

实验开源代码
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十三:测量步进电机的实时位置并在Arduino IDE的串口绘图监视器中显示
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
}

void loop() {
  uint16_t readValue = 0;
  byte readArray[2];

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36);
  Wire.write(0x0C);
  Wire.endTransmission(false);

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2);
  if (Wire.available() == 2) {
    readArray[0] = Wire.read();
    readArray[1] = Wire.read();
    readValue = (readArray[0] << 8) | readArray[1];
    float angle = (readValue / 4096.0) * 360.0; // 将原始数据转换为度数
    float filteredAngle = as5600_filter(angle);
    Serial.println(filteredAngle); // 输出到串口监视器
  } else {
    Serial.println("Error reading data");
  }
  delay(50);
}

实验串口返回情况

 

45.jpg

为了测量步进电机的实时位置并在Arduino IDE的串口绘图监视器中显示,可以使用AS5600传感器读取角度数据,并将其转换为度数。

要点解读
1、I2C初始化:使用Wire.begin()初始化I2C总线。
2、数据请求:使用Wire.requestFrom()直接向从机发送数据请求信号。
3、数据读取:使用Wire.read()获取传感器数据。
4、数据转换:将原始数据除以4096,再乘以360,得到角度值。
5、低通滤波:对转换后的角度值进行低通滤波处理。
6、串口输出:将处理后的角度值通过串口输出,便于在串口绘图监视器中查看。

使用串口绘图监视器
1、打开Arduino IDE。
2、选择工具菜单中的“串口监视器”。
3、在串口监视器窗口中,选择右下角的“绘图”模式。
4、你将看到传感器数据的实时图形显示。

 

46.jpg
47.jpg
48.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十四:通过AS5600读取电机轴的实时原始数据和角度值

实验开源代码

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十四:通过AS5600读取电机轴的实时原始数据和角度值
*/

#include <Wire.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);
#define AS5600_ADDRESS 0x36
#define ANGLE_REG 0x0C

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("完成初始化I2C,准备就绪!");
}

void loop() {
  uint16_t rawAngle = readAS5600Angle();
  float angle = (rawAngle * 360.0) / 4096.0;
  Serial.print("原始输出: ");
  Serial.print(rawAngle);
  Serial.print(" - 角度: ");
  Serial.println(angle);
  delay(500);
}

uint16_t readAS5600Angle() {
  Wire.beginTransmission(AS5600_ADDRESS);
  Wire.write(ANGLE_REG);
  Wire.endTransmission();
  Wire.requestFrom(AS5600_ADDRESS, 2);
  uint16_t angle = Wire.read() << 8 | Wire.read();
  return angle;
}

实验串口返回情况

 

50.jpg

实验串口绘图器返回情况

 

51.jpg

代码的整体要点:
1、库文件导入:
#include <Wire.h>:用于I2C通信。
#include <SimpleFOC.h>:用于低通滤波。

2、定义和初始化:
LowPassFilter as5600_filter(0.01);:创建一个低通滤波器实例,用于平滑角度数据。
#define AS5600_ADDRESS 0x36:定义AS5600的I2C地址。
#define ANGLE_REG 0x0C:定义角度数据寄存器的地址。

3、设置函数:
void setup():初始化串口通信(波特率115200)和I2C通信,并打印初始化完成的消息。

4、主循环:
void loop():在主循环中,读取AS5600的原始角度数据,将其转换为角度值,并通过串口打印出来。每次循环后延迟500毫秒。

5、读取角度数据的函数:
uint16_t readAS5600Angle():这个函数负责从AS5600读取角度数据。具体步骤包括开始I2C通信、写入寄存器地址、请求数据、读取数据并返回。

这个代码的主要功能是通过I2C接口从AS5600读取原始角度数据,并将其转换为0°到360°之间的角度值,然后通过串口监视器输出。这样可以实时监控AS5600的角度数据。

 

03 (6).jpg

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十五:转动42步进电机主轴从AS5600读取实时位置和速度值

实验开源代码

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十五:转动42步进电机主轴从AS5600读取实时位置和速度值
*/

#include <Wire.h>
#include <AS5600.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);
#define AS5600_ADDRESS 0x36
#define ANGLE_REG 0x0C

AS5600 encoder;

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("完成初始化I2C,准备就绪!");
}

void loop() {
  // 读取位置
  uint16_t position = encoder.getCumulativePosition();
  float angle = fmod(position * 0.08789, 360.0);// 将位置值转换为角度(0.08789度/LSB)

  // 计算速度
  static float last_angle = 0;
  static unsigned long last_time = 0;
  unsigned long current_time = millis();
  float delta_time = (current_time - last_time) / 1000.0; // 转换为秒
  float speed = (angle - last_angle) / delta_time; // 角速度,单位为度/秒

  // 打印位置和速度
  Serial.print("角度= ");
  Serial.print(angle);
  Serial.print(" 度, 速度= ");
  Serial.print(speed);
  Serial.println(" 度/秒");

  // 更新上一次的角度和时间
  last_angle = angle;
  last_time = current_time;

  delay(500); // 延迟500毫秒
}

实验串口返回情况

52.jpg


实验串口绘图器返回情况

 

53.jpg
54.jpg
55.jpg

 【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十六:转动电机轴,从AS5600读取原始数据,并计算角度、速度和位置

实验开源代码
 

 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十六:转动电机轴,从AS5600读取原始数据,并计算角度、速度和位置
*/

#include <Wire.h>
#include <AS5600.h>
#include <SimpleFOC.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01);
#define AS5600_ADDRESS 0x36
#define ANGLE_REG 0x0C

AS5600 encoder;

void setup() {
  Serial.begin(115200);
  Wire.begin(); // 初始化I2C
  Serial.println("完成初始化I2C,准备就绪!");
}

void loop() {
  // 读取原始位置
  uint16_t rawPosition = readAS5600Angle();
  float angle = (rawPosition * 360.0) / 4096.0; // 将原始数据转换为角度

  // 计算速度
  static float last_angle = 0;
  static unsigned long last_time = 0;
  unsigned long current_time = millis();
  float delta_time = (current_time - last_time) / 1000.0; // 转换为秒
  float speed = (angle - last_angle) / delta_time; // 角速度,单位为度/秒

  // 打印原始位置、角度和速度
  Serial.print("原始位置: ");
  Serial.print(rawPosition);
  Serial.print(" - 角度: ");
  Serial.print(angle);
  Serial.print(" 度, 速度: ");
  Serial.print(speed);
  Serial.println(" 度/秒");

  // 更新上一次的角度和时间
  last_angle = angle;
  last_time = current_time;

  delay(500); // 延迟500毫秒
}

uint16_t readAS5600Angle() {
  Wire.beginTransmission(AS5600_ADDRESS);
  Wire.write(ANGLE_REG);
  Wire.endTransmission();
  Wire.requestFrom(AS5600_ADDRESS, 2);
  uint16_t angle = Wire.read() << 8 | Wire.read();
  return angle;
}

实验串口返回情况

 

56.jpg


实验串口绘图器返回情况

 

57.jpg
58.jpg
59.jpg
60.jpg
61.jpg

14.jpg
22.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十七:动态读取AS5600角度变化并设阙值LED报警

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十七:动态读取AS5600角度变化并设阙值LED报警
*/

#include <Wire.h> // 包含Wire库,用于I2C通信
#include <AS5600.h> // 包含AS5600库,用于与AS5600传感器通信
#include <SimpleFOC.h> // 包含SimpleFOC库,用于低通滤波器

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01); // 创建一个低通滤波器对象,滤波系数为0.01
#define AS5600_ADDRESS 0x36 // 定义AS5600传感器的I2C地址
#define ANGLE_REG 0x0C // 定义AS5600传感器的角度寄存器地址

AS5600 encoder; // 创建AS5600传感器对象
const int ledPin = 13; // 定义LED引脚

void setup() {
  Serial.begin(115200); // 初始化串口通信,波特率为115200
  Wire.begin(); // 初始化I2C通信
  Serial.println("完成初始化I2C,准备就绪!"); // 输出初始化完成信息
  pinMode(ledPin, OUTPUT); // 设置LED引脚为输出模式
}

void loop() {
  // 读取原始位置
  uint16_t rawPosition = readAS5600Angle(); // 调用函数读取AS5600传感器的原始角度数据
  float angle = (rawPosition * 360.0) / 4096.0; // 将原始数据转换为角度(度)

  // 使用低通滤波器平滑角度变化
  angle = as5600_filter(angle); // 使用低通滤波器平滑角度数据

  // 计算速度
  static float last_angle = 0; // 上一次的角度
  static unsigned long last_time = 0; // 上一次的时间
  unsigned long current_time = millis(); // 获取当前时间(毫秒)
  float delta_time = (current_time - last_time) / 1000.0; // 计算时间差(秒)
  float speed = (angle - last_angle) / delta_time; // 计算角速度(度/秒)

  // 打印原始位置、角度和速度
  Serial.print("原始位置: ");
  Serial.print(rawPosition);
  Serial.print(" - 角度: ");
  Serial.print(angle);
  Serial.print(" 度, 速度: ");
  Serial.print(speed);
  Serial.println(" 度/秒");

  // 检测角度变化并触发LED报警
  if (abs(angle - last_angle) > 15.0) { // 如果角度变化超过15度
    Serial.println("警报: 角度变化超过阈值,点亮LED灯!"); // 输出警报信息
    digitalWrite(ledPin, HIGH); // 点亮LED
    delay(1000); // LED亮1秒
    digitalWrite(ledPin, LOW); // 熄灭LED
  }

  // 更新上一次的角度和时间
  last_angle = angle; // 更新上一次的角度
  last_time = current_time; // 更新上一次的时间

  delay(500); // 延迟500毫秒
}

uint16_t readAS5600Angle() {
  Wire.beginTransmission(AS5600_ADDRESS); // 开始与AS5600传感器的I2C通信
  Wire.write(ANGLE_REG); // 写入角度寄存器地址
  Wire.endTransmission(); // 结束I2C通信
  Wire.requestFrom(AS5600_ADDRESS, 2); // 请求从AS5600传感器读取2字节数据
  uint16_t angle = Wire.read() << 8 | Wire.read(); // 读取并组合两个字节的数据
  return angle; // 返回角度数据
}

实验串口返回情况

 

62.jpg

实验场景图 

 

63.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
 项目实验之十八:动态读取AS5600位置变化并设阙值LED提示

实验开源代码
 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十八:动态读取AS5600位置变化并设阙值LED提示
*/

#include <Wire.h> // 包含Wire库,用于I2C通信
#include <AS5600.h> // 包含AS5600库,用于与AS5600传感器通信
#include <SimpleFOC.h> // 包含SimpleFOC库,用于低通滤波器

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01); // 创建一个低通滤波器对象,滤波系数为0.01
#define AS5600_ADDRESS 0x36 // 定义AS5600传感器的I2C地址
#define ANGLE_REG 0x0C // 定义AS5600传感器的角度寄存器地址

AS5600 encoder; // 创建AS5600传感器对象
const int ledPin = 13; // 定义LED引脚

void setup() {
  Serial.begin(115200); // 初始化串口通信,波特率为115200
  Wire.begin(); // 初始化I2C通信
  Serial.println("AS5600完成初始化I2C,准备就绪!"); // 输出初始化完成信息
  pinMode(ledPin, OUTPUT); // 设置LED引脚为输出模式
}

void loop() {
  // 读取原始位置
  uint16_t rawPosition = readAS5600Position(); // 调用函数读取AS5600传感器的原始位置数据

  // 使用低通滤波器平滑位置变化
  float filteredPosition = as5600_filter(rawPosition); // 使用低通滤波器平滑位置数据

  // 打印原始位置和滤波后的位置
  Serial.print("原始位置: ");
  Serial.print(rawPosition);
  Serial.print(" - 滤波后的位置: ");
  Serial.println(filteredPosition);

  // 检测位置变化并触发LED提示
  static float last_position = 0; // 上一次的位置
  if (abs(filteredPosition - last_position) > 100) { // 如果位置变化超过100
    Serial.println("提示: 位置变化超过阈值,点亮LED灯!"); // 输出警报信息
    digitalWrite(ledPin, HIGH); // 点亮LED
    delay(1000); // LED亮1秒
    digitalWrite(ledPin, LOW); // 熄灭LED
  }

  // 更新上一次的位置
  last_position = filteredPosition; // 更新上一次的位置

  delay(500); // 延迟500毫秒
}

uint16_t readAS5600Position() {
  Wire.beginTransmission(AS5600_ADDRESS); // 开始与AS5600传感器的I2C通信
  Wire.write(ANGLE_REG); // 写入角度寄存器地址
  Wire.endTransmission(); // 结束I2C通信
  Wire.requestFrom(AS5600_ADDRESS, 2); // 请求从AS5600传感器读取2字节数据
  uint16_t position = Wire.read() << 8 | Wire.read(); // 读取并组合两个字节的数据
  return position; // 返回位置数据
}

实验串口返回情况

 

64.jpg
65.jpg

 

要点解读
1、传感器初始化:使用Wire.begin()初始化I2C通信,并通过AS5600库初始化传感器,确保能够正确读取位置数据。
2、低通滤波器:使用SimpleFOC库中的LowPassFilter类对位置数据进行平滑处理,减少噪声影响,提高数据稳定性。
3、位置数据缩放:使用map()函数将滤波后的位置数据从0-4095映射到0-100的范围,便于监控和处理。
4、阈值检测:设置位置变化阈值,当位置变化超过10时,触发LED报警,提示异常情况。
5、数据输出:通过串口输出原始位置和转换后的位置数据,便于调试和监控系统运行状态。

实验场景图

 

63.jpg

  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)

  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块

  项目实验之十九:使用卡尔曼滤波器处理AS5600编码器数据

 

实验开源代码


 

代码
/*
  【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
  实验二百二十五:AS5600磁编码器 磁感应角度测量传感器  12bit高精度模块
  项目实验之十九:使用卡尔曼滤波器处理AS5600编码器数据
*/

#include <Wire.h>
#include <SimpleFOC.h>
#include <AS5600.h>

// 使用SimpleFOC库中的低通滤波器
LowPassFilter as5600_filter(0.01); // 创建一个低通滤波器实例,滤波系数为0.01
AS5600 encoder; // 创建一个AS5600编码器实例

// 定义卡尔曼滤波相关变量
float measured_angle = 0; // 测量的角度
float estimated_angle = 0; // 估计的角度
float Q_angle = 0.001; // 过程噪声
float R_measure = 0.03; // 测量噪声
float P = 1; // 估计误差协方差
float K; // 卡尔曼增益

void setup() {
  Serial.begin(115200); // 初始化串口通信,波特率为115200
  Wire.begin(); // 初始化I2C通信
  encoder.begin(); // 初始化AS5600编码器
  Serial.println("已完成初始化I2C,Baize_FOC准备就绪"); // 输出初始化完成信息
}

void loop() {
  uint16_t readValue = 0; // 存储读取的原始数据
  byte readArray[2]; // 存储读取的字节数据

  // 通知设备即将读取数据
  Wire.beginTransmission(0x36); // 开始与I2C地址为0x36的设备通信
  Wire.write(0x0C); // 写入寄存器地址0x0C,准备读取角度数据
  Wire.endTransmission(false); // 结束传输,但保持I2C总线激活状态

  // 读取数据的MSB和LSB
  Wire.requestFrom(0x36, (uint8_t)2); // 请求从设备读取2个字节的数据
  if (Wire.available() == 2) { // 检查是否有2个字节可用
    readArray[0] = Wire.read(); // 读取第一个字节(MSB)
    readArray[1] = Wire.read(); // 读取第二个字节(LSB)
    readValue = (readArray[0] << 8) | readArray[1]; // 将两个字节合并为一个16位的值
    float raw_angle = (float)readValue / 4096.0 * 360.0; // 将原始数据转换为0-360度
    float filteredValue = as5600_filter(raw_angle); // 对角度数据进行低通滤波

    // 卡尔曼滤波
    measured_angle = filteredValue; // 更新测量的角度

    // 预测步骤
    P = P + Q_angle; // 更新估计误差协方差

    // 更新步骤
    K = P / (P + R_measure); // 计算卡尔曼增益
    estimated_angle = estimated_angle + K * (measured_angle - estimated_angle); // 更新估计的角度
    P = (1 - K) * P; // 更新估计误差协方差

    // 确保角度在0-360度范围内
    if (estimated_angle < 0) {
      estimated_angle += 360;
    } else if (estimated_angle >= 360) {
      estimated_angle -= 360;
    }

    // 输出滤波后的角度
    Serial.print("卡尔曼滤波后的角度: ");
    Serial.println(estimated_angle);
  } else {
    Serial.println("Error reading data"); // 如果读取数据失败,输出错误信息
  }
  delay(50); // 延迟50毫秒
}

实验串口返回情况

 

66.jpg

要点解读

1、初始化与配置:在setup()函数中,初始化串口通信、I2C总线和AS5600编码器,确保系统准备就绪。2、数据读取:通过I2C总线从AS5600磁编码器读取角度数据,确保读取的MSB和LSB数据正确组合成16位的角度值。3、角度转换:将AS5600编码器的原始数据转换为0-360度范围内的角度值,便于后续处理和输出。4、低通滤波:使用SimpleFOC库中的低通滤波器对读取的角度数据进行滤波,减少噪声,提高数据的平滑度。5、简化的卡尔曼滤波算法:简化后的卡尔曼滤波算法去掉了复杂的矩阵运算,适合在资源有限的Arduino上实现。包括预测和更新步骤,以提高角度测量的精度,并确保角度值在0-360度范围内。

实验串口绘图器返回情况

 

67.jpg
68.jpg

实验场景图

 

22.jpg

评论

user-avatar
icon 他的勋章
    展开更多