干货—花钱都买不来的光栅编码器高倍细分算法—基础篇(图文)

背景知识

光栅编码器原理

  • 主要就是对莫尔条纹的理解,如果链接失效请自己补充相关知识,这里就不展开了。
  • 光栅编码器原理

编码器种类

  • 有增量编码器,绝对值编码器,增量/绝对值编码器又可以分为线性编码器、角度编码器(就那种按圈走的)。根据原理又可以分为一大堆,这里不展开了,感兴趣的可以自己查阅资料全面了解一下。这篇文章介绍的细分算法是基于线性编码器。

光栅编码器输出信号

编码器组件

  • 光栅编码器包括光栅尺+读数头;
  • 光栅尺的材质有玻璃、不锈钢或者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