当前位置:首页 >> 信息与通信 >>

NesC


1. Lesson_1—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 19:59:01 njain Exp $ */ /** * This configuration shows how to use the Timer and LED components * **/ configuration MyApp { } implementation { components Main, MyAppM, TimerC, LedsC; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MyAppM.StdControl; MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; }

2. Lesson_1—MyAppM.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.2 2007/04/26 19:59:09 njain Exp $ */

/** * This module shows how to use the Timer and LED components **/ module MyAppM { provides { interface StdControl; }

uses { interface Timer; interface Leds; } } implementation { /** * Initialize the components. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { call Leds.init(); return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() {

call Leds.redToggle(); return SUCCESS; } }

3. Lesson_2—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 19:59:29 njain Exp $ */

includes sensorboardApp; /** * This module shows how to use the Timer, LED, ADC and Messaging components. * Sensor messages are sent to the serial port **/ configuration MyApp { } implementation { components Main, MyAppM, TimerC, LedsC, Photo, GenericComm as Comm; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> Comm.Control; MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.SendMsg -> Comm.SendMsg[AM_XSXMSG]; }

4. Lesson_2—MyAppM.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc.

* All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.4 2007/04/26 19:59:38 njain Exp $ */ includes sensorboardApp; /** * This module shows how to use the Timer, LED, ADC and Messaging components * Sensor messages are sent to the serial port * **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface SendMsg; } } implementation { bool sending_packet = FALSE; TOS_Msg msg_buffer; XDataMsg *pack; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { call Leds.init(); call PhotoControl.init(); // Initialize the message packet with default values atomic { pack = (XDataMsg *)&(msg_buffer.data); pack->xSensorHeader.board_id = SENSOR_BOARD_ID; pack->xSensorHeader.packet_id = 2;

pack->xSensorHeader.node_id = TOS_LOCAL_ADDRESS; pack->xSensorHeader.rsvd = 0; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { call Leds.redToggle(); call PhotoControl.start(); call Light.getData(); return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send

**/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // send message to UART (serial) port if (call SendMsg.send(TOS_UART_ADDR,sizeof(XDataMsg),&msg_buffer) SUCCESS) sending_packet = FALSE; return; } /** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) { atomic pack->xData.datap1.light = data; atomic pack->xData.datap1.vref = 417; // a dummy 3V reference voltage, 1252352/3000 = 417 post SendData(); call Leds.yellowToggle(); return SUCCESS; } /** * Sensor data has been sucessfully sent over the UART (serial port) * Toggle green LED to signal message sent * * @return Always returns <code>SUCCESS</code> **/ event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; }

!=

}

5. Lesson_2—Photo.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 19:59:46 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */ /** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman */ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; } implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC;

PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; }

6. Lesson_2—PhotoM.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 19:59:54 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from * starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with * waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample * as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an

// asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady. // // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the // read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between // setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl; provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl;

interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0, sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t; SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample; command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle; dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() {

atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS; } // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); }; return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() { if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS; } async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample();

return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } }

Lesson_2—SensorboardApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.2.4.4 2007/04/26 20:00:03 njain Exp $ */ /* sensorboard.h - hardware specific definitions for the MTS300/310 */

TOSH_ALIAS_PIN(PHOTO_CTL, INT1); TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, };

enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

#define FEATURE_SOUNDER

1

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state #define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state // crossbow sensor board id //#define SENSOR_BOARD_ID 0x88 #define MTS310 #ifndef MTS310 #define SENSOR_BOARD_ID 0x83 #else #define SENSOR_BOARD_ID 0x84 #endif typedef struct XSensorHeader{ uint8_t board_id; uint8_t packet_id; // 3 uint8_t node_id; uint8_t rsvd; }__attribute__ ((packed)) XSensorHeader; typedef struct PData1 { uint16_t vref; uint16_t thermistor; uint16_t light; uint16_t mic; uint16_t accelX; uint16_t accelY; uint16_t magX; uint16_t magY; } __attribute__ ((packed)) PData1; typedef struct XDataMsg {

//XTYPE_XTUTORIAL=0x88

//MTS300 sensor board id //MTS310 sensor board id

XSensorHeader xSensorHeader; union { PData1 datap1; }xData; } __attribute__ ((packed)) XDataMsg; enum { AM_XSXMSG = 0, };

Lesson_3—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 20:00:23 njain Exp $ */ includes sensorboardApp; /** * This configuration shows how to use the Timer, LED, ADC and Messaging components. * Sensor messages are broadcast single-hop over the RF radio * **/ configuration MyApp { } implementation { components Main, MyAppM, TimerC, LedsC, Photo, GenericComm as Comm; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> Comm.Control; MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.SendMsg -> Comm.SendMsg[AM_XSXMSG]; }

