第七章 TinyOS典型应用
第一节 传感
现在再来看一下SenseC模块使用的Read<unit16_t>接口的语句:
components new DemoSensorC() as Sensor;
和
SenseC.Read -> Sensor;
通用组件DemoSensorC提供Read<unit16_t>接口给SenseC组件,但是我们还不知道SenseC模块到底被连接到哪个传感器。事实上, SenseC组件并不定义连接的传感器类型,它甚至也不关心是否能从传感器成功读取数据。这是因为具体的读取数据功能有提供read接口的组件来完成。了解这一点对更好的理解TinyOS系统是很有帮助的。由于每个平台都是不一样的,在不同的平台上将由不同的DemoSensorC组件来提供read接口供SenseC使用,这种做法很好的屏蔽了平台差异对上层开发的影响。例如,在一个既没有内置传感器也没有附带传感板的平台上(如MicaZ平台),DemoSensorC组件可能只是简单地返回一个常量。此外,传感板也可能附带有相应的DemoSensorC组件(比如在Mica系列的传感板上,针对板载的光照传感器定义了demoSensorC组件)。
接下来,让我们来看一下DemoSensorC组件如何定义采样的传感器。
1.DemoSensorC 组件
每一个DemoSensorC组件都采用如下方式进行声明:
generic configuration DemoSensorC()
{
Provides interface Read<unit16_t>;
}
在不同的节点平台上,DemoSensorC组件的实现部分是不同的。例如,在TelosB平台,DemoSensorC组件里实例化一个VoltageC组件,它可以从MCU内部的电压传感器获得节点的电池电压。而micaz平台没有内置的传感器,它的DemosensorC组件使用系统库组件,比如ConstantSensorC组件或SineSensorC组件,这些组件返回虚假的传感器数据。也就是说,DemoSensorC组件间接地从相关的传感器组件(如VoltageC组件)获得传感器数据,并提供给应用程序。通常,传感器的配置工作由DemoSensorC组件内部实例化的传感器组件完成。
那么,该怎样修改Sense应用程序,使其不再采用默认的传感器?通常的做法是修改DemoSensoeC,即将第一行代码修改为第二行代码:
components new VoltageC() as DemoSensor;
components new ConstantSensorC(unit16_t,Oxbeef) as Demosensor;
至于有哪些传感器可用,这就由具体平台决定。一般,传感器组件可能位于相应平台的子目录(/tos/platforms),或者传感板的子目录(/tos/sensorboards);如果是处理器内部的传感器,就可能位于各自芯片的子目录(/tos/chips)。ConstantSensorC组件和SineSensorC组件分别返回常量值和正弦值作为传感器数据,它们可以在系统组件库(/tos/system)找到。
2.运行Sense应用
在apps/Sense目录下,根据当前的硬件平台,输入以下编译命令,如果碰到如下错误:
$ make telosb install
SenseAppC.nc:50:component DemoSensorC not found
SenseAppC.nc:50:component `DemoSensorC`is not generic
SenseAppC.nc:50:no match
表明当前平台还没有DemoSensorC组件。可以从/tos/platform/micaz目录复制DemoSensor C.nc文件到当前的平台目录。
如果有一个Mica系列的节点和一个基本传感板(mda100),可以做一个更有趣的测试,输入以下命令告诉节点采集基本传感板mda100上的光照传感器数据:
SENSORBOARD=basicsb make platform install
下载运行该程序,传感数据的低3位就会显示在节点的LED上。之所以是低3位,是因为Sense应用不知道返回值的精确范围。如果是unit_16类型值的高3位,当数值经过12位ADC转换后就毫无意义(除非数值是左对齐)。如果DemoSensorC组件从传感器那里获得的数值在上下波动,将会看到LED灯在不停地闪烁。
7.1.3 Oscilloscope实例
Oscilloscope应用是一个可以在计算机上显示数据曲线的应用程序。节点周期性地启动传感器采集数据,当传感数据达到10个后将它们通过无线发送出去。另一个运行着BaseStation应用的节点通过无线接收这些数据并通过串口转发至PC机。因此要运行Oscilloscope应用,至少需要两个节点:一个基站节点,通过串口连接到PC(BaseStation应用位于“tinyos-2.x/apps/BsaeStation”目录),另一个节点运行Oscilloscope应用。
OscilloscopeAppC配件的代码如下:
configuration OscilloscopeAppC
{
}
implementation
{
components OscilloscopeC, MainC, ActiveMessageC, LedsC,
new TimerMilliC(), new DemoSensorC() as Sensor,
new AMSenderC(AM_OSCILLOSCOPE),
new AMReceiverC(AM_OSCILLOSCOPE);
OscilloscopeC.Boot -> MainC;
OscilloscopeC.RadioControl -> ActiveMessageC;
OscilloscopeC.AMSend -> AMSenderC;
OscilloscopeC.Receive -> AMReceiverC;
OscilloscopeC.Timer -> TimerMilliC;
OscilloscopeC.Read -> Sensor;
OscilloscopeC.Leds -> LedsC;
}
OscilloscopeC模块的部分代码如下:
module OscilloscopeC
{
uses {
interface Boot;
interface SplitControl as RadioControl;
interface AMSend;
interface Receive;
interface Timer;
interface Read;
interface Leds;
}
}
Oscilloscope应用与Sense应用一样,使用了DemoSensorC组件和一个周期性的定时器。当它收集了10个传感器数据,就把它们放到一个消息包里,然后通过AMSend接口发送出去。在OscilloscopeC组件中,SplitControl接口开启无线服务,通过Receive接口接收控制信号,从而同步采样速率。