旋转编码器如何工作?有哪些类型?

描述

旋转编码器是一种输入设备,可帮助用户与系统进行交互。它看起来更像是一个无线电电位计,但它输出一系列脉冲,这使得它的应用独一无二。当编码器的旋钮旋转时,它以小步长的形式旋转,这有助于它用于步进/伺服电机控制,浏览一系列菜单以及增加/减少数字的值等等。

在本文中,我们将了解不同类型的旋转编码器及其工作原理。我们还将它与 Arduino 连接,并通过旋转编码器来控制整数的值,并在 16*2 LCD 屏幕上显示其值。在本教程结束时,您将习惯于为您的项目使用旋转编码器。所以让我们开始吧...

所需材料

旋转编码器 (KY-040)

Arduino UNO

16*2字母数字液晶显示器

电位器 10k

面包板

连接线

旋转编码器如何工作?

旋转编码器是一种机电换能器,这意味着它将机械运动转换为电子脉冲。它由一个旋钮组成,当旋转时,旋钮将逐步移动,并为每个步骤产生一系列具有预定义宽度的脉冲序列。有许多类型的编码器,每种都有自己的工作机制,我们稍后将了解这些类型,但现在让我们只关注KY040 增量编码器,因为我们在教程中使用它。

编码器的内部机械结构如下所示。它基本上由一个圆形圆盘(灰色)组成,导电垫(铜色)放置在该圆形圆盘的顶部。这些导电垫放置在相等的距离上,如下所示。输出引脚固定在这个圆形圆盘的顶部,这样当旋钮旋转时,导电垫与输出引脚接触。这里有两个输出引脚,输出A和输出B,如下图所示。

旋转编码器

输出引脚A和输出B产生的输出波形分别以蓝色和绿色显示。当导电焊盘直接位于引脚下方时,它会变高,从而按时导通,当导电焊盘移开时,引脚变低,导致上面所示波形的关断时间。现在,如果我们计算脉冲数,我们将能够确定编码器移动了多少步。

现在可能会出现一个问题,为什么我们需要两个脉冲信号,而一个脉冲信号足以计算旋转旋钮时采取的步数。这是因为我们需要确定旋钮的旋转方向。如果你看一下这两个脉冲,你会发现它们都是90°的异相。因此,当旋钮顺时针旋转时,输出 A 将首先变高,当旋钮逆时针旋转时,输出 B 将首先变高。

旋转编码器的类型

市场上有许多类型的旋转编码器,设计人员可以根据自己的应用选择一种。下面列出了最常见的类型

增量编码器

绝对值编码器

磁编码器

光学编码器

激光编码器

这些编码器根据输出信号和传感技术进行分类,增量编码器和绝对编码器根据输出信号进行分类,磁性、光学和激光编码器根据传感技术进行分类。此处使用的编码器是增量类型编码器。

KY-040 旋转编码器引脚排列和说明

KY-040增量式旋转编码器的引脚排列如下所示

旋转编码器

前两个引脚(接地和Vcc)用于为编码器供电,通常使用+5V电源。除了顺时针和逆时针方向旋转旋钮外,编码器还有一个开关(低电平有效),可以通过按下内部旋钮来按下。来自该开关的信号通过引脚 3(开关)获得。最后,它具有两个输出引脚,可产生如上所述的波形。现在让我们学习如何将其与Arduino接口。

Arduino 旋转编码器电路图

旋转编码器与Arduino接口的完整电路图如下图所示

旋转编码器

旋转编码器有 5 个引脚,顺序如上标签所示。前两个引脚是接地和Vcc,连接到Arduino的接地和+5V引脚。编码器的开关连接到数字引脚D10,并通过一个1k电阻被拉高。两个输出引脚分别连接到D9和D8。

为了显示通过旋转编码器增加或减少的变量值,我们需要一个显示模块。这里使用的是一种常见的16 * 2字母数字LCD显示器。我们已经连接了显示器以4位模式运行,并使用Arduino的+5V引脚为其供电。电位计用于调整LCD显示屏的对比度。如果您想了解有关使用Arduino接口LCD显示器的更多信息,请点击链接。完整的电路可以建在面包板的顶部,一旦所有连接完成,我的下面看起来像这样。

旋转编码器

为旋转编码器编程 Arduino

如果您了解旋转编码器的工作原理,那么对Arduino板进行编程以将旋转编码器与其连接是相当容易和直接的。我们只需要读取脉冲数来确定编码器转了多少圈,并检查哪个脉冲先变高,以找到编码器旋转的方向。在本教程中,我们将在LCD的第一行显示递增或递减的数字,在第二行显示编码器的方向。用于执行相同操作的完整程序可以在此页面底部找到演示视频,它不需要任何库。现在,让我们将程序分成小块以了解工作原理。

由于我们使用了LCD显示器,因此我们包含了默认情况下存在于Arduino IDE中的液晶库。然后我们定义用于将LCD与Arduino连接的引脚。最后,我们初始化这些引脚上的LCD显示。

#include //Default Arduino LCD Library is included

const int rs = 7, en = 6, d4 = 5, d5 = 4, d6 = 3, d7 = 2; //Mention the pin number for LCD connection

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

lcd.begin(16, 2); //Initialise 16*2 LCD

接下来在设置功能中,我们在LCD屏幕上显示一条介绍性消息,然后等待2秒钟,以便该消息可供用户阅读。这是为了确保液晶屏工作正常。

lcd.print(" Rotary Encoder "); //Intro Message line 1