Lesson_3—MyAppM.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.4 2007/04/26 20:00:32 njain Exp $ */ includes sensorboardApp; /** * This module shows how to use the Timer, LED, ADC and Messaging components. * Sensor messages are broadcast single-hop over the RF radio * **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface SendMsg; } } implementation { bool sending_packet = FALSE; TOS_Msg msg_buffer; XDataMsg *pack; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { call Leds.init(); call PhotoControl.init();

// Initialize the message packet with default values atomic { pack = (XDataMsg *)&(msg_buffer.data); pack->xSensorHeader.board_id = SENSOR_BOARD_ID; pack->xSensorHeader.packet_id = 3; pack->xSensorHeader.node_id = TOS_LOCAL_ADDRESS; pack->xSensorHeader.rsvd = 0; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { call Leds.redToggle(); call PhotoControl.start(); call Light.getData();

return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send **/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // broadcast message over radio if (call SendMsg.send(TOS_BCAST_ADDR,sizeof(XDataMsg),&msg_buffer) != SUCCESS) sending_packet = FALSE; return; } /** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) { atomic pack->xData.datap1.light = data; atomic pack->xData.datap1.vref = 417; // a dummy 3V reference voltage, 1252352/3000 = 417 post SendData(); call Leds.yellowToggle(); return SUCCESS; } /** * Sensor data message has been sucessfully sent over the radio * Toggle green LED to signal message sent * * @return Always returns <code>SUCCESS</code> **/

event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; } }

Lesson_3—Photo.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 20:00:40 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */ /** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman */ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; }

implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC; PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; }

Lesson_3—PhotoM.h
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 20:00:48 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from * starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with * waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample

* as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an // asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady. // // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the // read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between // setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl;

provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl; interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0, sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t; SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample; command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle;

dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() { atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS; } // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); }; return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() { if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS;

} async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample(); return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } }

Lesson_3—SensorboardApp.h
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.2.4.4 2007/04/26 20:00:57 njain Exp $ */ /* sensorboard.h - hardware specific definitions for the MTS300/310 */

TOSH_ALIAS_PIN(PHOTO_CTL, INT1);

TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, }; enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

#define FEATURE_SOUNDER

1

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state #define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state // crossbow sensor board id //#define SENSOR_BOARD_ID 0x88 #define MTS310 #ifndef MTS310 #define SENSOR_BOARD_ID 0x83 #else #define SENSOR_BOARD_ID 0x84 #endif typedef struct XSensorHeader{ uint8_t board_id; uint8_t packet_id; // 3 uint8_t node_id; uint8_t rsvd; }__attribute__ ((packed)) XSensorHeader; typedef struct PData1 { uint16_t vref; uint16_t thermistor; uint16_t light; uint16_t mic; uint16_t accelX;

//XTYPE_XTUTORIAL=0x88

//MTS300 sensor board id //MTS310 sensor board id

uint16_t accelY; uint16_t magX; uint16_t magY; } __attribute__ ((packed)) PData1; typedef struct XDataMsg { XSensorHeader xSensorHeader; union { PData1 datap1; }xData; } __attribute__ ((packed)) XDataMsg; enum { AM_XSXMSG = 0, };

Lesson_4—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 20:01:17 njain Exp $ */ #include "appFeatures.h" includes sensorboardApp; /** * This configuration shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio **/ configuration MyApp { } implementation { components Main, GenericCommPromiscuous as Comm, MULTIHOPROUTER, MyAppM, TimerC, LedsC, Photo; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> Comm.Control; Main.StdControl -> MULTIHOPROUTER.StdControl;

MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.RouteControl -> MULTIHOPROUTER; MyAppM.Send -> MULTIHOPROUTER.MhopSend[AM_XMULTIHOP_MSG]; MULTIHOPROUTER.ReceiveMsg[AM_XMULTIHOP_MSG] ->Comm.ReceiveMsg[AM_XMULTIHOP_MSG]; }

Lesson_4—MyAppM.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.5 2007/04/26 20:01:26 njain Exp $ */ #include "appFeatures.h" includes MultiHop; //includes sensorboard; /** * This module shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio * * @author Crossbow Technology Inc. **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface MhopSend as Send; interface RouteControl; } }

implementation { bool sending_packet = FALSE; TOS_Msg msg_buffer; XDataMsg *pack; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { uint16_t len; call Leds.init(); call PhotoControl.init(); // Initialize the message packet with default values atomic { pack = (XDataMsg*)call Send.getBuffer(&msg_buffer, &len); pack->board_id = SENSOR_BOARD_ID; pack->packet_id = 4; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop();

} /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { call Leds.redToggle(); call PhotoControl.start(); call Light.getData(); return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send **/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // send message to XMesh multi-hop networking layer pack->parent = call RouteControl.getParent(); if (call Send.send(BASE_STATION_ADDRESS,MODE_UPSTREAM,&msg_buffer,sizeof(XDataM sg)) != SUCCESS) sending_packet = FALSE; return; } /** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) {

atomic pack->light = data; atomic pack->vref = 417; // a dummy 3V reference voltage, 1252352/3000 = 417 post SendData(); call Leds.yellowToggle(); return SUCCESS; } /** * Sensor data has been sucessfully sent through XMesh * Toggle green LED to signal message sent * * @return Always returns <code>SUCCESS</code> **/ event result_t Send.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; } }

Lesson_4—Photo.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 20:01:34 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */

/** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman */ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; } implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC; PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; }

Lesson_4—PhotoM.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 20:01:43 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from

* starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with * waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample * as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an // asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady. // // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the

// read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between // setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl; provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl; interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0, sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t;

SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample; command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle; dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() { atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS; } // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); };

return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() { if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS; } async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample(); return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } }

Lesson_4—appFeatures.h

