玩转电机驱动——电机编码器


文章目录

  • 玩转电机驱动——电机编码器
  • 前言
  • 一、旋转编码器
    • 1. 光学编码器
    • 2. 光学旋转编码器与Arduino连接
    • 3. 程序
  • 二、Arduino Encoder.h库相关知识
    • 1.硬件要求
    • 2. 基本用法
    • 3. 了解正交编码信号
    • 4. 示例程序
    • 5. 中断延迟要求
    • 6. 优化中断选项
    • 7. 最大速度和 CPU 使用率
    • 8. 低性能轮询模式
  • 总结

前言

编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。(对于电机测速来说应该需要将角位移转变为电信号,所以应该是码盘。)按照信号原理编码器可分为增量式和绝对式两类。

增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。这种类型的编码器提供脉冲作为输出,可以将其视为增量信号。因为它没有任何唯一位置的唯一值,这意味着当该编码器断电时,它失去了位置参考并从零开始。

淘宝上搜“带编码器的电机”大多是这种类型的编码器,增量式编码器有有光电编码器和霍尔编码器两种,两者的主要区别是:
(1)检测方式不同:霍尔编码器是电磁检测位置,光电编码器是光电检测位置;
(2)精度不同:霍尔编码器一般是精度不高,用作粗略的位置反馈,而光电编码器精度高,可以实现高精度的位置检测。


绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。这种类型的编码器比增量编码器更为先进。同时它们具有磁盘来代替插槽磁盘,因此它在每个位置都有独特的价值,因此即使在断电后也能记住它的位置。


一、旋转编码器

旋转编码器是一种光电式或电磁式旋转测量装置,它将被测的角位移直接转换成数字信号(高速脉冲信号)。我们通常用的是增量型编码器,不同型号的旋转编码器,其输出脉冲的相数也不同,有的旋转编码器输出A、B、Z三相脉冲,有的只有A、B相两相,最简单的只有A相。
(1)如单相联接,用于单方向计数,单方向测速。
(2)A.B两相联接,用于正反向计数、判断正反向和测速。
(3)A、B、Z三相联接,用于带参考位修正的位置测量。Z即圈数。

1. 光学编码器

光学旋转编码器是一种机械设备,在圆柱形外壳的内部有一个旋转轴,其结构与电机相同。一个圆形的平盘,上面有两组插槽。光学传感器安装在此光盘的两侧,发射器设置在一侧,接收器设置在一侧。

因此,当开槽光盘在传感器之间旋转时,它会切断光学传感器,并在接收器末端生成信号。

接收器还与微控制器连接以处理生成的信号,这样我们就可以知道旋转了多少轴。

我们还可以通过比较两个输出的信号极性来确定轴的旋转方向。因为两组插槽之间有一定的偏移,光学旋转编码器一般有两个输出“ A”和“ B”。

下图是了解每转400脉冲编码器如何产生脉冲的图像,它使每转总计1600过渡。这意味着它可以提供非常高的精度。

2. 光学旋转编码器与Arduino连接

白色(OUT A):PIN 3( arduino的中断器引脚)
绿色(OUT B):PIN 2( arduino的中断器引脚)
红色:5V
黑色:GND
在这里,我们必须注意,编码器的A、B相输出必须有一个连接到Aorduino的中断引脚。否则,arduino无法记录来自编码器的脉冲。

3. 程序

