本文主要介绍个人学习、应用设备通信与数据采集的经历。
作为力学专业的人,数据采集对我而言并不陌生。我们做力学试验的时候,就经常用采集器采集试验件的应变和位移。尤其是分级加载的时候,为了保证载荷和变形的对应,当载荷到达后,需要通知采集变形的人员手动完成一次采集。
后来因为某个项目需要自行开发一个数据采集软件,我才开始接触设备通信。作为入门的概念,这里首先介绍一下上位机和下位机的概念。
简单理解,上位机就是我们在windows端操作的采集软件,下位机就是采集器。如果我们扩展一个这个概念,发出指令的就是上位机,提供数据的就是下位机。
我们软件开发中,大部分情况是在开发上位机,下位机一般是设备厂家做的。
之前作为门外汉,我对数据采集软件模模糊糊的印象就是LABVIEW,感觉大部分数据采集都是靠LABVIEW。
为了尽快入门,我给自己规划了一个快速入门计划:
1)网上买一个简单的电信号采集器;
2)根据店家提供的LABVIEW示例,掌握通信方法,可以控制采集的开始、停止,可以获取到采集数据然后绘制成动态曲线。

通信方式
目前常用的通信方式有TCP、Modbus TCP、UDP、串口。网上或者书里介绍这些东西的时候,过于注重概念,什么第几层协议,什么几次握手几次挥手,越看越迷糊。我写了这么多通信软件,到现在也不知道怎么握手怎么挥手,咱们不是计算机专业的,不需要把这个搞那么清楚,会用即可。
不管什么协议,使用方法无非:
(1) 定义好接口,TCP、Modbus TCP、UDP指定网络ip和端口,串口则是插上后就能扫描出来端口号。这些东西就类似于电话号码,我们知道对方的电话号码才能拨打电话;
(2)建立连接关系,根据接口一行代码就能创建连接,相当于电话拨通;
(3)上位机发出指令,这个相当于“对暗号”,双方事先商定好,什么暗号对应什么指令。我们开发的时候,找厂家要这个暗号就行了;
(4)上位机接收数据,一般这些数据是字节化的,可以是一堆二进制。不要慌,这个按照厂家给的解码方式,解码就行。
我刚开始接触这些的时候,看到一堆二进制字节也感觉有点懵。实际上根据“密码本”转码后,就是一堆数据而已,并不高级。
我买来练习的用的电信号采集器,就是串口的。这种一般就是一个USB插口,插到电脑上就连上了。
LABVIEW
我起初希望用LABVIEW完成目标,可是我拿到厂家给的LABVIEW示例,怎么摸索都没跑通,那年过年一个假期都在学习LABVIEW和测试这个玩意,但是折腾一个假期也没搞定。
后来过年回来,我联系店家,才知道给我的代码和我买的设备版本不匹配。拿到新代码以后能运行了。
LABVIEW是NI公司用来给其旗下各类设备通信使用的图形化编程软件。简单理解,这个东西是没有代码的,它把各种函数和工具都做成图标,用户通过拖拽连接,搭建程序。随着NI设备在各个行业的广泛使用,LABVIEW也成了近乎通用的基础通信软件,很多非NI公司的产品也都开发了LABVIEW的接口给用户使用。

这种方式最大的好处就是不需要编程,最大的缺陷也在这。对初学者来说,似乎不需要编程基础,简单拖拽几下就搭建一个软件。
但是简单的功能可以这么干,稍微复杂的点功能,尤其各种循环、判断互相嵌套的时候,这个图形代码看着非常头大,编起来麻烦,排故更麻烦。
Python
一番折腾下来,我感觉还是用代码写更方便。这个时候,我也拿到了项目购买的数采设备。
那个设备提供了动态链接库,供上位机调用。简单理解,上位机可以引用动态链接库里面的函数完成各种指令发送和数据接收。
实际上我之前购买的那个电信号采集卡也提供了动态链接库,并且在使用LABVIEW的时候还要导入它。

