先说下为了采集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要高很多。

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

         private int GetCncDada(string ip)
{
TcpClient client = new TcpClient();
int cnc = -;
try
{
client.Connect(new IPEndPoint(IPAddress.Parse(ip), ));
if (client.Connected)
{
var networkStream = client.GetStream();
var buffer = Encoding.UTF8.GetBytes("%CLOD    WKCNTR    \r\n00%");
networkStream.Write(buffer, , buffer.Length);
networkStream.ReadTimeout = ;
var readBuffer = new byte[];
var len = networkStream.Read(readBuffer, , readBuffer.Length);
var result = Encoding.UTF8.GetString(readBuffer, , len);
//_logger.Debug(result);
networkStream.Close(); var lines = result.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
foreach (var line in lines)
{
if (line.StartsWith("A01"))
{
var fields = line.Split(',');
_logger.Debug("工件计数 = " + fields[].Trim());
cnc = Convert.ToInt32(fields[].Trim());
break;
}
}
}
return cnc;
}
catch (Exception err)
{
_logger.Error(err);
return cnc;
}
finally
{
if (client.Connected)
{
client.Close();
}
} }

以下是python版的代码:

 # coding: utf8
import socket
import pymysql
import os
import time
cnc_config = [('J01', "192.168.1.40"), ('J02', "192.168.1.41"), ('J03', "192.168.1.42"), ('J04', "192.168.1.43"),
('J22', "192.168.1.44"), ('J21', "192.168.1.45"), ('J20', "192.168.1.46"), ('J19', "192.168.1.47"),
('J18', "192.168.1.48"), ('J17', "192.168.1.49"), ('J16', "192.168.1.50"), ('J15', "192.168.1.51"),
('J14', "192.168.1.52"), ('J13', "192.168.1.53"), ('J12', "192.168.1.54"), ('J11', "192.168.1.55"),
('J37', "192.168.1.56"), ('J36', "192.168.1.57"), ('J35', "192.168.1.58"), ('J34', "192.168.1.59")] def get_from_brother(ip='127.0.0.1', port=10000):
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.settimeout(3)
try:
client.connect((ip, port))
instruct = '%CLOD    WKCNTR    ' + os.linesep + '00%'
client.send(instruct.encode())
lines = client.recv(1024).decode().split(os.linesep)
lines = [line for line in lines if line.startswith('A01')] # 选出以A01开头的行
fields = lines[0].split(',') # 拆分出字段,第3个字段就是目标[工件计数]
return int(fields[2].strip())
except Exception as e:
print(ip, e)
return -1
finally:
client.close() def save_db(name='J44', qty=-1):
try:
conn = pymysql.Connect(user='root', password='', database='dademes', charset='utf8')
cus = conn.cursor()
if qty == -1:
cus.execute('update kbequipment set running=%s where name=%s', ('关机', name))
else:
cus.execute('update kbequipment set running=%s, status=%s where name=%s', ('正常', qty, name))
conn.commit()
cus.close()
conn.close()
except Exception as e:
print('机台号=%s保存数据异常,%s' % (name, e)) if __name__ == '__main__':
while True:
try:
for cnc_name, ip in cnc_config:
print('正在读取机台号=%s,ip=%s' % (cnc_name, ip))
qty = get_from_brother(ip=ip)
save_db(qty=qty, name=cnc_name)
except Exception as e:
print('__main__', e)
finally:
print('CNC数据读取完毕...30秒后再次读取...')
time.sleep(30)

