hi all.

THE EXAMPLE: 
i have 4 motes: 0,1,3,4 (these are their TOS_NODE_ID)
Inside them i have basically the same application that use a single collection 
with AREA_ID as colllection id BUT:
node 0 and 1 have a enum inside them like this:
        AREA_ID=0
node 3 and 4 have 
        AREA_ID=1

(for every node: i change the AREA_ID, i recompile and finally i deploy)

Node 0 and 2 will act as root of the collection service.
Node 1 and 3 will measure the ambient temperature and send it the the leader 
of their respective area (using the collection sender)
so node 1 will send its data to node 0 and
node 4 to node 3

This is (my) exptected behavior.

THE PROBLEM: 
but this case sometimes work and sometimes not. both "temperature" nodes sent 
their data (connecting them to the pc i can see their printf )
node 0 and 2 indeed, sometimes both thei receive the data, sometimes only one 
of the two.

INFO
i'm using the tinyos 2 from CVS
4 tmotesky motes
i attach the files of the application

ANSWER?!
am i missing something about the collection protocol?
what can i check to understand what is failing?
why sometimes work and sometimes not?


thanks to all who will read this help request. 
regards, Mauro
/**
 * Test per provare vari nodi con diverse collection con differenti id nella stessa rete
 */
#include "printf.h"

enum{
	AREA_ID= 0 ,
	TEMPERATURE_CHECK_INTERVAL=3000
};


configuration NullAppC{}
implementation {
  components MainC, NullC, LedsC;
  components new TimerMilliC() as TimerC;
  components CollectionC;
  components ActiveMessageC;
  components new CollectionSenderC(AREA_ID);
  components new TemperatureSensorC();

  MainC.Boot <- NullC;
  NullC.Leds->LedsC;
  NullC.TemperatureTimer->TimerC;
  NullC.TemperatureRead->TemperatureSensorC;
  NullC.CollectionControl->CollectionC;
  NullC.RadioControl->ActiveMessageC;
  NullC.RootControl->CollectionC;
  NullC.TemperatureSend->CollectionSenderC;
  NullC.TemperatureReceive->CollectionC.Receive[AREA_ID];
}

#include "printf.h"
#define boolToString(bool) ((bool) ? "TRUE" : "FALSE") 

	typedef nx_struct TemperatureMsg{
		nx_uint16_t sender_id;
		nx_uint16_t value;
	}TemperatureMsg_t;


