霍尔编码器的使用方法

霍尔编码器介绍

什么是霍尔编码器

霍尔编码器(Hall Encoder)是一种传感器,用于检测和测量磁场的变化。它基于霍尔效应,这是一种电磁现象,当磁场作用于一种特定类型的材料时,会在该材料内部产生电势差。

霍尔编码器通常由霍尔传感器和磁场源组成。磁场源可以是一个永久磁铁或一个电磁线圈,而霍尔传感器则是一种能够测量磁场的变化并将其转换为电信号的器件。

在霍尔编码器中,磁场源和霍尔传感器之间存在相对运动。当磁场源靠近或远离霍尔传感器时,磁场的变化会导致霍尔传感器输出一个电信号。这个电信号的特点可以用来确定磁场源的位置和方向。

霍尔编码器常用于测量旋转运动或线性运动的位置和速度。它们被广泛应用于各种设备和系统,例如电机控制、机器人、位置传感器等。由于霍尔编码器不接触物体,因此具有非接触式测量、长寿命和高可靠性等优点,使其成为许多应用中的理想选择。
霍尔编码器

霍尔编码器与光电编码器的区别

原理:霍尔编码器使用磁场变化来测量旋转位置和方向,而光电编码器则使用光电检测原理,通过测量光电信号的脉冲数来确定旋转角度和方向。

精度:通常情况下,光电编码器的精度要高于霍尔编码器。光电编码器可以实现高精度的位置控制,因为它可以生成更多的信号脉冲,从而提高了分辨率。而霍尔编码器通常比较适合用于需要较少精度的应用。

环境适应性:霍尔编码器在恶劣的环境下有更好的适应性,例如高温、高湿度、高腐蚀等。而光电编码器则对环境有较高的要求,需要避免光照强烈、尘埃等干扰。

应用场景:由于光电编码器的精度更高,它通常被用于需要高精度位置控制的应用,例如机器人、半导体加工等。而霍尔编码器则更适用于工业自动化、医疗设备、汽车控制等应用,这些应用对精度要求不高,但需要传感器能够适应恶劣的环境。

编码器主要种类

  • 旋转霍尔编码器(Rotary Hall Encoder):用于测量旋转运动的位置和速度。它们通常由一个旋转磁场源和一个或多个固定的霍尔传感器组成。通过检测磁场的变化,可以确定旋转轴的位置和方向。

  • 线性霍尔编码器(Linear Hall Encoder):用于测量线性运动的位置和速度。线性霍尔编码器通常由一个磁场源和一个或多个线性排列的霍尔传感器组成。随着磁场源或传感器的移动,可以通过测量磁场的变化来确定位置和方向。

  • 磁性条码霍尔编码器(Magnetic Stripe Hall Encoder):这种类型的霍尔编码器通常用于读取磁性条码。磁性条码包含一系列的磁极,而霍尔传感器则用来检测磁极的变化,并将其转换为数字信号进行解码。

  • 磁性环霍尔编码器(Magnetic Ring Hall Encoder):这种编码器通常由一个环形磁体和多个固定的霍尔传感器组成。磁性环上的磁极和传感器之间的相对运动可以用于测量旋转运动的位置和速度。

  • 增量式霍尔编码器(Incremental Hall Encoder):这种编码器输出的信号是增量式的,它们提供有关位置变化的信息,但无法直接确定绝对位置。增量式霍尔编码器通常包括两个或多个输出通道,如A、B相和一个指针信号。

  • 绝对式霍尔编码器(Absolute Hall Encoder):与增量式编码器不同,绝对式霍尔编码器可以直接确定位置的绝对值。它们通常包含多个霍尔传感器和一个编码器,用于将磁场的位置映射到具体的编码值。

主要测速方法

  • 增量式测速法:增量式霍尔编码器通常具有A相和B相两个输出通道,每个通道都会输出脉冲信号。通过计算A相和B相脉冲信号的数量和相对位置变化,可以确定物体的转速。通过统计单位时间内的脉冲数量,并根据编码器的分辨率进行转换,可以得到物体的角速度或转速。

  • 计时测速法:在计时测速法中,通过测量霍尔编码器输出信号中相邻脉冲之间的时间间隔来计算速度。可以使用计时器或微控制器来记录脉冲信号的时间戳,并计算相邻脉冲之间的时间差。通过将脉冲时间差与编码器的分辨率和单位时间进行计算,可以得到物体的速度。

  • 频率测速法:频率测速法通过统计霍尔编码器输出信号的脉冲频率来计算速度。可以使用计数器或频率计来测量单位时间内脉冲的数量,并将其转换为速度值。这种方法适用于高速运动,因为频率计可以快速测量脉冲频率。

  • 相位差测速法:相位差测速法利用霍尔编码器的A相和B相信号之间的相位差来计算速度。通过比较两个相位信号的相对位置变化,可以确定物体的速度。可以使用相位差计算器或编码器解码器来测量相位差,并将其转换为速度值。