我这里给大家的建议是,千万千万别用这个方式,前面提到了,通信这个玩意本身很简单,就是我一个指令,下位机一个动作,我们直接和它通信就行,一定要要求厂家提供解码方式,而不是图省事用这个动态库。动态库只是把转码解码的东西给弄了,没有它照样干。有了它,反而多了一道手续。
最主要的很多设备的动态库是基于WIN7甚至是XP的,在win10/11上开发的时候,这个东西非常难搞。
我熬了很多天,勉强跑通了,但是采集非常不稳定。最后放弃了这个方式,老老实实自己写通信指令和数据转码。结果很快就搞定了,前面走了半年的弯路。

再次玩LABVIEW
就在上面的项目搞完不久,我又遇到一个用LABVIEW做数据采集的问题。当时我们的采集设备刚好是NI的,用LABVIEW是最好的选择。但是问题在于,除了NI的设备还要其他厂家设备,有的没有提供LABVIEW示例,同时项目还要求了很多数据分析、后处理、数据库功能。这些LABVIEW开发就很扯了,我根据自己的技术积累,决定NI的设备用LABVIEW通信,然后让LABVIEW和我的软件进行通信。
相当于我的软件是上位机,LABVIEW当成下位机用。为了实现这个功能,我需要在LABVIEW里面写一个TCP通信,把厂家提供的采集代码集成在TCP通信框架里面。

用LABVIEW写TCP的经历,再次坚定了我以后能不用LABVIEW就不用LABVIEW的想法。这个玩意就适合简单和设备完成个数据采集和显示,其他的功能不是不能做,而是非常费劲。编程几行代码的事情,在这里面都费老劲了。



虽然最后成功了,但是得到的图形代码,一个屏幕都看不完。当图形代码一个屏幕放不下的时候,梳理起来非常费事。

除此之外,我还摸索出LABVIEW代码封装成exe独立运行的方法。不过它这个独立,并不独立,如果更换一个电脑,仍然需要先进行LABVIEW环境的配置。这再次证明,LABVIEW并不适合用在大型工业软件的开发,和MATLAB类似,在实验室中用一下还行。
Python NI库
我后面了解到Python中也有NI库,于是我决定把LABVIEW抛弃掉,全部采用Python开发。
这样一转变,软件开发就顺畅多了,很快就完成数据的采集控制,还能同步做很多实时动态渲染。

对于通道数量很多、传感器类型很多的数据采集问题,难点已经完全不再是通信和数据获取了,那是最基础的。这个时候的着眼点就是数据结构的设计了,传感器通道和物理模型上对应点如何映射,各类采集的数据如何存储,如何二次打开并渲染、分析,绘图用的数据和原始数据怎么快速映射,采集过程中,多个采集卡如何协同,等等。
拓展
就在上面技术基础上,我又开发了结构变形监测与实时渲染软件,集成了更复杂的算法和功能。

然后自己写了一个更通用的串口通信工具:

最近写的一个比较好玩的就是和一个机械臂通信,实时获取机械臂的位置,然后在三维视口让数模同步运动。
这个是用所谓的Modbus TCP进行通信的,我之前问厂家,你们是不是TCP,他们一直说Modbus TCP。我还以为是什么不一样的东西,实际上就是TCP,只是它的指令和数据编码有一套特定的规则。
还是之前说的,不管多么玄乎的通信名词,无非就是指令和转码,那些人为编制的特殊名词,不必理会。

特殊场景处理
我在实际项目中遇到两次特殊情况。一次是串口通信问题,厂家没有提供明确的采集数据保存功能,非常离谱,几百块的东西就是不靠谱。
我查了很多方法,最后使用Device Monitoring Studio软件,监测了设备和上位机(厂家的软件)之间的通信,获取到了它们之间的通信数据历史,然后根据设备手册写了一个解码工具,这才完成了历程数据的获取。
还有一次也很夸张,和合作方商定好使用UDP通信。结果到了试验现场,我怎么也连不上设备,无法建立通信连接。
原因竟然是,他们的设备竟然没有写对外的UDP通信接口,我当时是两眼一黑,直呼卧 槽。
最后,我基于Wireshark库,写了抓包监听的工具,监测设备内部的通信,拿到了数据包。
还是那句话,设备通信本身并不难,作为初学者,只要别像我这样走那么长的弯路就行,然后就是防着合作方挖的坑。