Some usefull tips for TinyOS

Makefile

             COMPONENT=wsnAppC
             include $(MAKERULES)
The first line introduces the configuration file, the second line is invariant.

Compiling and downloading

Use this command to compile your program and to download into telosB.
            make telosb install

Writing on PC using serial port

  1. You must use the component SerialPrintfC in your configuration file:
  2.        components SerialPrintfC
  3. Add the following line in your Makefile
  4.    PFLAGS+= -I$(TOSDIR)/lib/printf
  5. Include in your module the files: stdio.h and string.h
  6. You can now use the printf instruction
  7.               printf(%d\r\n", val); 
  8. In the PC side, you need a serial port tool with 115200 as the baud rate

Reading the sensor

We are using the sensor on the board TelosB
  1. In the configuration file add:
  2.             components new SensirionSht11C( ) as TempC ; 
  3. Define the Read interafce in the module
  4.               uses interface Read <uint16_t>; 
  5. In the configuration use the linking of your Read to the Temperature interface of the TempC component:
  6.      App.Read  -> TempC.Temperature; 
  7. To initiate the reading
  8.      call Read.read( ); 
  9. To read the value you must wait the event Read.readDone et get the value.
  10.      event void Read.readDone(error_t result, uint16_t val)
                  {
                        if (result == SUCCESS) val .... 
    Note: Temperature in degree can be calculated as :
                  double temp = (-39.6+0.01*val);
                  uint8_t temp_int = temp; 
    And with temp declared as uint16_t :
                  printf("Temper = %d.%d\r\n", temp_int, (temp-temp_int)*100+0.5); 
    For the humidity sensor you can use the formula:
         H = -2.0468 + val*(0.0367- 1.5966e-6 * val);

Transmiting/Receiving a packet

  1. Create the payload of the packet in a header file. For example in mote2mote.h file, add:
  2.      typedef nx_struct MyMsg_t { 
                        nx_uint8_t NodeID;
                        nx_uint8_t Data;
                  } MyMsg_t; 
  3. You need the following components:
  4.                 components ActiveMessageC;
                    components new AMSenderC(AM_RADIO);
                    components new AMReceiverC(AM_RADIO);
    Note: you can add a constant in the mote2mote.h file:
                    enum{
                        AM_RADIO = 6; // Active Message type of packet
                        }
    This can define the type of the packet. You receive the packet of the same type that you had sent.
  5. You need the following linking
  6.         App.Packet -> AMSenderC;
            App.AMPacket -> AMSenderC;
            App.AMSend -> AMSenderC;
            App.AMControl -> ActiveMessageC;
            App.Receive -> AMReceiverC; 
  7. In the module you use the following interfaces
  8.         interface Packet;
            interface AMPacket;
            interface AMSend;
            interface SplitControl as AMControl;
            interface Receive; 
  9. In the boot event, turn on the radio
  10.         call AMControl.start ( );
  11. In the event done, check if it is done correctly, if not re-trun on the radio:
  12.         event void AMControl.startDone(error_t error){
                if (error != SUCCESS) call AMControl.start();
            } 
  13. To send a message you need first to fill the payload:
    1. Define the pointer pointing into the payload:
    2.   MyMsg * mesg; 
    3. Initialize the pointer
    4.  
                 message_t  pkt;
                 mesg = call Packet.getPayload(& pkt, sizeof(MyMsg_t)); 
    5. Fill the payload
    6.            mesg->NodeID = TOS_NODE_ID;
                 mesg->Data = val; 
  14. Initialize a transmission:
    1. Define the packet, which is the non-formatted pointer to the payload:
    2.            message_t _packet;
    3. Ask to send the packet
    4.             if (call AMSend.send(AM_BROADCAST_ADDR, &_packet, sizeof(MyMsg_t)) == SUCCESS)
                  {
                      you can do something here
                  }
    5. When the packet is sent, you receive an event:
    6.             event void AMSend.sendDone(message_t *msg, error_t error)
                  {
                      you can do something
                  }
  15. When a packet is received by radio, it create an event:
    1. Defining a pointer to the payload of the recieved message :
    2.            MyMsg_t * incomingPacket;
    3. Receiving the message
    4.             event message_t * Receive.receive(message_t *msg, void *payload, uint8_t len)
                  {
                      incomingPacket = (MyMsg_t *)payload;
                      data = incomingPacket->Data;
                      ....

You can initialize the variable TOS_NODE_ID when you downloading the program in the mote:
            make telosb install.1 bsl,/dev/ttyUSB0 // the id will be 1
            make telosb install.2 bsl,/dev/ttyUSB1 // the id will be 2
            make telosb install.5 bsl,/dev/ttyUSB0 // the id will be 5