/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: appFeatures.h,v 1.2.4.3 2007/04/26 20:01:51 njain Exp $ */ /** * Compile-time flags for defining application specific feature preferences. * * @file appFeatures.h * @author Martin Turon * * @version 2004/8/8 mturon Initial version * */ /// FEATURE_LEDS -- powers up the LEDs for debugging purposes #ifndef FEATURE_LEDS #define FEATURE_LEDS 0 #endif /// FEATURE_UART_SEND -- enable serial port debugging of a node #ifndef FEATURE_UART_SEND #define FEATURE_UART_SEND 0 #endif /// FEATURE_SOUNDER -- enable test of speaker output #ifndef FEATURE_SOUNDER #define FEATURE_SOUNDER 0 #endif // crossbow sensor board id //#define SENSOR_BOARD_ID 0x88 #define MTS310 #ifndef MTS310 #define SENSOR_BOARD_ID 0x83 #else #define SENSOR_BOARD_ID 0x84 #endif /**

//XTYPE_XTUTORIAL=0x88

//MTS300 sensor board id //MTS310 sensor board id

* Define wiring macros for various application features. */ /** FEATURE_LEDS will enable debugging Leds when set to 1. */ #if FEATURE_LEDS #define LEDS_COMPONENT LedsC, #define LEDS_WIRING(X) X.Leds -> LedsC; #else #define LEDS_COMPONENT NoLeds, #define LEDS_WIRING(X) X.Leds -> NoLeds; #endif

Lesson_4—SensorboardApp.h
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.2.4.2 2007/04/26 20:01:59 njain Exp $ */ /* sensorboard.h - hardware specific definitions for the MTS300/310 */ // controls for the voltage reference monitor #define MAKE_BAT_MONITOR_OUTPUT() sbi(DDRA, 5) #define MAKE_ADC_INPUT() cbi(DDRF, 7) #define SET_BAT_MONITOR() sbi(PORTA, 5) #define CLEAR_BAT_MONITOR() cbi(PORTA, 5) TOSH_ALIAS_PIN(PHOTO_CTL, INT1); TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, }; enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state

#define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state typedef struct XDataMsg { uint8_t board_id; uint8_t packet_id; //uint8_t node_id; uint16_t parent; // 4 uint16_t vref; uint16_t thermistor; uint16_t light; uint16_t mic; uint16_t accelX; uint16_t accelY; uint16_t magX; uint16_t magY; } __attribute__ ((packed)) XDataMsg; enum { BATT_PORT = 7, }; enum { AM_XDEBUG_MSG = 49, AM_XSENSOR_MSG = 50, AM_XMULTIHOP_MSG = 51, };

//adc port for battery voltage

// xsensor multihop

#ifdef APP_RATE uint32_t XSENSOR_SAMPLE_RATE = APP_RATE; #else #ifdef USE_LOW_POWER uint32_t XSENSOR_SAMPLE_RATE = 184320; #else uint32_t XSENSOR_SAMPLE_RATE = 1843; #endif #endif uint32_t timer_rate;

Lesson_5—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 20:02:21 njain Exp $ */ #include "appFeatures.h" includes sensorboardApp; /** * This configuration shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio **/ configuration MyApp { } implementation { components Main, GenericCommPromiscuous as Comm, MULTIHOPROUTER, MyAppM, TimerC, LedsC, Photo; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> MULTIHOPROUTER.StdControl; Main.StdControl -> Comm.Control; Main.StdControl -> TimerC.StdControl; MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.RouteControl -> MULTIHOPROUTER; MyAppM.Send -> MULTIHOPROUTER.MhopSend[AM_XMULTIHOP_MSG]; MyAppM.ReceiveAck -> MULTIHOPROUTER.ReceiveAck[AM_XMULTIHOP_MSG]; MULTIHOPROUTER.ReceiveMsg[AM_XMULTIHOP_MSG] ->Comm.ReceiveMsg[AM_XMULTIHOP_MSG]; }

Lesson_5—MyAppM.nc

/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.5 2007/04/26 20:02:29 njain Exp $ */ #include "appFeatures.h" includes MultiHop; //includes sensorboard; /** * This module shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface MhopSend as Send; interface Receive as ReceiveAck; interface RouteControl; } } implementation { bool sending_packet = FALSE; TOS_Msg msg_buffer; XDataMsg *pack; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { uint16_t len; call Leds.init(); call PhotoControl.init();

// Initialize the message packet with default values atomic { pack = (XDataMsg*)call Send.getBuffer(&msg_buffer, &len); pack->board_id = SENSOR_BOARD_ID; pack->packet_id = 5; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms (only if not base station) if (TOS_LOCAL_ADDRESS != BASE_STATION_ADDRESS) return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { call Leds.redToggle(); call PhotoControl.start(); call Light.getData();

return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send **/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // send message to XMesh multi-hop networking layer pack->parent = call RouteControl.getParent(); if (call Send.send(BASE_STATION_ADDRESS,MODE_UPSTREAM_ACK,&msg_buffer,sizeof(XD ataMsg)) != SUCCESS) sending_packet = FALSE; return; } /** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) { atomic pack->light = data; atomic pack->vref = 417; // a dummy 3V reference voltage, 1252352/3000 = 417 post SendData(); return SUCCESS; } /** * Sensor data has been sucessfully sent through XMesh * Toggle green LED to signal message sent * * @return Always returns <code>SUCCESS</code> **/