使用ESP32解码获取电机速度

使用方法

本文中使用的为增量式霍尔编码器。
由于Arduino与ESP32均无正交解码功能,而编码器返回的数据是一组正交信号,所以要想实现正交解码功能的话就需要用两个io口来同时判断当前是属于状态。
首先定义两个GPIO接受编码器脉冲信号,与中断时间,我们将接受脉冲信号计算速度写在中断里。

1
2
3
4
5
6
7
8
#include <Arduino.h>
#include<Ticker.h>

#define L_encoder_1 5
#define L_encoder_2 18
#define R_encoder_1 4
#define R_encoder_2 19
#define interrupt_time 10 // 中断时间

注意头文件引用
计数测速原理图示如下

我们使用两个编码器的1(A)通道测速,使用2(B)通道检测旋转方向。
代码编写方法参考了文末参考文献内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Ticker timer_read_encoder; 

int32_t Velocity_L, Velocity_R; //左右轮编码器数据
int16_t Velocity_Left, Velocity_Right; //左右轮速度

void READ_ENCODER_L(void);
void READ_ENCODER_R(void);
void myread(void);

void READ_ENCODER_L(void) {
if (digitalRead(ENCODER_L) == LOW) { //如果是下降沿触发的中断
if (digitalRead(DIRECTION_L) == LOW) Velocity_L--; //根据另外一相电平判定方向
else Velocity_L++;
}
else { //如果是上升沿触发的中断
if (digitalRead(DIRECTION_L) == LOW) Velocity_L++; //根据另外一相电平判定方向
else Velocity_L--;
}
}

void READ_ENCODER_R(void) {
if (digitalRead(ENCODER_R) == LOW) { //如果是下降沿触发的中断
if (digitalRead(DIRECTION_R) == LOW) Velocity_R--;//根据另外一相电平判定方向
else Velocity_R++;
}
else { //如果是上升沿触发的中断
if (digitalRead(DIRECTION_R) == LOW) Velocity_R++; //根据另外一相电平判定方向
else Velocity_R--;
}
}

void myread(void)
{
/**************************************************************************
计算为转速n/s 500线光电编码器数据 定时时间为20MS
转速 = num/500/20ms
转速 = num*2/time
**************************************************************************/
Velocity_Left = Velocity_L*2/interrupt_time; Velocity_L = 0; //读取左轮编码器数据,并清零,这就是通过M法测速(单位时间内的脉冲数)得到速度。
Velocity_Right = Velocity_R*2/interrupt_time; Velocity_R = 0; //读取右轮编码器数据,并清零

}

Setup与loop函数内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);

pinMode(ENCODER_L, INPUT);
pinMode(ENCODER_R, INPUT);
pinMode(DIRECTION_L, INPUT);
pinMode(DIRECTION_R, INPUT);

//编码器接口1 开启外部跳边沿中断
attachInterrupt(ENCODER_L, READ_ENCODER_L, CHANGE); //中断函数READ_ENCODER_L
//编码器接口2 开启外部跳边沿中断
attachInterrupt(ENCODER_R, READ_ENCODER_R, CHANGE); //中断函数READ_ENCODER_R

interrupts(); //打开外部中断
timer_read_encoder.attach_ms(interrupt_time, myread);
}

void loop() {
// put your main code here, to run repeatedly:
Serial.print("Velocity_L:");Serial.print(Velocity_L); //左轮编码器计数
Serial.print(" | Velocity_Left:");Serial.println(Velocity_Left); //左轮速度
Serial.print("Velocity_R:");Serial.println(Velocity_R); //右轮编码器计数
Serial.print(" | Velocity_Right:");Serial.println(Velocity_Right); //右轮速度

}

参考文献

ESP32 Arduino平衡小车制作】(一)霍尔编码器解码

上一篇:
ROS数据展示系统
下一篇:
使用Arduino IDE中eSPI库驱动TFT、OLED