1.   volatile long temp, encoderCounter =0; //这个变量将根据编码器的旋转增加或减少
2.  int encoderPinA = 2; //interrupt pin 2
3.  int encoderPinB = 3; //interrrupt pin 3
4.
5.  void setup() {
6.  Serial.begin (115200);
7.  pinMode (encoderPinA, INPUT);
8.  pinMode (encoderPinB, INPUT);
9.
10. //设者中断函数
11. //将中断连接到Arduino的引脚encoderPinA和encoderPinB,
12. //当脉冲在CHANGE边缘时,调用函数doEncoderA()/doEncoderB()
13. attachInterrupt (digitalPinToInterrupt(encoderPinA), doEncoderA, CHANGE);
14. //编码器的A上升沿脉冲触发了中断。
15. attachInterrupt (digitalPinToInterrupt(encoderPinB), doEncoderB, CHANGE);
16. //编码器的B上升沿脉冲触发了中断。
17.
18. /*中断函数的使用
19. attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
20. pin: 中断引脚号
21. ISR: 中断服务程序名
22. mode:中断模式
23.
24. 中断模式(mode)有以下几种形式:
25. LOW: 当引脚为低电平时触发中断服务程序
26. CHANGE: 当引脚电平发生变化时触发中断服务程序
27. RISING: 当引脚电平由低电平变为高电平时触发中断服务程序
28. FALLING: 当引脚电平由高电平变为低电平时触发中断服务程序
29. */
30. }
31.
32. void loop() {
33.   // Send the value of counter
34. if ( encoderCounter!= temp){
35.   Serial.println (encoderCounter);
36.   temp = encoderCounter;
37. }
38. }
39.
40. void doEncoderA(){
41.
42.   // 在A脉冲中寻找上升沿信号,若A编码器引脚为高电平,
43.   // 若B编码器引脚为低电平,encoderCounter计数+1,否则-1
44.   if (digitalRead(encoderPinA) == HIGH) {
45.     // check channel B to see which way encoder is turning
46.     if (digitalRead(encoderPinB) == LOW) {
47.       encoderCounter = encoderCounter + 1;         // CW
48.     }
49.     else {
50.       encoderCounter = encoderCounter - 1;         // CCW
51.     }
52.   }
53.   else   // 在A脉冲中寻找下降沿信号
54.   {
55.     // check channel B to see which way encoder is turning
56.     if (digitalRead(encoderPinB) == HIGH) {
57.       encoderCounter = encoderCounter + 1;          // CW
58.     }
59.     else {
60.       encoderCounter = encoderCounter - 1;          // CCW
61.     }
62.   }
63.   //Serial.println (encoder0Pos, DEC);
64.   //这段用于调试,记得删去
65. }
66.
67. void doEncoderB(){
68.
69.   // 在B脉冲中寻找上升沿信号
70.   if (digitalRead(encoderPinB) == HIGH) {
71.    // check channel A to see which way encoder is turning
72.     if (digitalRead(encoderPinA) == HIGH) {
73.       encoderCounter = encoderCounter + 1;         // CW
74.     }
75.     else {
76.       encoderCounter = encoderCounter - 1;         // CCW
77.     }
78.   }
79.   // Look for a high-to-low on channel B
80.   else {
81.     // check channel B to see which way encoder is turning
82.     if (digitalRead(encoderPinA) == LOW) {
83.       encoderCounter = encoderCounter + 1;          // CW
84.     }
85.     else {
86.       encoderCounter = encoderCounter - 1;          // CCW
87.     }
88.   }
89. } 

将代码上传到arduino后,打开串行监视器

并旋转编码器轴,如果沿顺时针方向旋转编码器,则值会增加;如果沿逆时针方向旋转,则值会减小。

进一步通过,下列函数可以获取电机转动角度。

double angle = encoderCounter*360/172032.0;//ppr=172032

注:具体使用时,AB相编码器,只需要用一个中断引脚即可,例如:A编码器引脚触发中断后,B相引脚只要接发高低电平即可,无需再进入中断了。

A脉冲为上升沿,B脉冲为高电平,方向为负;
A脉冲为上升沿,B脉冲为低电平,方向为正。

二、Arduino Encoder.h库相关知识

原文:https://www.pjrc.com/teensy/td_libs_Encoder.html

1.硬件要求

编码器有2个信号,必须2个引脚,接法有3种选择:

(1)最佳性能:两个信号都连接到中断引脚。

(2)良好的性能:第一个信号连接到中断引脚,第二个信号连接到非中断引脚。

(3)低性能:两个信号都连接到非中断引脚。

常见Arduino开发板的中断引脚选择如下表所示,记住不要选择13号引脚,13号引脚是自带指示灯引脚。

低成本编码器仅将其引脚接地,此时编码器将激活片上上拉电阻。如果连接较长的电线,添加 1K 上拉电阻可能会提供更好的信号。

2. 基本用法

(1)Encoder myEnc(pin1, pin2);
使用 2 个引脚创建一个编码器对象。您可以创建多个Encoder对象,每个对象使用自己的 2 个引脚。第一个引脚应该能够中断。如果两个引脚都具有中断功能,则两者都将用于获得最佳性能。如果两个引脚都没有中断,编码器也将在低性能轮询模式下工作。

(2)myEnc.read();
返回累积位置。这个数字可以是正数或负数。

(3)myEnc.write(newPosition);
将累积位置设置为新数字。

3. 了解正交编码信号

编码器可以通过检测孔或标记移动超过2个位置来感知任一方向的移动。下图中的蓝色圆盘顺时针旋转时,首先由引脚 1 检测到变化,然后由引脚 2 检测到变化。当它逆时针旋转时,引脚 2 首先检测到变化。这种方案被称为“正交编码”,因为 2 个引脚检测到的波形相位相差 90 度。

