AS5600磁编码器的使用以及简单的滤波算法(arduino)

目录

前言

实践

示例一:发现IIC设备

示例二:读取AS5600原始数据

示例三:对读取到的AS5600原始数据进行低通滤波

1. 一阶滤波算法的原理 

2.编程实现


前言

AS5600磁编码器常用于电机的角位移测量,如下图为使用AS5600芯片的一款编码器。

 该磁编码器支持IIC,SPI和模拟输出三种方式,具体的引脚定义如下:

这款编码器的原理图如下:

 AS5600的iic地址为0X36,数据所在寄存器地址如下

在这里插入图片描述

实践

示例一:发现IIC设备

#include <SimpleFOC.h>
TwoWire I2Cone = TwoWire(0);
 
void setup(){
  Serial.begin(115200); 
  I2Cone.begin(18, 5, 100000); 
  for(int i=0;i<255;i++)
  {
    I2Cone.beginTransmission(i);
    if(I2Cone.endTransmission()==0)
    {
      Serial.print("0x");
      Serial.println(i,HEX);
    }
  }
}
 
void loop(){}

 可以查看串口看效果:

可以发现,单片机已经发现了其他的iic设备

示例二:读取AS5600原始数据

#include <SimpleFOC.h>
TwoWire I2Cone = TwoWire(0);

uint16_t readValue = 0;
byte readArray[2];

void setup(){
  Serial.begin(115200); 
  I2Cone.begin(18, 5, 400000); 
  // notify the device that is aboout to be read
  I2Cone.beginTransmission(0X36);
  I2Cone.write(0X0C);
  I2Cone.endTransmission(false);
}
 
void loop(){
  // read the data msb and lsb
  I2Cone.requestFrom(0X36, (uint8_t)2);
  for (byte i=0; i < 2; i++) {
    readArray[i] = I2Cone.read();
  }

  // depending on the sensor architecture there are different combinations of 
  // LSB and MSB register used bits
  // AS5600 uses 0..7 LSB and 8..11 MSB
  // AS5048 uses 0..5 LSB and 6..13 MSB
  //readValue = ( readArray[1] &  lsb_mask );
  //readValue += ( ( readArray[0] & msb_mask ) << lsb_used );
  readValue=readArray[0]*256+readArray[1];
  Serial.println(readValue);
  delay(100);
}

可以从串口查看效果:

可以看到,当我用手旋转电机一圈的过程中,这个数字从0增加到了4095 

以下示例也可以:

主要删掉了setup函数中的begintransmission()等函数。

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

#include <SimpleFOC.h>

TwoWire I2Cone = TwoWire(0);

uint16_t readValue = 0;
byte readArray[2];
 
void setup(){
  Serial.begin(115200); 
  I2Cone.begin(18, 5, 400000); 
}
 
void loop(){
  // read the data msb and lsb
  I2Cone.requestFrom(0X36, (uint8_t)2);
  for (byte i=0; i < 2; i++) {
    readArray[i] = I2Cone.read();
  }
 
  // depending on the sensor architecture there are different combinations of 
  // LSB and MSB register used bits
  // AS5600 uses 0..7 LSB and 8..11 MSB
  // AS5048 uses 0..5 LSB and 6..13 MSB
  //readValue = ( readArray[1] &  lsb_mask );
  //readValue += ( ( readArray[0] & msb_mask ) << lsb_used );
  readValue=readArray[0]*256+readArray[1];
  Serial.println(readValue);
  delay(100);
}

示例三:对读取到的AS5600原始数据进行低通滤波

这里我们把读取到的数据,进行一个低通滤波处理。

1. 一阶滤波算法的原理 

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

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

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

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

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

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

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

2.编程实现

#include <SimpleFOC.h>

class LowPassFilte{
  public:
    LowPassFilte(float Tf);//低通滤波器时间常量
    ~LowPassFilte() = default;
    float operator() (float x);
    float Tf; //!< 低通滤波器时间常量
  protected:
    unsigned long timestamp_prev;  //!< 上次执行时间戳
    float y_prev; //!< 经过上次执行后过滤到的值
};

LowPassFilte::LowPassFilte(float time_constant)
    : Tf(time_constant)
    , y_prev(0.0f)
{
    timestamp_prev = micros();
}

float LowPassFilte::operator() (float x)
{
    unsigned long timestamp = micros();
    float dt = (timestamp - timestamp_prev)*1e-6f;

    if (dt < 0.0f || dt > 0.5f)
        dt = 1e-3f;

    float alpha = Tf/(Tf + dt);
    float y = alpha*y_prev + (1.0f - alpha)*x;

    y_prev = y;
    timestamp_prev = timestamp;
    return y;
}

TwoWire I2Cone = TwoWire(0);
LowPassFilte as5600_filter(0.001);

void setup(){
  Serial.begin(115200); 
  I2Cone.begin(18, 5, 400000); 
  I2Cone.beginTransmission(0X36);
  I2Cone.write(0X0C);
  I2Cone.endTransmission(false);
}
 
void loop(){
  // read the data msb and lsb
  I2Cone.requestFrom(0X36, (uint8_t)2);
  byte readArray[2];
  for (byte i=0; i < 2; i++) {
    readArray[i] = I2Cone.read();
  }
  uint16_t readValue = 0;
  readValue=readArray[0]*256+readArray[1];
//  Serial.print(readValue);
//  Serial.print(",");
  Serial.println(as5600_filter(readValue));
}

 通过arduino的串口监视器,我们可以看到滤波后的数据跳动范围更小,变化更加平缓。

原数值

 滤波后数值

 放在一起对比(蓝色为原数值,红色为滤波后数值)

我们把时间常数从0.001改成0.01,可以看到输出数据更加稳定了。

参考链接:

1.算法学习笔记之一阶低通滤波算法_一颗偏执的心-CSDN博客_低通滤波算法

版权声明:本文为CSDN博主「Allen953」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qqliuzhitong/article/details/121795481

生成海报
点赞 0

Allen953

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

数码管轮播显示

硬件: 数码管10个引脚,8个控制二极管亮、灭,2个引脚为负极。1k欧电阻链接负极,接gnd。 将8个二极管引脚依次链接0-7号引脚。 软件: /*共阳极单数码管显示&