尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

LabVIEW与固高运动卡实现平面度自动测量系统改造

LabVIEW与固高运动卡实现平面度自动测量系统改造 简介这是一份融合LabVIEW编程、固高运动控制、激光位移传感与PLC通讯的工业自动化实例面向自动化设备开发、运动控制及精密测量方向的技术人员。案例以LabVIEW为控制核心驱动固高运动板卡执行圆弧插补并利用基恩士ILS025激光位移传感器经串口采集高度数据采用最小二乘法拟合平面并计算平面度同时通过MODBUS等协议与欧姆龙PLC联动完整展示从硬件选型到算法落地的闭环流程。资源包内含1200个文件以1052个VI程序为主另有DLL动态库、CTL自定义控件、PNG图片、lvlib库及工程配置等压缩包大小23.24MB便于按需查阅与二次开发。目前已有436人学习下载适合希望借鉴实际项目框架、快速搭建平面度检测原型或研究LabVIEW与多设备集成的中高级开发者。1. 从千分表到激光扫描固高运动卡与平面度自动测量的一次改造先交代一下背景。一条产线上需要对一批加工后的铝合金平板做全检图纸上平面度要求是0.05 mm。原先的做法是用千分表手动打点一块板要测十几分钟手一抖数据就废了而且报告全靠手填。后来拆成了一套LabVIEW 固高运动控制卡 基恩士ILS025激光位移传感器的方案固高卡带着激光探头按规划的路径扫过被测表面探头通过串口把高度数据实时回传LabVIEW在采集结束后用最小二乘法拟合出一个参考平面算出平面度。整套流程跑下来单件检测时间从十几分钟压缩到两分钟以内数据自动归档。这篇文章就把这套系统的拆解过程写出来包含圆弧插补运动控制、ILS025串口数据解析、平面度算法落地以及欧姆龙PLC的MODBUS对接每个环节都给出可复现的参数和代码思路。2. 固高运动卡控制与圆弧插补从加载配置文件到路径规划2.1 固高运动控制卡在整条链路中的定位这套系统里运动控制部分的任务不是简单走个点位而是要让激光探头沿一条S形或者弓字形路径扫过整个被测面。固高运动控制卡在这个场景下有两个不可替代的优势。第一是插补能力固高的GTS系列包括项目里提到的Motion.cfg对应的配置环境支持直线插补、圆弧插补和连续插补路径由上位机下发卡本身负责实时计算各轴脉冲输出不占用Windows的CPU时间片。第二是IO同步平面度测量需要在运动过程中触发传感器采样固高的IO可以配置为与轴运动同步避免出现走了三毫米才触发采样这种位置误差。项目文件里出现的ADO210.CHM是固高提供的光盘帮助文档我实际翻下来发现里面最有价值的部分不是API列表而是控制器运动模式那一节里面明确了点位运动、电子齿轮和插补运动各自适用的场景。Motion.cfg则是运动控制卡的配置备份里面保存了各轴的加减速时间、位置误差报警阈值、伺服使能极性等参数。拿到一台新机器时直接把配置通过固高的调试软件写回去就能省去重新整定参数的环节这个文件上线前务必用FTPS或U盘做双备份。2.2 LabVIEW调用gts.dll从打开控制器到轴参数初始化固高官方提供的是C接口的动态库gts.dll在LabVIEW里通过CLN节点调用即可这也是LabVIEW集成外部硬件最标准的做法。先看一个最简初始化流程包含打开控制器、读取配置、轴参数配置、清除报警和伺服使能// 固高GTS运动控制卡初始化流程C描述LabVIEW通过CLN结点调用同一组API short gtOpen(); // 打开第一块控制器 short gtLoadConfig(Motion.cfg); // 载入轴参数含加减速、报警阈值 short gtClearSts(1, 8); // 清除1~8轴的状态报警 short gtClrPrfMode(1, 8); // 清除规划模式缓存 short gtSetPrfMode(1, 6, 0); // 1轴设为梯形速度模式 short gtAxisOn(1, 8); // 所有轴伺服使能对应到LabVIEW里在程序框图放置调用库函数节点库路径指向gts.dll函数名选gtOpen然后依次串联下去。需要特别注意的是返回值的检查固高的API约定返回值非零即为错误码比如0x0001表示控制器打开失败0x0010表示轴编号越界。我见过不少现场的LabVIEW程序从一开始就没做返回值判断控制器没上电导致初始化失败后续所有运动指令全部静默丢弃表现为设备怎么点都不动。轴初始化完成后务必从Motion.cfg里核对几个关键参数各轴的运动方向是否与机械方向一致正向软限位和负向软限位是否设到了安全范围速度前馈增益是否已整定。IO和限位信号可以在LabVIEW里做一次回环测试让固高输出一个DO信号再从DI读回来。2.3 圆弧插补的路径实现与参数陷阱平面度测量时的扫描路径设计成弓字形遇到圆形凸台或凹坑区域时需要绕行这时就用到了圆弧插补。固高的圆弧插补函数是GT_Arc2D核心参数有6个圆心坐标、终点坐标、方向标志和圆心角。// 在XY平面做一段90度圆弧插补由当前位置(x0, y0)运动到终点(x1, y1) short centerX x0 100; // 圆心X相对起点偏移 short centerY y0; // 圆心Y相对起点偏移 short endX x0 100; // 终点X相对起点偏移 short endY y0 100; // 终点Y相对起点偏移 short flag 1; // 1为逆时针-1为顺时针 double circleAngle PI / 2; // 圆心角单位为弧度 gtArc2D(axisXY, centerX, centerY, endX, endY, flag, circleAngle, 1);在LabVIEW中通过CLN调用这段代码之前需要先弄清楚固高的坐标是相对当前点还是绝对坐标。实际测试后发现GT_Arc2D的终点坐标是以圆弧起点为原点的相对坐标圆心坐标同样是相对起点的偏移量。如果直接把CAD图纸上的绝对坐标填进去轨迹会跑出一个完全不在预期位置的圆。比较稳妥的处理方式是先用GT_GetPrfPos读取当前规划位置由LabVIEW做一次坐标偏移计算生成相对坐标再传给GT_Arc2D。这里还涉及一个精度问题固高的规划器内部对终点坐标有量化误差分段数量越多拼接后的实际轨迹与理论轨迹偏差越小但速度波动也会随之增大。对于ILS025这种测量光斑直径大约0.1 mm的传感器来说把圆弧段插补速度设为60 mm/s以内量化误差对采样点位置的影响可以控制在0.01 mm级别不影响后续平面度计算。下表是GT_Arc2D关键参数在LabVIEW接线时的实际经验值加工程序里直接套这套配置能少走很多弯路。参数建议值/处理方式说明圆心坐标相对起点偏移单位脉冲若机械单位为mm需先乘以电子齿轮比终点坐标相对起点偏移单位脉冲由CAD坐标转相对坐标要减掉起点绝对坐标方向flag逆时针1顺时针-1方向反了轨迹会绕远路圆心角0到2PI之间决定实际走过的弧度缺省会报错插补速度40~80 mm/s速度过快会引入机械振动影响传感器读数3. ILS025激光位移传感器串口采集从串口报文中解出高度值3.1 ILS025传感器的数据输出与通讯约定基恩士ILS025是一款量程为25 mm的激光位移传感器分辨率可以达到微米级别。实际使用中并非直接输出模拟量电压通讯性能要站在串口数据帧解析的角度设计。ILS025出厂时支持两种输出模式一种是最简单的模拟电压输出另一种是通过专用串口线输出数字量。平面度计算要求把传感器读数与运动轴坐标严格对应模拟量方案在LabVIEW里还要自己拟合电压到毫米的标定曲线而且抗干扰能力弱所以直接用串口数字输出是更合适的选择。接线方式是将ILS025的通讯口通过基恩士专用转换线连接到电脑的串口或USB转串口模块。通讯参数中波特率出厂是9600数据位8位停止位1位无校验。需要留意的是ILS025在上电后默认处于单片输出模式需要先发送指令切换到连续输出或指令触发模式才能做到运动过程中不间断采样。3.2 LabVIEW VISA串口初始化与报文解析逻辑在LabVIEW中操作串口最标准的方式是VISA初始化时关键是把通讯超时设短一些。平面度采集场景下如果某个采样点超时与其等1秒然后继续不如把超时设为100 ms以下配合重试机制来保证运动过程中不会因为等待数据而卡住运动缓冲。// LabVIEW VISA串口初始化框图逻辑关键节点序列 VISA资源名ASRL3::INSTR // 串口号需要跟实际设备管理器对应 VISA配置串口.vi 波特率9600数据位8停止位1.0校验NONE 超时100ms VISA写入.vi发送切换指令例如 M1 回车 // 进入循环每读到一帧完整数据立即处理传感器返回的数据帧格式需要在代码中细化处理。在二进制模式下ILS025每帧固定为若干字节其中包含了状态字节、测量值的高16位和低16位以及用于校验的和校验字节。这里要特别强调一个最容易犯的错不要用字符串截取的方式来取数值。ILS025的测量值虽然是按字节传输的但字节序是按照基恩士的协议排布的直接用字符串转数值会把高低字节搞反导致读数放大256倍或者出现负值。正确做法是把测量值区域的4个字节先以U8数组形式取出来按照协议拼接成32位整数再把整数通过除以分辨率系数的方式转换成实际毫米值。3.3 4字节IEEE 754浮点转换与丢帧处理ILS025输出的是整数编码但有些其他型号的激光传感器比如后续替换成其他品牌时会直接输出4字节的IEEE 754单精度浮点数这是LabVIEW串口数据处理里非常典型的一个需求。将4字节转换为浮点数的方式很直接// 字节数组转单精度浮点数IEEE 754 U8字节数组byte[0]..byte[3] 将byte[0]左移24位OR byte[1]左移16位 OR byte[2]左移8位OR byte[3]得到U32整数 将U32数值通过类型转换节点直接转换为SGL单精度浮点数这里的前提是确认传感器输出的字节序是大端还是小端。基恩士的IL系列多是大端输出即最高字节在前欧姆龙的一些传感器则可能不同。如果按错误字节序拼接出来的浮点数会变成一个极大或极小的异常值放进平面度算法里会让整组数据全部报废。一个保险做法是先固定传感器不动读100帧看转换后的数值波动是否在20微米以内如果看到数量级都不对优先怀疑字节序搞反了。另一个实际问题是丢帧。固高运动卡在运动中会不断触发采集信号但Windows下的串口通讯在不使用实时系统时无法保证每一帧都能稳定送达。我们的处理方式是在LabVIEW的采集循环里做一个超时重发机制如果200 ms内没收到一帧完整数据就向ILS025补发一次单次测量指令并把数据帧里自带的计数序号记录下来。一次完整的平面度测量流程结束之后检查计数序号是否连续如果发现跳号就对缺失区域补一次重扫而不是用插值去填充。这么做虽然多花一点时间但能保证参与平面度计算的每一个点都是真实测量值而不是算法猜出来。4. 平面度计算最小二乘拟合在LabVIEW中的工程落地4.1 从测量点集到平面度误差的数学定义平面度的定义是被测实际平面相对于理想平面的变动量而理想平面的位置需要通过一定的评定方法来确定。常用的评定方法有最小区域法、最小二乘法和对角线法三种。最小区域法的结果最接近真实平面度但计算需要迭代寻优工程上很少在LabVIEW里直接实现最小二乘法能够给出唯一解析解计算速度快且当表面质量较好时结果与最小区域法非常接近因此这套系统选择最小二乘拟合作为核心算法。数学上讲假设采集到了n个点的坐标x和y是运动轴位置z是ILS025测量得到的高度值。最小二乘平面拟合的目标是找到一个平面方程z ax by c使得所有测量点到该平面在z方向偏差的平方和最小可以用矩阵方式求解。构建上述超定方程组后最小二乘解即法向方程的闭式解通过对一个3x3矩阵求逆并乘以一个3x1矩阵得到。平面度误差的计算方式是先算出每个点到拟合平面的法向距离取最大值与最小值之差作为平面度误差值。采用法向距离而不是z方向偏差的原因是当被测面相对水平面存在较大倾斜时z方向偏差会混入倾斜分量导致平面度结果虚高。4.2 矩阵求解过程与参考实现为了在LabVIEW里落地这段算法可以先用Python做一次离线验证确认数学推导正确后再移植到LabVIEW。下面的实现直接展示了从测量点到平面参数的完整过程import numpy as np # 假设测量点数据x、y为运动轴坐标(mm)z为传感器高度值(mm) points np.array([ [0.0, 0.0, 0.102], [10.0, 0.0, 0.095], [20.0, 0.0, 0.104], [0.0, 10.0, 0.098], [10.0, 10.0, 0.090], [20.0, 10.0, 0.106] ]) x points[:, 0].reshape(-1, 1) y points[:, 1].reshape(-1, 1) z points[:, 2].reshape(-1, 1) # 构造系数矩阵 A [x, y, 1] A np.hstack([x, y, np.ones_like(x)]) # 最小二乘求解 A * [a, b, c]^T z theta, _, _, _ np.linalg.lstsq(A, z, rcondNone) a, b, c theta.flatten() print(f拟合平面: z {a:.4f}x {b:.4f}y {c:.4f}) # 计算每个点到平面的法向距离 plane_normal np.array([a, b, -1.0]) for point in points: dist (a * point[0] b * point[1] - point[2] c) / np.linalg.norm(plane_normal) print(f点 ({point[0]}, {point[1]}) 的法向偏差 {dist:.4f} mm) # 平面度误差 最大偏差 - 最小偏差 dists (A theta - z).flatten() flatness np.max(dists) - np.min(dists) print(f平面度误差 {flatness:.4f} mm)关键点在于法向偏差的分母项即平面法向量的模长。当a和b都很小说明拟合平面接近水平此时法向距离与z方向偏差几乎一致当a或b较大时两者差异明显。实际测量中如果发现平面度计算结果与塞尺实测结果对不上先检查是不是在这里少除了一个法向模长。4.3 LabVIEW中的求解实现与数据验证在LabVIEW中实现同样的计算有两种路径。第一种是在程序框图中使用线性代数数学函数例如解线性方程节点通过构造法向方程矩阵来求解系数。这种方式贴近LabVIEW原生风格但矩阵维度稍高时手动接线容易出错。第二种是直接写公式节点把上述推导公式转化为文本代码更方便维护和排错。对于平面度计算而言公式节点方式直观便于后续改造成最小区域法。LabVIEW中还需要处理一个采样点坐标同步的问题。固高运动控制卡记录的路径位置是以脉冲为单位的脉冲数需要乘以电子齿轮比换算成毫米再与ILS025的高度数据按时间戳对齐。建议在LabVIEW中为每个采样点构造一个包含x、y、z的聚类数组全部采集完成后再一次性送入平面度计算子VI不要在采集过程中逐点计算否则因为传感器数据到达时序抖动引入的误差点会导致拟合平面偏移。如果需要实时显示当前平面度趋势可以单独开一个循环每20个点做一次局部拟合只是用来观察趋势而非最终结果。验证算法正确性的一个实用方法是做倾斜验证将一块已知平面度的标准平晶放在一块角度垫块上让被测面产生约2度的倾斜角拿到一组带有明显倾斜分量的数据。如果算法的拟合结果在扣掉倾斜分量后平面度仍与平晶标称值在同一数量级说明法向距离计算是正确的。有一个案例中验证时发现计算出的平面度波动达到0.1 mm排查到最后是x、y坐标的单位是毫米而z的单位是微米矩阵条件数异常导致系数a和b虚大统一单位后结果恢复正常。5. 欧姆龙PLC的MODBUS通讯测量站与产线主控的对接5.1 通讯链路设计LabVIEW作为主站主动读写在实际产线中LabVIEW测量站需要把平面度计算结果发给欧姆龙PLC同时从PLC读取当前被测工件的批次号和工位状态。对应关系是LabVIEW作为MODBUS主站欧姆龙PLC作为从站。理由是LabVIEW程序可以主动控制数据交换节奏测量完成后主动上报结果PLC不需要去适配传感器的采集时序。如果反过来让PLC做主站PLC的扫描周期和测量流程的时序耦合会很麻烦。欧姆龙PLC的串口默认支持HostLink协议而不是MODBUS但CP系列和CJ系列的串口选项中可以切换为MODBUS-RTU从站模式。切换到RTU模式后PLC的D区数据也可以经由MODBUS功能码被外部主站访问。这里需要在欧姆龙PLC一侧做的是把平面度结果保存到特定的D寄存器区域并在程序里做一次数值缩放把带小数的平面度值乘以10000转成整数存储因为MODBUS寄存器本身不携带小数信息。5.2 MODBUS RTU报文构造与轮询逻辑以Modbus功能码03为例读取保持寄存器的请求报文的格式为从站地址、功能码、起始寄存器地址、寄存器数量以及CRC16校验码。LabVIEW与欧姆龙PLC通讯时可以直接使用LabVIEW的Modbus库它会自动处理CRC和报文封装但理解报文结构有助于排查地址对不上的问题。以读取PLC的D100开始的2个寄存器为例请求报文的构造是报文头部为从站地址、功能码随后是起始地址和寄存器数量的高字节与低字节最后是CRC16校验值。响应报文则是从站地址、功能码、字节数、数据区和CRC。实际开发中地址偏移是最常遇到的问题。许多现场人员直接把PLC程序里显示的D100地址填进Modbus函数但程序里填的地址应为从零开始的偏移量D100对应偏移量99。这是因为MODBUS协议中地址从0开始计数而欧姆龙PLC中的数据区地址从1开始。如果不做这个转换读到的一直是D99的数据结果牛头不对马嘴。LabVIEW侧通过Modbus Master函数库实现一次读取操作的典型步骤如下// LabVIEW Modbus库读取保持寄存器示意 MODBUS初始化.vi Mode Serial RTU COM口 COM3或根据实际设备管理器调整 常见选项 9600, 8, 1, Even校验需与PLC侧一致 MODBUS创建通道.vi作为Master MODBUS读取保持寄存器.vi Modbus地址 99 // 对应PLC D100的偏移量 读取数量 2 // 读两个寄存器拼成32位数据抓起这两处之后再强调一个通讯模式问题。欧姆龙PLC的CPU扫描周期通常在10 ms级别MODBUS从站响应是在扫描周期的特定阶段处理的所以LabVIEW作为主站轮询时轮询间隔建议设在200 ms以上。轮询太快会导致PLC侧通讯缓冲区溢出表现为主站报超时错误而从站侧却没有任何程序报错。上位机显示通讯超时时不要第一时间怀疑CRC校验或者波特率最常见的根因是轮询间隔太短把轮询间隔从50 ms调大到300 ms故障往往直接消失。5.3 现场排错三板斧串口选型、超时重试与运行引擎工程落地的最后一个环节是调试阶段最耗时的部分。第一板斧是串口选型USB转串口线优先选用FT232或CH340方案的模块不要用那种无法安装驱动的杂牌转接线。固高控制卡本身需要占用一个PCI或PCIe插槽工控机上再挂两个USB转串口模块一个给ILS025一个给欧姆龙PLC实际测试中USB3.0口和USB2.0口在串口通讯稳定性上没有实质差别但尽量避免把两个USB转串口模块插在同一个USB Hub下面会产生竞争性中断导致偶发超时。第二板斧是超时重试机制。MODBUS通讯中偶发的超时必须由业务逻辑吸收掉常见的做法是在LabVIEW中把读写操作封装成一个带重试的子VI通讯超时时自动重发3次每次重发间隔100毫秒三次都失败才向主界面报错。判断标准定为连续三个扫描周期都失败才算真正的通讯故障可以避免单次偶发干扰直接中断整条产线的运行。还有一个在项目交付时最容易踩坑的地方是LabVIEW Run-Time Engine版本匹配。开发机上跑得好好的程序部署到产线工控机上提示找不到运行引擎或者报错错误说明已知但未处理。解决方法是到NI官网下载对应版本的Run-Time Engine并安装同时在LabVIEW项目属性里将程序生成规格设置为包含Micrium实时引擎则不勾选依赖项包含运行引擎则勾选。更稳妥的做法是在安装程序里把运行引擎的安装包一起打包进去构建安装程序时在附加安装程序里勾选NI LabVIEW运行引擎对应版本这样目标机器上即使没有预装NI软件也能直接运行编译好的EXE程序。本文还有配套的精品资源点击获取
返回列表