300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Fanuc发那科数据采集

Fanuc发那科数据采集

时间:2018-11-24 16:04:18

相关推荐

Fanuc发那科数据采集

最近在完善CNC数控车床的数据采集,做之前没接触过这东西,只知道是使用Fanuc数控系统,在网上搜索一圈,资料少到令人蛋疼。按正常来说,发那科数控系统是非常常见的。最后加了几个群,提的问题没人管,但跑出来很多各种收费解决问题,捂得紧紧的,无奈只能自己研究。

废话少说,进入正题,Fanuc的SDK包叫Focas2,里面有说明文档和开发要用的DLL,而我们数据采集只需要文件:fwlib32.cs、Fwlib32.dll和车床系统版本对应的DLL,如果你不知道,那就把所有DLL全部复制进bin目录。

SDK有开发案例和每个函数的代码实例(doc文件),但是不全,并不是每个函数都有,常用的函数没有问题。

开发时注意,使用cnc_allclibhndl3连接后得到的Flibhndl,使用时必须和使用cnc_allclibhndl3保持在同一线程里,否则获取到就会全是0,不是实际数据。

本次使用多线程采集多个设备的 机械位置,主轴速度,进给率,负载

using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Diagnostics;using workInformation;using System.Threading;namespace CNCServ{public class DeviceInfo{public Guid DeviceID { get; set; }public string DeviceCode { get; set; }public string DeviceName { get; set; }public string IP { get; set; }public ushort Port { get; set; }public bool Connected { get; set; }public ushort Flibhndl { get; set; }public bool run { get; set; } = true;//最后获取到数据的时间,处理重连public DateTime LastHasDateTime { get; set; }//获取到机械位置为0的次数,处理是否显示(偶尔会为0,不作显示)public int ZeroCount { get; set; }//采集数据频率 间隔public int GetDataInterval { get; set; }/// <summary>/// 机械坐标/// </summary>/// <returns></returns>public string GetCNC_Machine(){#region cnc_machine 机械坐标Focas1.ODBAXIS odbaxis = new Focas1.ODBAXIS();c_machine(Flibhndl, (short)(1), 8, odbaxis);string x = (odbaxis.data[0] / 1000.000).ToString("0.000");c_machine(Flibhndl, (short)(2), 8, odbaxis);string y = (odbaxis.data[0] / 1000.000).ToString("0.000");c_machine(Flibhndl, (short)(3), 8, odbaxis);string z = (odbaxis.data[0] / 1000.000).ToString("0.000");var d = new { X = x, Y = y, Z = z };string result = JsonConvert.SerializeObject(d);return result;#endregion}/// <summary>/// 主轴实际速度/// </summary>/// <returns></returns>public int GetCNC_Acts(){#region cnc_acts2 主轴实际速度 Focas1.ODBACT odbact = new Focas1.ODBACT();c_acts(Flibhndl, odbact);return odbact.data;#endregion}/// <summary>/// 伺服器给进率/// </summary>/// <returns></returns>public int GetCNC_Actf(){#region cnc_actf 伺服器给进率Focas1.ODBSPEED odbspeed = new Focas1.ODBSPEED();var odbact = new Focas1.ODBACT();c_actf(Flibhndl, odbact);return odbact.data;#endregion}/// <summary>/// 系列轴负载/// </summary>/// <returns></returns>public short GetCNC_Rdspload(){#region cnc_rdspload 系列轴负载Focas1.ODBSPN odbspn = new Focas1.ODBSPN();c_rdspload(Flibhndl, Focas1.ALL_SPINDLES, odbspn);return odbspn.data[0];#endregion}/// <summary>/// 从设备获取实时数据/// </summary>/// <param name="fh">连接句柄</param>public void GetDeviceData(){//上一次检测设备的状态int runstate = 0;//0停止,1待机,开动while (run){bool reConnect = false;string result = "连接失败";int cnc_acts2 = 0, cnc_actf = 0;#region 检查连接情况,断开则重连TimeSpan ts = DateTime.Now - LastHasDateTime;if (ts.TotalSeconds >= 60 * 3) //3分钟判断一次连接状态{Focas1.ODBST buf = new Focas1.ODBST();c_statinfo(Flibhndl, buf);runstate = buf.run; //状态+模式if ((buf.run + buf.aut) <= 0) //buf.run //0停止,1待机,开动{reConnect = true; //3分钟重连一次 Connected = false;}LastHasDateTime = DateTime.Now;}#endregion#region 连接设备if (!Connected && reConnect) //3分钟重连一次,降低频率{reConnect = false;if (!Ping(IP)){result = "Ping不通,连接失败";SysLog.WriteEntry("CNCServ", $"{DeviceCode} ping不通,无法连接!", SysLog.LogType.Information, 0);}else{ushort f;var connect = c_allclibhndl3(IP, Port, 10, out f);if (connect != Focas1.EW_OK){SysLog.WriteEntry("CNCServ", $"{DeviceCode} 连接失败!错误代码:{connect}!", SysLog.LogType.Information, 0);Flibhndl = 0;Connected = false;}else{Flibhndl = f;Connected = true;LastHasDateTime = DateTime.Now;SysLog.WriteEntry("CNCServ", $"{DeviceCode} 连接成功!{Flibhndl}!", SysLog.LogType.Information, 0);result = "连接成功";}}LastHasDateTime = DateTime.Now;UpdateServiceData("connectstate", result, DeviceID, DeviceCode, DeviceName);}#endregion#region 获取数据if (Connected){//UpdateServiceData("connectstate", "连接成功", DeviceID, DeviceCode, DeviceName); try{#region cnc_machine 机械坐标var machine = GetCNC_Machine();#endregion#region cnc_acts2 主轴实际速度 cnc_acts2 = GetCNC_Acts();#endregion#region cnc_actf 伺服器给进率 cnc_actf = GetCNC_Actf();#endregion#region cnc_rdspload 系列轴负载string rdspload = GetCNC_Rdspload();#endregion var data = new{connectstate = "连接成功",cnc_machine = machine,cnc_acts2 = act2,cnc_actf = actf,cnc_rdspload = rdspload};var updatedata = JsonConvert.SerializeObject(data);UpdateServiceData("all", updatedata, DeviceID, DeviceCode, DeviceName);}catch (Exception ex){SysLog.WriteEntry("CNCServ", ex, 1); }}#endregion Thread.Sleep(GetDataInterval);}}/// <summary>/// 更最新数据到接口/// </summary>/// <param name="dataCode"></param>/// <param name="dataValue"></param>/// <param name="deviceID"></param>/// <param name="deviceCode"></param>/// <param name="deviceName"></param>private void UpdateServiceData(string dataCode, string dataValue, Guid deviceID, string deviceCode, string deviceName){try{//接口方式 var t = new Thread(delegate () {APIHelper.TestCNCData(dataCode, deviceCode, deviceName, dataValue);});t.Start();}catch (Exception ex){SysLog.WriteEntry("CNCServ", ex, 2); }}/// <summary>/// 设置失去连接,不再使用循环重连,而是先ping通再连接,防止重连消耗资源/// </summary>/// <param name="ip"></param>/// <returns></returns>private bool Ping(string ip){bool result = false;using (var ping = new Ping()){PingReply pingReply = ping.Send(ip);if (pingReply.Status == IPStatus.Success)result = true;elseresult = false;}return result;}}}

上面代码为一个对象,多台设备可以实例化多个对象,每个对象放进一个线程里,可以做成win服务或都winfrom程序

下面是调用例子(windows service)

protected override void OnStart(string[] args){ Bind();}/// <summary>/// 设置设备列表,并启动采集线程/// </summary>private void Bind(){int interval = int.Parse(ConfigurationManager.AppSettings["GetDataInterval"]); //采集数据频率 毫秒DeviceInfo deviceInfo0002;DeviceInfo deviceInfo0003;DeviceInfo deviceInfo0004;DeviceInfo deviceInfo0007;deviceInfo0002 = new DeviceInfo{Connected = false,DeviceID = Guid.NewGuid(),,DeviceCode = "001",DeviceName = "数控车床", IP = "192.168.0.1",Port = 8193,GetDataInterval = interval,LastHasDateTime = DateTime.Now.AddDays(-1)};Thread thread2 = new Thread(new ThreadStart(deviceInfo0002.GetDeviceData));this.threadPool.Add(thread2);deviceList.Add(deviceInfo0002);deviceInfo0003 = new DeviceInfo{Connected = false,DeviceID = Guid.NewGuid(),DeviceCode = "002",DeviceName = "数控车床",IP = "192.168.0.2",Port = 8193,GetDataInterval = interval,LastHasDateTime = DateTime.Now.AddDays(-1)};Thread thread3 = new Thread(new ThreadStart(deviceInfo0003.GetDeviceData));this.threadPool.Add(thread3);deviceList.Add(deviceInfo0003);deviceInfo0004 = new DeviceInfo{Connected = false,DeviceID = Guid.NewGuid(),DeviceCode = "003",DeviceName = "数控车床",IP = "192.168.0.3",Port = 8193,GetDataInterval = interval, LastHasDateTime = DateTime.Now.AddDays(-1)};Thread thread4 = new Thread(new ThreadStart(deviceInfo0004.GetDeviceData));this.threadPool.Add(thread4);deviceList.Add(deviceInfo0004);deviceInfo0007 = new DeviceInfo{Connected = false,DeviceID = Guid.NewGuid(),DeviceCode = "004",DeviceName = "数控车床",IP = "192.168.0.4",Port = 8193,GetDataInterval = interval,LastHasDateTime = DateTime.Now.AddDays(-1)};Thread thread7 = new Thread(new ThreadStart(deviceInfo0007.GetDeviceData));this.threadPool.Add(thread7);deviceList.Add(deviceInfo0007);foreach (Thread t in this.threadPool){t.Start();}}//停止服务时,关闭线程和释放连接,网上说连接有1000的限制,没明白是怎么个限制法,但释放总没错protected override void OnStop(){foreach (var m in deviceList){m.run = false;}foreach (Thread t in this.threadPool){t.Abort();}this.threadPool.Clear();foreach (var m in deviceList){ int ret = c_freelibhndl(m.Flibhndl);}deviceList.Clear();}

完成,因为代码里我加了保存到数据库,这部分已删减,能获取到数据,怎么处理都好办。如果想采集更多其它数据,可以自己查看SDK包的函数说明书,然后在Model里添加上代码

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。