一,概述
前面介绍过,发那科CNC数据采集一般有两种方法:
(1)通过FOCAS 1/2 开发包进行二次开发采集数据(仅适用于windows系统)
(2)通过纯TCP协议方法。该方法不局限于CPU架构(x86、ARM、MIPS等等),不局限操作系统(Windows、Linux、FreeRTOS、RT-Thread、μC/OS、裸机等等均可),不局限编程语言(Java、Python、C/C++、C#、Go等等均可)。
下面对两种方法都进行相应介绍。
PS:建议直接用纯协议方式。比如产品使用ARM Cortex-M,可以做到非常高的性价比。也可以方便集成到软件平台里,欢迎交流扣扣17082750
二,FOCAS 1/2 开发包方式
1,使用SDK的Demo源码可以从下面地址下载
发那科CNCSDKDemo源码,Focas1_2SDKDemosourcecode,,C#-C#文档类资源-CSDN下载
主要的库是Fwlib32.dll以及fwlib1.dll。
(1)Fwlib32.dll是负责和fanuc通讯的组件,用来对客户端发送的数据进行转义加密再和数控系统通讯。
(2)fwlib32.dll是核心的函数操作库,封装了各类数据读取函数。
所以,采集程序是对fwlib32.dll进行函数调用,fwlib32.dll再将数据通过Fwlib32.dll库和数控系统进TCP通讯,数控系统响应数据返回给Fwlib21.dll,Fwlib21.dll再将数据返回给fwlib32.dll进行解析,最终反馈采集程序。
2,撸代码
namespace FANUC
{
public partial class control_axis : Form
{
public control_axis()
{
InitializeComponent();
}
Fanuc.ODBPOS fos = new Focas1.ODBPOS();
private void duqu_position_rel_info()//读取相对的位置信息
{
short num = Fanuc.MAX_AXIS;
short type = -1; ;
short ret = Fanuc.cnc_rdposition(Fanuc.h, type, ref num, fos);
if (ret == 0)
{
listBox1.Items.Add(fos.p1.rel.name.ToString() + ": " + fos.p1.rel.data * Math.Pow(10, -fos.p1.rel.dec));
listBox1.Items.Add(fos.p2.rel.name.ToString() + ": " + fos.p2.rel.data * Math.Pow(10, -fos.p2.rel.dec));
listBox1.Items.Add(fos.p3.rel.name.ToString() + ": " + fos.p3.rel.data * Math.Pow(10, -fos.p3.rel.dec));
listBox2.Items.Add(fos.p1.dist.name.ToString() + ": " + fos.p1.dist.data * Math.Pow(10, -fos.p1.dist.dec));
listBox2.Items.Add(fos.p2.dist.name.ToString() + ": " + fos.p2.dist.data * Math.Pow(10, -fos.p2.dist.dec));
listBox2.Items.Add(fos.p3.dist.name.ToString() + ": " + fos.p3.dist.data * Math.Pow(10, -fos.p3.dist.dec));
}
}
public void duqu_position_ab_info()//获取绝对位置信息
{
short num = Fanuc.MAX_AXIS;
short type = -1; ;
short ret = Fanuc.cnc_rdposition(Fanuc.h, type, ref num, fos);
if (ret == 0)
{
listBox8.Items.Add(fos.p1.abs.name.ToString() + ": " + fos.p1.abs.data * Math.Pow(10, -fos.p1.abs.dec));
listBox8.Items.Add(fos.p2.abs.name.ToString() + ": " + fos.p2.abs.data * Math.Pow(10, -fos.p2.abs.dec));
listBox8.Items.Add(fos.p3.abs.name.ToString() + ": " + fos.p3.abs.data * Math.Pow(10, -fos.p3.abs.dec));
listBox7.Items.Add(fos.p1.dist.name.ToString() + ": " + fos.p1.dist.data * Math.Pow(10, -fos.p1.dist.dec));
listBox7.Items.Add(fos.p2.dist.name.ToString() + ": " + fos.p2.dist.data * Math.Pow(10, -fos.p2.dist.dec));
listBox7.Items.Add(fos.p3.dist.name.ToString() + ": " + fos.p3.dist.data * Math.Pow(10, -fos.p3.dist.dec));
}
}
public void get_postion()//获取位置信息
{
listBox3.Items.Clear();
listBox4.Items.Clear();
listBox5.Items.Clear();
listBox6.Items.Clear();
short num = Fanuc.MAX_AXIS;
short type = -1;
short ret = Fanuc.cnc_rdposition(Fanuc.h, type, ref num, fos);
if (ret == 0)
{
//绝对
listBox3.Items.Add(fos.p1.abs.name.ToString() + ": " + fos.p1.abs.data * Math.Pow(10, -fos.p1.abs.dec));
listBox3.Items.Add(fos.p2.abs.name.ToString() + ": " + fos.p2.abs.data * Math.Pow(10, -fos.p2.abs.dec));
listBox3.Items.Add(fos.p3.abs.name.ToString() + ": " + fos.p3.abs.data * Math.Pow(10, -fos.p3.abs.dec));
listBox3.Items.Add(fos.p4.abs.name.ToString() + ": " + fos.p4.abs.data * Math.Pow(10, -fos.p3.abs.dec));
listBox3.Items.Add(fos.p5.abs.name.ToString() + ": " + fos.p5.abs.data * Math.Pow(10, -fos.p5.abs.dec));
//相对
listBox4.Items.Add(fos.p1.rel.name.ToString() + ": " + fos.p1.rel.data * Math.Pow(10, -fos.p1.rel.dec));
listBox4.Items.Add(fos.p2.rel.name.ToString() + ": " + fos.p2.rel.data * Math.Pow(10, -fos.p2.rel.dec));
listBox4.Items.Add(fos.p3.rel.name.ToString() + ": " + fos.p3.rel.data * Math.Pow(10, -fos.p3.rel.dec));
listBox4.Items.Add(fos.p4.rel.name.ToString() + ": " + fos.p4.rel.data * Math.Pow(10, -fos.p4.rel.dec));
listBox4.Items.Add(fos.p5.rel.name.ToString() + ": " + fos.p5.rel.data * Math.Pow(10, -fos.p5.rel.dec));
//机器
listBox5.Items.Add(fos.p1.mach.name.ToString() + ": " + fos.p1.mach.data * Math.Pow(10, -fos.p1.mach.dec));
listBox5.Items.Add(fos.p2.mach.name.ToString() + ": " + fos.p2.mach.data * Math.Pow(10, -fos.p2.mach.dec));
listBox5.Items.Add(fos.p3.mach.name.ToString() + ": " + fos.p3.mach.data * Math.Pow(10, -fos.p3.mach.dec));
listBox5.Items.Add(fos.p4.mach.name.ToString() + ": " + fos.p4.mach.data * Math.Pow(10, -fos.p4.mach.dec));
listBox5.Items.Add(fos.p5.mach.name.ToString() + ": " + fos.p5.mach.data * Math.Pow(10, -fos.p5.mach.dec));
//距离
listBox6.Items.Add(fos.p1.dist.name.ToString() + ": " + fos.p1.dist.data * Math.Pow(10, -fos.p1.dist.dec));
listBox6.Items.Add(fos.p2.dist.name.ToString() + ": " + fos.p2.dist.data * Math.Pow(10, -fos.p2.dist.dec));
listBox6.Items.Add(fos.p3.dist.name.ToString() + ": " + fos.p3.dist.data * Math.Pow(10, -fos.p3.dist.dec));
listBox6.Items.Add(fos.p4.dist.name.ToString() + ": " + fos.p3.dist.data * Math.Pow(10, -fos.p4.dist.dec));
listBox6.Items.Add(fos.p5.dist.name.ToString() + ": " + fos.p5.dist.data * Math.Pow(10, -fos.p5.dist.dec));
}
}
Fanuc.ODBACT pindle = new Focas1.ODBACT();
public void get_pindle()//获取主轴的速度
{
short ret = Fanuc.cnc_acts(Fanuc.h, pindle);
if (ret == 0)
{
label5.Text = pindle.data.ToString();
}
else
{
MessageBox.Show(ret+"");
}
}
Fanuc.ODBSVLOAD sv = new Focas1.ODBSVLOAD();
Fanuc.ODBSPLOAD sp = new Focas1.ODBSPLOAD();
public void get_load()//主,伺服轴的加载计//测试成功
{
short a = 6;//伺服轴的数量
short ret = Fanuc.cnc_rdsvmeter(Fanuc.h, ref a, sv);
short type = Convert.ToInt16(textBox1.Text);//1朱轴压力,-1俩者都有,0主轴监控速度表
short ret2 = Fanuc.cnc_rdspmeter(Fanuc.h, type, ref a, sp);
if (ret == 0 && ret2 == 0)
{
listBox9.Items.Add("伺服的加载值:" + sv.svload1.data + " " + sv.svload2.data + " " + sv.svload3.data + " ");
listBox9.Items.Add("主轴的加载值:" + sp.spload1.spload.data);
}
else
MessageBox.Show(ret+"");
}
}
}
三,协议方式
//读轴相关的坐标
void CMDC_FANUCDlg::F_READ_AXIS()
{
int block_sum = 4;
int len = 0;
union{
unsigned char d_byte[2];
int dat;
}i_d;
unsigned char p_send[] =
{
0x**,0x**,0x**,0x**, //HEAD
0x**,0x**,0x**,0x**, //READ DATA
0x00,len, //length
0x00,block_sum, //发送的数据块个数
//1.机械坐标
0x00,0x1c,0x00,0x01,
0x00,0x01,0x00,0x26, //ID
0x00,0x00,0x00,0x01, //起始地址=1 机械坐标,4,ABS 6 REAL 7 DISTANCE
0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//2.ABS
0x00,0x1c,0x00,0x01,
0x00,0x01,0x00,0x26, //ID
0x00,0x00,0x00,0x04, //起始地址=1 机械坐标,4,ABS 6 REAL 7 DISTANCE
0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//3.REAL
0x00,0x1c,0x00,0x01,
0x00,0x01,0x00,0x26, //ID
0x00,0x00,0x00,0x06, //起始地址=1 机械坐标,4,ABS 6 REAL 7 DISTANCE
0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
//4.DISTANC
0x00,0x1c,0x00,0x01,
0x00,0x01,0x00,0x26, //ID
0x00,0x00,0x00,0x07, //起始地址=1 机械坐标,4,ABS 6 REAL 7 DISTANCE
0xff,0xff,0xff,0xff,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
//调整数据长度
len = 28 * block_sum + 2;
i_d.dat = len;
p_send[8] = i_d.d_byte[1];
p_send[9] = i_d.d_byte[0];
READ_GROUP = 3;//用于设备返回时候判断是哪个函数发出的数据返回
Send_Message(0, p_send, len+10);
}
从上面代码可以看出,不再需要调用官方的库文件,直接填充send buffer,通过TCP连接发送出去即可,所以适用性非常强。
四,机台IP设置
可以参考下面链接
发那科(Fanuc)CNC IP地址与FOCAS端口设置 | 巫迪科技
五,现场问题
1、能ping通但不能够访问到端口
(1)检查设备端的端口是否配置正确。
(2)检查机台IP是否被其他网络设备占用。
(3)检查是否网口插错,有些机器有两个网卡。不同网卡的配置界面还非常相似。
2、没有网口
(1)有网口配置界面,但是没有网卡的MAC地址,这类就是无自带网口,但可以通过PCMCIA网卡进行扩展。
(2)找不到网口的配置界面。这类一般是厂家限制了功能,想要重新把界面搞出来,非常麻烦。建议采集I/O。
(3)网卡选择错误。在配置网卡的时候可以选择,使用机台自带网口需要选择内置有效,选择PCMCIA有效就是使用PCMCIA扩展网口。
3、PCMCIA网卡丢包
国内做这个卡的就那么两家,用过其中一家,用某些交换机不会出现丢包,用其他交换机会出现严重丢包。