Title: Lab4
1Lab4
- Objectives
- Learn to read light sensor data from sensor board
- Learn to transmit a message containing the sensed
data - through Mote serial port (UART) connected
directly to the programming board
2Required Hardware and PC Setup
- Two MICA Motes standard editions of MICA2
(MPR4x0) or MICAz (MPR2600) - One sensor or data acquisition board MDA100,
MTS300 or MTS310 - One gateway board MIB510, MIB520, or MIB600 and
the associated hardware (cables, power supply)
for each - A Windows PC with MoteWorks installed
3MyApp Application Review
- Under the directory /MoteWorks/apps/tutorials/less
on_ 2 - The Makefile and Makefile.component are exactly
the same as the MyApp of lesson_1.
4About MyApp
- What does MyApp do?
- a simple sensing application that samples the
light sensor (photodetector) on a sensor board,
packetizes the data, and sends the data back to
the base station. - How does it differ from the application in
lesson_1 ? - Take light readings using sensors boards
- Use the Mote serial port (UART) to send sensor
data to the base station - Blink the green LED when the sensor is sampled
- Blink the yellow LED when the sensor data message
is successfully sent to the base station
5Sensor Application MyApp_Sensor
- Whats new?
- The sensorboardsApp.h file
- What is it used for?
- Define packet structure
- Defines the XSensor header
- Defines the sensor data payload
- So you can understand what the bytes mean in a
serial data stream - Defines the default values for critical fields
- SENSOR_BOARD_ID
- Tags the packet so XServe can identify what
application sent it - Sensor data packets are put into the proper
database table or flat file by XServe
6MyApp
- Steps
- Makefile
- Makefile.component
- Top-level application configuration
- Top-level module
- Compile app and flash Motes
- nesC Auto documentation
7MyApp Makefile.component
- Specify the sensorboard in the Makefile.component
file - For example, the Makefile.component for MyApp is
- What does this do?
- Tells the nesC compiler to link in all the TinyOS
components (drivers) required to access the
sensors on the MTS310 sensorboard. - Drivers for the MTS310 sensorboard are located in
the /MoteWorks/tos/sensorboards/mts310 folder. - NOTE There are drivers for other sensorboards
located in under /MoteWorks/tos/sensorboards.
COMPONENTMyApp SENSORBOARDmts310
Note well need to use SENSORBOARDmda100cb
8Review MyApp
- Steps
- Makefile
- Makefile.component
- Top-level application configuration
- Top-level module
- Compile app and flash Motes
- nesC Auto documentation
9/MoteWorks/apps/tutorials/lesson_2/MyApp.nc
Configuration Sampling the Light Sensor
Include a header file
- 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 -gt TimerC.StdControl
- Main.StdControl -gt MyAppM.StdControl
- Main.StdControl -gt Comm.Control
-
- MyAppM.Timer -gt TimerC.Timerunique("Timer")
- MyAppM.Leds -gt LedsC.Leds
- MyAppM.PhotoControl -gt Photo.PhotoStdControl
NEW! The Photo component is used to actuate the
sensorboard photo sensor device.
NEW! The GenericComm component is used to send
messages over the serial port or radio.
10MyApp.nc Configuration Sampling the Light
Sensor
- 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 -gt TimerC.StdControl
- Main.StdControl -gt MyAppM.StdControl
- Main.StdControl -gt Comm.Control
-
- MyAppM.Timer -gt TimerC.Timerunique("Timer")
- MyAppM.Leds -gt LedsC.Leds
- MyAppM.PhotoControl -gt Photo.PhotoStdControl
The Photo component implements the StdControl
interface for turning on and off the light sensor
and the ADC interface for sampling the sensor
value through the hardware ADC port.
11MyApp.nc Configuration Sampling the Light
Sensor
- 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 -gt TimerC.StdControl
- Main.StdControl -gt MyAppM.StdControl
- Main.StdControl -gt Comm.Control
-
- MyAppM.Timer -gt TimerC.Timerunique("Timer")
- MyAppM.Leds -gt LedsC.Leds
- MyAppM.PhotoControl -gt Photo.PhotoStdControl
- MyAppM.PhotoControl (StdControl interface) to the
Photo.PhotoStdControl (StdControl interface for
the light sensor) - The MyAppM.Light (ADC interface) to the
- Photo.ExternalPhotoADC (ADC interface for
light sensor).
12MyApp.nc Configuration Sampling the Light
Sensor
- 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 -gt TimerC.StdControl
- Main.StdControl -gt MyAppM.StdControl
- Main.StdControl -gt Comm.Control
-
- MyAppM.Timer -gt TimerC.Timerunique("Timer")
- MyAppM.Leds -gt LedsC.Leds
- MyAppM.PhotoControl -gt Photo.PhotoStdControl
- This wires the XSensor channel of GenericComm
into the applications send interface.
13Review MyApp
- Steps
- Makefile
- Makefile.component
- Top-level application configuration
- Top-level module
- Compile app and flash Motes
- nesC Auto documentation
14Top Level Module
- Located in MoteWorks/apps/tutorials/lesson_2/MyApp
M.nc - How does this module differ from
MoteWorks/apps/tutorials/lesson_1/MyAppM.nc? - It adds the functionality of sampling the light
sensor when the timer fires - Then a sensor message is sent through the Motes
serial (UART) port when the sampling is complete.
15nesC Keywords Implementation
Basic implementation keywords Basic implementation keywords
call Execute a command
signal Execute an event
post Put a task on the execution queue
task A function to be executed in the background
includes Include a header file
Support for automatic prevention of race conditions Support for automatic prevention of race conditions
async For code that is reachable from at least one interrupt
atomic For a block of code that runs interrupted to prevent race conditions
norace Eliminates warnings of race conditions nesC detected
16MyAppM.nc Specification
- Hardware specific definitions for the MTS300/310.
- Located in the application directory
- 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
-
17MyAppM.nc Implementation
- implementation
- bool sending_packet FALSE
- TOS_Msg msg_buffer
- XDataMsg pack
-
- /
- Initialize the component.
-
- _at_return Always returns ltcodegtSUCCESSlt/codegt
- /
- 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-gtxSensorHeader.board_id
SENSOR_BOARD_ID - pack-gtxSensorHeader.packet_id 2
- pack-gtxSensorHeader.node_id
TOS_LOCAL_ADDRESS
18nesC Keywords Implementation
Basic implementation keywords Basic implementation keywords
call Execute a command
signal Execute an event
post Put a task on the execution queue
task A function to be executed in the background
includes Include a header file
Support for automatic prevention of race conditions Support for automatic prevention of race conditions
async For code that is reachable from at least one interrupt
atomic For a block of code that runs interrupted to prevent race conditions
norace Eliminates warnings of race conditions nesC detected
19atomic Keyword (Review)
- atomic keyword is used to denote a block of code
that runs uninterrupted (interrupts disabled) - Prevents race conditions
- When should it be used?
- Required to update global variables that are
referenced in async event handlers - Must use atomic block in all other functions and
tasks where variable is referenced - nesC compiler will generate warning messages for
global variables that need atomic blocks - Example
-
SensorAppM.nc44 warning non-atomic accesses
to shared variable voltage
20nesC Interface -- ADC
- interface ADC
- async command result_t getData()
- async command result_t getContinuousData()
- async event result_t dataReady(uint16_t data)
- The ADC interface is specified with two commands
- getData
- getContinuousData
- and one event
- dataReady
- What to do to sample the sensor?
- call the getData command
- This will start a process of sampling the light
sensor through the processor hardware ADC
interface - At some later time this process will complete and
receive the current light sensor value through
the dataReady event
21Sample Sensor and Call Back with Value
- event result_t Timer.fired()
-
- call Leds.redToggle()
- call PhotoControl.start()
- call Light.getData()
-
- async event result_t Light.dataReady(uint16_t
data) - atomic pack-gtxData.datap1.light data
- atomic pack-gtxData.datap1.vref 417 // a
dummy 3V reference voltage, 1252352/3000 417 - post SendData()
- call Leds.yellowToggle()
1
2
3
- In Timer.fired() event function, we first turn on
the light sensor by calling the start() command
through the StdControl interface. The red LED
will blink (heartbeat) when this happens. - Next we call the getData() command through the
ADC interface to start the process of sampling
the current value. - At some time in the near future when the sampling
has completed, we receive a callback in the form
of a dataReady() event.
22Sample Sensor and Call Back with Value
- event result_t Timer.fired()
-
- call Leds.redToggle()
- call PhotoControl.start()
- call Light.getData()
-
- async event result_t Light.dataReady(uint16_t
data) - atomic pack-gtxData.datap1.light data
- atomic pack-gtxData.datap1.vref 417 // a
dummy 3V reference voltage, 1252352/3000 417 - post SendData()
- call Leds.yellowToggle()
5
4
- The dataReady() event passes the 16-bit (10
significant bits) photodetector value that we
store in our message packet. - The last thing we do is to post a task (a
split-phase operation) to send a message
containing the sensor data and fire the yellow LED
23nesC Keywords Implementation
Basic implementation keywords Basic implementation keywords
call Execute a command
signal Execute an event
post Put a task on the execution queue
task A function to be executed in the background
includes Include a header file
Support for automatic prevention of race conditions Support for automatic prevention of race conditions
async For code that is reachable from at least one interrupt
atomic For a block of code that runs interrupted to prevent race conditions
norace Eliminates warnings of race conditions nesC detected
24Split-Phase -- Request Done Sequence
- Non-blocking commands initiate an operation
- Continue/idle
- Event indicates completion at some future time
Component1
Component2
commandA call Comp2.goCmdX //continue return
SUCCESS
goCmdX post task1() return SUCCESS
Task1 //do stuff signal cmdXDone() return
SUCCESS
Event handler
event cmdXDone //process result return SUCCESS
TOS Scheduler
25When to Use Split-Phase
- Variable duration processes
- Hardware I/O operations
- e.g., ADC start conversion gt Data Ready
- Slow devices
- e.g., Flash memory, Write buffer gt Done
- Asynchronous or Complex Processes
- Send a message to communications stack and
continue with operations until sendDone
26Sending a Message Packet GenericComm
- How to send a packet of data to the outside
world? - Use the TinyOS communication component named
GenericComm. - GenericComm is able to send packets in two ways
- The UART port or
- Over the radio
- How is that specified?
- Through destination node address
- Reserved node addresses
- Broadcast 0xFFFF
- UART Channel 0x007E
- Otherwise send directly to a specific node ID in
its RF neighborhood
27MoteWorks/apps/tutorials/lesson_2/MyApp.nc
Configuration Revisited
- implementation
- components Main, MyAppM, TimerC, LedsC, Photo,
GenericComm as Comm - Main.StdControl -gt TimerC.StdControl
- Main.StdControl -gt MyAppM.StdControl
- Main.StdControl -gt Comm.Control
-
- MyAppM.SendMsg -gt Comm.SendMsgAM_XSXMSG
- The GenericComm (aliased as Comm) is connected
through its Comm.Control (StdControl) interface - The MyAppM module connects to one instance of the
Comm.SendMsg interface. - The AM_XSXMSG identifies the active message type.
- It is used to distinguish between multiple
messages you may wish to send.
28nesC Interface -- SendMsg
- interface SendMsg
-
- command result_t send(uint16_t address, uint8_t
length, TOS_MsgPtr msg) - event result_t sendDone(TOS_MsgPtr msg,
result_t success)
- The SendMsg interface specifies one command
- Send
- and one event
- sendDone
- To send a message call the send command with the
correct parameters - A sendDone event is received after the message
has been sent
29nesC Interface -- SendMsg
- interface SendMsg
-
- command result_t send(uint16_t address, uint8_t
length, TOS_MsgPtr msg) - event result_t sendDone(TOS_MsgPtr msg,
result_t success)
- Each message that is sent using the SendMsg
interface is defined by a data structure named
TOS_Msg
30nesC Data Structure -- TOSMsg
- typedef struct TOS_Msg
-
- / The following fields are transmitted/received
on the radio. / - uint16_t addr
- uint8_t type
- uint8_t group
- uint8_t length
- int8_t dataTOSH_DATA_LENGTH
-
- typedef TOS_Msg TOS_MsgPtr
- addr the destination address
- type the active message type (for this
application it is AM_XSXMSG) - group group id specified during programming
- length the payload length
- data variable length payload area (sensor data)
31MoteWorks/apps/tutorials/lesson_2/MyAppM.nc
Application Data Payload
- command result_t StdControl.init()
-
- // Initialize the message packet with default
values - atomic
- pack (XDataMsg )(msg_buffer.data)
- pack-gtxSensorHeader.board_id
SENSOR_BOARD_ID - pack-gtxSensorHeader.node_id
TOS_LOCAL_ADDRESS - pack-gtxSensorHeader.rsvd 0
-
- The data region in the TOS_Msg is where we place
our application specific payload. - The code excerpt above is from the
MoteWorks/apps/tutorials/lesson_2/MyAppM.nc
module that shows how we initialize the payload
area of the TOS_Msg for our specific sensor
application
32MoteWorks/apps/tutorials/lesson_2/MyAppM.nc
Application Data Payload
Notice first how the sendData task calls the stop
command for the light sensor component. This is
done in order to save power when we are not using
the sensor.
- 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(XDataM
sg),msg_buffer) ! SUCCESS) - sending_packet FALSE
-
- event result_t SendMsg.sendDone(TOS_MsgPtr msg,
result_t success) - call Leds.greenToggle()
- atomic sending_packet FALSE
If we are currently in the process of sending a
message (sending_packet TRUE), we just return.
This means the sendDone event has yet to be
called and we must wait.
33MoteWorks/apps/tutorials/lesson_2/MyAppM.nc
Application Data Payload
- 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(XDataM
sg),msg_buffer) ! SUCCESS) - sending_packet FALSE
-
- event result_t SendMsg.sendDone(TOS_MsgPtr msg,
result_t success) - call Leds.greenToggle()
- atomic sending_packet FALSE
We call the SendMsg.send command passing the
destination node address, in this case
TOS_UART_ADDR and a pointer to the actual message
packet we wish to send.
34MoteWorks/apps/tutorials/lesson_2/MyAppM.nc
Application Data Payload
- 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(XDataM
sg),msg_buffer) ! SUCCESS) - sending_packet FALSE
-
- event result_t SendMsg.sendDone(TOS_MsgPtr msg,
result_t success) - call Leds.greenToggle()
- atomic sending_packet FALSE
Finally the SendMsg.sendDone event is called
notifying us the packet has been sent. We are now
ready to start the whole process over again the
next time the timer fires.
35Review MyApp
- Steps
- Makefile
- Makefile.component
- Top-level application configuration
- Top-level module
- Compile app and flash Motes
- nesC Auto documentation lab
36MyApp Compile and Install Program
- Compile the MyApp sensor application
- Install program to (flash) a mote
- Watch the LED pattern. What is happening?
- You should see the red, green and yellow LEDs
blinking every second.
LED color Indication
Red 1 second timer event fired
Yellow Light sensor has been sampled
Green Sensor message has been sent back to base station
37nesC Auto documentation
- Follow steps stated in Lab 1
38What you need to do?
- Finish Lab4 (posted in HuskyCT)