event result_t Send.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; } /** * Sensor data has been sucessfully sent through XMesh and * and acknowledgement has been sent back from the base station * Toggle yellow LED to signal ack message received * * @return Always returns <code>SUCCESS</code> **/ event TOS_MsgPtr ReceiveAck.receive(TOS_MsgPtr pMsg, void* payload, uint16_t payloadLen) { call Leds.yellowToggle(); return pMsg; } }

Lesson_5—Photo.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 20:02:38 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */

/** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman */ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; } implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC; PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; }

Lesson_5—PhotoM.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 20:02:46 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from

* starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with * waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample * as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an // asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady. // // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the

// read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between // setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl; provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl; interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0, sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t;

SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample; command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle; dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() { atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS; } // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); };

return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() { if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS; } async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample(); return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } }

Lesson_5—appFeatures.h

/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: appFeatures.h,v 1.1.4.3 2007/04/26 20:02:55 njain Exp $ */

/** * Compile-time flags for defining application specific feature preferences. * * @file appFeatures.h * @author Martin Turon * * @version 2004/8/8 mturon Initial version * * $Id: appFeatures.h,v 1.1.4.3 2007/04/26 20:02:55 njain Exp $ */ /// FEATURE_LEDS -- powers up the LEDs for debugging purposes #ifndef FEATURE_LEDS #define FEATURE_LEDS 0 #endif /// FEATURE_UART_SEND -- enable serial port debugging of a node #ifndef FEATURE_UART_SEND #define FEATURE_UART_SEND 0 #endif /// FEATURE_SOUNDER -- enable test of speaker output #ifndef FEATURE_SOUNDER #define FEATURE_SOUNDER 0 #endif // crossbow sensor board id //#define SENSOR_BOARD_ID 0x88 #define MTS310 #ifndef MTS310 #define SENSOR_BOARD_ID 0x83 #else #define SENSOR_BOARD_ID 0x84 #endif

//XTYPE_XTUTORIAL=0x88

//MTS300 sensor board id //MTS310 sensor board id

/** * Define wiring macros for various application features. */ /** FEATURE_LEDS will enable debugging Leds when set to 1. */ #if FEATURE_LEDS #define LEDS_COMPONENT LedsC, #define LEDS_WIRING(X) X.Leds -> LedsC; #else #define LEDS_COMPONENT NoLeds, #define LEDS_WIRING(X) X.Leds -> NoLeds; #endif

Lesson_5—SensorboardApp.h /* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.1.4.2 2007/04/26 20:03:03 njain Exp $ */ /* sensorboard.h - hardware specific definitions for the MTS300/310 */ // controls for the voltage reference monitor #define MAKE_BAT_MONITOR_OUTPUT() sbi(DDRA, 5) #define MAKE_ADC_INPUT() cbi(DDRF, 7) #define SET_BAT_MONITOR() sbi(PORTA, 5) #define CLEAR_BAT_MONITOR() cbi(PORTA, 5)

TOSH_ALIAS_PIN(PHOTO_CTL, INT1); TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, }; enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state

#define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state typedef struct XDataMsg { uint8_t board_id; uint8_t packet_id; //uint8_t node_id; uint16_t parent; // 4 uint16_t vref; uint16_t thermistor; uint16_t light; uint16_t mic; uint16_t accelX; uint16_t accelY; uint16_t magX; uint16_t magY; } __attribute__ ((packed)) XDataMsg; enum { BATT_PORT = 7, }; enum { AM_XDEBUG_MSG = 49, AM_XSENSOR_MSG = 50, AM_XMULTIHOP_MSG = 51, };

//adc port for battery voltage

// xsensor multihop

#ifdef APP_RATE uint32_t XSENSOR_SAMPLE_RATE = APP_RATE; #else #ifdef USE_LOW_POWER uint32_t XSENSOR_SAMPLE_RATE = 184320; #else uint32_t XSENSOR_SAMPLE_RATE = 1843; #endif #endif

uint32_t timer_rate; Lesson_6—MyApp.nc /* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 20:03:24 njain Exp $ */ #include "appFeatures.h" includes sensorboardApp; /** * This configuration shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio * This application also accepts commands from the base for changing the reporting * rate and to toggle the LED states * **/ configuration MyApp { } implementation { components Main, GenericCommPromiscuous as Comm, MULTIHOPROUTER, MyAppM, TimerC, LedsC, Photo, XCommandC; Main.StdControl -> TimerC.StdControl; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> Comm.Control; Main.StdControl -> MULTIHOPROUTER.StdControl; MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.RouteControl -> MULTIHOPROUTER; MyAppM.Send -> MULTIHOPROUTER.MhopSend[AM_XMULTIHOP_MSG]; MyAppM.XCommand -> XCommandC; MULTIHOPROUTER.ReceiveMsg[AM_XMULTIHOP_MSG] ->Comm.ReceiveMsg[AM_XMULTIHOP_MSG]; }

Lesson_6—MyAppM.nc

