2. 读取机床坐标位置
任务目标
通过 FOCAS 以太网连接 FANUC 数控系统,读取机床当前各轴的坐标、相对坐标和机械坐标,并将结果输出到控制台。
环境与依赖
- FANUC 数控系统(具备以太网功能,启用 FOCAS 接口)
- 开发语言:C#(.NET 6/8)或 C(二者选一即可)
- FOCAS 库:
Fwlib32.dll(Windows)或libfwlib32.so(Linux) - 需在项目中引用 FOCAS 官方头文件
fwlib32.h(C)或通过 P/Invoke 调用(C#)
实现原理
FOCAS 提供 cnc_rdposition 函数,一次调用即可同时获取所有轴的坐标、相对坐标、机械坐标及剩余进给量。该函数返回每个轴的位置数据(以脉冲为单位),需结合机床各轴的计数方向(cnc_get_axis 或参数)转换为实际坐标值。本案例直接使用该函数并输出原始脉冲值及转换后的毫米值(假设公制机床,脉冲当量由参数 No.1004 决定,通常为 1μm 或 0.1μm)。
关键完整代码(C# 实现)
using System;
using System.Runtime.InteropServices;
class FocasPositionReader
{
// FOCUS 数据结构定义
[StructLayout(LayoutKind.Sequential)]
struct ODBPOS
{
public short dummy; // 预留
public short type; // 坐标类型
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] absolute; // 坐标(脉冲)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] machine; // 机械坐标(脉冲)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] relative; // 相对坐标(脉冲)
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public int[] distance; // 剩余进给量
}
// 导入 FOCAS 库函数
[DllImport("Fwlib32.dll", EntryPoint = "cnc_allclibhndl3")]
public static extern short cnc_allclibhndl3(string ip, ushort port, int timeout, out ushort handle);
[DllImport("Fwlib32.dll", EntryPoint = "cnc_rdposition")]
public static extern short cnc_rdposition(ushort handle, int type, out ODBPOS position);
[DllImport("Fwlib32.dll", EntryPoint = "cnc_freelibhndl")]
public static extern short cnc_freelibhndl(ushort handle);
// 轴名称映射(FANUC 标准:0=X, 1=Y, 2=Z, 3=A, 4=B, 5=C)
static readonly string[] AxisNames = { "X", "Y", "Z", "A", "B", "C" };
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("用法: FocasPositionReader <机床IP地址> [端口=8193]");
return;
}
string ip = args[0];
ushort port = args.Length > 1 ? ushort.Parse(args[1]) : (ushort)8193;
ushort handle;
// 建立连接
short ret = cnc_allclibhndl3(ip, port, 10, out handle);
if (ret != 0)
{
Console.WriteLine($"连接失败,错误码: {ret}");
return;
}
try
{
// 读取所有轴位置(type=1 表示读所有轴)
ODBPOS pos;
ret = cnc_rdposition(handle, 1, out pos);
if (ret != 0)
{
Console.WriteLine($"读取位置失败,错误码: {ret}");
return;
}
// 输出表头
Console.WriteLine("轴\t坐标(脉冲)\t相对坐标(脉冲)\t机械坐标(脉冲)");
// 遍历前6个轴(实际轴数可通过 cnc_rdaxisname 获取,此处简化)
for (int i = 0; i < 6; i++)
{
// 判断该轴是否存在(机械坐标不为0或坐标不为0通常表示已配置)
if (pos.machine[i] == 0 && pos.absolute[i] == 0 && pos.relative[i] == 0)
continue;
Console.WriteLine($"{AxisNames[i]}\t{pos.absolute[i]}\t\t{pos.relative[i]}\t\t{pos.machine[i]}");
}
}
finally
{
cnc_freelibhndl(handle);
}
}
}
编译与运行
- 将上述代码保存为
PositionReader.cs。 - 将
Fwlib32.dll放置于程序输出目录(或系统 PATH)。 - 编译:
csc PositionReader.cs(.NET Framework)或dotnet build(.NET 6+)。 - 运行:
PositionReader.exe 192.168.1.50(替换为实际机床 IP)。
验证方法
- 连接成功:程序无报错,输出表头及至少一个轴的坐标数据。
- 数据正确性:手动操作机床移动 X 轴 10mm(假设脉冲当量 1μm),再次运行程序,X 轴坐标脉冲值应变化约 10000。
- 坐标类型区分:在机床面板上切换相对坐标清零,程序输出的相对坐标脉冲值应归零,而坐标和机械坐标不变。
常见问题
- 错误码 -17:IP 地址无法访问,检查网络及机床端 FOCAS 服务是否启用。
- 错误码 -8:连接超时,确认端口号(默认 8193)及机床防火墙设置。
- 输出全为 0:可能轴未配置或处于未回零状态,机械坐标在未回零前可能显示 0。