企业简介

作为中国自动化领域的权威旗舰网络媒体,控制网创立于1999年7月,是中国举行的第十四届IFAC (International Federation of Automatic Control)大会的中国官方组织机构的唯一指定网站。控制网是中国自动化学会专家咨询工作 委员会(ECC)的秘书处常设之地。是北京自控在线文化传播有限公司开设的网站。

  • 公司类型:其他

联系方式
  • 控制网
  • 地址:北京市海淀区上地十街辉煌国际2号楼1504室
  • 邮编:100085
  • 电话:010-57116291 / 59813326
  • 传真:010-59813329
  • 网址:http://www.kongzhi.net
  • Email:mahongliang@kongzhi.net
  • 联系人:市场部
案例详细
标题基于多线程的气象传感器数字网络化系统
技术领域PLC&PAC
行业
简介阐述了一种基于多线程串口通信的远程气象监控系统的设计和实现方法,讨论了在系统设计和实现时所遇到的难点和解决方法,并较为详尽地分析了系统在实现中所涉及关键技术:多线程处理技术、串行通信、数据库访问技术和socket通信技术。
内容



1.引言

    随着计算机技术、通信技术和数据处理技术的发展,利用计算机实现生成过程的自动化成为了提高生产力、减轻劳动强度的有效手段。其中对周围环境气象数据的实时监控不仅与人们的生活息息相关,而且对工业生产中设备的正常运作也起到至关重要的作用。鉴于串行通信是计算机与其他设备进行数据交换时经常使用的方法之一,它具有实现简单,使用灵活方便,数据传输可靠等优点,因此基于串口通信技术,构建一个多线程的气象监控系统是有十分有必要的。

    本文采用串口通信的方式接收由温度、湿度传感器采集到当前环境参数,利用Visual C++ 6.0提供的Windows API实现对串口的控制,采用多线程以及双缓冲队列技术可以实时获取采集数据、本地存储采集处理;同时还利用Socket通信技术使采集数据传送到远程监控中心,进行数据分析滤波处理以及数据库的存储,并绘制出相应的P—T曲线。

2.软件系统设计方案

    本系统由本地采集计算和远程监控中心构成一个C/S结构监控系统。在环境恶劣的工业现场,无法进行人为的实时监控,由硬件设备采集环境气象参数首先发送给本地计算机,然后传送给远程监控中心进行处理。本地采集计算机利用Visual C++ 6.0提供的Windows API实现对串口的操作。主要包括串口通信、设备控制、数据存储等模块,操作方便,人机界面简单清晰。在应用过程中,首先需要设定串口配置参数,如波特率、数据位、奇偶校验等,串口初始化后,程序开始运行,采集到的数据同时被保存在扩展名为.txt文件中。然后通过Socket的通信方式把采集到的数据传送给远程监控中心,由它来进行数据在数据库中的存储,以及数据平滑滤波处理,并绘制出P—T曲线。整个系统实现流程如图1所示。
  
