原理参考:https://www.arduino.cn/thread-42559-1-1.html

https://blog.csdn.net/qq_42795251/article/details/90057308

摘要:

利用Arduino、增量式光电编码器测量速度、方向、位移。

材料:

  • Arduino mega 2560
  • 分辨率256 ABZ相增量式编码器
  • pc

编码器简介

编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。(对于电机测速来说应该需要将角位移转变为电信号,所以应该是码盘。)按照工作原理编码器可分为增量式和绝对式两类。增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。(淘宝上搜“带编码器的电机”大多是这种类型的编码器)绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。(From 百度百科)

旋转编码器

旋转编码器是一种光电式旋转测量装置,它将被测的角位移直接转换成数字信号(高速脉冲信号)。编码器如以信号原理来分,有增量型编码器,绝对型编码器。我们通常用的是增量型编码器,不同型号的旋转编码器,其输出脉冲的相数也不同,有的旋转编码器输出A、B、Z三相脉冲,有的只有A、B相两相,最简单的只有A相。

  1. 如单相联接,用于单方向计数,单方向测速。
  2. A.B两相联接,用于正反向计数、判断正反向和测速。
  3. A、B、Z三相联接,用于带参考位修正的位置测量。

测速原理


脉冲数/(编码器分辨率*时间)

A脉冲为下降沿,B脉冲为高电平,方向为正;

A脉冲为下降沿,B脉冲为低电平,方向为负。
————————————————


测试代码

