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

资讯详情

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

FANUC数控系统数据采集实战:FOCAS协议函数详解与开发指南

FANUC数控系统数据采集实战:FOCAS协议函数详解与开发指南 简介面向FANUC数控系统二次开发工程师这份资源为FOCAS1/2 4.2版函数库的完整说明文档。该版本发布于2013年支持Windows 32/64位及32位Linux系统覆盖机床数据采集、刀具管理、报警监控等常用接口调用方法是当前较为新颖的FOCAS1/2参考资料。压缩包共1657个文件主要由741个xml与738个htm说明页组成辅以173张gif示意图、xsl样式表及css样式表用户可通过浏览器快速检索函数原型、参数定义与返回值阅读体验接近在线帮助文档整体仅2.69MB便于携带。目前已有945人学习使用值得参考。对于需要基于FANUC CNC进行智能产线集成、设备状态监控或OPC UA网关开发的工程师可按模块查阅重点函数也可对照htm与xml数据交叉定位细节省去零散查找资料的麻烦是一份轻量而实用的开发助手。 作为一个常年跟车间设备打交道的上位机工程师我太清楚FANUC数控系统数据采集的痛点了要么开着DNC软件人工看屏幕要么就是靠操作工拿U盘导程序等到MES要产量、要报警、要主轴负载的时候才发现数据根本拿不出来。而FANUC官方提供的FOCAS1/2协议就是专门解决这个问题的标准接口。这玩意儿说白了就是一套Windows或者Linux下的动态库你通过TCP/IP就能把CNC内部的坐标、程序、报警、宏变量、刀具信息一股脑读出来也能往里写宏变量、传程序。这篇文章我结合FOCAS1/2 Version 4.2这个库版本把常用的几十个函数按用途分类拆开讲从环境准备、连接建立、数据读取到异常排查全流程走一遍。适合正在做设备数据采集、MES对接、DNC远程传输、刀具寿命管理的工程师参考也适合刚接手车间信息化项目、对FOCAS还一脸懵的新手快速入门。1. FOCAS是个什么“黑盒”先说清楚协议本身的逻辑1.1 从命名看门道FOCAS1和FOCAS2到底差在哪FOCAS的全称是FANUC Open CNC API Specification就是发那科开放CNC应用程序接口规范。名字里带“Open”是因为发那科从FS16/18系列开始不再把数控系统当成一个封闭的黑盒子而是通过以太网口把系统内部的数据访问能力对外开放。你只要按规范调用库函数就能用C/C、C#、VB、LabVIEW这些语言和CNC通信。先说容易被绕晕的FOCAS1和FOCAS2。FOCAS1是早期协议面向FS6、FS11、FS15这些老型号物理上走的是串口或者专用内存板现在基本没有新项目用了。FOCAS2则面向FS16/18/21/30i/31i/32i这些主流系统底层走以太网或者HSSB高速串行总线我们平时做数据采集用的基本都是FOCAS2。标题里的“FOCAS1/2”是指这套API规范覆盖了两代协议而4.2这个版本号对应的是官方提供的开发库版本比如Fwlib32.dll的版本信息。1.2 通信模型和端口为什么连个CNC还要IP地址FOCAS2的通信模型特别简单就是一个标准的TCP/IP客户端-服务器架构。CNC端是服务器开机后自动在8193端口监听这个端口是FANUC固定使用的上位机作为客户端主动发起连接。连接建立后你调用的每个函数都对应一组请求-响应报文底层库帮你封装好了你不需要关心报文格式。这里有个容易忽略的概念FOCAS库处理的是一次“会话”。一个句柄ODBHND类型代表一条与某台CNC的连接多台设备就是多个句柄。不要在一个句柄上并发调多个函数一会儿读坐标一会儿读报警同一个句柄的底层Socket不是线程安全的我见过有人用多线程并发读导致数据错乱最后不得不加锁。2. 动手前的准备环境、头文件和系统侧设置2.1 官方库文件与开发环境搭建FANUC官方提供的FOCAS2库文件分平台Windows下主要是Fwlib32.dll、Fwlib32.lib和fwlib32.h另外还有供C#调用的Focas32.dll封装实际是对DLL的P/Invoke封装官方一般随库一起给。Linux下对应的是libfwlib32.so和fwlib32.h。安装过程不复杂就是拷贝库文件到工程目录、配置头文件路径、链接库但有几个细节坑很多新人会踩32位和64位问题Fwlib32.dll这个名字里的32不代表只能在32位系统用实际有x86和x64两个版本。如果你的上位机是64位程序必须用64位的DLL否则加载就会报错。语言绑定C#开发时如果不用官方封装要自己写DllImport声明。比如[DllImport(Fwlib32.dll)] public static extern short cnc_allclibhndl3(string ip, ushort port, int timeout, out IntPtr handle);声明错了会导致调用约定不匹配直接崩溃。用表格总结一下常用库文件和对应语言文件/库适用场景备注Fwlib32.dllC/C、C#DllImport需区分x86/x64libfwlib32.soLinux C/C服务端编译时加 -lfwlib32Fwlib32.hC/C工程包含所有函数声明和结构体Focas32.dllC#快速开发封装了常用函数直接引用2.2 CNC侧的参数与以太网设置连不上时先查这里很多人写好了代码却连不上CNC原因往往不在电脑上而在机床参数上。FOCAS2以太网功能需要在CNC面板上先激活这几项是必须确认的确认机床安装有以太网功能板或内置以太网口一般从系统版本画面能看到“Embedded Ethernet”字样。按SYSTEM键进入以太网参数设置界面给CNC分配一个空闲的IP地址子网掩码和上位机要在同一网段。参数设置里确认端口号是8193一般默认不用改。有些系统还需要在“数据服务器/DNC”相关参数里把FOCAS接口置为有效。具体参数号因系统系列而异不能一概而论但思路是一样的IP通、端口通、功能激活三个条件缺一个都连不上。我在现场还遇到过某台设备IP能PING通但FOCAS就是不响应最后查出来是这台机器的FOCAS功能授权没开通折腾了半天。3. 核心函数分类拆解这些函数占了实际开发的八成工作量3.1 连接管理三件套cnc_allclibhndl3、cnc_releaseclibhndl连接函数是整个FOCAS开发的第一步也是最容易出错的一步。新版本推荐用cnc_allclibhndl3它比老的cnc_allclibhndl多了端口号参数适用于以太网连接#include fwlib32.h ODBHND handle; short ret; // 参数IP地址端口号8193超时时间10秒输出句柄 ret cnc_allclibhndl3(192.168.0.100, 8193, 10, handle); if (ret EW_OK) { printf(连接成功\n); } else { printf(连接失败错误码: %d\n, ret); }返回值的判断必须重视。我见过不少人在连接后不检查ret直接往下读数据结果句柄是无效的读出来的数据全是垃圾值。EW_OK是0其余的错误码在fwlib32.h里都有宏定义比如EW_BUSY-9代表CNC忙、EW_PROT-15代表以太网协议错误、EW_SOCKET-17是Socket相关错误。对应的断开函数是cnc_releaseclibhndlret cnc_releaseclibhndl(handle);这个函数的返回值一般不用太纠结程序退出前调用一次就好。但注意不要在回调函数或者线程终止时忘记释放句柄长时间运行的服务端程序频繁连接断开不释放会耗尽系统Socket资源。3.2 必读的状态与坐标函数cnc_rdstat、cnc_rdposition状态读取是FOCAS最常用的功能。cnc_rdstat返回一个ODBSTAT结构体里面最关键的是status字段它是一个按位定义的状态字可以用来判断机床当前是自动、手动、MDI还是编辑模式以及是不是处于运行状态、是否急停、是否有报警。ODBSTAT stat; ret cnc_rdstat(handle, stat); if (ret EW_OK) { unsigned short status stat.status; // 判断自动模式status 0x0001 等位运算 // 不同系统版本位定义有细微差异建议对照头文件注释 }位置读取用的是cnc_rdposition这个函数参数里有个type用来指定读取哪种坐标0是绝对坐标1是机械坐标2是相对坐标-1是全部坐标。输出结构体是ODBPOS里面的Position是一个联合体按轴索引存了double类型的坐标值。ODBPOS pos; ret cnc_rdposition(handle, 0, pos); // 读绝对坐标 if (ret EW_OK) { printf(X: %.3f\n, pos.Position.m_abs[0]); printf(Y: %.3f\n, pos.Position.m_abs[1]); }这里有个细节坑拿到的轴坐标顺序是按系统轴定义的不一定X是0、Y是1最好用cnc_rdaxisname先读出每个轴的名字再和坐标数组对应起来。我曾经在五轴机上踩过这个坑想当然地按前三个轴就是XYZ结果把A轴数据当成了Z轴来统计工件尺寸监控直接偏了十万八千里。3.3 报警和程序读取别看不上这几个函数报警读取cnc_rdalm的用处非常大尤其是做车间集中监控大屏的时候。它返回ODBALM结构体包含报警号AlarmNo和报警类型TypeType区分了NC报警、操作报警、PMC报警等不同类型。ODBALM alm; ret cnc_rdalm(handle, alm); if (ret EW_OK alm.AlarmNo ! 0) { printf(当前报警号: %d\n, alm.AlarmNo); }要注意cnc_rdalm一次只返回第一条报警如果机床同时有多个报警需要循环读取还是只读一条取决于报警类型字段。官方文档里对每种Type有说明有些类型支持随后一条一条读取。程序相关的两个常用函数是cnc_rdopn读取当前打开的程序路径和cnc_rdprgnum读取当前程序号。这两个函数配合起来就能知道机床在跑哪个程序、程序号是多少再结合坐标数据就能做产量统计和程序运行状态追溯。3.4 宏变量读写车间柔性化改造的“万能钥匙”宏变量读写是FOCAS里最灵活的一对函数cnc_rdmacro和cnc_wrmacro。变量号从1到999公共变量从100到249各系统有差异用起来就是一个按变量号存取的数值空间。你可以在CNC程序里通过#1001这样的指令把状态写到宏变量里上位机再去读这样就不用去解析复杂的系统状态位了。ODBMACRO macro; ret cnc_rdmacro(handle, 100, macro); // 读#100 if (ret EW_OK) { printf(#100 %d\n, macro.value); }反过来上位机往宏变量里写值就能实现远程设定坐标系偏移量、刀具寿命计数清零等功能。很多自动化改造项目比如自动门控制、夹具切换、工单号下发都是靠宏变量作为“中间媒介”实现的因为CNC程序里可以很方便地读取和判断#变量避免了直接去改系统内部偏置的复杂操作。实际用下来宏变量读写比直接操作刀补参数安全得多不容易把系统弄乱。4. 编一套完整的采集流程从连接到容错4.1 建连的正确姿势重试和超时策略实际项目里我建议把FOCAS连接封装成一个独立的类或者模块不要到处裸调连接函数。以C#为例一个稳定可用的连接流程大概是这样的public bool Connect(string ip, int timeout 10) { if (_connected) return true; short ret FocasAPI.cnc_allclibhndl3(ip, 8193, timeout, out _handle); if (ret FocasAPI.EW_OK) { _connected true; return true; } // 断开后重试最多3次 for (int i 0; i 3; i) { Thread.Sleep(2000); ret FocasAPI.cnc_allclibhndl3(ip, 8193, timeout, out _handle); if (ret FocasAPI.EW_OK) { _connected true; return true; } } Log.Error(${ip} 连接失败错误码 {ret}); return false; }为什么一定要重试因为CNC在开机启动过程中以太网服务并不是瞬间就绪的有时候系统刚上电你上位机采集程序启动得比CNC快就会连不上。加个重试逻辑程序就稳定得多。同时建议每台设备用独立的连接标识把设备号、IP、当前连接状态放在一起管理。4.2 数据采集循环怎么读才能不卡死连接建立后就要进入采集循环了。一个典型的采集任务间隔可能是500毫秒或者1秒具体取决于业务需求。采集循环里要注意FOCAS调用是同步的如果CNC响应慢或者网络抖动单次调用可能阻塞数秒。所以采集线程别开一个死循环傻等建议用一个定时器或者带超时机制的任务队列来触发采集。private void PollData(object state) { int cncId (int)state; // 先判断连接是否有效 if (!_sessions[cncId].IsConnected) return; // 读取坐标 FocasAPI.ODBPOS pos new FocasAPI.ODBPOS(); short ret FocasAPI.cnc_rdposition(_handle, 0, ref pos); if (ret ! FocasAPI.EW_OK) { // 如果返回EW_BUSY说明上一次调用还没完成跳过本次 return; } // 解析坐标数据写入数据库或消息队列 double x pos.Position.m_abs[0]; double y pos.Position.m_abs[1]; SaveToDatabase(cncId, x, y); }特别要提醒有些开发者发现采集偶尔卡一下就以为是FOCAS有问题其实很多时候是采集线程把数据库写入操作也放在同一个线程里数据库慢了FOCAS调用就被堵住了。建议把“读FOCAS”和“写库/上报”拆成两个线程中间用队列解耦读到的数据先丢队列写库线程慢慢消化。这样即使数据库抖动也不会反过来拖垮FOCAS采集。4.3 断开和重连长时间运行的保命逻辑车间采集程序一般要求7乘24小时运行所以断线重连机制是必须的。我的习惯是每次采集前先验证连接如果发现连接失效就调用cnc_releaseclibhndl强制释放旧句柄然后按启动时的连接参数重新连接。这里有个细节如果同一台CNC被多个上位机程序同时连接FANUC系统有最大连接数限制一般有限制数量具体要看系统设置超出后新的连接请求会失败。在重连逻辑中如果返回的错误码表示连接数已满不要无限重试要通过日志或者消息推送通知现场人员处理。5. 常见问题与排查技巧那些文档上没写的坑5.1 连接不上先PING还是先查参数我总结了一个排查顺序遇到连接不上先照着走上位机是否可以PING通CNC的IP地址如果不通查网线、交换机端口、IP网段。如果PING通但cnc_allclibhndl3失败检查CNC侧FOCAS功能是否激活以太网端口是否是8193。可以在CNC侧用系统自带的网络诊断功能查看连接状态。检查Windows防火墙是否放行了8193端口或者临时关掉防火墙测试。看错误码。EW_HOST-16一般是主机名错误EW_SOCKET-17大概率是网络不通或对端拒绝EW_PROT-15可能是CNC的FOCAS服务未启动。不同错误码对应的排查方向差别很大。我遇到过最离奇的一次是上位机换了新IP后FOCAS连不上但PING是通的。查了半天发现是因为新IP网段跟CNC侧设置的“允许访问IP白名单”不一致CNC侧的安全设置限制了连接来源。这种问题不会体现在报错里纯靠排查经验。5.2 数据读取失败注意返回值与结构体占用读数据的时候返回EW_BUSY-9表示CNC正在执行上一个请求这时候重试或者跳过即可。返回EW_LENGTH-11表示传入的缓冲区长度不对检查结构体大小是否和库版本匹配。不同版本的FOCAS库结构体可能增加了字段如果你用旧的头文件编译但运行时加载了新版本的DLL就可能出现长度不匹配。还有读取数据和读取参数用的结构体定义在头文件里都是紧凑排列的但在C#里默认使用的是Auto布局可能导致结构体大小和C不一致。解决办法是给结构体加[StructLayout(LayoutKind.Sequential)]强制按字段顺序排列。这个坑我排了一个下午最后一行特性解决。5.3 老版本兼容性和系统差异FOCAS Library Version 4.2算是比较新的库版本函数基本向下兼容但有一个注意点老版本FOCAS1的函数和FOCAS2的函数不能混用比如cnc_rdposition的自定义类型在不同CNC系统上返回的轴数不一样不能假设永远是三轴。五轴机读出来的数组就有5个有效值。在开发多型号CNC数据采集系统时我一般会建议先调用cnc_getcncinfo读取系统型号和系列根据返回值做适配。不同系列的CNC在报警类型定义、状态位定义上有细微差别不能拿FS16的经验直接套到FS30i上。6. 几个常用函数速查开发时随手翻下面把FOCAS2最常用、我在项目中确实频繁使用的函数整理成速查表方便参考功能分类函数名用途说明连接管理cnc_allclibhndl3以太网连接推荐用这个连接管理cnc_allclibhndl老式连接串口/板卡连接管理cnc_releaseclibhndl断开连接状态cnc_rdstat读CNC状态自动/手动/运行/暂停报警cnc_rdalm读当前报警坐标cnc_rdposition读绝对/相对/机械坐标轴名cnc_rdaxisname读轴名称映射程序cnc_rdopn读当前程序路径/名程序cnc_rdprgnum读当前程序号程序传输cnc_uplod上传程序到上位机程序传输cnc_downlod下载程序到CNC宏变量cnc_rdmacro读#变量宏变量cnc_wrmacro写#变量参数cnc_rdparam读CNC参数参数cnc_wrparam写CNC参数诊断cnc_rddiagnosis读诊断信息伺服负载cnc_rdsvmeter读伺服轴负载率部分库版本支持主轴负载cnc_rdspmeter读主轴负载率部分库版本支持系统信息cnc_getcncinfo读系统型号序列信息这个表不用背开发的时候对照着查就行。真正的重点不是记住每个函数签名而是理解每个函数在什么业务场景下用。比如做设备开机率统计核心是cnc_rdstat做刀具寿命监控核心是读宏变量和主轴负载做DNC远程传输核心是cnc_uplod与cnc_downlod。再提醒一句FOCAS库自带了一份官方手册叫FOCAS2 Library Users Manual里面每个函数都有参数说明、返回值和示例是权威参考资料。任何人跟你说“我手头有整理好的函数大全”都不如官方手册靠谱。开发前先花两天把手册里常用函数的说明过一遍比在网上搜各种零碎代码高效得多。7. 给刚入坑的工程师几个实在建议说实话FOCAS开发的门槛不在函数调用本身而在你对数控系统工作方式的理解。我见过不少写代码很溜的同事到了现场看到FANUC系统面板就懵了不知道IP在哪设置也不知道怎么在MDI模式下测试宏变量。做这行光会调API是不够的至少得懂一点CNC的基本操作怎么开机、怎么进入SYSTEM设置界面、怎么在MDI模式下跑一段小程序、怎么看报警履历。这些看似基础的东西在调试FOCAS上位机时天天用得上。另外不要一上来就想读所有数据。先从连接成功、读状态、读坐标这三个最小功能做起跑通一条链路再逐步扩展。我早期一个项目就是贪多想一步到位把所有采集项都做出来结果报警解析的程序没处理好连基础数据都采集不连续返工了好几次。先小步快跑把采集链路做稳定后面加功能就只是加函数调用的问题了。最后再分享一个调试技巧抓包工具很好用。FOCAS走的是TCP协议用Wireshark抓包可以看到上位机和CNC之间的报文交互。虽然报文是FANUC私有格式但至少能看到TCP握手是否正常、请求发出后有没有响应。很多时候排查连接故障抓包一看就明白了。比如TCP握手都成功但应用层没数据基本可以断定是CNC侧FOCAS服务没就绪如果连握手都失败就是网络链路的问题。多抓几次包你对FOCAS通信的体感会比看十遍文档都来得深。本文还有配套的精品资源点击获取
返回列表