实验时间:2012-12-21
实验内容:获取MCU电压参数,并通过串口上传到上位机,并分析数据。
传感参数采集的组件为DemoSensorC组件,不同的平台,该组件的实现不一样。在telosb平台中,默认返回值是MCU内部的电压值。通过Read接口可是实现参数的读取。
功能实现:系统上电后三个LED灯全亮。之后触发定时器,每隔1秒对电压进行采样(读取),若成功读取则发送采样数据到串口,并反转第三个LED。据此,得到如上图所示的框架图。
【实验情况】在实验过程中,发现如下问题:
Ø LED灯按期望方式点亮或闪烁,但是,串口无法接收数据
通过查找资料得知,串口之所以没正常接收到数据是因为没有调用SplitControl接口实现电源的管理。一方面,电压传感器与串口的开启与关闭没有得到正常的申请使用,另一方面设备的开启与关闭时间不可忽略。同样,在使用无线通信模块时,SplitControl也是不可少的。
注:TinyOS平台的能量十分有限,因此对所有的设备(如串口设备、SPI总线及定时器等)使用统一的电源管理策略显然是不合适的,因为它们在预热阶段、电源配置和工作延迟上有很大的不同。有些设备,例如微控制器,可以高效地计算出所允许的最低功率状态;而其他一些设备,如带有预热阶段的传感器,就需要获得额外信息才能实现电源状态的高校管理。
【实验结果】因为节点是通过USB供电,同时也作为串口通信接口,因此实际检测的电压为“满格”电压,从串口接收的数据为:
7E 45 00 00 FF00 00 02 00 06 0F FB FD E1 7E 0.999U U为满格电压
7E 45 00 00 FF00 00 02 00 06 0F DC 78 85 7E 0.991U
7E 45 00 00 FF00 00 02 00 06 0F F9 BF C1 7E 0.998U
7E 45 00 00 FF00 00 02 00 06 0F D9 DD E5 7E 0.991U
7E 45 00 00 FF00 00 02 00 06 0F F9 BF C1 7E 0.998U
7E 45 00 00 FF00 00 02 00 06 0F DD 59 A5 7E 0.991U
7E 45 00 00 FF00 00 02 00 06 0F FB FD E1 7E 0.999U
……
【VoltageSenseAppC.nc文件】
configuration VoltageSenseAppC
{
}
implementation
{
//components
components VoltageSenseC,MainC,LedsC;
components new SerialAMSenderC(6);
components new TimerMilliC() as T0;
components new DemoSensorC() as VolSensor;
components SerialActiveMessageC as SerialAcMsg;
//Links
VoltageSenseC.Boot -> MainC;
VoltageSenseC.Leds -> LedsC;
VoltageSenseC.Timer0 -> T0;
VoltageSenseC.Read -> VolSensor;
VoltageSenseC.UartSend -> SerialAMSenderC;
VoltageSenseC.UartPacket -> SerialAMSenderC;
VoltageSenseC.SerialControl -> SerialAcMsg;
}
【VoltageSenseC.nc文件】
#include
#include "pr.h"
module VoltageSenseC
{
uses {
interface SplitControl as SerialControl;
interface Boot;
interface Leds;
interface Timer as Timer0;
interface Read;
interface AMSend as UartSend;
interface Packet as UartPacket;
}
}
implementation
{
typedef nx_struct RealMsg
{
nx_uint16_t Voltage;
}RealMsg;
message_t ToUartMsg;
uint8_t SetLeds;
//初始显示,点亮三个LEDs
event void Boot.booted()
{
call SerialControl.start();
}
event void SerialControl.startDone(error_t error)
{
if(error == SUCCESS)
{
SetLeds=7;
call Leds.set(SetLeds);
call Timer0.startPeriodic(1000);//采集周期为1s
}
}
event void SerialControl.stopDone(error_t error){}
//读取获取电压传感数据
event void Timer0.fired()
{
// 读取电源电压
call Read.read();
}
event void Read.readDone(error_t result,uint16_t data)
{
if(result == SUCCESS)
{
//定义指向payload段指针
RealMsg *btrpkt = (RealMsg *)(call UartPacket.getPayload(&ToUartMsg,sizeof(RealMsg)));
//转载载荷区
btrpkt -> Voltage = data;
// pr("%d\n",data);
//发送数据
if(call UartSend.send(0xff,&ToUartMsg,sizeof(RealMsg)) == SUCCESS)
{
call Leds.led2Toggle();
}
}
}
event void UartSend.sendDone(message_t *msg,error_t error)
{}
}