串口服务器通信时间试验

  试验使用USR-N520串口服务器,从COM1发送"hello"到COM2,形成一个TCP-COM-TCP的转发通道。转发的时间由两个TCP传输时间、一个COM传输时间和串口服务器及上位机软件运行时间。上位机和单片机的软件运行是非常快的,因此可以认为这个时间主要是由线路消耗。

  本试验的默认时间单位为ms。如果是与波特率有关,则以字节或节拍为单位。

  以下是不同波特率下的转发时间记录表和COM波特周期-总时间散点图。

  由图可知,通信时间近似于直线。

  对数据进行线性回归:



		double[] xs = new double[] {
				0.004340278,
				0.008680556,
				0.017361111,
				0.026041667,
				0.052083333,
				0.104166667,
				0.208333333,
				0.416666667,
				0.833333333,
				1.666666667,
		};
		double[] ys = new double[] {
				3.1,
				3.4,
				3.7,
				4.3,
				6.5,
				11.1,
				20.3,
				38.8,
				76.6,
				151.3,

		};
		DoublePolynomialTransformer fun = StaticMathUtils.regressAxisFunction(xs, ys, 1);
		System.out.println(fun);
		fun = StaticMathUtils.regressLinearAxisFunction(xs, ys);
		System.out.println(fun);

	

  计算得方程:

f(x) = 89.42724395637012x + 2.0621047652936966
f(x) = 89.4272439563701x + 2.0621047652936997

  上面两个方程分别是由多项式回归函数和线性回归函数计算的。结果非常接近。

  由于TCP的波特率不可调整,因此常数项对应的就是TCP传输两次的时间。可以粗略计算出TCP传送5个字节需要的时间约为1ms。需要注意的是,TCP的一个包最多可以传输2500个字节。5字节和2500字节的时间是非常接近的。

  由于USR-N520一次串口通信可转换的包长度为512字节,所以再做一次512字节的测试。测试结果出下:

  计算得回归方程为:

f(x) = 5159.123501379577x + 2.282298649633958
f(x) = 5159.123501379577x + 2.2822986496340576

  可以看到长度512时,一次项系数接近于每个字节10个节拍,而之前的长度为5时,一次项系数接近于每个字节18个节拍。这是串口服务器内部的组包机制造成的。由8位字节的串口通信帧格式可知1个字节需要10个节拍,那么可以算出尾部超时约为3.9个字节的时间(39个节拍)。

  常数项似乎变大了一点点,多出来的部分一方面是第二次试验精度更高,一方面是数据增多上位机的运算需要更多的时间,但是回归计算本身也是有一定的误差的,常数项并没有成比例地变大,即可认为是不受影响。

  常数项的成分还包括0.16ms×2次的线程信号传递时间。这个时间是用阻塞队列测量得到的,是操作系统线程调度的特性。TCP通信的API函数内部也可能不止一级信号传递。512个字节在内存中的复制时间小于1us,可以忽略。

  再次进行UDP发送512字节的测试,回归方程为:

f(x) = 5159.298633803901x + 1.831656314981592
f(x) = 5159.298633803901x + 1.8316563149818328

  一次项几乎没有变化,常数项小了一些。说明UDP发送512个字节的时间略小于1ms,UDP确实比TCP快一些。

  再次进行通过USR-VCOM虚拟串口以TCP连接发送512字节的通信测试,回归方程为:

f(x) = 5118.946895231009x + 41.83233469137791

  使用USR-VCOM虚拟串口以UCP连接发送512字节的通信测试,回归方程为:

f(x) = 5119.266225253171x + 41.20304665027626

  常数项的差异与直连TCP和UCP时的差异相近,但整体增加了约39ms。TCP与UCP的增量相近,说明USR-VCOM软件处理需要消耗约19.5ms。这是多数工业软件的通病。我原以为是因为Negal算法未关闭导致的。但据查UDP并不经过Negal算法粘包,所以这个时间完全是消耗在软件上。

  为什么一个简单的转换软件会产生如此大的延时。(我第一次猜错了,以为是USR-VCOM的问题。其实不是,经过下文所述的试验,我发现是串口服务器造成的。)

  反正已经研究了这么多了,趁着手里有硬件,本篇再多加一项:USR-N520如何利用网络端更改串口参数(这个参数是隐式的,不会在配置页面显示出来)。

  报文的结构为:55 aa 55 00 25 80 03 a8。

  报文这么短,我就不加颜色了。

  55 aa 55是起始符;

  00 25 80是波特率的16进制,这里是9600bps;

  03是标志位。

    第0~1比特定义:0:5位、1:6位、2:7位、3:8位;

    第2比特:0:1个停止位、1:1.5个(5位字节)或2个(6~8位字节)停止位;

    第3~5比特:0:无校验;1:奇校验、3:偶校验、5:mark、7:space;

  a8是校验位。(00 + 25 + 80 + 03) & ff = a8。

  撤销的报文是:55 aa 55 00 00 00 ff ff。如果不撤消,则配置网页中的配置参数是不起作用的。

  一般不会在自己的软件正式运行时还去改串口服务器的参数。但是要小心自己的报文不要和串口服务器的动态配置报文重合了。

  由我的程序动态配置波特率再进行的测试中,最终确定了为什么使用USR-VCOM会这么慢的原因了。原来问题出在串口服务器上,如果使用报文配置参数,则转换的过程会变慢。这是产品的特性,与我的程序及USR-VCOM都无关。至于为什么要这么长时间,目前看来已经超出了我可以研究的范围了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的Python代码示例,可以实现UDP程序和串口服务器通信: ```python import socket import serial # 串口服务器配置 SERIAL_PORT = 'COM1' SERIAL_BAUDRATE = 9600 # UDP服务器配置 UDP_IP = '127.0.0.1' UDP_PORT = 5005 ser = serial.Serial(SERIAL_PORT, SERIAL_BAUDRATE) # 创建UDP socket sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定IP和端口号 sock.bind((UDP_IP, UDP_PORT)) while True: # 读取串口数据 data = ser.readline().decode().strip() # 发送数据到UDP服务器 sock.sendto(data.encode(), (UDP_IP, UDP_PORT)) # 接收UDP服务器的响应数据 resp, addr = sock.recvfrom(1024) # 打印响应数据 print(resp.decode()) ser.close() sock.close() ``` 上述代码中,我们使用了Python内置的socket库和serial库来实现UDP程序和串口服务器通信。首先,我们通过serial.Serial()函数创建一个串口对象,并指定串口服务器的配置参数。然后,我们使用socket.socket()函数创建一个UDP socket对象,并通过sock.bind()方法绑定UDP服务器的IP地址和端口号。 在while循环中,我们使用串口对象的readline()方法读取串口数据,并将数据发送到UDP服务器,使用sock.recvfrom()方法接收UDP服务器的响应数据,并打印出来。最后,我们通过ser.close()和sock.close()方法关闭串口对象和UDP socket对象。 需要注意的是,上述代码只是一个简单的示例,实际应用中需要根据具体的需求进行修改和完善。同时,需要保证串口服务器和UDP服务器之间的通信协议和数据格式一致。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值