module NullC
{
  uses interface Boot;
  uses interface SplitControl as RadioControl;
  uses interface StdControl as CollectionControl;
  uses interface Read<uint16_t> as TemperatureRead;
  uses interface Send as TemperatureSend;
  uses interface Leds;
  uses interface Timer<TMilli> as TemperatureTimer;
  uses interface RootControl;
  uses interface Receive as TemperatureReceive;
}
implementation
{

  message_t packet;
  bool sendBusy = FALSE;
    
  event void Boot.booted() {
    if(call RadioControl.start()!=SUCCESS){
		call Leds.led0On();
    	printf("NODE %d\t| ERROR | radio start\n",TOS_NODE_ID);
    	printfflush();
    }
	printf("NODE %d\t| \n",TOS_NODE_ID);
	printfflush();
  }
  
  event void RadioControl.startDone(error_t OK){
  	if(OK!=SUCCESS){
 		call Leds.led0On();
    	printf("NODE %d\t| ERRORE | radio start\n",TOS_NODE_ID);
    	printfflush();  		
		call RadioControl.start();
    	return;
  	}
	printf("NODE %d\t| radio ok. collection start\n",TOS_NODE_ID);
	printfflush();
  	call CollectionControl.start();
  	switch(TOS_NODE_ID){
  	case 0:
  	case 2:
  		//leaders simply catch arriving data
  		call RootControl.setRoot();
		printf("NODE %d\t| AREA_ID: %d, IS_ROOT: %s \n",TOS_NODE_ID,AREA_ID,boolToString(call RootControl.isRoot()));
		printfflush();
  		break;
  	case 1:
  	case 3:
  		//sensor nodes
  		call RootControl.unsetRoot();
  		call TemperatureTimer.startPeriodic(TEMPERATURE_CHECK_INTERVAL);
		printf("NODE %d\t| AREA_ID: %d, IS_ROOT: %s \n",TOS_NODE_ID,AREA_ID,boolToString(call RootControl.isRoot()));
		printfflush();
  		break;
  	default:
		call Leds.led0On();
		printf("NODE %d\t| ERRORE | node id out of range\n",TOS_NODE_ID);
		printfflush();
		return;
  	}
  }
  
  event void RadioControl.stopDone(error_t OK){  }
  
  event void TemperatureTimer.fired(){
		printf("NODE %d\t| timer fired\n",TOS_NODE_ID);
		printfflush();  	
		call TemperatureRead.read();
  }
  
  event void TemperatureRead.readDone(error_t OK, uint16_t temperature){
  	if(OK!=SUCCESS){
		call Leds.led0On();
		printf("NODE %d\t| ERRORE | temperature read\n",TOS_NODE_ID);
    	printfflush();  	
    	return;
  	}
	printf("NODE %d\t| temperature: %d\n",TOS_NODE_ID, temperature);
	printfflush();  	
	if(!sendBusy){
		TemperatureMsg_t * msg =(TemperatureMsg_t*)call TemperatureSend.getPayload(&packet, sizeof(TemperatureMsg_t));
		msg->sender_id=TOS_NODE_ID;
		msg->value = temperature;
		
		if (call TemperatureSend.send(&packet, sizeof(TemperatureMsg_t)) != SUCCESS){ 
			call Leds.led0On();
			printf("NODE %d\t| ERRORE | temperature read\n",TOS_NODE_ID);
			printfflush();  	
			return;
		}else {
			printf("NODE %d\t| temperature send\n",TOS_NODE_ID);
			printfflush();  	
			sendBusy = TRUE;
		}
	}else{
		call Leds.led0On();
		printf("NODE %d\t| ERRORE | send blocked: radio busy\n",TOS_NODE_ID);
    	printfflush();  	
    	return;
	}
  }
  
  event void TemperatureSend.sendDone(message_t* m, error_t OK) {
  	if(OK!=SUCCESS){
		call Leds.led0On();
		printf("NODE %d\t| ERRORE | temperature send\n",TOS_NODE_ID);
    	printfflush();  	
    	return;
  	}
  	call Leds.led2Toggle();
  	sendBusy=FALSE;
	printf("NODE %d\t| temperature send done\n",TOS_NODE_ID);
	printfflush();  	
  }

  event message_t* TemperatureReceive.receive(message_t* msg, void* payload, uint8_t len) {
    TemperatureMsg_t* tempmsg = (TemperatureMsg_t*)payload;  	
  	if(len!=sizeof(TemperatureMsg_t)){
		call Leds.led0On();
		printf("NODE %d\t| ERRORE | out of size message\n",TOS_NODE_ID);
    	printfflush();  	
    	return msg;
  	}
	printf("NODE %d\t| received temperature: %d from node: %d\n",TOS_NODE_ID,tempmsg->value,tempmsg->sender_id);
	printfflush();    
    call Leds.led1Toggle();    
    return msg;
  }
}
/**
 * This is a wrapper of the real temperature sensor telosb platform
 * 
 */
generic configuration TemperatureSensorC(){
	provides{
		interface Read<uint16_t>;
	}
}implementation{
	components new SensirionSht11C() as RealTemperatureC;
	components new TemperatureSensorP();
	
	TemperatureSensorP.RealRead->RealTemperatureC.Temperature;
	Read=TemperatureSensorP.Read;

}
/**
 * This module does a conversion of the temperatures arriving from the SensirioSht11 board to celsius degree.
 */
generic module TemperatureSensorP(){
	provides{
		interface Read<uint16_t> as Read;
	}uses{
		interface Read<uint16_t> as RealRead;
	}
}implementation{
	command error_t Read.read(){
		return call RealRead.read();
	}
	
	event void RealRead.readDone(error_t OK, uint16_t temperature){
	 	uint16_t tempCelsius=0;
	 	if(OK==SUCCESS)
			//temperature returned by sensirion must be converted by a formula to get celsius	. Vedi:  http://www.eecs.iu-bremen.de/wiki/index.php/TinyOS	
	 		tempCelsius=-40 + 0.01 * temperature;
		signal Read.readDone(OK, tempCelsius);
	}
}
_______________________________________________
Tinyos-help mailing list
[email protected]
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help

Reply via email to