【ESP32 Arduino平衡小车制作】(一)霍尔编码器解码
在接下来的时间里,我将记录ESP32 Arduino平衡小车制作的全部过程。
esp32 arduino平衡小车制作(一)
- 一、编码器介绍
- 1-1增量式编码器
- 1-2 绝对式编码器
- 二、常用测速方法
- 2-1 M 法(高速):
- 2-2 T 法(低速):
- 2-3 M-T 法:
- 三、ESP32编码器程序
- 3-1正交信号
- 3-2 代码编写
- 四、速度计算
一、编码器介绍
1-1增量式编码器
增量式旋转编码器是将设备运动时的位移信息变成连续的脉冲信号,脉冲个数表示位移量的大小。只有当设备运动的时候增量式编码器才会输出信号。编码器一般会把这些信号分为通道A和通道B 两组输出,并且这两组信号间有90° 的相位差。同时采集这两组信号就可以知道设备的运动和方向。
增量式编码器只输出设备的位置变化和运动方向,不会输出设备的绝对位置。
1-2 绝对式编码器
绝对式旋转编码器是将设备运动时的位移信息通过二进制编码的方式变成数字量直接输出。
这种编码器与增量式编码器的区别主要在内部的码盘。
二、常用测速方法
2-1 M 法(高速):
在一个固定的定时时间内(以秒为单位),统计这段时间的编码器脉冲数,计算速度值。
设编码器单圈总脉冲数为C,在时间T0 内,统计到的编码器脉冲数为M0,则转速n 的计算公式为:公式中的编码器单圈总脉冲数C 是常数,所以转速n 跟M0 成正比。
2-2 T 法(低速):
建立一个已知频率的高频脉冲并对其计数,计数时间由捕获到的编码器相邻两个脉冲的间隔时间TE 决定,计数值为M1。
设编码器单圈总脉冲数为C,高频脉冲的频率为F0,则转速n 的计算公式为:公式中的编码器单圈总脉冲数C 和高频脉冲频率F0 是常数,所以转速n 跟M1 成反比
2-3 M-T 法:
既测量编码器脉冲数又测量一定时间内的高频脉冲数。在一个相对固定的时间内,计数编码器脉冲数M0,并计数一个已知频率为F0 的高频脉冲,计数值为M1,计算速度值
设编码器单圈总脉冲数为C,则转速n 的计算公式为:
由于M/T 法公式中的F0 和C 是常数,所以转速n 就只受M0 和M1 的影响。电机高速时,M0增大,M1 减小,相当于M 法,低速时,M1 增大,M0 减小,相当于T 法。
三、ESP32编码器程序
3-1正交信号
编码器返回的数据是一组正交信号,由于Arduino和ESP32都没有正交解码功能,所以要想实现正交解码功能的话就需要用两个io口来同时判断当前是属于状态。
一个脉冲信号周期完成4次跳变。精度提高
1时刻:TI2为低电平,TI1上升沿跳变,计数器向上计数;
2时刻:TI1为高电平,TI2上升沿跳变,计数器仍然向上计数;
3时刻:TI2为高电平,TI1下降沿跳变,计数器仍然向上计数;
4时刻:TI1为低电平,TI2下降沿跳变,计数器仍然向上计数。
3-2 代码编写
首先需要宏定义当前的使用的io口和中断时间。
#define ENCODER_L 5 //编码器采集引脚 每路2个 共4个
#define DIRECTION_L 18
#define ENCODER_R 4
#define DIRECTION_R 19
#define interrupt_time 20 // 中断时间
配置对应的io口,一个编码器需要两个io口,一个用来检测外部跳边沿中断,另一个来判断方向。
但是这个对于毛刺确实无法识别的,当有毛刺出现的时候也会计做是正常的脉冲,这也就是为什么esp32做软件正交解码的缺点,计数值也会改变
#include <Arduino.h>
#include<Ticker.h>Ticker timer_read_encoder; // 中断函数定时器定义void setup()
{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_Rinterrupts(); //打开外部中断 timer_read_encoder.attach_ms(interrupt_time, read);
}void loop()
{Serial.print("Velocity_L:");Serial.print(Velocity_L);Serial.print(" | Velocity_Left:");Serial.println(Velocity_Left);Serial.print("Velocity_R:");Serial.print(Velocity_R);Serial.print(" | Velocity_Right:");Serial.println(Velocity_Right);
}
下面的部分放到主函数之前就可以,主要是跳变沿中断函数READ_ENCODER_L ()和READ_ENCODER_R()和定时器中断函数READ()。
int32_t Velocity_L, Velocity_R; //左右轮编码器数据
int16_t Velocity_Left, Velocity_Right; //左右轮速度void READ_ENCODER_L(void);
void READ_ENCODER_R(void);
void read(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 read(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; //读取右轮编码器数据,并清零}
四、速度计算
首先我们的esp32实际使用的m法测速,即:计算固定时间内的脉冲数。
编码器如果想把速断计算为转速n/s具体步骤如下:
①明确参数:编码器规格:500线(转一圈是500个脉冲), 定时时间为interrupt_time(单位MS)
②固定时间内的圈数M:脉冲数num/500
③转换为秒:固定时间内的圈数/interrupt_time(单位ms)
总的来说公式就是num*2/interrupt_time,
这里我的时间是20ms,所以转速为num/500/20ms=num*40。
【ESP32 Arduino平衡小车制作】(一)霍尔编码器解码相关推荐
- Arduino ESP32自平衡小车制作实现(不需编码器)
1_mpu6050陀螺仪角度方向和静态平衡角度测试 /*说明:1[陀螺仪补偿值的计算]试时提前用calcGyroOffsets(true)函数计算出,补偿值.知道mpu6050的补偿值后用setGyr ...
- Arduino平衡小车
Arduino平衡小车 1.概述 此Arduino平衡小车在主控方面由Arduino UNO R3和Arduino sensor shield v5.0传感器扩展板组成.采用TB6612FNG作为电源 ...
- TT马达平衡小车制作
TT马达平衡小车制作 假期无聊本来买个淘宝的寻迹小车套件,做了个寻迹小车和遥控功能.后来看到了平衡小车就想搞一个. 去搜了方案基本都是平衡小车之家的编码器电机和车模,一搜好几百,学生党不太买得起. 还 ...
- 【平衡小车制作】(一)硬件原理图讲解(超详解)
大家好,我是小政.之后的一系列文章我将介绍我玩平衡小车的过程以及遇到的一些问题,将这些内容记录下来分享给大家,也让大家少走一些弯路.接下来我将从硬件框架选择.软件编程.PID算法.PID调参.蓝牙 ...
- 平衡小车制作系列之八——总结
文章目录 一. 前言 二. 说在最前面 2.1 模块总结 2.2 时间分配(2 Weeks In All) 2.3 一些问题 三. 收获与总结 四. 碎碎念 一. 前言 本博客原题目叫做"我 ...
- 【平衡小车制作】(七)串级PID调参及平衡成果展示(超详解)
大家好,我是小政.本篇文章我将针对PID调参进行详细的讲解,让每位小伙伴能够对比例.积分.微分三个参数如何调节有更加清晰的理解. 一.调参步骤 确立机械中值 直立环(内环)--Kp极性.Kp大小. ...
- 平衡小车制作系列之二——模块原理解析
文章目录 一. 模块概述 二. 直流电机 2.1 直流电机介绍 2.2 直流电机外围设备介绍 2.2.1 减速器 2.2.2 控制PWM的单片机 2.2.3 编码器 三. 编码器 3.1 编码器介绍 ...
- 简单平衡小车制作过程中遇到的问题
本人最近做了一个平衡小车,过程中遇到不少问题,在这里总结一下,可能也会帮助到大家 文章目录 前言 一.嫖资料,找教程 二.小车结构 三.电子元件的组装 四.写程序时(改嫖到的程序)遇到的问题 总结 前 ...
- arduino平衡小车教程
[Arduino项目]使用 arduinoDIY平衡小车教程 --------------------------------------------------------------------- ...
- (六)【平衡小车制作】位置式PID、直立环与速度环编程
本篇文章我将针对位置式PID算法.直立环.速度环等的编程进行详细的讲解,让每位小伙伴能够对这三个概念的编程逻辑有更加清晰的理解. 一.直立环(PD控制器) 1.中文公式 直立环输出=Kp1×角度偏差 ...
最新文章
- ACM 中常用的算法有哪些?
- java400状态,java – HttpURLConnection:如何读取400响应的有效负载
- 单链表的操作_二分查找
- 运用多种知识点实现一个综合小游戏
- OS_CORE.C(2)
- SpringBoot热部署之devtools案例(学习笔记)
- CTSCAPIO被教做人记
- java 监控 native 内存_JVM NativeMemoryTracking 分析堆外内存泄露
- CentOS7环境下搭建ElasticSearch
- 风起云涌、战火通明,2019 年云计算大盘点
- python日志记录_Python日志记录
- HTML5 — 知识总结篇《III》【文本元素】
- Mysql:日志管理:二进制事务日志
- 利用Python收发邮件
- DiskImage磁盘镜像工具下载使用手册
- MAC终端命令自动补全
- mysql 前缀索引_mysql索引做前缀原则
- oracle新增字段 加注释,Oracle数据库表的字段添加注释和向现有表添加字段 | 学步园...
- 我的测试图片vr(后前-上下-左右)
- esp笔记(4)esp8266 连接路由器