lcd.setCursor(0, 1);

lcd.print("  With Arduino  "); //Intro Message line 2

delay(2000);

lcd.clear();

旋转编码器有三个输出引脚,它们将成为Arduino的输入引脚。这三个引脚分别是开关、输出 A 和输出 B。这些使用pinMode函数声明为输入,如下所示。

//pin Mode declaration

pinMode (Encoder_OuputA, INPUT);

pinMode (Encoder_OuputB, INPUT);

pinMode (Encoder_Switch, INPUT);

在 void 设置功能中,我们读取输出 A 引脚的状态以检查引脚的最后状态。然后,我们将使用此信息与新值进行比较,以检查哪个引脚(输出 A 或输出 B)已变高。

Previous_Output = digitalRead(Encoder_OuputA); //Read the inital value of Output A

最后,在主循环函数中,我们必须将输出 A 和输出 B 的值与上一个输出进行比较,以检查哪个先变高。这可以通过简单地将A和B的电流输出值与先前的输出进行比较来完成,如下所示。

if (digitalRead(Encoder_OuputA) != Previous_Output)

{

if (digitalRead(Encoder_OuputB) != Previous_Output)

{

Encoder_Count ++;

lcd.clear(); 

lcd.print(Encoder_Count);

lcd.setCursor(0, 1); 

lcd.print("Clockwise");

}

在上面的代码中,如果输出 B 与上一个输出相比发生了变化,则执行第二个 if 条件。在这种情况下,编码器变量的值递增,LCD显示编码器按顺时针方向旋转。类似地,如果条件失败,在随后的 else 条件中,我们递减变量并显示编码器沿逆时针方向旋转。相同的代码如下所示。

else

{

Encoder_Count--;

lcd.clear(); 

lcd.print(Encoder_Count);

lcd.setCursor(0, 1); 

lcd.print("Anti - Clockwise");

}

}

最后,在主循环结束时,我们必须使用当前输出值更新以前的输出值,以便可以使用相同的逻辑重复循环。以下代码执行相同的操作

Previous_Output = digitalRead(Encoder_OuputA);

另一个可选的事情是检查编码器上的开关是否被按下。这可以通过检查旋转打码机上的开关引脚来监控。此引脚是有效的低引脚,这意味着按下按钮时它将变为低电平。如果不按下引脚保持高电平,我们还使用上拉电阻器来确保在未按下开关时保持高电平,从而避免浮点情况。

if (digitalRead(Encoder_Switch) == 0)   {     lcd.clear();     lcd.setCursor(0, 1);     lcd.print("Switch pressed");   }

旋转编码器与Arduino的工作

硬件和代码准备就绪后,只需将代码上传到Arduino板并启动Arduino板即可。您可以通过 USB 电缆或使用 12V 适配器为其供电。通电后,液晶屏应显示介绍消息,然后变为空白。现在旋转旋转编码器,您应该会看到值开始根据旋转方向递增或递减。第二行将显示编码器是顺时针还是逆时针旋转。下图显示相同

旋转编码器

此外,当按下按钮时,第二行将显示按钮已按下。完整的工作可以在下面的视频中找到。这只是一个示例程序,用于将编码器与Arduino连接并检查其是否按预期工作。到达此处后,您应该能够将编码器用于任何项目和相应的程序。

/*

* Interfacing Rotary Encoder with Arduino

* Power LCD and Rotary encoder from the +5V pin of Arduino

* LCD RS -> pin 7

* LCD EN -> pin 6

* LCD D4 -> pin 5

* LCD D5 -> pin 4

* LCD D6 -> pin 3

* LCD D7 -> pin 2

* Encoder Switch -> pin 10

* Encoder Output A -> pin 9

* Encoder Output B -> pin 8

*/


int Encoder_OuputA = 9;

int Encoder_OuputB = 8;

int Encoder_Switch = 10;


int Previous_Output;

int Encoder_Count;





#include //Default Arduino LCD Librarey is included 


const int rs = 7, en = 6, d4 = 5, d5 = 4, d6 = 3, d7 = 2; //Mention the pin number for LCD connection

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);


void setup() {

lcd.begin(16, 2); //Initialise 16*2 LCD


lcd.print(" Rotary Encoder "); //Intro Message line 1

lcd.setCursor(0, 1);

lcd.print(" With Arduino "); //Intro Message line 2


delay(2000);

lcd.clear();


//pin Mode declaration 

pinMode (Encoder_OuputA, INPUT);

pinMode (Encoder_OuputB, INPUT);

pinMode (Encoder_Switch, INPUT);


Previous_Output = digitalRead(Encoder_OuputA); //Read the inital value of Output A

}


void loop() {

//aVal = digitalRead(pinA);



if (digitalRead(Encoder_OuputA) != Previous_Output)



if (digitalRead(Encoder_OuputB) != Previous_Output) 



Encoder_Count ++;

lcd.clear(); 

lcd.print(Encoder_Count);

lcd.setCursor(0, 1); 

lcd.print("Clockwise");



else 

{

Encoder_Count--;

lcd.clear(); 

lcd.print(Encoder_Count);

lcd.setCursor(0, 1); 

lcd.print("Anti - Clockwise");

}

}


Previous_Output = digitalRead(Encoder_OuputA);


if (digitalRead(Encoder_Switch) == 0)

{

lcd.clear(); 

lcd.setCursor(0, 1); 

lcd.print("Switch pressed");

}

}

 


 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分