Tcp方式采集CNC兄弟设备数据的更多相关文章

  1. 【AT91SAM3S】ADC中断方式采集数据

    板子依旧是英倍特的EK-SAM3S.ADC部分的原理图如下: PB1是一个复用引脚,在这里被用作AD功能,对应芯片上的AD5.即,使用片内ADC的5通道测VR1上2号引脚的电压. 实验采用了SysTi ...

  2. 计算机组成原理——I/O接口以及I/O设备数据传送控制方式

    接口可以看作是两个部件之间交接的部分.硬件与硬件之间有接口,硬件与软件之间有接口,软件与软件之间也有接口. 这里我们所说的I/O接口,一边连接着主机,一边连接着外设. I/O接口的功能 I/O接口的基 ...

  3. 用vlc搭建简单流媒体服务器(UDP和TCP方式)

    .UDP(legacy)传统模式 .RTP方式 .RTSP方式 RTSP方式是通过RTP进行流媒体数据的传输的,VLC的实现也是基于UDP的.这种方式网上的参考资料比较多,我就不截图了,直接叙述命令行 ...

  4. FFmpeg获取DirectShow设备数据(摄像头,录屏)

    这两天研究了FFmpeg获取DirectShow设备数据的方法,在此简单记录一下以作备忘.本文所述的方法主要是对应Windows平台的. 1.       列设备 ffmpeg -list_devic ...

  5. 【转】FFmpeg获取DirectShow设备数据(摄像头,录屏)

    这两天研究了FFmpeg获取DirectShow设备数据的方法,在此简单记录一下以作备忘.本文所述的方法主要是对应Windows平台的. 1.       列设备 ffmpeg -list_devic ...

  6. [转帖]IP /TCP协议及握手过程和数据包格式中级详解

    IP /TCP协议及握手过程和数据包格式中级详解 https://www.toutiao.com/a6665292902458982926/ 写的挺好的 其实 一直没闹明白 网络好 广播地址 还有 网 ...

  7. ffmpeg强制使用TCP方式推流到EasyDarwin开源流媒体服务器进行直播

    我们的EasyDarwin目前部署在阿里云的服务器上面,运行的效果是非常好的,而且无论是以TCP方式.还是UDP的方式推送,都可以非常好地进行直播转发: 但并不是所有的用户服务器都是阿里云的形式,有很 ...

  8. TCP/IP UDP 协议首部及数据进入协议栈封装的过程

    数据的封装 UDP 封装 TCP 封装 IP 封装 检验和算法 当应用程序用TCP传送数据时,数据被传送入协议栈中,然后逐一通过每一层直到被当作一串比特流送入网络 注: UDP数据TCP数据基本一致. ...

  9. 设备数据通过Azure Functions 推送到 Power BI 数据大屏进行展示(2.Azure Functions实战)

    本案例适用于开发者入门理解Azure Functions/ IoT Hub / Service Bus / Power BI等几款产品. 主要实战的内容为: 将设备遥测数据上传到物联网中心, 将遥测数 ...

随机推荐

  1. Spring Security 从配置入门 学习讲解。刽子手------------securityConfig.xml

    不知道我的web.xml 大家都理解了没.  废话确实有点多,可能很多知识点,大家都知道,可是我学的时候,压根什么都不懂啊.... 这篇我们要讲刽子手  securityConfig. 为什么要说他是 ...

  2. 亲身试用python简单小爬虫

    前几天基友分享了一个贴吧网页,有很多漂亮的图片,想到前段时间学习的python简单爬虫,刚好可以实践一下. 以下是网上很容易搜到的一种方法: #coding=utf-8 import urllib i ...

  3. Java Swing 第02记 标签和按钮

    JLable的常用构造器 Public JLabel() 创建无图像且其标题为空字符串的JLabel对象 Public JLabel(String text) 使用指定的字符串text(也就是标签显示 ...

  4. Linux中vim的简单配置

    本文主要分享Linux中vim的简单配置 ★配置文件的位置     在目录/etc.下面,有个名为vimrc的文件,这就是系统中公共的vim配置文件,对所有用户都开放.而在每个用户的主目录下,都可以自 ...

  5. EntityFrameworkCore 试用

    引用 EF Core Sqlite Install-Package Microsoft.EntityFrameworkCore.SqlServer 引用 EF Core Tool Install-Pa ...

  6. 实时控制软件设计 第二次作业 myRobot

    #include<iostream> #include <Eigen/Dense> #include <math.h> #include <vector> ...

  7. 最适合和最不适合新手使用的几款 Linux 发行版

    大多数知名的Linux发行版都属于"比较容易使用"这一类.一些观察人士可能会驳斥这个观点,但事实上,说到Linux,大多数并非从事IT或软件开发工作的人会被最容易的使用体验所吸引. ...

  8. Samba - 文件共享服务器的搭建和配置

    下载与安装: deb包安装 官方deb包下载:http://packages.ubuntu.com/ 命令安装dpkg –i xxxx.deb (安装不成功留意日志安装依赖包) apt安装 apt-g ...

  9. Asp.net Web.Config - 配置元素 trace

    一.trace的元素的属性 属性 说明 enabled 是否启用应用程序跟踪.为了使用 Trace.axd 查看器,必须启用跟踪.默认情况下,Trace.axd 查看器被添加到httpHandlers ...

  10. C++继承,多重继承,虚继承的构造函数以及析构函数的调用顺序问题

    #include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = ; cout < ...