编码器库监视 2 个引脚并更新位置相对变化的计数。库在每次更改时更新其计数,这通常称为 4X 计数,因为编码器硬件中的每个物理标记或孔都有 4 个计数可用。

顺时针转动




逆时针转动



4. 示例程序

该示例程序可从以下菜单获得:文件 > 示例 > Encoder> TwoKnobs。

1.   #include <Encoder.h>
2.
3.  // 将这些引脚号更改为连接到编码器的引脚
4.  // 最佳性能:两个引脚都具有中断能力
5.  // 良好性能:只有第一个引脚具有中断能力
6.  // 低性能:两个引脚都没有中断能力
7.
8.  Encoder knobLeft(5, 6);
9.  Encoder knobRight(7, 8);
10.
11. // 避免使用带有 LED 的引脚,一般为13号引脚
12.
13. void setup() {
14.   Serial.begin(9600);
15.   Serial.println("TwoKnobs Encoder Test:");
16. }
17.
18. long positionLeft  = -999;
19. long positionRight = -999;
20.
21. void loop() {
22.   long newLeft, newRight;
23.   newLeft = knobLeft.read();
24.   newRight = knobRight.read();
25.   if (newLeft != positionLeft || newRight != positionRight) {
26.     Serial.print("Left = ");
27.     Serial.print(newLeft);
28.     Serial.print(", Right = ");
29.     Serial.print(newRight);
30.     Serial.println();
31.     positionLeft = newLeft;
32.     positionRight = newRight;
33.   }
34.   // 如果从串行监视器发送一个字符,将两者knobLeft、knobRight都重置为零
35.   if (Serial.available()) {
36.     Serial.read();
37.     Serial.println("Reset both knobs to zero");
38.     knobLeft.write(0);
39.     knobRight.write(0);
40.   }
41. } 

5. 中断延迟要求

编码器需要对信号变化的低延迟响应。使用带中断的第一个或两个引脚效果很好。但是,如果中断被您的代码或其他库长时间禁用,编码器可能会错过更改。结果是计数不正确。接下来的 1、2 或 3 次更改可能会产生错误的结果。

SoftwareSerial 和 NewSoftSerial 很可能会导致问题。

6. 优化中断选项

在Arduino种,Encoder 使用以汇编语言编写的非常优化的中断例程。通常,Encoder 使用 attachInterrupt (),它允许将函数动态附加到每个中断。动态函数调用会增加一些开销overhead。要消除此额外开销,您可以使用此选项。

1.   // 此选项可以设置使Encoder使用更优化的代码,
2.  // 必须放在Encoder.h前定义。
3.  #define ENCODER_OPTIMIZE_INTERRUPTS
4.  #include <Encoder.h>

注:overhead是系统开销,本来直接走路不用花钱,可是浪费时间。有时候,路远了,花点钱坐车还是必要的。在计算机里面,系统开销可能会暂用一些资源,但有时候能提高效率。

编码器将直接定义中断的最小开销。但是如果任何其他代码或您使用的任何库需要 attachInterrupt()函数,将会发生冲突。

7. 最大速度和 CPU 使用率

SpeedTest 示例,在File > Examples > Encoder > SpeedTest中,提供了一种简单的方法来验证 Encoder 消耗了多少 CPU 时间。测量了以下 SpeedTest 结果:

8. 低性能轮询模式

如果两个引脚都没有中断能力,编码器仍然可以工作。仅在每次使用 read () 函数期间检查信号。只要你的程序继续足够快地调用read (),你就会得到准确的结果。用于仅由人类手指转动的刻度盘或旋钮的低分辨率旋转编码器是低性能轮询模式的良好候选者。连接到电机的高分辨率编码器通常需要中断!

对于 Arduino Uno、Duemilanove 或 Mega,Serial.print() 可能会造成麻烦。Arduino 1.0 提供传输缓冲,比 Arduino 0023 和更早版本的效果要好得多。无论哪种方式,都应使用高速波特率,并且最大限度地减少传输的数据量会有所帮助。


总结

本文介绍了编码器相关的知识,以及ARDUINO Encoder.h库的使用。

