基于Android系统ZigBee传感器信息显示实验
【实验目的】
1. 熟悉ZigBee协议关于集中供电传感器----温湿度的通讯协议;
2. 利用协议,在Android平台上编写一个显示温湿度数据的安卓程序。
【实验内容】
1. Eclipse集成开发环境中编写温度传感器采集Android程序。
【实验设备】
1. 硬件: Android、PC机;
2. 软件:PC机操作系统 Win7 + Eclipse开发环境。
【基础知识】
1. ZIGBEE物联网实验系统应用层交互协议V2.3
(1)传感器发送命令格式如下:
对于ZIGBEE物联网集中供电传送,Byte2、3: 0x47B8 (cmd,控制命令,低字节在前)
(2)传感器采集的传感数据说明如下:
协议内容如上,那么无非就是一串以0x02开头,以校验结尾的数据。下面我们考虑如何从设备中获取这些数据。
2.WSN物联网通讯原理
(1)zIgbee之间通讯肯定是Z-Stack Pro之间的通讯。这里就不做介绍,需要详细了解的,请看书前面的内容。
(2)zIgbee从节点把传感器数据发送给网关后,网关将收集的数据,封包,然后发给zIgbee的串口。而硬件部分,zIgbee的串口已经和ARM的串口1连接。那么我们要做的就是从ARM的UART1采集数据,然后解析出来。
我们提供的demo程序,用C/S架构完成,在android的底层建立一个服务,负责采集串口的信息并同时把采集的信息发送给网口。然后,Android程序采集网口的数据。我们下面的实验提供的demo例程WsnTest,就是采用这种方式。
3.提供的Wsntest 模块例子源码解析
WsnTest只完成主界面“建立连接”按钮和退出“按钮”。“建立连接”按钮负责连接底层的(串口采集,并发送到网口的)服务。其余的功能需要我们自己去添加。
(1)如何启动底层的(串口采集,并发送到网口的)服务。
因为我们是编写Android程序,所以需要不停的调试设备,那么我们利用adb shell手动启动服务。确保实验箱上电和mini USB线的连接正常,确保adb工具的正常使用。启动过程如下图:
这样的好处就是我们每次通过Eclipse调试程序的时候,可以缩短程序启动时间,只需要每次在启动程序的时候,Ctrl+C 停止服务,等程序启动完成后,在启动iot服务。
(2)Wsntest启动过程截图如下:
没有启动服务时,提示“建立连接失败!”
启动服务后,点击“建立连接”按钮,弹出对话框,输入实验箱IP地址(192.168.1.X)和端口号(2012),点击“连接”按钮,提示连接成功。
如果是先启动服务,在打开WsnTest程序,那么其实这时候的网络交互已经是畅通的了,可以直接接收来自网口的程序。我们把温湿度传感器通电,就可以看到数据发送到WsnTest上。如下:
看到界面上打印出收到的字符串。可以把这个字符串跟我们前面提到的通讯协议进行比较。下面我们要进行的就是解析这些数据,并把温湿度传感器的数据显示到界面中。
WsnTest关键点1:模块通信切换的实现
这部分具体协议,参看上一节“Android模块切换通信”实验。首先使用程序使串口切换到ZigBee模块。
WsnTest关键点2:串口波特率的设置
在我们的例程中,使用“myservice.socketSend("4C4B0104");”就是设置使用串口1,波特率为115200。部分代码如下:
myservice.socketSend("4C4B0101");
new Handler().postDelayed(new Runnable(){
public void run() {
//execute the task
SetZigbee();
}
}, 500);
new Handler().postDelayed(new Runnable(){
public void run() {
//execute the task
//115200
myservice.socketSend("4C4B0104");
}
}, 1000);
WsnTest关键点3:串口数据的接收
我们这里处理用的关键函数如下:
private void ScanData() {
if (bLock == false) {
bLock = true;
if (iRecDataLen > 0) {
int iFirstPosition = 0;
while (iFirstPosition < iRecDataLen) {
// 判断包头
if (byteRecBuff[iFirstPosition] == HEAD) {
int PacketLen = (int) byteRecBuff[iFirstPosition + 1] + 3;
// 判断数据包是否完整
if (PacketLen <= iRecDataLen - iFirstPosition) {
// 读出一个数据包
byte[] Packet = new byte[PacketLen];
int i;
for (i = 0; i < PacketLen; i++) {
Packet[i] = byteRecBuff[iFirstPosition + i];
}
// 数据包处理
DateDispose(Packet);
// 缓冲区删除已读部分
for (i = 0; i < iRecDataLen - iFirstPosition - PacketLen; i++) {
byteRecBuff[i] = byteRecBuff[iFirstPosition + PacketLen + i];
}
iRecDataLen -= PacketLen + iFirstPosition;
}
bLock = false;
return;
} else {
iFirstPosition++;
}
}
iRecDataLen = 0;
}
bLock = false;
}
}
可以看到对数据包进行了简单的处理,并把最终的数据传入DateDispose()函数处理。现在的DateDispose()函数如下:
private void DateDispose(byte[] Packet) {
if (SummationCheck(Packet) == Packet[Packet.length - 1]) {
Log.i("...WsnTest DateDispose...", Bytes2HexString(Packet));
}
}
可以看到对数据包进行了校验,以保证最后的正确性。并且把完整的数据包通过Log.i打印到了Eclipse的控制台。
下面我们来进行温湿度传感器数据的显示。
【实验步骤】
(1)构思界面。
Android界面的设计在前面的内容我们已经学过了。这里不做复杂的设计,简单的把温湿度以数字的方式显示到WsnTest界面中.
我们在activity_wsntest.xml文件中,添加4个TextView,分别用来提示温度,温度数据,湿度,湿度数据。
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_weight="1"
android:gravity="center">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="温度:"
android:textSize="30dp"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
android:id="@+id/tem"
android:textSize="30dp"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="湿度:"
android:textSize="30dp"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" "
android:id="@+id/hum"
android:textSize="30dp"/>
</LinearLayout>
(2)在WsnTest.java初始化刚才添加的Textview,代码如下:
在Activity中添加 “TextView textTem,textHum;”
在OnCreat中添加“
textTem = (TextView)findViewById(R.id.tem);
textHum = (TextView)findViewById(R.id.hum);”
(3)根据协议和收到的数据,修改WsnTest.java中的DateDispose()函数,实现数据的显示。
根据协议,可以看到SHT10的温湿度数据,是在包的byte11和byte12两个字节。
那么添加如下代码:
private void DateDispose(byte[] Packet) {
if (SummationCheck(Packet) == Packet[Packet.length - 1]) {
Log.i("...WsnTest DateDispose...", Bytes2HexString(Packet));
int TypeboardByte,SensorType = 0;
TypeboardByte = (int)Packet[10];
SensorType = TypeboardByte & 0x3f;
if(SensorType == 0x0 ){
textTem.setText(String.valueOf(Packet[11])+" °C");
textHum.setText(String.valueOf(Packet[12])+" %");
}
}
(4)然后运行android程序,先启动服务,在启动程序。可以看到结果如图:
- 点赞
- 收藏
- 关注作者
评论(0)