问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

利用霍尔效应传感器测量旋转运动的绝对角度

创作时间:
作者:
@小白创作中心

利用霍尔效应传感器测量旋转运动的绝对角度

引用
CSDN
1.
https://m.blog.csdn.net/qq_54846451/article/details/145278905

霍尔效应传感器是一种广泛应用于旋转类器件角度测量的非接触式检测技术。本文详细介绍了如何使用线性霍尔传感器测量旋转运动的绝对角度,包括原理、硬件设计、软件设计以及实验结果。通过这篇文章,读者可以深入了解霍尔效应传感器在实际应用中的具体实现方法。

为什么使用线性霍尔传感器

转盘、操纵杆、恒温器、电子转向总成和通常用于万向节或机械臂的电机控制接头等旋转类器件都依赖于精确定义角度位置的能力。虽然可以使用机械触点等方法来监测旋转角度,但这些类型的传感器在使用时容易磨损,并且在有污垢的情况下会降低性能。霍尔效应传感器是一种非接触式检测替代产品,可提供更长的产品寿命、更高的可靠性及角度检测性能

线性测角度原理

径向磁铁
磁通量方向
由于这种类型的磁体轴向旋转,磁场矢量的各种分量(表征磁通密度)会发生周期性变化。根据相对于磁体的位置,始终至少有两个分量可供选择。当传感器放置在与磁体表面相距适当的距离时,这些分量为正弦。注意以下曲线,它们表示旋转磁体产生的每个分量。

正交放置线性霍尔磁场分量
线性霍尔元件摆放位置

方案实施

使用DMA对ADC通道进行采样获取霍尔输出值、投入算法。

硬件设计

设置角度计算的一种方法是使用两个一维传感器。对于这种方法,放置两个传感器时必须确保它们在物理上围绕磁铁中心间隔 90°。这可以通过将传感器放在平面内(与磁体的磁极共面)或平面外来实现。平面内方法将传感器放置在与磁极直接对齐的位置,因此观察到的输入更大,但平面外对齐所需的物理空间更小。

软件设计思路

  • 对于不平滑运动、需要对数据进行滤波处理。
  • 由于线性霍尔标定不同,这将导致霍尔元件输出模拟量幅值不同(如下图),需要对峰值校准。
    校准公式
  • 由于物理位置确定,迟滞90°,理想状态下可以根据波形算出角度(事实上不理想 误差缘故)
    增加传感器数量能够减小误差,但是我们知道单片机算力和ADC资源有限,不可能每个信号都交给单片机来解码。

方法一:

一般选择四个间隔90°传感器,将两个间隔180°的传感器数据接入差分减法器的正反相输入端,由于间隔180°波形相反,减法器输出的是反向叠加的波形,起到一个叠加滤波的效果。
将两个减法器输出的正余弦信号输入单片机后,再进行插值校准。原理也很简单,使用查找表校准系统,记录已知角度的传感器电压数据,然后从已知电压之间的线性插值中获取任何测量电压的角度。具体过程就是通过开环强拖或者其他方式使磁环旋转一周,对于每个期望的校准角度,将磁铁旋转到该角度,并记录每个传感器的测量电压(类似于MITcheetah的线性化校准),然后,在正常操作期间,每个传感器的测量电压落在先前记录的两个电压之间,称为Vsbover和Vsbower。使用两个传感器时,确保每个传感器的Vavover和Vbewer与相同的校准角度相关联,然后将测量的角度作为这两个电压和各自已知角度的比率。

但是我们在这里不使用外围电路实现这一方法

方法二:

同样使用四个线性霍尔,但是硬件上直接抛弃减法器电路、直接在AD通道中直接使用差值计算、实现减法器、在经过滤波器进行二次滤波。

理论存在实践开始

实现样本通道结构

  • 支持一阶低通滤波因子
  • 支持动态峰值
  • (注意)峰值初始值一定要设定为相反(最大值设置为最小值、最小值设置为最大值)
struct _filter {
    float a;
    float sample_pre;
    float sample_cur;
    float sample_max;
    float sample_min;
};
struct _filter x1 = { 0.1, 0, 0, 0, 4095 };
struct _filter y1 = { 0.1, 0, 0, 0, 4095 };
struct _filter x2 = { 0.1, 0, 0, 0, 4095 };
struct _filter y2 = { 0.1, 0, 0, 0, 4095 };
  

实现一阶低通滤波

void filter_deal(struct _filter *filter)
{
    filter->sample_cur = filter->sample_cur * filter->a +
                         filter->sample_pre * (1.0 - filter->a);
    filter->sample_pre = filter->sample_cur;
}
  

实现动态峰值

void dynamic_deal(struct _filter *filter)
{
    if (filter->sample_cur > filter->sample_max)
        filter->sample_max = filter->sample_cur;
    
    if (filter->sample_cur < filter->sample_min)
        filter->sample_min = filter->sample_cur;
}
  

系统完整流程

#define M_PI 3.14159265358979323846
float angle;
void APP_DMATransferCompleteCallback() {
    static int cnt = 0;
    
    // Update the sample values from ADC data
    x1.sample_cur = (float)(ADCxConvertedDatas[0]);
    y1.sample_cur = (float)(ADCxConvertedDatas[1]);
    x2.sample_cur = (float)(ADCxConvertedDatas[2]);
    y2.sample_cur = (float)(ADCxConvertedDatas[3]);
    
    // subtractor circuit
    x1.sample_cur = x1.sample_cur - x2.sample_cur;
    y1.sample_cur = y1.sample_cur - y2.sample_cur;
    
    filter_deal(&x1);
    filter_deal(&y1);
    filter_deal(&x2);
    filter_deal(&y2);
    
    dynamic_deal(&x1);
    dynamic_deal(&y1);
    dynamic_deal(&x2);
    dynamic_deal(&y2);
    // Only call task() once when cnt reaches 500
    if (cnt < 500) {
        ++cnt;
        return;
    }
    
    // Calculate A and V for x filter
    float A_x = fabs(x1.sample_max - x1.sample_min);
    float V_x = (x1.sample_cur - x1.sample_min - A_x / 2) / (A_x / 2);
    float A_y = fabs(y1.sample_max - y1.sample_min);
    float V_y = (y1.sample_cur - y1.sample_min - A_y / 2) / (A_y / 2);
    angle = atan2f(V_x, V_y) * 180 / M_PI + 180;
    
    // Printing should be done less frequently, or in debug mode only
    printf("%f,%f,%f\r\n", x1.sample_cur, y1.sample_cur, angle);
}
  

实验结果

上位机使用VOFA探测输出波形

参考资料

线性霍尔实现离轴式绝对位置反馈
利用霍尔效应传感器测量旋转运动的绝对角度

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号