资讯动态

FOCAS协议开发实战:FANUC数控系统数据采集与避坑指南

发布时间:2026/10/27 16:51:35 来源:尧图企业网站定制
简介FANUC开发包.zip面向需要与发那科数控系统进行二次集成的工业自动化开发者围绕FOCAS开放协议提供一整套可参考的通信实现资料。FOCAS基于TCP/IP与XML支持远程监控、数据采集、程序管理、参数设置及报警处理是打通CNC与上位机应用的关键接口。压缩包共1627个文件以xml数据/配置、htm说明文档、gif示意图居多并包含dll动态库、h头文件、bas示例程序等便于开发者直接查阅协议规范、调用接口并调试客户端程序整体6.22MB轻量易部署。已有1598人下载学习说明该资料在发那科二次开发场景中具有一定参考价值。借助包内文档与示例开发者可快速掌握FOCAS的连接配置、方法调用与数据解析思路减少从零摸索协议细节的时间更高效地实现机床状态采集、程序上传下载与远程运维等生产管理功能。1. FOCAS 协议是什么把 FANUC 数控系统搬进软件里的那把钥匙车间里几十台 FANUC 加工中心MES 要产量、设备管理系统要主轴负载、质量系统要刀具寿命这些数据全锁在 0i-F 或 31i-B 控制器的 PMC 与 CNC 参数里。FOCAS 协议FANUC Open CNC API Specification是 FANUC 官方开放给外部软件的数据通道通过以太网把坐标、报警、程序、参数、PMC 信号读出来也能写回去。这套协议对应的开发包在网上常以 FANUC开发包.zip 的形式流通解压后就是库文件、头文件、示例代码和 PDF 手册。做机床数据采集的工程师、写 MES 对接程序的开发者、搞预测性维护的团队都绕不开它——不用碰梯形图不用加数采板卡一根网线加一个 DLL 就能开工。2. 开发包与运行前提fwlib32 库文件、文档和 CNC 侧网络配置解压 FANUC开发包.zip 之后别急着写代码先花半小时把目录结构和版本关系摸清楚。FOCAS 这东西对版本极其敏感头文件和动态库版本错配是翻车率最高的第一个坑后面排错排一整天往往就是这里埋下的。2.1 开发包目录结构三件套库文件、示例代码与手册的版本对应典型的 FANUC 开发包会按协议版本和运行平台分好目录。FOCAS1 和 FOCAS2 是两个代际FOCAS2 支持更新的控制系统比如 30i-B、31i-B、0i-F函数命名风格一致但内部结构体和部分函数的参数项有差异。每个版本子目录下都是同一套三件套fwlib32.h 头文件、fwlib32.lib 导入库、fwlib32.dll 动态库64 位环境再加一套 fwlib64 前缀的同名文件。示例代码放在 Samples 目录下每个示例对应一类功能比如坐标读取、程序上下载、PMC 信号读写。如果你之前翻过网上流传的 FANUC 机器人指令大全 PDF会发现 CNC 侧这套文档风格完全不同权威依据是那本 FOCAS1/FOCAS2 CNC/PMC API 说明书按函数逐个讲参数和返回值写代码时基本是把它当字典查。拿到开发包先做三件事。第一确认目标机床控制系统型号据此确定用 FOCAS1 还是 FOCAS2 的库第二确认上位机是 32 位还是 64 位选对应的 DLL32 位进程只能加载 fwlib32.dll64 位进程优先用 fwlib64.dll第三翻手册里「支持的 CNC 一览表」确认你的系统型号在清单里。这三步十分钟做完比后边排错省一天时间。提示在 Visual Studio 里建工程时至少把「字符集」设为多字节Multibyte。FOCAS 示例代码大量使用 char 数组Unicode 模式下编译会报参数类型不匹配这种错误最消磨耐心。工程里链接 fwlib32.lib 之后记得把 fwlib32.dll 复制到 exe 同目录或者放到系统 PATH 里。现场部署时我习惯把 DLL 直接放在采集程序安装目录下避免多版本 DLL 冲突。2.2 CNC 侧以太网参数配置IP、端口 8193 与连通性验证上位机准备好了机床不配合也没用。FOCAS1/Ethernet 通信基于 TCPCNC 侧要先把网络接口激活。在系统参数里找到以太网设定界面不同系统路径不一样0i-F 是通过 MDI 的参数菜单进去给控制器以太网口配置固定 IP子网掩码 255.255.255.0端口号默认 8193。这个端口是 FOCAS1/Ethernet 的约定端口除非有特殊需求不要改。FOCAS 功能本身还受使能位控制有些系统需要把 FOCAS 使能参数打开具体参数号在手册的 Setting FOCAS 章节按系统型号列表做这一步必须对照手册别照搬别的型号参数。配置完成后在上位机上用 ping 验证网络通再用 telnet 连 8193 端口验证可达性。ping 通但 telnet 连不上多半是使能位没打开或者端口被改写。走通这一步CNC 侧相当于准备好了「监听」等上位机来连接。提示上位机和 CNC 不要在同一个网段里再跑 DHCP 或组播协议。FOCAS 的 TCP 长连接对网络抖动敏感交换机上给这台机床单独划一个 VLAN 或静态端口别让它和办公网视频流量抢带宽。3. 用 C 语言跑通第一个 FOCAS 连接从句柄到坐标环境就绪后写一个最小可运行的 C 程序把连接建起来再把机床当前坐标读回来。这一步通了FOCAS 这套架构就打通了一半。下面代码用 FOCAS1 库的经典函数配合 Visual Studio 编译命令行执行cl connect.c fwlib32.lib就能出可执行文件。3.1 建立与断开连接cnc_allclibhndl3 的超时、端口与句柄#include fwlib32.h #include stdio.h #include string.h int main(void) { unsigned short handle 0; char ip[] 192.168.1.1; // CNC 侧设定好的控制器 IP unsigned short port 8193; // FOCAS1/Ethernet 默认端口 long timeout 5000; // 连接超时, 单位毫秒 // 第四个参数是输出参数, 成功后拿到一个非 0 句柄 short ret cnc_allclibhndl3(ip, port, timeout, handle); if (ret ! EW_OK) { printf(connect failed, error code %d\n, ret); return -1; } printf(connected, handle %d\n, handle); // 所有数据读写都在这中间, handle 是它们共用的第一个参数 ret cnc_freelibhndl(handle); if (ret EW_OK) { printf(disconnected\n); } return 0; }cnc_allclibhndl3 返回的 handle 是后续一切调用的凭证它对应 CNC 侧一个 TCP 会话。程序退出前必须调用 cnc_freelibhndl 释放句柄否则会话残留在 CNC 侧直到 TCP 超时被系统回收下次连接可能撞上资源不足的返回码。timeout 参数控制的是连接阶段等待 CNC 侧响应的时间不是每次读写的超时写数据采集程序时要在语言层面单独处理读写超时。有一个常见错误码表值得先记住排错时能少翻半天手册。EW_OK 是 0一切正常EW_BUSY 是 -2CNC 正忙EW_HANDLE 是 -9句柄无效通常是没连接成功就开始读EW_TIMEOUT 是 -14超时EW_REJECT 是 -15连接被 CNC 拒绝大概率是使能位或端口配置问题。3.2 读取坐标数据cnc_rdposition 与 ODBPOS 字段路径ODBPOS pos; memset(pos, 0, sizeof(pos)); // 第二参数 -1 表示读取全部位置类型; 按手册用 1 只读绝对坐标 ret cnc_rdposition(handle, -1, sizeof(pos), pos); if (ret ! EW_OK) { printf(read position failed, error code %d\n, ret); return -1; } // ODBPOS 里 abs 是绝对坐标, rel 是相对坐标, mch 是机械坐标 // data[0]/data[1]/data[2] 依次对应 X/Y/Z 轴 (车床一般是 X/Z/C) printf(abs X %.3f Y %.3f Z %.3f\n, pos.abs.data[0], pos.abs.data[1], pos.abs.data[2]); printf(mach X %.3f Y %.3f Z %.3f\n, pos.mch.data[0], pos.mch.data[1], pos.mch.data[2]);ODBPOS 结构体里abs、rel、mch、dist 四个子结构分别对应绝对坐标、相对坐标、机械坐标和剩余移动量每个子结构内部是 6 个 double 的数组按轴顺序排列。铣床三轴就是 data[0] 到 data[2] 对应 X、Y、Z车床一般是 X、Z、C 的排列。坐标数据是 double 类型公制机床直接读出毫米值英制机床读出英寸值上抛给 MES 之前要统一换算我一般会在采集层做一次单位归一化避免下游系统各自换算出错。提示ODBPOS 在 FOCAS2 库里的结构体字段比 FOCAS1 多了轴类型信息如果编译环境混用了两个版本的文件读出来的坐标会出现错位这正是下一章要讲的避坑问题。4. 常用数据采集的读写套路报警、程序与 PMC 信号连接建好了坐标也能读了接下来是设备监控系统最常用的三类数据报警信息、NC 程序和 PMC 信号。这三类覆盖了故障看板、程序管理、状态判断三个核心场景。把 FOCAS 当黑匣子用没问题但每类数据的结构和边界条件得搞清楚。4.1 报警轮询cnc_rdalm 与 ODBALM 的解析#include fwlib32.h #include stdio.h #include string.h void read_alarm(unsigned short handle) { ODBALM alm; memset(alm, 0, sizeof(alm)); // type1 读 CNC 侧报警; 机床有 PMC 报警时换 type2 再读一次 short ret cnc_rdalm(handle, 1, 1, alm); if (ret ! EW_OK) { printf(read alarm failed, error code %d\n, ret); return; } if (alm.all_no 0) { printf(active alarms: %d\n, alm.all_no); for (int i 0; i alm.all_no i 10; i) { printf( %03d axis%d : %s\n, alm.alm1[i].num, alm.alm1[i].axis, alm.alm1[i].msg); } } else { printf(no alarm\n); } }ODBALM 结构体里 all_no 是当前活动报警总数alm1 数组里每条记录包含报警号、轴号、报警信息文本。做故障看板时直接轮询这个函数把报警号映射到中文描述表。注意这条函数读的是「当前活动报警」不是报警履历——历史报警要用另一组带时间戳的功能手册里 Alarm History 章节别拿活动报警去凑历史报表。轮询频率控制在 500ms 到 1s 一次足够机床报警出现的频率远低于这个量级高频轮询只会浪费带宽和 CNC 侧处理资源。4.2 加工程序上传cnc_rdprogram 的缓冲区分配与分段读取char buffer[8 * 1024 sizeof(ODBPRO)]; ODBPRO *prog (ODBPRO *)buffer; long length 8 * 1024; // 每次最多读 8KB short length2 1; // 1 表示从程序开头读 FILE *fp_out fopen(O0001.txt, wb); while (1) { memset(prog, 0, sizeof(buffer)); // type1 按程序号检索, 程序号必须带 O 前缀 short ret cnc_rdprogram(handle, 1, O0001, length, length2, prog); if (ret ! EW_OK) { printf(read program failed, error code %d\n, ret); break; } fwrite(prog-data, 1, length, fp_out); if (length 8 * 1024) break; // 读到最后一段 length 8 * 1024; // 复位缓冲区大小 length2 0; // 后续读取 } fclose(fp_out);cnc_rdprogram 的缓冲机制和 read() 系统调用类似ODBPRO 是一个柔性数组结构data 字段只是占位实际存储空间由调用方分配。length 参数输入时告诉库缓冲区有多大输出时变成实际读取的字节数。程序超过缓冲区大小时调用方把 length2 设为 0 继续读下一段直到返回长度小于缓冲区大小代表读完了。这个循环模式是标准做法实际采集系统里程序动辄几百 KB一次读满不现实。程序名格式是常见坑FOCAS 按程序号检索时要求传 O0001 这种带 O 的字符串少个 O 直接返回查无此程序。4.3 PMC 信号与系统参数cnc_rdpmsignal 和 cnc_rdparam 的实务long val 0; // 读 G54.0: type1 对应 G 地址, m_no54 是字节号, l_no0 是位号 ret cnc_rdpmsignal(handle, 1, 54, 0, val); if (ret EW_OK val 1) { printf(G54.0 is ON\n); } // 读系统参数 3202 号, 轴号和 CNC 号不确定时填 1 long param_val 0; ret cnc_rdparam(handle, -1, 1, 1, 3202, param_val); if (ret EW_OK) { printf(parameter 3202 0x%lX\n, param_val); }PMC 地址分 G、F、Y、X 四大类G 是 PMC 发给 NC 的信号F 是 NC 发给 PMC 的状态。做设备状态判断时循环启动、进给保持、门锁状态这些布尔量全在 G/F 地址里。具体哪个字节对应哪个信号要看这台机床 PMC 梯形图的信号地址表不同机床厂的标准不一样别拿另一台机器的地址表硬套。cnc_rdpmsignal 的 type 参数在 FOCAS 手册 PMC 章节有明确定义不同版本略有差异落实到你手里的库时以 fwlib32.h 头文件里的注释为准。系统参数用 cnc_rdparam 读比如 3202 号参数控制程序保护1320 号参数是正方向行程极限。改参数对应 cnc_wrparam但写参数前务必确认 CNC 处于允许写入的状态改完要评估是否需要重启生效。基于 FOCAS 做参数下发不是不能做但一定要在操作界面上加二次确认——工业现场改参数没有后悔药一个错误的行程极限值可能直接顶坏刀塔。提示做 PMC 地址对照表时我一般会写一个小工具批量读取 G 和 F 地址段配合机床空运行时主轴正转、夹紧、门开关这些动作记录信号翻转来生成映射表比对着梯形图手工抄省力得多。5. FOCAS 避坑指南连接失败、数据错乱与线程安全FOCAS 调试到后期成功率往往卡在那些玄学问题上。下面五条是从项目里踩出来的血泪经验每条按现象、原因、解决的顺序写照着排查能省下大量现场时间。5.1 连接超时FOCAS 使能位与防火墙的连环坑现象cnc_allclibhndl3 返回 -14EW_TIMEOUTping 机床 IP 能通。原因最常见是 CNC 侧 FOCAS 使能位没打开其次是端口号被改过然后是上位机防火墙拦截出站 TCP 到 8193 端口。很多现场工程师只测了 ping没测端口结果卡在使能位上。解决对照手册检查使能位确认端口确实是 8193在防火墙入站规则里显式放行 8193 端口。如果现场安全策略不允许开端口把采集程序注册为 Windows 服务并绑定固定程序路径服务程序的网络行为与普通 exe 有不同的拦截规则这条结合现场策略评估。5.2 数据错乱头文件与 DLL 版本错配现象读出来的坐标要么是天文数字要么 X、Y、Z 对不上机械坐标和绝对坐标完全一样。原因fwlib32.h 是旧版本DLL 是 FOCAS2 新版本或者反过来。ODBPOS 结构体在不同版本里字段布局不同头文件按旧布局解释新 DLL 返回的字节流数据自然错位。解决开发包保留一套完全匹配的头文件、导入库和 DLL编译、链接、运行时全部用这一套升级时整体替换而不是只换 DLL。把这项写进代码评审清单能拦下一大半莫名其妙的「协议 bug」。5.3 64 位工程加载 DLL 失败现象程序编译通过运行时提示找不到 fwlib32.dll 或报 0x000007B 加载错误。原因fwlib32.dll 是 32 位动态库放进 AnyCPU 的 64 位进程里当然加载不了。这种错误在部署阶段出现开发机上好好的到现场工控机上就崩。解决采集程序编译时强制 x86 平台或者换 fwlib64.dll fwlib64.h 用 64 位版本。fwlib64 的函数签名和结构体与 32 位版完全一致换的时候头文件和导入库同步换别只换 DLL。5.4 多线程并发读数据崩溃现象两个线程同时调 cnc_rdposition运行几分钟后偶发崩溃返回码飘忽不定有时候是 -9 有时候是 -1。原因同一个 handle 的并发调用不是线程安全的FOCAS 库内部没有对这个场景做互斥保护。多个线程同时往同一个 TCP 会话写请求响应报文乱序解析进程直接崩。解决最稳妥的是用一个独立采集线程所有 FOCAS 调用串行执行采集结果放进队列供业务线程消费。如果确实需要并发读不同类型数据为每个线程建立独立连接独立 handle但要注意 CNC 侧对同时连接数有限制。5.5 运行几小时后断线且重连失败现象程序稳定运行七八个小时后连接断开重连时报资源不足或直接被拒。原因CNC 侧 TCP 会话被回收但上位机不知情句柄变成僵尸状态或者断线后重连太频繁触发了 CNC 侧连接保护机制。解决加心跳机制每 30 秒调用一次轻量函数探活比如 cnc_sysinfo返回异常就主动 cnc_freelibhndl 后重新连接。重连要有退避策略连续失败就拉长间隔到 30 秒一次不要暴力循环重试否则 CNC 侧保护会让重连窗口越来越长。6. 采集性能验证从 1Hz 到 20Hz 的实测方法与线程模型连接跑通、数据能读之后下一个绕不开的问题是采集频率。FOCAS 没有批量读接口坐标、报警、PMC 信号是三个独立函数每次调用都是一次 TCP 请求-响应往返。优化方向不是减少调用次数而是压缩单次调用延迟和线程切换开销。建议的线程模型很直接一个采集线程持有 FOCAS 连接按固定周期依次调 cnc_rdposition、cnc_rdalm、cnc_rdpmsignal把结果打包进内存队列业务侧按需消费。采集线程只干活不断连把长连接优势发挥到极致。局域网环境下单次调用延迟通常在 0.5 到 5 毫秒之间三次调用加一点余量20Hz50ms 周期完全够用。有人在 30 台机床的项目里用多线程各自去连结果车间交换机不堪重负连接被批量重置——单线程串行采集在几十台机床的规模下远比多线程可靠。验证方法比你想的简单采集程序里加一个计数器每 1000 次采样记录耗时算出平均值和 P95 延迟。如果 P95 超过 30ms优先查网络链路交换机端口、网线质量、是否存在广播风暴再回头看程序里有没有在读写路径上做了日志写盘之类的阻塞操作。做机器人的同事会拿 KAREL Socket Messaging 来类比两者都是 TCP 长连接但 KAREL 的 socket 是流式收发自定义报文FOCAS 是固定的请求-响应 API理解这个差异就不会在两边之间反复横跳。我自己踩过的坑是一开始为了省事把采集程序写成每次轮询都重新 connect、读完马上 disconnect结果单次周期稳定在 200ms 以上还把 CNC 侧的 TCP 会话开了一堆。后来改成启动时连接一次、进程退出时断开加上心跳探活采样周期压到 30ms 以内机床数量从 5 台扩到 30 台都没再动过代码。FOCAS 这个方案值不值得投入我的结论很直接只要你的机床是 FANUC 系统且带以太网接口这套协议就是成本最低的官方采集路径开发包里的示例代码加本文的避坑清单足够支撑一个稳定的采集服务落地。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