试验使用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都无关。至于为什么要这么长时间,目前看来已经超出了我可以研究的范围了。