/** 测速原理脉冲数/(编码器分辨率*时间)A脉冲为下降沿,B脉冲为高电平,方向为正;A脉冲为下降沿,B脉冲为低电平,方向为负。*/#include <FlexiTimer2.h>  //定时器库头文件#define PinA 2 //外部中断0
#define PinZ 3 //外部中断1
#define PinB 8 //编码器的OUT_B信号连接到数字端口8//变量初始化
const double sampTime = 100;  // 定时器周期100ms,采样频率10Hzvolatile long time1;
volatile int num = 0;//采样周期内圈数,由Z相中断计数
volatile double count = 0;   // 脉冲数计数器,由A相计数
int tmp = 0;  //暂存编码器计数脉冲数值volatile float spdVal = 0;  //采样周期内,返回的速度计算结果
volatile double distance = 0;
const float D = 0.30; //轮子的直径,单位m
const float pi = 3.141592654;//圆周率Z相零位中断子程序
//void Set_state(){
//    tmp = count; //暂存当前A相计数
//    count = 0;  //脉冲计数归零
//    num +=1;
//}// 编码器B相脉冲计数中断子程序
void Encode()
{//为了不计入噪音干扰脉冲,//当2次中断之间的时间大于0.1ms时,计一次有效计数if ((millis() - time1) > 0.1){//当编码器码盘的OUTA脉冲信号下跳沿每中断一次,if ((digitalRead(PinA) == LOW) && (digitalRead(PinB) == HIGH)){count++;}else{count--;}}time1 == millis();
}// 编码器转速计算中断子程序
void Speed(){spdVal = 60 * (count/256)/(sampTime/1000);distance += (count/256) * pi * D;count = 0;Serial.print("The wheel has run : ");Serial.print(distance); Serial.println("m.");Serial.print("The w_speed is:  ");Serial.print(spdVal); Serial.println("r/min.");
}
void setup(){pinMode(PinA, INPUT_PULLUP);//因为编码器信号为欧姆龙E6B2-CWZ6C,为开漏输出,因此需要上拉电阻,此处采用arduino的内部上拉输入模式,置高pinMode(PinB, INPUT_PULLUP);//同上pinMode(PinZ, INPUT_PULLUP);//同上attachInterrupt(0, Encode, FALLING);//触发脉冲中断函数:执行Encode函数,捕捉A相信号,并判断A、B相先后顺序
//    attachInterrupt(1, Set_state , FALLING);//用于在捕捉到Z的零信号时,进行状态置零FlexiTimer2::set(sampTime,Speed);  //设置计时器参数以及终端子程序FlexiTimer2::start(); Serial.begin (9600);}void loop(){}

测试结果

用手转动编码器码盘,转速测量结果如下,但可信度和准确度有待考量,请按需改进优化。


定时器中断

arduino-mega2560上要用FlexiTimer2.h,否则编译能通过,但不会产生定时中断,中断库函数在附件中查看。

#include <FlexiTimer2.h >

void flash() {
  static boolean output = HIGH;

digitalWrite(13, output);
output = !output;
}

void setup() {
  pinMode(13, OUTPUT);
  FlexiTimer2::set(1000, flash);
  FlexiTimer2::start();
}

void loop() {

}


变量命名

volatile (易变变量)

volatile关键字

volatile这个关键字是变量修饰符,常用在变量类型的前面,以告诉编译器和接下来的程序怎么对待这个变量。

声明一个volatile变量是编译器的一个指令。编译器是一个将你的C/C++代码转换成机器码的软件,机器码是arduino上的Atmega芯片能识别的真正指令。

具体来说,它指示编译器编译器从RAM而非存储寄存器中读取变量,存储寄存器是程序存储和操作变量的一个临时地方。在某些情况下,存储在寄存器中的变量值可能是不准确的。

如果一个变量所在的代码段可能会意外地导致变量值改变那此变量应声明为volatile,比如并行多线程等。在arduino中,唯一可能发生这种现象的地方就是和中断有关的代码段,成为中断服务程序。
例子

//当中断引脚改变状态时,开闭LEDint pin = 13;
volatile int state = LOW;void setup()
{pinMode(pin, OUTPUT);attachInterrupt(0, blink, CHANGE);
}void loop()
{digitalWrite(pin, state);
}void blink()
{state = !state;
}

Arduino学习笔记(14)-- Arduino使用增量编码器测速相关推荐

  1. 学习笔记:多目标跟踪对车辆进行测速

    基本原理: 最近一直在研究车辆的多目标跟踪,经常可以看到基于目标跟踪进行测速的视频,进行了短暂的研究,记录一下学习笔记. 视频车辆测速一般需要知道两帧的目标坐标,也就是像素坐标,根据其两帧之间的时间间 ...

  2. arduino学习笔记十--Arduino 读红外测距传感器

    Arduino 读红外测距传感器GP2D12 实例,仅供大家参考! 器材:Arduino 开发板,GP2D12,1602 字符液晶,连接线若干. GP2D12 是日本SHARP 公司生产的红外距离传感 ...

  3. 【Arduino学习笔记】Arduino的反正切函数atan()

    用法: float a: a=atan(x): 得到的是弧度

  4. Arduino学习笔记2

    一.蜂鸣器输出实验 1.源代码 int buzzer=2;//设置控制蜂鸣器的数字口对应板子上2口 void setup() { pinMode(buzzer,OUTPUT);//设置对应的输出模式 ...

  5. Arduino学习笔记(1):太极创客 第一部分

    Arduino学习笔记 太极创客 第一部分 笔记 1-5 变量 1-6 程序结构 1-7 变量操作 1-8/1-9 程序函数 1-10/1-11 数字输出 1-12 面包板 1-13/1-14 数字输 ...

  6. 单片机学习笔记(Arduino Uno r3)

    单片机学习笔记(Arduino  Uno r3) Aduino是什么? 分为硬件和软件两个部分,硬件和软件共同组成了Arduino,使用时须将Arduino硬件和软件配合使用 硬件:Arduino系列 ...

  7. arduino 学习笔记及课件01基础入门

    arduino 学习笔记及课件01基础入门 以下学习笔记中图片部分由太极创客视频截图所得 概论 一. 引脚及信号 1.1引脚模式 INPUT:当Arduino没有使用上拉电阻或下拉电阻而直接与开放的开 ...

  8. Arduino学习笔记(5)-- 步进电机转速和方向控制

    本文尝试用Arduino开发版控制42步进电机,搭配通用的步进电机驱动器,实现对步进电机的转速控制和方向控制. 原材料: Arduino开发板及附件 42步进电机和配套驱动器 电源 接线方式:共阴 总 ...

  9. node.js学习笔记14—微型社交网站

    node.js学习笔记14-微型社交网站 1.功能分析 微博是以用户为中心,因此需要有注册和登录功能. 微博最核心的功能是信息的发表,这个功能包括许多方面,包括:数据库访问,前端显示等. 一个完整的微 ...

最新文章

  1. 香港中文大学 (深圳) -博士硕士招生 -智能优化及规划方向
  2. 华为云计算FusionCompute环境部署实验之使用批量部署工具安装
  3. wdtree简介、使用
  4. ecs 云服务器 管理控制台_阿里云ECS服务器监控资源使用情况
  5. jQuery10种不同动画效果的响应式全屏遮罩层
  6. 【faebdc的模拟赛】T2分组
  7. 【Webpack】TypeError: Cannot read property ‘tap‘ of undefined at HtmlWebpackPlugin.
  8. 远程mysql用ssh连接_使用SSH密钥连接到远程MySQL服务器
  9. Java并发容器--ConcurrentLinkedQueue
  10. 修改hosts文件,解决端口占用方法
  11. MOSSE相关滤波跟踪算法
  12. 2020-2023保时捷Taycan维修手册电路图技术培训手册用户手册电动汽车技术资料
  13. EXCEL 电子游戏销售数据分析项目
  14. 如何用自己的电脑开WiFi热点
  15. 苏州外包php,【苏州IT外包经验】Ubuntu 17.10系统下配置PHP+Apache+Mysql
  16. sturts2框架知识点(Struts2框架----今天脑子有点炸)
  17. mysql建立数据库并给定别名_MySQL数据库基本操作(四)
  18. 算法警告!该图片涉嫌违规不予显示
  19. Ionic + Vue3 + Capacitor 配置应用信(App 包名、应用名、应用图标、启动动画、版本信息)
  20. 计算机成下一个土木了??

热门文章

  1. 塑造成功性格的15种方法
  2. Docker——Docker 容器数据卷(Volumes)
  3. 进阶篇-SpringBoot2.x自定义starter启动器
  4. mysql从数据库误删.idb / .frm 文件,恢复数据方法
  5. arduino实现rgb灯循环亮起
  6. 计算机沟通管理技巧,语言沟通技巧
  7. 2021高考成绩特长生查询,2021高考体育生分数怎么算 体育四项评分标准及分值一览表...
  8. 查看linux 系统 服务器型号
  9. layui 如何取得select下拉框选中的值
  10. 查找网站真实IP的方法大全