/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.5 2007/04/26 20:03:32 njain Exp $ */ #include "appFeatures.h" includes MultiHop; //includes sensorboard; /** * This module shows how to use the Timer, LED, ADC and XMesh components. * Sensor messages are sent multi-hop over the RF radio * This application also accepts commands from the base for changing the reporting * rate and to toggle the LED states * **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface MhopSend as Send; interface RouteControl; interface XCommand; } } implementation { bool sending_packet = FALSE; TOS_Msg msg_buffer; XDataMsg *pack; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() {

uint16_t len; call Leds.init(); call PhotoControl.init(); // Initialize the message packet with default values atomic { pack = (XDataMsg*)call Send.getBuffer(&msg_buffer, &len); pack->board_id = SENSOR_BOARD_ID; pack->packet_id = 6; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { call Leds.redToggle();

call PhotoControl.start(); call Light.getData(); return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send **/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // send message to XMesh multi-hop networking layer pack->parent = call RouteControl.getParent(); if (call Send.send(BASE_STATION_ADDRESS,MODE_UPSTREAM,&msg_buffer,sizeof(XDataM sg)) != SUCCESS) sending_packet = FALSE; return; } /** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) { atomic pack->light = data; atomic pack->vref = 417; // a dummy 3V reference voltage, 1252352/3000 = 417 post SendData(); call Leds.yellowToggle(); return SUCCESS; } /** * Sensor data has been sucessfully sent through XMesh * Toggle green LED to signal message sent

* * @return Always returns <code>SUCCESS</code> **/ event result_t Send.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; } /** * Handles all broadcast command messages sent over network. * * NOTE: Bcast messages will not be received if seq_no is not properly * set in first two bytes of data payload. Also, payload is * the remaining data after the required seq_no. * @return Always returns <code>SUCCESS</code> **/ event result_t XCommand.received(XCommandOp *opcode) { uint16_t timer = 0; switch (opcode->cmd) { case XCOMMAND_SET_RATE: // Change the data collection rate. timer = opcode->param.newrate; call Timer.stop(); call Timer.start(TIMER_REPEAT,timer); break; default: break; } return SUCCESS; } }

Lesson_6—Photo.nc /* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved.

* See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 20:03:41 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */ /** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman */ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; } implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC; PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; }

Lesson_6—PhotoM.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California

* Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 20:03:49 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from * starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with * waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample * as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an // asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady.

// // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the // read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between // setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl; provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl; interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0,

sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t; SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample; command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle; dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() { atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS;

} // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); }; return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() { if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS; } async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample(); return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } } Lesson_6—appFeatures.h /* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: appFeatures.h,v 1.1.4.3 2007/04/26 20:03:57 njain Exp $ */ /** * Compile-time flags for defining application specific feature preferences. * * @file appFeatures.h * @author Martin Turon * * @version 2004/8/8 mturon Initial version * */ /// FEATURE_LEDS -- powers up the LEDs for debugging purposes #ifndef FEATURE_LEDS #define FEATURE_LEDS 0 #endif /// FEATURE_UART_SEND -- enable serial port debugging of a node #ifndef FEATURE_UART_SEND #define FEATURE_UART_SEND 0 #endif /// FEATURE_SOUNDER -- enable test of speaker output

#ifndef FEATURE_SOUNDER #define FEATURE_SOUNDER #endif

0

// crossbow sensor board id //#define SENSOR_BOARD_ID 0x88 #define MTS310 #ifndef MTS310 #define SENSOR_BOARD_ID 0x83 #else #define SENSOR_BOARD_ID 0x84 #endif

//XTYPE_XTUTORIAL=0x88

//MTS300 sensor board id //MTS310 sensor board id

/** * Define wiring macros for various application features. */ /** FEATURE_LEDS will enable debugging Leds when set to 1. */ #if FEATURE_LEDS #define LEDS_COMPONENT LedsC, #define LEDS_WIRING(X) X.Leds -> LedsC; #else #define LEDS_COMPONENT NoLeds, #define LEDS_WIRING(X) X.Leds -> NoLeds; #endif

Lesson_6—SensorboardApp.h
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.1.4.2 2007/04/26 20:04:06 njain Exp $ */ /* sensorboard.h - hardware specific definitions for the MTS300/310 */ // controls for the voltage reference monitor #define MAKE_BAT_MONITOR_OUTPUT() sbi(DDRA, 5) #define MAKE_ADC_INPUT() cbi(DDRF, 7) #define SET_BAT_MONITOR() sbi(PORTA, 5) #define CLEAR_BAT_MONITOR() cbi(PORTA, 5)

TOSH_ALIAS_PIN(PHOTO_CTL, INT1); TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, }; enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state

#define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state typedef struct XDataMsg { uint8_t board_id; uint8_t packet_id; //uint8_t node_id; uint16_t parent; // 4 uint16_t vref; uint16_t thermistor; uint16_t light; uint16_t mic; uint16_t accelX; uint16_t accelY; uint16_t magX; uint16_t magY; } __attribute__ ((packed)) XDataMsg; enum { BATT_PORT = 7, }; enum {

//adc port for battery voltage

AM_XDEBUG_MSG = 49, AM_XSENSOR_MSG = 50, AM_XMULTIHOP_MSG = 51, };

// xsensor multihop

#ifdef APP_RATE uint32_t XSENSOR_SAMPLE_RATE = APP_RATE; #else #ifdef USE_LOW_POWER uint32_t XSENSOR_SAMPLE_RATE = 184320; #else uint32_t XSENSOR_SAMPLE_RATE = 1843; #endif #endif uint32_t timer_rate;

