摘 要:介绍了以VC6.0为开发平台,用无线单片机CC2530进行多节点多参数的低功耗数据采集系统。下位机设计了可灵活扩展的无线数据帧,并设计了采集控制命令,实现广播模式和单目标地址控制两种功能。上位机利用CSerialPort类对串口数据选择性接收,提高了效率和稳定性,可保存和识别随机分配的节点地址,并改进了CSerialPort类可实现十六进制数的发送。
关键词:无线传感器网络;VC6.0;串口通信;CSerialPort类;数据帧
无线传感器网络是由部署在监测区域内部或附近的大量廉价、具有通信、感测及计算能力的微型器节点通过自组织构成的“智能”测控网络[1]。本系统下位机利用SHT11温湿度传感和美国TI公司的无线片上系统CC2530单片机构成终端传感器节点,对温室内的温度和相对湿度及终端传感器片上电压三个参数进行实时测量,通过在环境内布置多个测量节点来获取现场信息。在众多集成可视化开发环境中,VisualC6.0是底层编程环境的最佳选择,它提供了相当齐备的类和各种控件,编程界面友好。
1 系统下位机硬件组成
系统下位机硬件组成如图1示,由I2C总线的SHT11数字温湿度传感器连接CC2530芯片的VDD/3的ADC通道,经CC2530单片机采集处理后打包数据无线发送到与PC机连接的协调器节点。其中协调器节点与PC机通过串口转USB线连接。
下位机使用TI公司SensorDemo例程在IAR7.5集成开发环境下进行二次开发,在应用层对传感器节点和协调器节点分别编写程序,协调器节点接收传感器节点的数据以数据帧格式串行发送到PC机[2]。
2 下位机数据帧设计
下位机数据帧编程固定长度为20 B的数据,有些字节可变,有些字节是固定的。比如一个数据帧用十六进制表示为:FE 0F 46 87 DE 65 02 00 09 00 1B 20 00 00 38 33 00 00 00 9E。其中:FE是帧头字节,46 87是双字节数据,低字节在前,标识为8746为接收标志;9E是前面19个字节的“异或”运算值,为整个数据帧的CRC校验位,可变;0F是固定值,表示除了帧开始和0F、46、87、9E 5个字节外的15个字节数;DE65是传感器节点16 bit地址号65DE,是随着数据来自不同节点变化;0002、0009也是固定的字节,表示数据包和有效数据位;1 B是节点温度的整数部分,换算为十进制值为26℃,可变;20是节点片上电压值(乘10倍值),换算为十进制值为3.2 V,可变;0000为父节点地址;38是节点相对湿度值,换算为十进制值为56%,可变;33是节点温度的小数部分,换算为十进制值为(3×16+3)/256=0.199 2℃,可变;00 00 00是预留下来的3个字节给节点其他传感器数据的传送。
3 采集控制命令两种模式实现
在传感器节点C文件中添加命令输入集合COLLECTOR_CMD_ID,协调器节点C 添加同样的命令输出集。为协调器节点设计3 B的串口数据,前2个字节为目标地址,第3个字节为采集控制命令,如设置80为停止采集,40为开始采集命令。因为协调器地址是固定的0x0000十六进制数,其他传感节点地址不可能是这个数,所以当发送前2个字节为0000时,可将此作为向全体传感器节点广播的命令的判断,如果是具体单个节点地址,则只有相应节点接收控制命令,其中广播命令发送的地址模式为0xFFFF。
4 上位机程序设计
4.1 CSerialPort类加入程序
CSerialPort类是remon spekreijse写的一个免费的串口类,可在互联网下载到其头文件(h文件)和源程序(cpp文件),它可直接用于串口的读写操作。首先建立一个基于窗口的MFC应用程序,再将CSerialPort.h和CSerialPort.cpp两个类文件复制到工程文件夹中,并用project-add to project-files命令将上述两个文件加入工程[3]。
因为CSerialPort类是第三方类,所以其串口消息响应函数不能由VC的classwizd自动生成,需通过手动增加消息响应函数的消息映射。在建立的窗口类头文件下添加以下代码:
afx_msg LONG OnComm(WPARAM ch,LPARAM port);
在窗口类ccp文件下进行串口接收一个字符的响息映射,只要串口中有一个字节就触发这个事件,代码如下:
ON_MESSAGE(WM_COMM_RXCHAR,OnComm)
最初的CSerialPort类的发送函数只有一种发送字符类型WriteToPort( char* string)。而考虑到上位机对下位机控制命令都是十六进制数传送,且传送数据的最终原理都是以二进制数传递的,所以增加一种可按字节数发送的函数类型WriteToPort(unsigned char*string,int n)。其中,string是发送的一个字节数据,n是要发送的字节数。代码如下:
void CSerialPort::WriteToPort(unsigned char*string,int n)
{
assert(m_hComm != 0);
memset(m_szWriteBuffer,0,sizeof(m_szWriteBuffer));
memcpy(m_szWriteBuffer,string,n);
m_nWriteSize=n;
//set event for write
SetEvent(m_hWriteEvent);
}
上位机软件设计流程如图2所示。
4.2 串口数据接收
对接收的数据进行帧头判断,如果接收字节为FE则继续接收,保存在无符号字符数组buf中,接收后面的字节保存在数组中,并对连续的18个字节进行“异或”运算。如果这个“异或”运算值与第20个字节的值相等,表示这20个字节为一个有效数据串,然后再将其中的源节点地址提取出来并保存,再分别对其中的参数值进行处理,根据节点地址写入VC表格控件中的相应行。串口数据帧选择性接收和多节点地址保存函数片段如下:
LONG CMYSerialPortDlg::OnComm(WPARAM ch,LPARAM port)
{ static char checksum=0; //校验和初值
static char checksum1=0; //校验和获取值
static int count=0; //接收字符数
static unsigned char buf[21];
static unsigned char SAddrL[5];//源地址低字节
static unsigned char SAddrH[5];//源地址高字节
static int i=0; //源节点个数
if(ch= =0xFE)
{ count=0;
buf[count]=ch;
}
else
{count++;
buf[count]=ch;
if(count==1)
checksum=buf[count];
else if(count<19)
checksum^=buf[count];//ch
else if(count= =19)
{checksum1=buf[count];
if(checksum1= =checksum)
{ //源节点地址存放
if(i==0)
{SAddrL[0]=buf[4];SAddrH[0]=buf[5];i++;}
if(i==1)
{if((buf[4]==SAddrL[0])&&(buf[5]==SAddrH[0]));
else{i++;SAddrL[1]=buf[4];SAddrH[1]=buf[5];}
}
if(i==2)
… …
UpdateData(0);return 0;
}
4.3 串口命令的发送
在应用程序的发送数据编辑框中输入3 B的十六进制数据,而且要让发送函数明白这是3 B的数据,而不是默认地把这些十六进制数当作6个单独的字符来处理。在窗口CPP文件中加入“字符转十六进制数”的函数String2Hex(m_strSend,hexdata),其返回值为转化后的十六进制数的个数,在此即是要发送的命令字节数(该函数原型来自参考文献[4])。发送命令函数如下:
void CMYSerialPortDlg::OnSend()
{UpdateData(1); //更新参数数据
CByteArray hexdata;
int len=String2Hex(m_strSend,hexdata);
unsigned char *str;
str=(unsigned char*)malloc(sizeof(char)*len);
for(int j=0;j
}
m_spSerialPort.WriteToPort(str,3);
//m_spSerialPort是在窗口中定义的CSerialPort类成员变量
}
程序运行结果如图3示。
本文设计的无线传感器网络数据采集系统能够实现多节点多参数的数据实时采集,并对测量的数据进行波形和表格显示及存储。设计的串口接收中断程序可应用到其他串口数据采集系统中,发送命令实现了对所有节点和个别节点采集过程的控制,在后期还运用了计数求模的方法,可通过上位机发送改变除数来改变节点的采集时间间隔,整个程序可移植性强。
参考文献
[1] 孙利民,李建中,陈渝,等.无线传感器网络[M].北京:清华大学出版社,2005.
[2] 深圳飞比电子科技公司.Z-STACK SensorDemo实验. [EB/OL].[2011-10-13].http://wenku.baidu.com/view/dfe9d82ee2bd960590c6770c.html.
[3] 潘石柱,于仲安.VC实现串行通信的三种途径[J].电子工程师.2002,28(9).
[4] 龚建伟.串口调试助手源程序及编程详细过程.[EB/OL].(2001-06-20)[2010-12-21].http://hi.baidu.com/laoyang1018/ blog/item/641491ef565756fece1b3ecc.html.