摘 要:基于S3C2440-Linux嵌入式平台和nRF24L01射频模块,介绍了一种远程数据接收器的设计。该数据接收器利用SQLite3存储nRF24L01射频模块接收来自数据采集节点的数据,用户通过浏览器访问接收器上的BOA服务器进行数据管理。在CGI程序设计中采用Posix消息队列给数据接收器的射频接收单元传递命令,利用多线程的方式对接收到的数据进行处理。这种将传感器采集到的数据通过2.45 GHz无线射频模块发送到数据接收器的方式非常适合用于远程环境监测、旅游管理等场合。
关键词:数据接收器; nRF24L01射频模块; CGI程序; 多线程; 消息队列
在传统的数据采集中,较多采用RS485或CAN现场总线将分散节点的数据传给数据接收器。由于有线传输,在安装和维修方面会给实际应用带来许多不必要的麻烦。若采集数据节点对移动性要求比较高,则这种有线传输方式有时却行不通。因此,若各数据采集节点通过无线方式将数据传给数据接收器,则可以很好地解决上述的问题。在工业应用中2.45 GHz无线通信具有频段免费、通信距离远的优点。目前基于2.45 GHz无线通信比较成熟的应用有无绳电话、ZigBee、WiFi、蓝牙等。它们有统一的协议标准,但是具有协议复杂、开发难度大、周期长等不足。Nordic Semiconductor 公司的nRF24L01 系类单片无线收发芯片采用封闭协议通信, 而各个厂家可以根据自己的需求制定自己的通信协议[1-3]。因此采用以nRF24L01芯片为核心的射频模块对节点采集的数据进行无线传输具有低成本、易开发等优点。
但2.45 GHz无线通信的距离还是非常有限的,如ZigBee在2~20 m、WiFi在2~200 m。因此可以在接收器上移植TCP/IP网络协议,最终通过远程网络来实现对数据接收器的控制。远程访问管理数据接收器有两种方式:C/S(客户机/服务器)模式和B/S(浏览器/服务器)模式。C/S模式只能在小范围内的网络环境中应用,缺乏灵活性,开发周期长而且升级难。而采用B/S模式,只要在和设备联网的任何地方,合法用户就可以通过浏览器远程管理控制接收器[4]。因此它具有系统维护方便、开发周期短的优势。
1 远程数据接收系统设计
基于nRF24L01射频模块的远程数据接收系统结构如图1所示。数据接收器以S3C2440为处理器,外围扩展nRF24L01射频模块、存储模块和网络通信模块。各数据采集节点由低功耗MCU、射频模块和传感器数据采集电路构成。每个节点有一个ID号,将它与采集到数据一起写到发送包的数据域中,然后通过射频模块发送给接收器的射频接收单元进行处理。在该系统中,S3C2440与nRF24L01射频模块通信由6根信号线组成,它们分别为:主机出从机进数据线(MOSI) 、主机进从机出数据线(MISO)、时钟线(SCK)、设备选择线(CS) 、中断标志线(IRQ)和接收发送模式选择线(CE) [2-4]。IRQ中的信号可以代表不同突发情况的中断事件:nRF24L01在发送模式下成功发送数据中断;nRF24L01在接收模式下正确接收数据中断;nRF24L01在发送模式下,达到最大重传次数中断。
S3C2440通过SPI接口对nRF24L01的相关寄存器进行操作,以实现对射频模块的初始化和相关信息处理。为了利用Linux中比较成熟的网络功能实现远程控制,在接收器上移植了嵌入式Linux操作系统。而在Linux系统中,所有的外部设备都被看作是目录/dev下的一个文件,并为用户的访问提供了一种标准接口[4]。因此在本系统开发前要实现nRF24L01射频模块字符设备驱动程序。
2 nRF24L01通信功能实现
nRF24L01单片无线收发器芯片内置频率发生器、功率放大器、晶体振荡器、调制器和解调器等功能模块。通过在芯片外围扩展少量的器件形成的射频模块可以利用全双工的SPI串行接口与MCU实现通信。它有125个频点,能够实现点对点、点对多点的无线通信。当nRF24L01工作在“ShockBurstTM”方式下时,数据包格式由前导码、地址、数据域和CRC校验这4部分组成。其中前导码由硬件自动进行处理,当nRF24L01在发送模式下自动加入前导码,在接收模式下自动去除前导码。它的作用是给芯片稳定接收或发送预留一定的时间。地址长度为3~5 B,它由寄存器SETUP_AW进行设定。数据域为发送包的有效载荷,长度可以为1~32 B。CRC校验是可以选择的,它由控制寄存器中的EN_CRC位来决定[3]。
数据采集节点中的nRF24L01设置为发送模式,节点将采集到的数据按照自己规定的格式填充到发送包的数据域。接收器的nRF24L01设置为接收模式用于接收节点发送的数据。在发送模式下芯片有6个数据通道可供选择,而每个数据通道作为RF信道中一个逻辑通道,它们有自己的地址[2-3]。因此可以将数据采集节点的数据包地址设置为接收器nRF24L01芯片6个数据通道中某个未被利用的通道地址。从而实现一个接收器可以接收6个节点的数据。若节点个数大于6,则要采用一些防碰撞算法来解决数据冲突。
采用纯ALOHA算法即随机延迟算法可以用于解决上述问题,数据采集节点利用随机数生成函数产生一个在(N1,N2)之间的随机数,把这个随机数给定时计数器赋值,使得定时器的定时间隔在(T1,T2)之间[5]。若增大T2-T1,则发生碰撞的概率减小。
在nRF24L01射频模块驱动程序设计中主要实现了open()、close()、ioctl()、poll()等函数。其中open()和close()函数完成对设备模块的打开与关闭;poll() 函数是用户空间调用select()函数的接口,用来监测设备文件的状态。若射频模块成功接收到发射单元发送的数据则会返回文件可读,而在其他时候则处于阻塞状态。ioctl()函数为用户程序提供了对nRF24L01射频模块操作的相关命令,如:RDID_NUM命令用于接收数据,SENDID命令用于修改并发送数据。
3 数据接收器软件设计
远程数据接收器的软件基于Linux操作系统,主要由BOA服务器、CGI程序、nRF24L01射频模块驱动程序和SQLite3数据库组成,如图2所示。用户通过浏览器向远程BOA服务器发出HTTP请求,服务器的守护进程接收到请求后创建一个CGI进程,它将浏览器发送的相关数据设置成环境变量,然后执行URL指定的CGI程序[4]。在整个软件设计中CGI程序起着承上启下的作用:一方面它从环境变量或标准输入读取用户输入数据,并根据浏览器发送的相关命令对nRF24L01射频模块和SQLite3数据库进行操作;另一方面它把处理结果回送给BOA服务器及Web浏览器。
4 CGI程序设计
用户通过浏览器管理远程数据接收器主要实现以下功能:控制nRF24L01射频模块接收或不接收来自数据采集节点中的数据、显示采集到的实时数据和历史数据。在本系统设计中,将用户提交HTML表单数据的方式设置为GET方法,因此当表单提交时,用户的控制命令被保存到环境变量QUERY_STRING中。CGI程序首先通过getenv()函数获取环境变量QUERY_STRING的内容,然后根据环境变量的内容执行不同的操作,CGI程序流程图如图3所示。
4.1 射频模块应用程序设计
射频模块通过Posix消息队列接收CGI程序发送的消息,消息的内容有两种:使射频模块接收数据采集节点到达的数据包命令和停止接收命令。由于System V 消息队列无法通知CGI程序何时在消息队列中放置了一个消息,同时,若采用msgrcv()函数一直轮询,CPU的效率会比较低,而Posix消息队列中的mq_notify()函数,可以实现当CGI程序发送消息时,能够通过异步事件通知消息队列的接收端。但是消息队列描述字(mqd_t变量)不是“普通”描述字,不能通过select()函数检测消息队列是否为可读状态[6]。然而可以通过以下方式实现:首先,创建一个管道,通过select()函数等待检测管道的可读状态;然后通过mq_notify()函数使当消息队列有消息到来时产生一个SIGUSR1信号,并且通过signal()函数捕获这个信号。在信号处理函数中向管道写入任意一个字符的数据,使select()函数返回管道为可读状态,从而程序向下执行,通过mq_receive()函数读取消息队列的消息。之后根据消息的内容对nRF24L01射频模块执行不同的操作。射频模块应用程序的流程图如图4所示。
在主线程中,设置了一个初始化为0的变量flag,用于标记射频模块当前是否已设置为接收节点数据。若第一次从消息队列接收到使射频模块接收数据的命令,则将flag设置为1,并创建采集线程。当flag为1且接收到停止接收数据命令时,则调用close()函数关闭射频模块设备,同时调用pthread_cancel()函数结束采集线程。
在采集线程中,首先调用SQLite3提供的C API接口函数sqlite3_open()打开或创建数据库,并调用sqlite3_exec()函数创建两个数据表,其中一个用于存储实时数据,一个用于存储历史数据。其次,通过open()函数打开射频模块设备,调用ioctl()函数向射频模块发送一些设备初始化的设置命令。初始化后设备等待节点数据的到来,一旦数据到达便返回设备为可读状态,于是可以调用ioctl()函数中的RDID_NUM命令接收数据。最后通过sqlite3_exec()函数执行数据库操作的insert语句,将数据存储在实时数据表中。
4.2 数据显示线程
用户通过浏览器查询各节点采集到的数据,是由CGI程序中数据显示子线程实现的。数据显示子线程根据接收到的命令从不同的数据表中读取数据。该系统对数据的显示以简洁的直方图形式呈现,而没有采用图片这种比较占用资源的方式。以直方图形式显示数据能够满足大多数工业控制中对数据显示的需求。系统测试时,各数据采集节点以MSP430F2121单片机为MCU、以DS18B20温度传感器采集周围的温度、用nRF24L01射频模块将采集到温度以无线的方式传输给数据接收器。同时节点中射频模块的天线采集PCB天线,而接收器的天线采用增益为3 dBi棒状天线,在此条件下,该数据接收器能够接收100 m范围内的节点数据,并通过网络把数据返回到Web页面中。应用本系统对室内温度进行监测得到的数据截图如图5所示。
将无线射频通信技术和网络技术应用于传感器数据采集领域具有非常好的前景,该数据接收器可用于在恶劣的环境下对环境参数的多点监测。数据接收器的射频模块PCB的布局对整体的性能有很大影响,同时采用大增益的天线可以使接收器获取更远距离的节点数据。在软件设计中由于采用了异步事件通知消息队列的机制,因此在select()等待管道为可读状态时要注意处理由于信号中断而使select()返回的EINTR状态。
参考文献
[1] 李雄飞,孙俊杰,陈磊,等.基于ZigBee技术的无线设备状态监测系统[J].仪表技术与传感器,2012(12):139-140.
[2] 黄智伟. 单片无线发射与接收电路设计[M].西安:西安电子科技大学出版社,2009.
[3] SEMICONDUCTOR N. nRF24L01 Single Chip 2.4 GHz Transceiver Product Specification[EB/OL].[2007]. http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01.
[4] 刘刚,赵剑川. Linux系统移植[M].北京:清华大学出版社,2011.
[5] 邓一文,张红雨,张鹏程,等.RFID高频读写器防碰撞算法研究[J].电子设计工程,2011(19):31-34.
[6] STEVENS W R. Unix 网络编程卷2:进程间通信[M].杨继张, 译.北京:清华大学出版社,2001.