Lesson_7—MyApp.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyApp.nc,v 1.1.2.2 2007/04/26 20:04:27 njain Exp $ */ includes sensorboardApp; /** * This module shows how to use the Timer, LED, ADC and Messaging components. * Sensor messages are sent to the serial port **/ configuration MyApp { } implementation { components Main, MyAppM, TimerC, LedsC, Photo, ByteEEPROM, GenericComm as Comm; Main.StdControl -> TimerC.StdControl; Main.StdControl -> ByteEEPROM; Main.StdControl -> MyAppM.StdControl; Main.StdControl -> Comm.Control;

MyAppM.Timer -> TimerC.Timer[unique("Timer")]; MyAppM.Leds -> LedsC.Leds; MyAppM.PhotoControl -> Photo.PhotoStdControl; MyAppM.Light -> Photo.ExternalPhotoADC; MyAppM.AllocationReq -> ByteEEPROM.AllocationReq[BYTE_EEPROM_ID]; MyAppM.ReadData->ByteEEPROM.ReadData[BYTE_EEPROM_ID]; MyAppM.WriteData->ByteEEPROM.WriteData[BYTE_EEPROM_ID]; MyAppM.SendMsg -> Comm.SendMsg[AM_XSXMSG]; }

Lesson_7—MyAppM.nc
/* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: MyAppM.nc,v 1.1.2.3 2007/04/26 20:04:35 njain Exp $ */ includes sensorboardApp; /** * This module shows how to use the Timer, LED, ADC and Messaging components * Sensor messages are sent to the serial port **/ module MyAppM { provides { interface StdControl; } uses { interface Timer; interface Leds; interface StdControl as PhotoControl; interface ADC as Light; interface SendMsg; interface AllocationReq; interface WriteData; interface ReadData; } } implementation { bool sending_packet = FALSE; bool ready = FALSE;

TOS_Msg msg_buffer; XDataMsg *pack; norace uint16_t lightData[PhotoLogCount]; /** * Initialize the component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.init() { call Leds.init(); call AllocationReq.request(PhotoLogCount*sizeof(uint16_t)); call PhotoControl.init(); // Initialize the message packet with default values atomic { pack = (XDataMsg *)&(msg_buffer.data); pack->xSensorHeader.board_id = SENSOR_BOARD_ID; pack->xSensorHeader.packet_id = 7; pack->xSensorHeader.node_id = TOS_LOCAL_ADDRESS; pack->xSensorHeader.rsvd = 0; } return SUCCESS; } /** * Start things up. This just sets the rate for the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.start() { // Start a repeating timer that fires every 1000ms return call Timer.start(TIMER_REPEAT, 1000); } /** * Halt execution of the application. * This just disables the clock component. * * @return Always returns <code>SUCCESS</code> **/ command result_t StdControl.stop() { return call Timer.stop(); }

event result_t AllocationReq.requestProcessed(result_t success) { // Allocation must succeed if (success){ ready = TRUE; } return SUCCESS; } /** * Toggle the red LED in response to the <code>Timer.fired</code> event. * Start the Light sensor control and sample the data * * @return Always returns <code>SUCCESS</code> **/ event result_t Timer.fired() { if(ready) { call PhotoControl.start(); call Light.getData(); } return SUCCESS; } /** * Stop the Light sensor control, build the message packet and send **/ void task SendData() { call PhotoControl.stop(); if (sending_packet) return; atomic sending_packet = TRUE; // send message to UART (serial) port if (call SendMsg.send(TOS_UART_ADDR,sizeof(XDataMsg),&msg_buffer) SUCCESS) sending_packet = FALSE; return; }

!=

/** * Light ADC data ready * Toggle yellow LED to signal Light sensor data sampled * * @return Always returns <code>SUCCESS</code> **/ async event result_t Light.dataReady(uint16_t data) { atomic pack->xData.datap1.light[0] = data; lightData[0]=data; if(call ReadData.read(0,(uint8_t*)(&lightData[1]),(PhotoLogCount-1)*2)==FAIL) { call Leds.redToggle(); } return SUCCESS; } event result_t WriteData.writeDone(uint8_t *data, uint32_t numBytesWrite, result_t success) { post SendData(); return SUCCESS; }

event result_t ReadData.readDone(uint8_t *buffer, uint32_t numBytesRead, result_t success) { call Leds.greenToggle(); if(numBytesRead==((PhotoLogCount-1)*2)) { memcpy((uint8_t*)(pack->xData.datap1.light)+2,(uint8_t*)(&lightData[1]),(Phot oLogCount-1)*2); call WriteData.write(0,(uint8_t*)(&lightData[0]),PhotoLogCount*2); } return SUCCESS; }

/** * Sensor data has been sucessfully sent over the UART (serial port) * Toggle green LED to signal message sent * * @return Always returns <code>SUCCESS</code> **/ event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success) { call Leds.greenToggle(); atomic sending_packet = FALSE; return SUCCESS; } }

