干货—花钱都买不来的光栅编码器高倍细分算法—基础篇(图文)
其他
2020-03-29 17:09:03
阅读次数: 0
背景知识
光栅编码器原理
- 主要就是对莫尔条纹的理解,如果链接失效请自己补充相关知识,这里就不展开了。
- 光栅编码器原理
编码器种类
- 有增量编码器,绝对值编码器,增量/绝对值编码器又可以分为线性编码器、角度编码器(就那种按圈走的)。根据原理又可以分为一大堆,这里不展开了,感兴趣的可以自己查阅资料全面了解一下。这篇文章介绍的细分算法是基于线性编码器。
光栅编码器输出信号
编码器组件
- 光栅编码器包括光栅尺+读数头;
- 光栅尺的材质有玻璃、不锈钢或者PCB基板,其实就是跟我们上学时用的尺子差不错,根据刻度精度不同,价格也不同。栅距有20um、50um等等。这篇文章用的是玻璃尺,栅距=20um;
- 读数头是光栅编码器的核心,他的作用是滤波—>放大—>采集光电信号—>数据处理—>滤波—>输出需要的A-quad-B或则Analog信号。
- 安装时,光栅尺是固定不动的,读数头是移动的;
输出信号类型
- 光栅编码器输出的信号类型有模拟量输出、数字量输出两种;
- 模拟量信号输出的是模拟信号sin/cos,有的编码器是直接输出模拟量sin/cos,有的是将sin/cos在读数头中处理成差分sin/cos再输出;
- 数字量输出的是数字信号A-quad-B,有的编码器是直接输出数字量信号A-quad-B,有的是将A-quad-B在读数头中处理成差分A-quad-B再输出;
- 编码器根据需要可以选用带有index标记也可以不选。这篇文章用的encoder带有index,但是没有使用。
输出信号电压
- 对于模拟量信号:当编码器供电5V时,输出的sin/cos信号共模电压=2.5V,Vpp=0.5V;当供电3.3V时,输出的sin/cos信号共模电压=1.65V,Vpp=0.5V;
- 对于A-quad-B信号:输出的信号是幅值=供电电压;
开发平台介绍
- 自制主控STM32开发板,芯片STM32F103RCT6;
- 自制细分盒开发板,芯片STM32F103C8T6;
- Visual Studio 2017 + Visual GDB;
- 线性光栅编码器1个;
- 示波器一台,观察光栅信号波形;
- 激光干涉仪一台,测试移动位移;
细分盒电路系统设计方案
- 这篇文章用的encoder输出差分模拟信号,带有index,虽然没有使用,但还是在图中标出来。
- encoder供电3.3V,所以输出的差分sin/cos信号共模电压=1.65V,Vpp=0.5V。
- 因为使用的是单极性ADC,满量程范围是0-3.3V,所以差分信号经过放大器后要转成0-3.3V的单端信号。
- 两路单端信号幅值相等,相位相差90°,所以就用sin/cos表示,然后用两路ADC分别采集sin/cos信号,送入MCU做数据处理。
细分算法原理(核心)
8倍细分(基础)
- 再进行高倍细分前,需要先进行8倍细分。先将ADC采集到的值归一化到[-1,1],归一的化的目的一是可以去除直流分量,二是为了更好细分做准备。8倍细分是利用值的正负来划分区间。具体用下图进行阐述。
- 光栅尺走完20um输出一个周期的波形。人为规定向右是正向移动(+),向左是反向移动(-);
- 假定t0时刻红色波形送入ADC1,黑色波形送入ADC2,同时构造一个新函数u=abs(sin)-abs(cos),u波形是蓝色。那么可以得出下列表格:
大区间号 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
u |
<0 |
>=0 |
>0 |
<0 |
<0 |
>=0 |
>0 |
<0 |
sin |
>=0 |
>0 |
>0 |
>0 |
<0 |
<0 |
<0 |
<0 |
cos |
>0 |
>0 |
<0 |
<0 |
<0 |
<0 |
>=0 |
>0 |
- 正向运动时大区间号的变化规律是12345678->1234…,是从8——>1的变化;反向运动的大区间号变化规律是87654321->876543…,是从1——>8的变化。通过符号就可以获得8倍细分即细分当量是20um/8=2.5um,并还可以进行辩向。
- 假定正向运动时ADC1的波形超前ADC2 90°,反向运动时ADC2超前ADC1 90°,但是不管运动方向如何,大区间号永远落在1-8之间。
- 如果2.5um的细分当量满足需求那么就不想再进一步细分了。
- 8倍细分的方式很多,各大论文上也都会提出不同的方法,但是这些各大论文对如何进行高倍细分以及如何辩向都是一笔带过。
4000/20000倍细分及辩向(进阶)
- 篇幅较长另开一篇博文介绍
- 内容包括:
- 1、如何实现4000倍、20000倍甚至更高倍细分;
- 2、如何只用两路模拟信号sin/cos就可以实现辩向功能
- 3、部分关键代码
- 4、细分算法实施步骤总结
细分误差原因分析及解决方案
- 影响细分精度的原因有sin/cos的正交性、sin/cos的幅值、sin/cos中含有的直流分量、sin/cos中含有的谐波分量;
- 硬件上调节放大器的反馈电阻改变放大倍数可以解决sin/cos幅值不一致的问题;
- 幅值修正后,在处理数据时可以让采集的ADC值减去共模电压值,比如用12bit ADC,adc_value-2^11就可以去除直流分量(因为幅值可以调整的基本相等并达到adc满量程,默认共模电压就是2047);幅值调好后可以直接进行归一化解决掉直流分量;
- 谐波分量没招,反正影响也不是很大;
- 正交性是影响最大的,在组装时如果安装不到位sin/cos相位正交性会很差,另外就算完美安装,可以用的光栅尺读数头性能并不是很好,也会导致正交性很差,差个2°,3°甚至十来度都有可能。即使正交性不好,没关系,我们还有相位补偿技术,相位补偿技术另开博文,这里不展开。
- 有的光栅编码器厂家,尤其是那些专门做精密编码器的厂家都会配有一个“adjust tool”帮助客户调整安装后的读数头,使其输出信号质量达到最优。
光栅尺闭环运动PID控制
- 细分算法带有辩向功能,所以得到的位移可以是正负值;
- 闭环期间,我会用一个变量存储得到的位移sum=sum+位移,然后把sum值发给控制器,sum值代表的是物体相对于起点的实际位移。闭环结束后释放sum,准备下一次闭环运动。
- PID的控制算法网上太多啦,我用的位置增量式PID。用C语言表达增量式PID和位置式PID理论公式
总结与展望
- 这里要提一下,在进行高倍细分时,细分用的电路板系统噪声很关键,在设计完板子后一定要评估下板子的静态噪声,看看adc输出的值波动情况,我自制的细分PCB,adc的输出噪声波动最大是1bit,大部分情况下不足1bit,我觉得已经很好了。ADC是3.3V供电,3.3V/2^11=805.66uV,就是说我的板子噪声大部分情况下不足805uV。
- 切记在高倍细分时板子系统噪声会影响你细分的性能。关于如何评估ADC采集系统噪声请看这篇博文ADC采集系统DC噪声测试及计算和ADC参数ENOB、有效分辨率、无噪声分辨率的理解及计算
- 我的这篇博客里提到的高倍细分算法虽然能进行4000细分甚至20000细分(20000的细分当量是1nm),而且细分的精度也还不错(得益与我的板子噪声很低),但是代码运行的效率并不是很高,经示波器观察发现,执行完一次4000细分代码需要耗时130us左右,我觉得这个时间耗费太长,不利于我接下来进行的高速闭环运动,所以经过一番研究,我又开发出了另外一套全新的细分算法,执行一次20000差值的代码只需60us,效率大大提升,而且细分精度也较优,至于稳定性,还需要大量测试。
发布了76 篇原创文章 ·
获赞 98 ·
访问量 16万+
转载自blog.csdn.net/aqwtyyh/article/details/105106520