3.程序设计思想

    当前,一般的MCU都内置了串口的硬件控制模块,用户通过查询和中断的方法编写比较简单的控制程序就可以使用串口通信。但是,本系统要求在接收数据采集设备发送大量数据的同时完成对己接收到数据的实时存储,如何处理好二者之间的关系,保证不会造成数据的缺失和程序的崩溃是程序设计的一个难点。本文重点对串口通信程序进行了改进,尽量做到不因为串口通信影响整个系统的性能。

    Window的最大特征之一是设备无关性,使得Window程序员不用对硬件直接进行操作。利用Window的SDK提供完备的API函数和以中断方式驱动的通信程序,可以更加简化串口通信编程。而且Window系统是抢先式的多任务操作系统,使得应用程序能够同时执行多个任务,即在一个进程中可以同时运行多个线程,系统可以不停的在多个线程之间切换。所以在串行通讯程序中应用多线程就可以简化应用程序的结构,把一些复杂的运算放在后台并行执行,从而大大提高应用程序的响应实时能力。

    串口通信程序的输出与输入是两个需要并发执行的操作。如果由主线程独自完成所有的工作,即在的单线程情况下,程序可能会不定期地锁定。因此,为了具备实时响应的能力和提高程序的效率,本文的串口通信程序程序设计如图2所示。



 图2 串口程序设计示意图

    应用程序创建了输出与输入两个子线程共同完成通信任务。而又由于串口发送和接收的数据是相对独立的,故可将其分开,设置两个缓冲区,一个是发送缓冲区m_TxQueue,另一个是接收缓冲区m_RxQueue,并为每个缓冲区分别设置两个指针,一个指向输出线程将要发送的数据,另一个指向输入线程将要从缓冲区读取数据的起始位置。这种方式称之为采用双缓冲队列的方法,保证了无关数据的顺序操作。

    3.1 多线程的设计

    线程是进程内的一条执行路径.它包含独立的堆栈和CPU寄存器。每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等等。一个进程内的所有线程使用同一个32位地址空间,而这些线程的执行由系统调度程序控制,调度程序决定哪个线程可执行和什么时候执行线程。线程有优先级别,优先权较低的线程必须等到优先权较高的线程执行完仃务后再执行。在VC++6.0中的MFC应用程序的线程是由CwinThread对象来表示,该线程分::用户界面线程(GUI-Thread)和工作者线程(Worker-Thread)。用户界面线程能够提供界面和用户交互,用于处理用户输入和响应各种信息和事件;工作者线程没有消息循环,主要用来处理应用程序的后台任务。本文所采用的串口操作线程即为工作者线程。程序通过调用AfxBejinThread()函数自动创建一个CwinThread对象,通过响应己设置好的一组事件句柄来启动一个线程的执行。

    3.1.1 输出线程

    输出线程比较简单,它只为串口的写操作创建一个OVERLAPPED结构,并设置一组事件的句柄。它可响应的事件有删除线程事件、写请求事件及中断请求事件,然后线程进入主循环,等待三个事件之一的发生,以便采取适当的行动。例如当检测到写请求事件时,表明输出缓冲区内有一些数据等待发送,输出线程便会试图发送传送队列中的所有数据。在写操作进行时,如果端口比较忙就会进入重叠模式。此时WriteFile( )返回FALSE,用GetLastError( )可以发现当前错误是ERROR_ IO_ PENDING,意味着重叠I/O操作已经开始了。若是删除线程消息到来,输出线程将跳出循环,关闭事件句柄,最后结束线程。

    3.1.2输入线程

    输入线程较为复杂一些,它既要处理串口数据的读操作,又要处理串口状态的读取。而且由于输入的数据是随机到达的,所以输入线程必须一直读。输入线程首先要创建两个OVERLAPPED结构,用于读数据和获得通信事件,并为它们分别创建两个事件。然后输入线程要响应四个需要监视的事件:删除线程事件、读信息事件、状态信息事件和读请求事件设置事件句柄。接着输入线程便进入主循环,直到删除线程的消息到来才退出。只要输入缓冲区有空间可用,输入线程就会一直读发送过来的数据。与输出一样,如果读操作失败了,而且返回的错误代码是ERROR_ IO_ PENDING,意味着还在进行读的重叠操作。输入线程在等待数据输入的同时,也在等待传入的事件。在输入线程里可以用SetCommMask( )函数建立事件掩模来监视特定通信资源上的事件。如图:



图3 输入线程示意图

    在应用程序中,输出线程只是简单的一直调用WaitForMu1tip1e0bject()等待事件的发生,并以一个Switch Case语句为每个已发生事件提供处理方案。输入线程的工作繁重许多,它分别调用ReadFile()和WaitCommEvent( )接收数据和通信状态。如果接收到的是数据,输入线程将它保存到指定位置。如果是通信状态,输入线程将它交给其它函数判断状态内容,指引程序下一步的活动。ReadFile()和WaitCommEvent ()都是在重叠模式下工作,其步骤与输出线程相同。

    3.1.3 线程同步
   
    在串口通信程序中,输入缓冲区和输出缓冲区能够被多个线程访问。它们用于在程序的主线程和输入、输出线程之间传送数据块。当端口上出现一些操作时,主线程和输入、输出线程会经常访问这两个对象。如果两个线程同时处理缓冲区,就会产生不正确的数据,这就破坏了数据的完整性。C++提供了信号量( Semaphore)、互斥对象(Mutex)、临界区(Critical Section)等手段来保护这些数据对象,防止两个线程在同一时间访问同一数据。保持在同一个进程内的线程工作协调一致(线程同步)。其中,临界区是一种保证在一个时间只有一个线程访问数据集的非常简单的方法。当你使用临界区,你就给了线程一个它们必须共享的对象。任何拥有临界区对象的线程可以访问被保护起来的数据,其它线程必须等待直到第一个线程释放了临界区对象。此后其它线程可以按照顺序抢占临界区对象,访问数据。因为线程只有拥有临界区对象才能访问数据,而且在一个时刻只有一个线程可以拥有临界区对象,所以决不会出现一个时刻有多个线程访问数据的现象。

    考虑到本文所设计的通信缓冲区既不允许多个线程同时访问,又不必供其它进程的线程访问。因此,临界区是串口通信程序多线程同步最有效的办法。  
  
    3.2 双缓冲队列的设计
   
    为了提高效率,本文把缓冲区数据存储在标准C++库中的deque<char>对象中,它作为一种优化的存储容器支持元素的添加和删除。它能高效地插入未知数量的对象,并且插入和删除元素时系统的负担很小。根据需要,本文创建了两个独立的缓冲区对象,一个是发送缓冲区m_TxQueue,另一个是接收缓冲区m_RxQueue,并将它们置于临界区的保护下,就能确保一次只有一个线程处理缓冲区。本文所设计的类MThreadDeque提供了对缓冲区的各种操作,如Extract(),Clear(),Insert()等,每种操作开始和结束的时候都要调用::EnterCriticalSection( &m_Lock )和::LeaveCriticalSection( &m_Lock ),关键代码如下:

class MThreadDeque
{
protected :
    const m_iMaxSize;
    deque<char> m_Queue;
    CRITICAL_SECTION m_Lock;
public :
    MThreadDeque( int max_size ) : m_iMaxSize( max_size )
    {
        ::InitializeCriticalSection( &m_Lock );
    }   
    ~ MThreadDeque ()
    {
        ::DeleteCriticalSection( &m_Lock );
    }      
    int Insert( char c )
    {
        int return_value;
        ::EnterCriticalSection( &m_Lock );
        if ( m_Queue.size() < m_iMaxSize ) {
            m_Queue.push_back( c );
            return_value = c & 0xff;
        } else
            return_value = -1;
        ::LeaveCriticalSection( &m_Lock );
        return return_value;
    }
       ……
};
  
    3.3 网络通信部分的设计

    当工业现场环境恶劣,不适合人为操作时,将硬件采集的数据传送到远程监控中心进行分析和处理是十分有必要的。Socket套接字是目前最流行的网络通信应用程序接口之一,利用它可以方便地实现局域网内的数据的传输,是开发客户机/服务器网络应用程序的重要方法。当向一个套接字写入时,所送数据会自动出现在套接宇的另一端,另一端可能是相同机器上运行的另一个进程,也可能是世界上任何地方互连的一台计算机。TCP/IP传输层有两个并列的协议:T C P ( Transport Contro1 Protocol)和UDP(User Datagram Protocol)其中TCP是面向连接的,UDP是无连接的,Socket同时支持这两种通信模式,所对应的Socket分别为数据流Socket和数据报Socket。数抓流Socket定义了一种可靠的面向连接的服务,实现无差错、无重复的顺序数据传输;数据报Socket定义了一个无连接的服务,数据通过相互独立的包进行传输,包的传输是无序,并且不保证是否出错、丢失和重复。本文采用了流式Socket来实现远程数据传输,工作过程如图4所示。
 



 图4 Socket通信流程图

    3.4 VC与Sql Sever数据库的数据交换

    VC提供一些接口,可以处理数据库操作,主要有:开放式数据库连接(ODBC) ,OLE DB、ActiveXDataObject( ADO )等。ADO基于通用对象组件模型(COM),操作灵活,代码添加少,本系统采用ADO操作Sql server2000数据库,主要包括四个基本步骤:

    ①COM库的初始化,用#import指令引入ADO库定义文件;

    ② 创建Connection对象指针,并用其连接Sql server2000数据库,本文通过DSN数据源对数据库进行连接,代码如下:

    m_pConnection->Open("Datasource=adotest;UID=sa;PWD=;","","",adModeUnknown)。

    ③利用建立好的连接,通过Connection、Command对象执行SQL命令,进行创建表、添加记录、添加字段等操作,或利用Recordset对象取得结果记录集进行查询、处理;

    ④使用完毕后关闭连接释放对象。

    有了以上基础,就可以方便的把采集来的数据按照制定的顺序存放在Sql Server数据中,可以完成对数据进行快速查询、浏览和删除等工作。

4.结论
   
    气象数据能够进行可靠和实时的采集和通信是本系统实现的的关键所在。在系统的实现过程中,遇到许多技术问题,如通信的可靠性、多线程之间的互斥与同步、突发性数据处理与计算机响应速度之间的协调和系统性能问题等,其中有些问题只能在现场调试的过程中发现并加以解决。本系统的实现为气象监控系统的更进一步发展提供了参考,同时对于实现工业监控系统的集成化、自动化具有极大的推进作用。

参考文献:

    [1]李现勇. Visual C++串口通信技术与工程实践[M].北京:人民邮电出版社,2002

    [2]汪翔,袁辉.Visual C++实践与提高一网络编程篇[M].北京:中国铁道出版社,2001:167-186

    [3] 徐军译.Visual C++开发人员指南[M],北京:机械工业出版社,1998

    [4] 潘爱民.VC++技术内幕(第四版)[M].北京:清华人学出版社,1997.
    
   
Remote Weather Date Acquisition System 

    Based On Multi-thread Serial Communication Technology

    YAO lan1,GUI xun2

    (1.Department of Control Engineering, ChengDu University of Information Technology Sichuan ,610225,China)

    (2.School of Electrical Engineering, Southwest Jiao tong University, Sichuan, 610031,China)

    Abstract: The paper introduces one of remote weather data acquisition system which is designed and implemented based on multi-thread serial communication technology. With discussing the key problem and solution of this system at the stage in designing and implementing, the paper gives a elaborate analysis of multi-thread processing technology, serial communication, database accessing technology and Socket communication technology.
Key words: multi-thread, serial communication, database, Socket

    姚兰1,桂勋2

    (1.成都信息工程学院控制工程系 成都 610225)

    (2.西南交通大学电气工程学院  成都  610031)