Lesson_7—Photo.nc
/* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: Photo.nc,v 1.1.2.2 2007/04/26 20:04:44 njain Exp $ */ /* * * Authors: Jason Hill, David Gay, Philip Levis * Date last modified: 6/25/02 * * Modifications: * 20Oct03 MJNewman: Add timer used for delays when sensor is switched. * */ /** * @author Jason Hill * @author David Gay * @author Philip Levis * @author Michael Newman

*/ //includes sensorboard; configuration Photo { provides interface ADC as ExternalPhotoADC; provides interface StdControl as PhotoStdControl; } implementation { components PhotoM, ADCC, TimerC; PhotoStdControl = PhotoM.PhotoStdControl; ExternalPhotoADC = PhotoM.ExternalPhotoADC; PhotoM.InternalPhotoADC -> ADCC.ADC[TOS_ADC_PHOTO_PORT]; PhotoM.ADCControl -> ADCC; PhotoM.TimerControl -> TimerC; PhotoM.PhotoTimer -> TimerC.Timer[unique("Timer")]; } Lesson_7—PhotoM.nc /* * Copyright (c) 2002-2005 Intel Corporation * Copyright (c) 2000-2005 The Regents of the University of California * Copyright (c) 2003 by Sensicast, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: PhotoM.nc,v 1.1.2.2 2007/04/26 20:04:52 njain Exp $ */ #define PhotoMedit 3 /* * Modification History: * 11Nov03 MJNewman 3: TinyOS 1.1 atomic updates. * 20Oct03 MJNewman 2: Redo copyright and initial comments. * 7May03 MJNewman 1: Add proper delays when sensor is switched. * It is important to wait about 10ms from * starting a sensor to reading data from the * sensor. * 7May03 MJNewman 1: Created. * * This module is a rewrite of the PhotoM.nc module written by * Jason Hill, David Gay and Philip Levis. This module solves * fundamental sampling problems in their module having to do with

* waiting for logic to settle when changing between the photo and * temperature sensors. * * ISSUE: Continuous data in ADCC is supposed to sample at some rate * controlled by ADCControl.setSamplingRate. The original Photo * example does not appear to do this. No support has been added. The * implementation of getContinuousData in the current code will sample * as fast as it can. When both Photo and Temp samples are requested * they will alternate producing one sample every 10 ms. */ // OS component abstraction of the analog photo sensor and temperature // sensor with associated A/D support. This code provides an // asynchronous interface to the photo and temperature sensors. One // TimerC timer is used, certain forms of clock use are not compatible // with using a timer. (i.e. the ClockC component) // // It is important to note that the temperature and photo sensors share // hardware and can not be used at the same time. Proper delays are // implemented here. Using ExternalXxxADC.getData will initiate the // appropriate delays prior to sampling data. getData for temperature // and light may both be invoked in any order and at any time. A // correct sample will be signalled by the corresponding dataReady. // // Photo and Temp provide the same interfaces. Exposed interfaces are // ExternalPhotoADC and ExternalPhotoADC as well as PhotoStdControl and // PhotoStdControl. The following routines are the public interface: // // xxxStdControl.init initializes the device // xxxADC.start starts a particular sensor // xxxADC.stop stops a particular sensor, this will also stop // any getContinuousData on that sensor. // xxxADC.getData reads data from a sensor. This may be called in // any order. A dataReady event is signalled // when the data is ready. Temperature and Photo // will wait for each other as needed. // xxxADC.getContinuousData reads data from a sensor and when the // read completes triggers an additional getData. // Continuous data from both sensors will work but // a 10 ms delay will occur between each sample. // Continuous data from a single sensor will run // at a higher sampling rate. // // A timer from TimerC is used to manage the delays required between

// setting up the hardware and reading the data. //includes sensorboard; module PhotoM { provides interface StdControl as PhotoStdControl; provides interface ADC as ExternalPhotoADC; uses { interface ADCControl; interface ADC as InternalPhotoADC; interface StdControl as TimerControl; interface Timer as PhotoTimer; } } implementation { // Logs what the hardware is set up to do. enum { sensorIdle = 0, sensorPhotoStarting, sensorPhotoReady, sensorTempStarting, sensorTempReady, } hardwareStatus; // Logs what a particular sensor is trying to do. When a single // read completes the value reverts to idle. typedef enum { stateIdle = 0, stateReadOnce, stateContinuous, } SensorState_t; SensorState_t photoSensor; SensorState_t tempSensor; // TRUE when waiting for a sample to be read and another sample can // not start. getSample will always be triggered again when this is // true. bool waitingForSample;

command result_t PhotoStdControl.init() { call ADCControl.bindPort(TOS_ADC_PHOTO_PORT, TOSH_ACTUAL_PHOTO_PORT); call TimerControl.init(); atomic photoSensor = stateIdle; dbg(DBG_BOOT, "TEMP initialized.\n"); return call ADCControl.init(); } command result_t PhotoStdControl.start() { atomic photoSensor = stateIdle; TOSH_SET_PHOTO_CTL_PIN(); return SUCCESS; } command result_t PhotoStdControl.stop() { atomic photoSensor = stateIdle; TOSH_CLR_PHOTO_CTL_PIN(); return SUCCESS; } // Gets the next sample. Deals with which sample to get now task void getSample() { TOSH_CLR_TEMP_CTL_PIN(); TOSH_MAKE_TEMP_CTL_INPUT(); TOSH_SET_PHOTO_CTL_PIN(); TOSH_MAKE_PHOTO_CTL_OUTPUT(); call PhotoTimer.stop(); // just in case if (call PhotoTimer.start(TIMER_ONE_SHOT, 10) != SUCCESS) { post getSample(); }; return; }

