• Tcp方式采集CNC兄弟设备数据


    先说下为了采集CNC兄弟设备的数据可谓是一波三折。

    因为首次接触brother设备(CNC)是直接在设备上设置IP、用户名、密码,然后直连PC,用Ftp可以查看和下载CNC brother设备里的数据库文件(NC文件)。其实我们最关心的是CNC的“工件计数”,经确认CNC可以实时的将计数写入WKCNTR.NC文件,现在理论上已经没有问题了,可是后面还有很多坑。

    我们刚开始是用dotnet来做的,写好demo程序连接brother测试,可是怎么都无法下载,一直提示“基础连接关闭,协议冲突”之类的异常,查资料发现下载后文件保存的是在中文目录下,立马移动文件保存位置保证都在英文目录下,还真的好了!这下太好了。

    后来我们就按照这个demo开始编写正式代码,结果怎么都无法下载,试了好多台设备都不行,真的莫名其妙、一头雾水。并且提示的异常都是“基础连接关闭,协议冲突”,这次可不是中文目录的问题了。于是就在google上查资料,各种方法都试了,结果还是不行,不能一头撞死南墙,最后放弃了。

    灵光一闪,为什么不用python试试呢,于是随手写了个demo程序,也就有了上一篇随笔《远程监控显示brother数控机床数据》,结果真的好了很轻松就搞定了,并且所有的16台CNC brother设备都可以正常采集数据,按照30秒频率将采集到的数据写入数据库(mariadb),别慌到这里才是欢喜了一半。

    真正运行起来稳定性可没那么好,刚开始16台都好好的,没过1天就有一台出现问题,现象是可以ping通,可以连接到设备,也可以登录,还可以列出设备上所有的文件,但就是无法下载,结果就是超时。后来经过不断调查发现,如果我同时开两个连接都访问这个文件,那么有一个失败超时,另一个居然可以下载读取,太奇妙了,没找到好的办法之前就用这个下下策吧。结果第三天又有一台出现问题,可以ping通,就不让连接了,就好像brother设备上没有开启ftp服务一样。本来好好的,就出现这种莫名其妙的问题,到这里简直郁闷到极点。

    总之对这种方案不满意,也考虑到还有4台brother CNC设备没有ftp服务可以利用,于是找设备科找brother的操作手册参考书,看是否有其他方法。结果在第五章关于通信,还真的找到了,Tcp通讯协议在眼前一亮,再细看具体的指令协议,只能看懂指令必须以%开始,以%结束,里面的就不懂了。只好再拨打供应商电话,说明情况请求两个%之间的内容怎么写,供应商回复:%CLOD    WKCNTR     + 换行 + 00%

    赶紧将指令贴在网络调试助手里,随便连接一台brother,结果真的返回数据了,目标工件计数就在返回的数据里面,接下来的就是解析返回字符串了,这都不是问题。结果不仅16台新的brother设备可以采集到数据,4台老的也可以,并且效率要比ftp要高很多。

    下面就把最重要的部分代码贴出来:

     1         private int GetCncDada(string ip)
     2         {
     3             TcpClient client = new TcpClient();
     4             int cnc = -1;
     5             try
     6             {
     7                 client.Connect(new IPEndPoint(IPAddress.Parse(ip), 10000));
     8                 if (client.Connected)
     9                 {
    10                     var networkStream = client.GetStream();
    11                     var buffer = Encoding.UTF8.GetBytes("%CLOD    WKCNTR    
    00%");
    12                     networkStream.Write(buffer, 0, buffer.Length);
    13                     networkStream.ReadTimeout = 3000;
    14                     var readBuffer = new byte[1024];
    15                     var len = networkStream.Read(readBuffer, 0, readBuffer.Length);
    16                     var result = Encoding.UTF8.GetString(readBuffer, 0, len);
    17                     //_logger.Debug(result);
    18                     networkStream.Close(3000);
    19 
    20                     var lines = result.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
    21                     foreach (var line in lines)
    22                     {
    23                         if (line.StartsWith("A01"))
    24                         {
    25                             var fields = line.Split(',');
    26                             _logger.Debug("工件计数 = " + fields[2].Trim());
    27                             cnc = Convert.ToInt32(fields[2].Trim());
    28                             break;
    29                         }
    30                     }
    31                 }
    32                 return cnc;
    33             }
    34             catch (Exception err)
    35             {
    36                 _logger.Error(err);
    37                 return cnc;
    38             }
    39             finally
    40             {
    41                 if (client.Connected)
    42                 {
    43                     client.Close();
    44                 }
    45             }
    46 
    47         }

     以下是python版的代码:

     1 # coding: utf8
     2 import socket
     3 import pymysql
     4 import os
     5 import time
     6 cnc_config = [('J01', "192.168.1.40"), ('J02', "192.168.1.41"), ('J03', "192.168.1.42"), ('J04', "192.168.1.43"),
     7               ('J22', "192.168.1.44"), ('J21', "192.168.1.45"), ('J20', "192.168.1.46"), ('J19', "192.168.1.47"),
     8               ('J18', "192.168.1.48"), ('J17', "192.168.1.49"), ('J16', "192.168.1.50"), ('J15', "192.168.1.51"),
     9               ('J14', "192.168.1.52"), ('J13', "192.168.1.53"), ('J12', "192.168.1.54"), ('J11', "192.168.1.55"),
    10               ('J37', "192.168.1.56"), ('J36', "192.168.1.57"), ('J35', "192.168.1.58"), ('J34', "192.168.1.59")]
    11 
    12 
    13 def get_from_brother(ip='127.0.0.1', port=10000):
    14     client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    15     client.settimeout(3)
    16     try:
    17         client.connect((ip, port))
    18         instruct = '%CLOD    WKCNTR    ' + os.linesep + '00%'
    19         client.send(instruct.encode())
    20         lines = client.recv(1024).decode().split(os.linesep)
    21         lines = [line for line in lines if line.startswith('A01')]  # 选出以A01开头的行
    22         fields = lines[0].split(',')  # 拆分出字段,第3个字段就是目标[工件计数]
    23         return int(fields[2].strip())
    24     except Exception as e:
    25         print(ip, e)
    26         return -1
    27     finally:
    28         client.close()
    29 
    30 
    31 def save_db(name='J44', qty=-1):
    32     try:
    33         conn = pymysql.Connect(user='root', password='1234', database='dademes', charset='utf8')
    34         cus = conn.cursor()
    35         if qty == -1:
    36             cus.execute('update kbequipment set running=%s where name=%s', ('关机', name))
    37         else:
    38             cus.execute('update kbequipment set running=%s, status=%s where name=%s', ('正常', qty, name))
    39         conn.commit()
    40         cus.close()
    41         conn.close()
    42     except Exception as e:
    43         print('机台号=%s保存数据异常,%s' % (name, e))
    44 
    45 if __name__ == '__main__':
    46     while True:
    47         try:
    48             for cnc_name, ip in cnc_config:
    49                 print('正在读取机台号=%s,ip=%s' % (cnc_name, ip))
    50                 qty = get_from_brother(ip=ip)
    51                 save_db(qty=qty, name=cnc_name)
    52         except Exception as e:
    53             print('__main__', e)
    54         finally:
    55             print('CNC数据读取完毕...30秒后再次读取...')
    56             time.sleep(30)
  • 相关阅读:
    Gridview如何用自定义按钮进行编辑和提交修改
    winform多线程中给datagridview绑定数据源
    DevExpress控件WebchartControl的学习记录
    datagridview右键选中单元格并获取到焦点
    asp.net局部页面打印,以及如何去掉打印时自动保留的URL地址(页眉页脚)
    GridView如何实现点击某行的指定列弹出新窗体
    C# Color Font 与String之间的转换
    推荐一款 asp.net js日历控件
    js浮点运算替代函数
    VSeWss 1.3 CTP 安装后出现错误
  • 原文地址:https://www.cnblogs.com/jonney-wang/p/6238768.html
Copyright © 2020-2023  润新知