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

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, };


相关文章:
nesc
nesC 编程语言在无线网络传感器设计中的应 用 2010 年 07 月 02 日 12:00 维库网 1 nosC 语言结构 nesC 是 C 语言的扩展,精通 C 语言的程序员掌握这种...
世界货币大全
21罗马尼亚列伊 罗马尼亚列伊(罗马尼亚语: Leuromacircnesc) ,复数为 Leiromacircnesc,ISO4217代码:RON,数字代码:946,是 罗马尼亚官方货币,辅币名为巴尼(Bani) ,1...
TinyOS-nesC 编程参考手册
58页 1财富值 NesC学习经验总结 3页 免费 tinyos编程教材 21页 免费如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。 ...
关于各种延时
tv_nesc 的值必须小于 109。 nanosleep 相比 sleep 具有另一个优点。与 sleep 相同,nanosleep 调用可以被信 号中断,这是 errno 将被设置为 EINTR 而调用将...
国外常用标准
国外常用标准: 〖美国标准〗 ANSI、 ASTM、 ASME、 API、 AGMA、 ABMA、 ASQC、 ASA、 AMS、AISI、EIA、MIL、MS、NEC、NEMA、NESC、NBS、SAE、IEEE 等 〖...
PAL制式和NTSC制式的定义及区别
PAL制式和NTSC制式的定义及区别_IT/计算机_专业资料。PAL制式和NTSC制式的定义及区别 NTSC 制式视频监控系统与 PAL 制式视频监控系统的区别对于 NTSC 制式与 PAL ...
nesC编程迷你教程
负责实现某一个接口的 nesC 组件称之为该接口的提供者,而需要使用该接 口的程序组件,则成为这一组件的使用者。当我们开发一个 nesC 程序的时候, 我们需要首先...
TinyOS系统与nesC程序设计课内实验指导书
TinyOS 系统与 nesC 程序设计课内实验指导书 一、 课内实验项目一览表 序号 实验项目 学时 类型 每组 人数 1 基本教学要求熟悉 TinyOS 安装过程, 了解系统环境 ...
经验总结
NesC学习经验总结 3页 免费 cognos 10培训的经验总结 20页 5财富值 电脑维修店经验 15页 免费 PLC的梯形图编程经验总结 5页 免费 项目开发经验总结 4页 免费如...
全美公认的世外桃源 鲍登学院校园生活攻略
女子篮球非常强大,已经拿过很多次 NESCAC 的冠军,女子曲棍球在 06-07 赛季拿过 NESCAC 冠军。 学生在校内运动项目中占主导地位, 百分之七十的学生参加学生组织...
更多相关标签:
nesc语言 | nesc教程 | nesc.cn | ntsc | nescafe | 会声会影x9 | 信息工程大学 | tinyos |