// After waiting a little we can take a reading event result_t PhotoTimer.fired() {

if (call InternalPhotoADC.getData() == SUCCESS) { // Trigger the read which will post a new sample TOSH_uwait(1000); return SUCCESS; }; return SUCCESS; } async command result_t ExternalPhotoADC.getData() { atomic photoSensor = stateReadOnce; post getSample(); return SUCCESS; } async command result_t ExternalPhotoADC.getContinuousData() { atomic tempSensor = stateContinuous; post getSample(); return SUCCESS; }

default async event result_t ExternalPhotoADC.dataReady(uint16_t data) { return SUCCESS; } async event result_t InternalPhotoADC.dataReady(uint16_t data) { return signal ExternalPhotoADC.dataReady(data); } } Lesson_7—SensorboardApp.h /* * Copyright (c) 2004-2007 Crossbow Technology, Inc. * All rights reserved. * See license.txt file included with the distribution. * * $Id: sensorboardApp.h,v 1.1.2.5 2007/04/26 20:05:01 njain Exp $ */

/* sensorboard.h - hardware specific definitions for the MTS300/310 */ TOSH_ALIAS_PIN(PHOTO_CTL, INT1); TOSH_ALIAS_PIN(TEMP_CTL, INT2); enum { TOSH_ACTUAL_PHOTO_PORT = 1, TOSH_ACTUAL_TEMP_PORT = 1, }; enum { TOS_ADC_PHOTO_PORT = 1, TOS_ADC_TEMP_PORT = 2, };

#define FEATURE_SOUNDER

1

// Define SOUND_STATE_CHANGE one of two ways: // One time sound at test init ==> FALSE // Continuous beeping throughout ==> !sound_state #define SOUND_STATE_CHANGE FALSE //#define SOUND_STATE_CHANGE !sound_state // crossbow sensor board id #define SENSOR_BOARD_ID 0x88 #ifndef PhotoLogCount #define PhotoLogCount #endif

//XTYPE_XTUTORIAL=0x88

8

enum { BYTE_EEPROM_ID = unique("ByteEEPROM"), }; typedef struct XSensorHeader{ uint8_t board_id; uint8_t packet_id; // 3 uint8_t node_id; uint8_t rsvd; }__attribute__ ((packed)) XSensorHeader;

typedef struct PData1 { uint16_t light[PhotoLogCount]; } __attribute__ ((packed)) PData1; typedef struct XDataMsg { XSensorHeader xSensorHeader; union { PData1 datap1; }xData; } __attribute__ ((packed)) XDataMsg; enum { AM_XSXMSG = 0, };


相关文章:
TinyOS-nesC 编程参考手册
TinyOS-nesC 编程参考手册_计算机软件及应用_IT/计算机_专业资料。TinyOS-nesC TinyOS/nesC 编程参考手册 第一部分 序言 阅读本书的前提: 1. 你对于 C/C++/JAVA...
nesC编程迷你教程
负责实现某一个接口的 nesC 组件称之为该接口的提供者,而需要使用该接 口的程序组件,则成为这一组件的使用者。当我们开发一个 nesC 程序的时候, 我们需要首先...
nesC实验报告一
nesC实验报告一_信息与通信_工程科技_专业资料。TinyOS 南昌航空大学实验报告二 O 一六年 3 月 28 日 课程名称:TinyOS 与 nesC 编程 班级: 指导教师评定: ...
一步步教你搭建TinyOS2.1.2开发环境
//tinyprod.net/repos/debian msp430-46 main 执行以下命令完成安装: sudo apt-get update sudo apt-get install msp430-46 nesc tinyos-tools 现在环境就搭建...
安装TinyOS需要六个步骤
nesc-1.2.8b-1.cygwin.i386.rpm(http://www.tinyos.net/dist-1.2.0/tinyo s/windows/nesc-1.2.8b-1.cygwin.i386.rpm) tinyos-tools-1.2.4-2....
关于各种延时
tv_nesc 的值必须小于 109。 nanosleep 相比 sleep 具有另一个优点。与 sleep 相同,nanosleep 调用可以被信 号中断,这是 errno 将被设置为 EINTR 而调用将...
TinyOS课后习题
3、关于 nesC 程序文件组成叙述正确的是___D___。 A 只能是 nc 文件 B 不可以包含 C 语言头文件 C 可以不使用 Makefile 文件 D.程序中的 nc 文件可分...
TinyOS 2.x 入门教程
图 2.11 可视化连接图 2.5 小结 本章简单地介绍了 nesC 的语言和特性。想要了解更详细的内容请参看 tinyos-2.x\doc\nesc 目录下的文档和 http://sourceforge...
无线传感器网络理论—【转载】几种用于WSN的仿真工具
并已有一些 研究职员在 OPNET 上使成为事实对 TinyOS 的 NesC 步伐的仿真. 但要使成为事实无线传 感器收集的仿真,还需要新增能+量模子,而 OPNET 自己彷佛更...
无线传感器网络-定时器设计
2. 使用 C 语言或 nesC 程序编写程序,进行调试、显示结果。 3. 撰写综合设计报告。 指导教师签名: 系主任(或责任教师)签名: 年年 月月 日日 定时器设计 1....
更多相关标签: