#define TEST_SERIAL_H
//定义数据包的格式
typedef nx_struct test_serial_msg { nx_uint16_t counter; //计数 } test_serial_msg_t;
enum {
AM_TEST_SERIAL_MSG = 0x89, //表明是AM测试串口数据。就是个标志 };
#endif
TestSerialC.nc文件,实现接口中的event,和基本的通信程序差不多,但接收的是计算机传来的数据
#include \#include \
module TestSerialC { uses {
interface SplitControl as Control; interface Leds; interface Boot; interface Receive; interface AMSend;
interface Timer
implementation {
message_t packet;//数据包
bool locked = FALSE;//节点是否忙,同busy uint16_t counter = 0;//数据包计数
event void Boot.booted() {
call Control.start(); //开始,向下找startDone }
//时间每次启动调用的函数 event void MilliTimer.fired() {
counter++; if (locked) { return; } else {
//设置数据包
test_serial_msg_t* rcm = (test_serial_msg_t*)call Packet.getPayload(&packet, sizeof(test_serial_msg_t)); if (rcm == NULL) {return;}
//所发的数据超界,返回-comm serial@/dev/ttyUSB0:telosb if (call Packet.maxPayloadLength() < sizeof(test_serial_msg_t)) { return; }
rcm->counter = counter;
//广播该计数数据,寻找sendDone
if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(test_serial_msg_t)) == SUCCESS) { locked = TRUE; } } }
//接收数据程序,接收到数据后三位设置led灯 event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {
if (len != sizeof(test_serial_msg_t)) {return bufPtr;} else {
test_serial_msg_t* rcm = (test_serial_msg_t*)payload; if (rcm->counter & 0x1) { call Leds.led0On(); } else {
call Leds.led0Off(); }
if (rcm->counter & 0x2) { call Leds.led1On(); } else {
call Leds.led1Off(); }
if (rcm->counter & 0x4) { call Leds.led2On(); } else {
call Leds.led2Off();
}
return bufPtr; } }
event void AMSend.sendDone(message_t* bufPtr, error_t error) { if (&packet == bufPtr) {
locked = FALSE;//发送成功,节点空闲 } }
event void Control.startDone(error_t err) { if (err == SUCCESS) {
call MilliTimer.startPeriodic(1000); //开始成功,调用时间函数,周期进行循环 } }
event void Control.stopDone(error_t err) {} //结束成功 }
该程序和收发程序一致,无需考虑于串口的通信,与串口的通信的代码是在java的代码中实现的。
TestSerialAppC.nc:该文件实现相应的连线,注意AM数据包的不同,为SerialActiveMessageC
#include \
configuration TestSerialAppC {} implementation {
components TestSerialC as App, LedsC, MainC; components SerialActiveMessageC as AM; components new TimerMilliC();
App.Boot -> MainC.Boot; App.Control -> AM;
App.Receive -> AM.Receive[AM_TEST_SERIAL_MSG]; App.AMSend -> AM.AMSend[AM_TEST_SERIAL_MSG]; App.Leds -> LedsC;
App.MilliTimer -> TimerMilliC; App.Packet -> AM; }
TestSerialMsg.java:该文件实现对接收到的数据包的解析,其继承的是net.tinyos.message.Message 本文件是有MIG自动生成的,不用编辑此文件,其自动生成的代码在makefile中,如下:
TestSerialMsg.java:
mig java -target=null $(CFLAGS) -java-classname=TestSerialMsg TestSerial.h test_serial_msg -o $@ 不做详细分析,在以后讲解makefile时在详细说明
TestSerial.java:实现对与串口的连接和显示数据 import java.io.IOException;
import net.tinyos.message.*; import net.tinyos.packet.*; import net.tinyos.util.*;
public class TestSerial implements MessageListener {
private MoteIF moteIF;
public TestSerial(MoteIF moteIF) { this.moteIF = moteIF;
this.moteIF.registerListener(new TestSerialMsg(), this); //为节点添加监听事件 }
//发送数据包,由节点发给计算机 public void sendPackets() { int counter = 0;
TestSerialMsg payload = new TestSerialMsg();
try {
while (true) {
System.out.println(\输出接收的数据包,接收数据包的个数 payload.set_counter(counter);
moteIF.send(0, payload);//计算机给节点发送数据 counter++;
try {Thread.sleep(1000);}
catch (InterruptedException exception) {} } }
catch (IOException exception) {
System.err.println(\ System.err.println(exception); } }
//接收节点向计算机发送的数据,MessageListener的实现 public void messageReceived(int to, Message message) { TestSerialMsg msg = (TestSerialMsg)message;
System.out.println(\
}
private static void usage() {
System.err.println(\ }
//调用程序,传入参数为-comm serial@/dev/ttyUSB0:telosb public static void main(String[] args) throws Exception { String source = null; if (args.length == 2) {
if (!args[0].equals(\ usage();//提示信息 System.exit(1); }
source = args[1]; //参数serial@/dev/ttyUSB0:telosb }
else if (args.length != 0) { usage();
System.exit(1); }
PhoenixSource phoenix; //??????
if (source == null) {
phoenix = BuildSource.makePhoenix(PrintStreamMessenger.err); } else {
phoenix = BuildSource.makePhoenix(source, PrintStreamMessenger.err);//连接串口 }
MoteIF mif = new MoteIF(phoenix);//设置节点 TestSerial serial = new TestSerial(mif); serial.sendPackets(); } }
运行时,先用命令make telosb将java代码编译,才可以使用 java TestSerial -comm serial@/dev/ttyUSB2:telosb 经过测试显示的数据为: Sending packet 0
Received packet sequence number 47 Sending packet 1
Received packet sequence number 48

