cc2530 web控制参考实现 | ||||
参考代码见附件。 安装步骤: 将basic\CC2530\WebMcuTempTerminal烧写到CC2530终端模块; 将basic\CC2530\SimpleLibApps\WebMcuGateway烧写到CC2530网关模块; 将网关模块与PC之间用usb转串口线连接(安装usb转串口驱动); 运行串口调试助手,设置波特率115200。16进制显示,应能每5秒收到一条消息。16进制发送数据:7e7e0401010202,应能看到终端模块的LED0闪烁。 (消息数据说明:7e7e为分组开始标识,04是后续字节数目,0101是目标终端节点地址(在终端代码中定义),02是消息类型,02是LED状态(toggle)) 在PC上安装JDK和Tomcat。 按照basic\PC_WebMcuV2\deploy\Readme.txt配置。 启动Tomcat,在浏览器中访问服务器的webmcucomm目录。 尝试在节点ID栏输入0101,在消息栏输入0202或者0201或者0200,点发送。 观察日志框是否有显示收到的消息。 多烧写一个终端节点,注意要更改其ID(地址),看工作是否正常。
终端代码说明 工程:basic\CC2530\WebMcuTempTerminal\IAR_files 注:该工程链接ZH_SimpleStack_2530.r51库,该库的库函数源代码请参考点对点通信函数的使用。 上行功能: 通过modTimerAddTimeoutCallback()增加一个定时任务,timeout时设置标志mBroadcastTimeoutFlag,通知主循环调用sendMsg()发送消息。 sendMsg()函数调用modAdcSampleSingle()采集温度数据和电压数据,放置在消息的第2个字节和第3个字节(7bit有效数据)。消息的第1个字节是自定义的消息类型,这里是0x02。注意:这个消息的结构和内容格式都是由设计者自行定义的,与PC中的消息解析代码一致即可。
下行功能: 在RF接收回调函数中,将收到的消息和RSSI复制到缓冲区,并设置标志mRfRxPktSize。 在主循环中,判断若下行消息类型是LED控制消息(mRfRxBuffer[0] == 0x01)则根据mRfRxBuffer[1]值设置LED0状态。注:该消息的结构和内容格式都是由设计者自行定义的,与PC中的消息解析代码一致即可。 网关模块代码说明: 工程:basic\CC2530\SimpleLibApps\WebMcuGateway\IAR_files 上行功能: 在RF的接收回调函数myRxCallback中,将消息来自的节点地址、收到的消息内容、RSSI保存到缓冲区,设置标志mRfRxPktSize提示主循环。主循环将消息通过串口发送(modUartSendPkt)。注意:消息的结构和内容格式都是由设计者自行定义的,与PC中的消息解析代码一致即可。 下行功能: 在串口的接收回调函数中,将整个消息复制到缓冲区,设置标志mUartRxPktSize提示主循环。主循环根据消息的前2个字节确定接收节点地址,将后续的消息内容发送(modRfSendPkt)。注意:消息的结构和内容格式都是由设计者自行定义的,与PC中的消息解析代码一致即可。 PC代码说明: 基于Windows XP+Tomcat,采用Java+JSP+html+javascript实现。参考实现代码可以分为3个层面: * 底层是串口通信的Java接口类,使用SUN公司提供的串口库,根据自定义的串口分组结构将字节流转换为分组; * 中间是JSP,将xml/html请求数据与底层的函数调用联系起来; * 上层是界面,用html和javascript编写,实现界面展现和动态更新(AJAX,利用了JQuery); 具体地: ===== 底层代码(basic\PC_WebMcuV2\src\service) 使用的SUN串口库在lib_ext子目录:comm.jar 主要类:hzheng.serial.moduleinterface.CommBufferController 上层应用通过getController()方法获取该类的实例(singleton模式); 上层应用通过connect ( String vPortName, int vPortRate )方法建立串口连接,指定串口名字和波特率; 在connect()函数中: 通过SUN的CommPortIdentifier.getPortIdentifiers()获得电脑的所有COM口对象列表,与输入的名字匹配,获得指定的COM口对象(mPortId.open()); 然后设置串口参数:mSerialPort.setSerialPortParams() 采用事件回调机制,设置事件回调接口:mSerialPort.addEventListener(this) 启动两个线程,一个用于读出(从串口接收,SerialReaderThread,mSerialPort.getInputStream),一个用于写入(向接口发送,SerialWriterThread,mSerialPort.getOutputStream())。 在事件回调函数serialEvent()中,当发送完成或者有收到数据时,分别调用SerialWriterThread或SerialReaderThread的notifyEvent()函数。 上层应用通过start()和stop()方法来启动或停止收发处理。 上层应用通过getMessage()方法来获取消息队列中最早的一条消息,消息以byte[]表示,当没有新消息时,返回null。 上层应用通过sendMsg(byte[] vMsgData)方法来发送消息。 消息发送过程: * 上层应用调用CommBufferController.sendMsg(byte[] vMsgData);(由主线程运行) * sendMsg()调用发送线程类mSerialWriter.sendMsg(vMsgData);(由主线程运行) * mSerialWriter.sendMsg()将消息放入发送队列Vector mMessageList,调用mMessageList.notifyAll()发送信号释放run()函数中的阻塞;(由主线程运行)[]> * 在run()函数中(由单独线程运行),从发送队列取出一条消息,如果消息长度超过串口分组的最大长度(这里规定为100字节),则拆分为多个分组发送。在分组发送函数writePkt()中,增加分组header(开始标志和长度),然后写入SUN串口类的OutputStream中。 * 在run()函数中,每发送完一个分组,要等待发送完成事件(mWaitObject.wait())再发送下一个分组;该事件由SUN控件发起(mSerialPort.notifyOnOutputEmpty(true);serialEvent(): mSerialWriter.notifyEvent(); mWaitObject.notifyAll();)。
消息接收过程: * 在SerialReaderThread.run()中,等待新数据到达事件:mWaitObject.wait();; * 读入数据:while (mInputStream.available() > 0), numBytes = mInputStream.read(readBuffer);; * 处理数据:handleNewByte(); mInputStream.read()不保证一次把一个分组的数据都读进来,有可能分成几段。 在handleNewByte()中,完成分组定界、接收完整分组数据、调用上层分组接收函数(mListener.handleData())的功能。 * mListener就是CommBufferController,其handleData()函数将分组加入接收消息队列mMessageList; * 当上层应用(JSP)调用getMessage()方法时,从队列mMessageList中取一个消息返回; ===== JSP代码 目录:basic\PC_WebMcuV2\src\gui_v2。 发送:SendMessage.jsp 与上层应用的接口为两个参数:msg和node,16进制数据字符串。(比如例子中的终端节点ID为0x101,令led状态反转的命令为0x0202,则msg="0202",node=“0101”) 先取出两个参数:
String sMsg = request.getParameter("msg");
byte[] pMsgBytes = BytesToHex.hexStringToBytes(sMsg);
//combine nodeid and msg
CommBufferController pController = CommBufferController.getController(); pController.sendMsg(pPkt); 生成发送结果的xml文档:(result-status) out.println()
接收:GetMessages.jsp
获取CommBufferController实例,启动: 取消息直到返回为空: byte[] pMsg=pController.getMessage(); 将消息内容转换为字符串,生成xml文本:
String pTerminalId = BytesToHex.byteToHexString(pMsg[0])+BytesToHex.byteToHexString(pMsg[1]);
===== 界面代码 目录:web\basic\PC_WebMcuV2\src\gui_v2 文件:index.html 这里只做了一个最简单的界面: 一个输入框输入终端节点ID(16进制字符串);(比如0101,注意前面那个0不能省) 一个输入消息(16进制字符串);(比如0202) 一个发送按钮; 一个收到的消息的显示框; 主要代码: 发送部分: 发送按钮调用sendMessage(); 在sendMessage()中: 获取输入的节点ID和消息:
var pMsg=document.getElementById("tx_msg").value;
$.post("SendMessage.jsp?msg="+pMsg+"&node="+pTermId, 返回的xml文档交给handleSendRet()函数处理,将结果显示在日志区:
var pStatus=vRetData.getElementsByTagName("status")[0].childNodes[0].nodeValue; 接收部分: 页面打开时,启动一个定时器: 在body标签中,onload="startTimer()",startTimer()调用pollMessage(); pollMessage()通过JQuery调用GetMessages.jsp并启动下一次定时:
var pCurrTime = new Date().getTime();
var pMsgs=vRetData.getElementsByTagName("msg");
|
||||
主索引
|
||||
附件 basic.zip |
||||
参考链接 |
用户1824123 2015-1-1 23:57