玩转电机驱动——电机编码器相关推荐

  1. STM32应用(九)编码器及其测速原理、L298N电机驱动控制编码器电机

    文章目录 1.L298N电机驱动 1.1 产品参数 1.2 实物图和接线 2.编码器 2.1 编码器简介 2.2 常用编码器分类 2.3 霍尔编码器实物图接线!!!! 2.4 编码器倍频原理 3.控制 ...

  2. 玩转电机驱动——A4950闭环驱动直流减速电机(Arduino)

    玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 文章目录 玩转电机驱动--A4950闭环驱动直流减速电机(Arduino) 前言 一.PWM信号 二.PID控制简介 三.增量式(速度 ...

  3. 计算机中编码器的作用,电机编码器的作用-与非网

    硬件型号:TRDS400BKOYO步进电机编码器 系统版本:电机编码器系统 速度测量和定位,编码器是一种将信号(如比特流)或数据编译并转换成可用于通信.传输和存储的信号形式的设备.编码器将角位移或线性 ...

  4. 电机编码器的使用方法

    电机编码器位置的校正原理(PMSM Encoder Calibration) 绝对编码器 不需要在运行开始前进行参考点的定位(增量编码器需要先找到Z信号),即便是在掉电期间产生的转动也不妨碍后续上电后 ...

  5. 电机编码器调零步骤_西门子伺服电机电缆选型

    点击上方蓝字"西家传动" 关注公众号! 一.伺服电机电缆简介 1.订货号编码 对于1FT7/ 1FK7/ 1PH8电机而言,电机使用的电源电缆和编码器信号电缆可以使用预制电缆.电缆 ...

  6. 电机编码器调零步骤_各种编码器的调零方法

    各种编码器的调零方法 增量式编码器的相位对齐方式 增量式编码器的输出信号为方波信号, 又可以分为带换相信号的增量式编码器和普通的增量 式编码器,普通的增量式编码器具备两相正交方波脉冲输出信号 A 和 ...

  7. 电机编码器调零步骤_编码器原理、霍尔应用原理、调整步骤三个方面进行解读编码器调试...

    电机中若具备电子铭牌功能,在应用中就可以直接使用,不需要需要调整编码器:如雷赛交流伺服电机具有电子铭牌功能,能自动识别电机型号,参数并对应匹配参数就能发挥伺服优异性能.若不具备电子铭牌功能的电机,则需 ...

  8. 电机编码器调零步骤_BLDC电机换向方法解析

    无刷直流电机 无刷直流电机(或简称 BLDC电机)是一种采用直流电源并通过外部电机控制器控制实现电子换向的电机.不同于有刷电机,BLDC 电机依靠外部控制器来实现换向.简言之,换向就是切换电机各相中的 ...

  9. 电机编码器调零步骤_蒂森电梯编码器整定和主机整定大全

    CT 编码器整定操作步骤 1. 断开电源,吊起轿厢,空开曳引轮钢丝绳. 2. 取出主板 JP5 的 9 与 10.11.13 的线并短接一起. 3. 送电后确认 KAS,KAD,继电器吸合,接触器 K ...

最新文章

  1. 开坑,写点Polymer 1.0 教程第3篇——组件注册与创建
  2. 停笔几天,休息一下也顺便思考一下人生
  3. bert中文预训练模型_[中文医疗预训练模型] MC-BERT
  4. [全文索引]非索引字表
  5. Hadoop MapReduce概念学习系列之mr程序详谈(二十三)
  6. 同类分析比较工具 google trend
  7. Linux企业级项目实践之网络爬虫(28)——爬虫socket处理
  8. Python连接SQL Server数据库 - pymssql使用基础
  9. 神经网络 tensorflow :损失函数
  10. 变量定义和声明的区别~~~概念上千万不要栽跟头!!!
  11. php做一个微信退款,PHP实现微信退款功能
  12. 双飞翼布局内容不换行_web前端入门到实战:圣杯布局和双飞翼布局
  13. fortran基础知识1----循环
  14. 类如何调用自己的私有成员_企业如何快速获取自己的私有领域流量?
  15. PHP使用CURL使用问题
  16. python:实现培根密码算法(附完整源码)
  17. 管理软件软件开发_管理在软件开发中的作用
  18. 以太坊2.0协议核心Beacon链详解
  19. 免费顺丰快递单号查询API接口demo【快递鸟API接口】
  20. 天气预报今天几点下雨_天气预报今天几点下雨【相关词_ 天气预报明天几点下雨】...

热门文章

  1. windows200/Xp关机重起代码
  2. 平民如何在Labview2017中安装正版的DAQmx和Mathscript驱动?
  3. vue数据恢复_Vue 恢复初始值的快速方法
  4. 使用Candance FPGA System Planner和Alitum Designer Scripting加速原理图设计
  5. 课堂讨论:软件改变世界
  6. 利用tc和iptables对ftp上传下载进行限速
  7. Mac m1恢复出厂设置
  8. 【JAVA基础速过】Java编程入门
  9. 初学者必学项目之C++实现简易通讯录
  10. 一篇很好的关于Android的本科毕业论文《基于android手机通讯录的设计与实现毕业论文》转自百度