Skip to content
Snippets Groups Projects
Commit 3428cedf authored by mikas34's avatar mikas34
Browse files

Updated lab3

parent d9bda886
No related branches found
No related tags found
No related merge requests found
Showing
with 2136 additions and 0 deletions
#ifndef ENERGYLPL_H
#define ENERGYLPL_H
enum {
AM_ENERGYLPL = 6,
group_number = 1,
};
/* The packet to be sent via serial interface */
typedef nx_struct EnergyLPLMsg {
nx_uint32_t RxOn;
nx_uint32_t RxOff;
nx_uint32_t TxOn;
nx_uint32_t TxOff;
} EnergyLPLMsg;
#endif
#include <Timer.h>
#include "EnergyLPL.h"
configuration EnergyLPLAppC {
}
implementation {
components MainC;
components LedsC;
components EnergyLPLC;
components PrintfC, SerialStartC;
components new TimerMilliC() as Timer0;
components PowerCycleP;
components ActiveMessageC;
EnergyLPLC.Boot -> MainC;
EnergyLPLC.Timer0 -> Timer0;
EnergyLPLC.Leds -> LedsC;
EnergyLPLC.DutyCycle -> PowerCycleP;
EnergyLPLC.RadioControl -> ActiveMessageC;
}
#include <Timer.h>
#include "EnergyLPL.h"
module EnergyLPLC {
uses interface Boot;
uses interface Leds;
uses interface Timer<TMilli> as Timer0;
uses interface RadioStats as DutyCycle;
uses interface SplitControl as RadioControl;
/* Add here the needed interfaces to use the serial packets */
}
implementation {
/* Initialize the radio at startup */
event void Boot.booted() {
call Timer0.startPeriodic(1000);
}
event void Timer0.fired(){
call Leds.led1Toggle();
}
event void RadioControl.startDone(error_t err) {}
event void RadioControl.stopDone(error_t err) {}
}
COMPONENT=EnergyLPLAppC
TINYOS_ROOT_DIR?=/courses/TDDI07/tinyos-main
CFLAGS += -I$(TINYOS_ROOT_DIR)/tos/lib/printf
CFLAGS += -DLOW_POWER_LISTENING
CFLAGS += -DLPL_DEF_LOCAL_WAKEUP=1024
CFLAGS += -DLPL_DEF_REMOTE_WAKEUP=1024
CFLAGS += -DDLAY_AFTER_RECEIVE=20
CONTRIBDIR = $(shell pwd)/tos
CFLAGS += -I$(CONTRIBDIR)/chips/cc2420/lpl
CFLAGS += -I$(CONTRIBDIR)/chips/cc2420/interfaces
PFLAGS = -DCC2420_DEF_CHANNEL=26
include $(TINYOS_ROOT_DIR)/Makefile.include
File added
import java.io.*;
import java.util.*;
import java.lang.Math.*;
import net.tinyos.packet.*;
import net.tinyos.util.*;
import net.tinyos.message.*;
public class SerialParser {
public static void main(String args[]) throws IOException {
String source = null;
PacketSource reader;
reader = BuildSource.makePacketSource();
BufferedWriter writer= new BufferedWriter (new FileWriter("mote.csv"));
if (reader == null) {
System.err.println("Invalid packet source (check your MOTECOM environment variable)");
System.exit(2);
}
long sleepTx=0,awakeTx=0,sleepRx=0,awakeRx=0;
float dutyCycleTx=0,dutyCycleRx=0;
int status=0;
//Date and time
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
//For calculating duty cycles
int firstByte = 0;
int secondByte = 0;
int thirdByte = 0;
int fourthByte = 0;
//Indexes
int start=8,offset=4;
System.out.println("SerialParser working");
try {
reader.open(PrintStreamMessenger.err);
writer.write("##,##");
writer.newLine();
writer.write("@Mote Energy");
writer.newLine();
writer.write("DutyCycleRx,DutyCycleTx");
writer.newLine();
for (;;) {
byte[] packet = reader.readPacket();
//Address
//byte st=packet[24];
//status=(int) st & 0xFF;
//writer.write(status+",");
sleepTx=0;awakeTx=0;sleepRx=0;awakeRx=0;
dutyCycleTx=0;dutyCycleRx=0;
//Awake and Sleep
firstByte = 0;
secondByte = 0;
thirdByte = 0;
fourthByte = 0;
firstByte = (0x000000FF & ((int)packet[start]));
secondByte = (0x000000FF & ((int)packet[start+1]));
thirdByte = (0x000000FF & ((int)packet[start+2]));
fourthByte = (0x000000FF & ((int)packet[start+3]));
awakeRx = ((long) (firstByte << 24
| secondByte << 16
| thirdByte << 8
| fourthByte))
& 0xFFFFFFFFL;
firstByte = (0x000000FF & ((int)packet[start+offset]));
secondByte = (0x000000FF & ((int)packet[start+offset+1]));
thirdByte = (0x000000FF & ((int)packet[start+offset+2]));
fourthByte = (0x000000FF & ((int)packet[start+offset+3]));
sleepRx = ((long) (firstByte << 24
| secondByte << 16
| thirdByte << 8
| fourthByte))
& 0xFFFFFFFFL;
firstByte = (0x000000FF & ((int)packet[start+2*offset]));
secondByte = (0x000000FF & ((int)packet[start+2*offset+1]));
thirdByte = (0x000000FF & ((int)packet[start+2*offset+2]));
fourthByte = (0x000000FF & ((int)packet[start+2*offset+3]));
awakeTx = ((long) (firstByte << 24
| secondByte << 16
| thirdByte << 8
| fourthByte))
& 0xFFFFFFFFL;
firstByte = (0x000000FF & ((int)packet[start+3*offset]));
secondByte = (0x000000FF & ((int)packet[start+3*offset+1]));
thirdByte = (0x000000FF & ((int)packet[start+3*offset+2]));
fourthByte = (0x000000FF & ((int)packet[start+3*offset+3]));
sleepTx = ((long) (firstByte << 24
| secondByte << 16
| thirdByte << 8
| fourthByte))
& 0xFFFFFFFFL;
if(awakeTx + sleepTx == 0) dutyCycleTx=110;
else dutyCycleTx=(float)awakeTx/(float)(awakeTx+sleepTx);
if(sleepRx + sleepRx == 0) dutyCycleTx=110;
else dutyCycleRx=(float)awakeRx/(float)(awakeRx+sleepRx);
writer.write(""+dutyCycleRx+",");
writer.write(""+dutyCycleTx);
writer.flush();
if(dutyCycleTx*100 > 100) System.out.println("DutyCycleRx: "+dutyCycleRx*100+"%");
else if(dutyCycleRx*100 > 100) System.out.println("DutyCycleTx: "+dutyCycleTx*100+"%");
else System.out.println("DutyCycleRx: "+dutyCycleRx*100+"% DutyCycleTx: "+dutyCycleTx*100+"%");
writer.newLine();
}
}
catch (IOException e) {
writer.close();
System.err.println("Error on " + reader.getName() + ": " + e);
}
}
}
##,##
@Mote Energy
DutyCycleRx,DutyCycleTx
0.039774675,110.0
0.039732795,110.0
0.039690703,110.0
0.039654743,110.0
0.039619766,110.0
0.039574973,110.0
0.039539643,110.0
0.039504506,110.0
0.039461184,110.0
0.039426465,110.0
0.039391935,110.0
0.039349288,110.0
0.039315164,110.0
0.039281227,110.0
0.039242305,110.0
0.03920295,110.0
0.0391696,110.0
0.039136752,110.0
0.039095286,110.0
0.0390625,110.0
0.03902989,110.0
0.038989365,110.0
0.038957126,110.0
0.038925063,110.0
0.038885146,110.0
0.03885344,110.0
0.03882191,110.0
0.038785648,110.0
0.038748756,110.0
0.038717747,110.0
0.038686905,110.0
0.038648345,110.0
0.038877077,110.0
0.038846057,110.0
0.038815908,110.0
0.038776707,110.0
0.03874619,110.0
0.038715832,110.0
0.038677894,110.0
0.038647864,110.0
0.03861799,110.0
0.038580593,110.0
0.038551044,110.0
0.038521644,110.0
0.03848761,110.0
0.03845316,110.0
0.03842423,110.0
0.038639843,110.0
0.038605858,110.0
0.03857146,110.0
0.03854252,110.0
0.038514018,110.0
0.038719356,110.0
0.03868492,110.0
0.03865599,110.0
0.038627204,110.0
0.038591165,110.0
0.038562678,110.0
0.038534332,110.0
0.038498785,110.0
0.038470734,110.0
0.038442817,110.0
0.038407847,110.0
0.038380124,110.0
0.03835263,110.0
0.03832091,110.0
0.03828842,110.0
0.038261343,110.0
0.038234394,110.0
0.038200412,110.0
0.03817374,110.0
0.038147192,110.0
0.038113657,110.0
0.03808738,110.0
0.038061224,110.0
0.038030483,110.0
0.037999887,110.0
0.03797412,110.0
0.037944686,110.0
0.03791362,110.0
0.037888233,110.0
0.037862964,110.0
0.037830867,110.0
0.037805848,110.0
0.037780944,110.0
0.037749253,110.0
0.037724596,110.0
0.037700046,110.0
0.03789941,110.0
0.03786774,110.0
0.037843037,110.0
0.037818443,110.0
0.03778952,110.0
0.03776056,110.0
0.037736315,110.0
0.037712947,110.0
0.037681434,110.0
0.037657533,110.0
0.037633736,110.0
0.037603363,110.0
0.037579797,110.0
0.03755633,110.0
0.03752633,110.0
0.03750309,110.0
0.037479952,110.0
0.037452683,110.0
0.0374252,110.0
0.037402384,110.0
0.037380237,110.0
0.03735051,110.0
0.037328005,110.0
0.037305597,110.0
0.03727679,110.0
0.037254587,110.0
0.037232485,110.0
0.03720402,110.0
0.03718212,110.0
0.03716031,110.0
0.037134558,110.0
0.037108444,110.0
0.03708693,110.0
0.037065744,110.0
0.03724573,110.0
0.0372196,110.0
0.037198033,110.0
0.037176795,110.0
0.037148874,110.0
0.03712759,110.0
0.0371064,110.0
0.037079033,110.0
0.03705803,110.0
0.037037116,110.0
0.03701006,110.0
0.03698933,110.0
0.036968686,110.0
0.036944386,110.0
0.036919422,110.0
0.03710238,110.0
0.037081674,110.0
0.037057187,110.0
0.03703235,110.0
0.037011914,110.0
0.036991786,110.0
0.036965203,110.0
0.036945026,110.0
0.03692493,110.0
0.036898866,110.0
0.036878943,110.0
0.036859103,110.0
0.036833327,110.0
0.036813658,110.0
0.036794066,110.0
0.036770932,110.0
0.03674716,110.0
0.036727816,110.0
0.03670855,110.0
0.03668343,110.0
0.036664326,110.0
0.036645297,110.0
0.03662045,110.0
0.03660158,110.0
0.036582787,110.0
0.03656016,110.0
0.03653762,110.0
0.03651906,110.0
0.036508627,110.0
0.036677934,110.0
0.03665921,110.0
0.036640562,110.0
0.03661827,110.0
0.03659578,110.0
0.03657736,110.0
0.0365595,110.0
0.03653499,110.0
0.03651679,110.0
0.03649866,110.0
0.03647489,110.0
0.03645691,110.0
0.036438994,110.0
0.036415476,110.0
0.036397707,110.0
0.036380008,110.0
0.036358815,110.0
0.036337297,110.0
0.036319807,110.0
0.03630259,110.0
0.0364661,110.0
0.036444675,110.0
0.036427118,110.0
0.03641023,110.0
0.03638664,110.0
0.036369283,110.0
0.036733985,110.0
0.036716055,110.0
0.03707878,110.0
0.037054777,110.0
0.037160926,110.0
0.037193544,110.0
0.037355628,110.0
0.037336763,110.0
0.03731251,110.0
0.03729379,110.0
0.03727514,110.0
0.03725113,110.0
0.037232623,110.0
0.037214182,110.0
0.03719048,110.0
0.037172113,110.0
0.037340295,110.0
0.03732179,110.0
0.037297998,110.0
0.03727964,110.0
0.037261344,110.0
0.03723785,110.0
0.03721963,110.0
0.03720154,110.0
0.03718037,110.0
0.037158493,110.0
0.037140604,110.0
0.03712278,110.0
0.037099753,110.0
0.03708206,110.0
0.037064433,110.0
0.037041627,110.0
0.03702413,110.0
0.037006695,110.0
0.036985908,110.0
0.03696507,110.0
0.036947824,110.0
0.036931213,110.0
0.036908343,110.0
0.036891285,110.0
0.036874287,110.0
0.0368522,110.0
0.036835328,110.0
0.03681851,110.0
0.036796633,110.0
0.03677994,110.0
0.036763307,110.0
0.036743455,110.0
0.036723424,110.0
0.036706965,110.0
0.036691003,110.0
0.03666916,110.0
0.03665288,110.0
0.036636654,110.0
0.03661545,110.0
0.03659934,110.0
0.036583286,110.0
0.036562275,110.0
0.036546335,110.0
0.036530446,110.0
0.036511473,110.0
0.0364922,110.0
0.036476478,110.0
0.036621172,110.0
0.036602173,110.0
0.036582876,110.0
0.036731612,110.0
0.036873292,110.0
0.036857102,110.0
0.03701006,110.0
0.036989946,110.0
0.036973648,110.0
0.0369574,110.0
0.036936328,110.0
0.03708743,110.0
0.03707108,110.0
0.037055198,110.0
0.037033685,110.0
0.0370175,110.0
0.037001364,110.0
0.03698046,110.0
0.03696444,110.0
0.036948465,110.0
0.036927745,110.0
0.036911882,110.0
0.036896072,110.0
0.0368773,110.0
0.036858242,110.0
0.036994997,110.0
0.036979154,110.0
0.03696043,110.0
0.036941297,110.0
0.036925614,110.0
0.036909983,110.0
0.03688968,110.0
0.036874153,110.0
0.036858674,110.0
0.036838546,110.0
0.036823172,110.0
0.036807843,110.0
0.03678795,110.0
0.036772665,110.0
0.036757488,110.0
0.0367396,110.0
0.036871262,110.0
0.036856003,110.0
0.03684079,110.0
0.036822654,110.0
0.036955144,110.0
0.03693985,110.0
0.0369246,110.0
0.036906395,110.0
0.03688813,110.0
0.03687303,110.0
0.036858484,110.0
0.036838405,110.0
0.036823448,110.0
0.03680854,110.0
0.03678913,110.0
0.03677432,110.0
0.03675955,110.0
0.036740303,110.0
0.036725633,110.0
0.036711004,110.0
0.03669353,110.0
0.036675885,110.0
0.036661398,110.0
0.036647335,110.0
0.036628075,110.0
0.03661372,110.0
0.036599413,110.0
0.03658069,110.0
0.036566474,110.0
0.0365523,110.0
0.03653373,110.0
0.036664423,110.0
0.036650166,110.0
0.03663595,110.0
0.036617365,110.0
0.036751576,110.0
0.036737274,110.0
0.036723014,110.0
0.03670441,110.0
0.036690243,110.0
0.036676113,110.0
0.03665766,110.0
0.03664362,110.0
0.03662962,110.0
0.03661303,110.0
0.036736354,110.0
0.036722284,110.0
0.03670825,110.0
0.036691483,110.0
0.03667455,110.0
0.03666065,110.0
0.036647156,110.0
0.036628667,110.0
0.03661489,110.0
0.036601152,110.0
0.036583174,110.0
0.03656952,110.0
0.03669675,110.0
0.036823623,110.0
0.036807265,110.0
0.03679012,110.0
0.036776274,110.0
0.03676246,110.0
0.03674446,110.0
0.036730733,110.0
0.036717046,110.0
0.03669918,110.0
0.037117615,110.0
0.037099242,110.0
0.037085116,110.0
0.037071027,110.0
0.037052795,110.0
0.037038792,110.0
0.03716671,110.0
0.03715259,110.0
0.037134346,110.0
0.037120305,110.0
0.037106305,110.0
0.0370882,110.0
0.037172228,110.0
0.03734419,110.0
0.03732996,110.0
0.03748887,110.0
0.037577376,110.0
0.037558775,110.0
0.03754433,110.0
0.037529923,110.0
0.03751146,110.0
0.037497137,110.0
0.037614845,110.0
0.03760042,110.0
0.037581965,110.0
0.037567623,110.0
0.037683245,110.0
0.03766881,110.0
0.037650358,110.0
0.037636004,110.0
0.037621684,110.0
0.03760472,110.0
0.0375878,110.0
0.037702307,110.0
0.037820525,110.0
0.03780606,110.0
0.037925616,110.0
0.037907925,110.0
0.037893396,110.0
0.03787891,110.0
0.037860475,110.0
0.03784607,110.0
0.0378317,110.0
0.037813403,110.0
0.037799116,110.0
0.037784867,110.0
0.03776812,110.0
0.03775122,110.0
0.03773709,110.0
0.037723344,110.0
0.037705008,110.0
0.037690993,110.0
0.037677016,110.0
0.03765916,110.0
0.03777957,110.0
0.03776553,110.0
0.03775153,110.0
0.037733667,110.0
0.03798178,110.0
0.03796755,110.0
0.03795336,110.0
0.03793533,110.0
0.037921216,110.0
0.037907142,110.0
0.037890725,110.0
0.037873957,110.0
0.03807697,110.0
0.038112774,110.0
0.038227882,110.0
0.038211014,110.0
0.03819409,110.0
0.03817981,110.0
0.03816478,110.0
0.03814627,110.0
0.038132105,110.0
0.038117975,110.0
0.03823581,110.0
0.038218956,110.0
0.03820477,110.0
0.038190957,110.0
0.038426224,110.0
0.03853697,110.0
0.038519505,110.0
0.038505033,110.0
0.038490593,110.0
0.038472433,110.0
0.038588252,110.0
0.038573764,110.0
0.03855965,110.0
0.038541157,110.0
0.038526785,110.0
0.038512446,110.0
0.038494416,110.0
0.03848015,110.0
0.03871007,110.0
0.038695574,110.0
0.038679074,110.0
0.038661756,110.0
0.038647372,110.0
0.038633026,110.0
0.038615026,110.0
0.038600754,110.0
0.03858652,110.0
0.038568642,110.0
0.038684238,110.0
0.03873231,110.0
0.03878026,110.0
0.038763594,110.0
0.038746685,110.0
0.038732395,110.0
0.03871828,110.0
0.03870027,110.0
0.03868609,110.0
0.03867194,110.0
0.038654197,110.0
0.03864012,110.0
0.038741894,110.0
0.038849447,110.0
0.038833246,110.0
0.03881615,110.0
0.038801964,110.0
0.038787812,110.0
0.0387701,110.0
0.038756017,110.0
0.038867433,110.0
0.038853597,110.0
0.038835566,110.0
0.038821474,110.0
0.038807414,110.0
0.038789827,110.0
0.03877584,110.0
0.038761884,110.0
0.038744412,110.0
0.03873053,110.0
0.038716678,110.0
0.038700636,110.0
0.03868436,110.0
0.038670614,110.0
0.038657036,110.0
0.038639694,110.0
0.038626045,110.0
0.03861243,110.0
0.038595337,110.0
0.03858179,110.0
0.038568273,110.0
0.038551293,110.0
0.03865311,110.0
0.038639557,110.0
0.038626038,110.0
0.03873089,110.0
0.03871382,110.0
0.03870026,110.0
0.038686734,110.0
0.038791347,110.0
0.03877397,110.0
0.038874473,110.0
0.03886081,110.0
0.03884532,110.0
0.038828976,110.0
0.03881541,110.0
0.038801875,110.0
0.038784936,110.0
0.038771465,110.0
0.038758025,110.0
0.038741197,110.0
0.038727824,110.0
0.03871448,110.0
0.03869898,110.0
0.03868334,110.0
0.038670093,110.0
0.03865718,110.0
0.038640294,110.0
0.038627136,110.0
0.038614012,110.0
0.038597535,110.0
0.038584474,110.0
0.03857144,110.0
0.038555067,110.0
0.038542096,110.0
0.038529158,110.0
0.038514134,110.0
0.038498886,110.0
0.038486037,110.0
0.038473345,110.0
0.038457077,110.0
0.038444318,110.0
0.03843159,110.0
0.03841555,110.0
0.038402878,110.0
0.038390234,110.0
0.038374297,110.0
0.038361713,110.0
0.03834916,110.0
0.038334634,110.0
0.038319718,110.0
0.03830725,110.0
0.03829481,110.0
0.0382791,110.0
0.03826672,110.0
0.03825436,110.0
0.03823875,110.0
0.03822645,110.0
0.03821418,110.0
0.038199753,110.0
0.038185354,110.0
0.03817317,110.0
0.03815925,110.0
0.03814453,110.0
0.03813243,110.0
0.03812035,110.0
0.038105052,110.0
0.03809303,110.0
0.03808104,110.0
0.038065832,110.0
0.038053893,110.0
0.03804198,110.0
0.03802802,110.0
0.038013928,110.0
0.038002096,110.0
0.037990578,110.0
0.037975293,110.0
0.037963543,110.0
0.037951816,110.0
0.037936907,110.0
0.037925232,110.0
0.037913587,110.0
0.037898768,110.0
0.03788717,110.0
0.0378756,110.0
0.03786205,110.0
0.03784829,110.0
0.037836794,110.0
0.037825447,110.0
0.03781071,110.0
0.037799295,110.0
0.0377879,110.0
0.03777337,110.0
0.037762027,110.0
0.03775071,110.0
0.037736267,110.0
0.037724998,110.0
0.037713755,110.0
0.03770064,110.0
0.037687153,110.0
0.037675984,110.0
0.03766484,110.0
0.03765059,110.0
0.037639495,110.0
0.037628423,110.0
0.037614252,110.0
0.03760323,110.0
0.03759223,110.0
0.03757918,110.0
0.037566155,110.0
0.03755523,110.0
0.037542645,110.0
0.037529312,110.0
0.037518457,110.0
0.037507623,110.0
0.037493724,110.0
0.037482936,110.0
0.037472174,110.0
0.037458353,110.0
0.03744764,110.0
0.037436944,110.0
0.0374243,110.0
0.037411533,110.0
0.03740091,110.0
0.03739057,110.0
0.03737667,110.0
0.03736611,110.0
0.037355576,110.0
0.037342012,110.0
0.037331525,110.0
0.037321053,110.0
0.03730757,110.0
0.03729715,110.0
0.037286744,110.0
0.037274458,110.0
0.03726197,110.0
0.037251636,110.0
0.037241433,110.0
0.03722801,110.0
0.03721774,110.0
0.03720749,110.0
0.037194256,110.0
0.037184052,110.0
0.037173867,110.0
0.037160706,110.0
0.03715056,110.0
0.03714044,110.0
0.037128534,110.0
0.037116278,110.0
0.037106223,110.0
0.037096184,110.0
0.03708319,110.0
0.037073195,110.0
0.037063222,110.0
0.0370503,110.0
0.037040368,110.0
0.037030455,110.0
0.03701859,110.0
0.037006747,110.0
0.036996897,110.0
0.036985464,110.0
0.036973324,110.0
0.036963537,110.0
0.03695377,110.0
0.036941078,110.0
0.03693135,110.0
0.036921643,110.0
0.03690902,110.0
0.036899354,110.0
0.036889706,110.0
0.0368782,110.0
0.03686657,110.0
0.03685698,110.0
0.03684766,110.0
0.036834948,110.0
0.03691845,110.0
0.036908846,110.0
0.03689937,110.0
0.0368868,110.0
0.036877256,110.0
0.036867727,110.0
0.036950715,110.0
0.03693825,110.0
0.036928695,110.0
0.036919154,110.0
0.036906756,110.0
0.036897257,110.0
0.036887776,110.0
0.036875475,110.0
0.036865998,110.0
0.036856573,110.0
0.03684547,110.0
0.036833968,110.0
0.0368246,110.0
0.036815252,110.0
0.036803067,110.0
0.036793757,110.0
0.036784466,110.0
0.036772344,110.0
0.03676309,110.0
0.036844686,110.0
0.03683538,110.0
0.036823258,110.0
0.03681399,110.0
0.03680474,110.0
0.03679369,110.0
0.036782525,110.0
0.03677333,110.0
0.036764394,110.0
0.03675218,110.0
0.036743037,110.0
0.036733914,110.0
0.036722,110.0
0.036712915,110.0
0.036703844,110.0
0.036691993,110.0
0.036776166,110.0
0.03676706,110.0
0.036757976,110.0
0.03674612,110.0
0.036737066,110.0
0.036728032,110.0
0.03671716,110.0
0.036706313,110.0
0.0367954,110.0
0.036786344,110.0
0.03677454,110.0
0.03676552,110.0
0.03675652,110.0
0.036745727,110.0
0.036734886,110.0
0.03672594,110.0
0.036716424,110.0
0.03670442,110.0
0.036695525,110.0
0.036686644,110.0
0.036675036,110.0
0.036666192,110.0
0.03675052,110.0
0.036741626,110.0
0.03673001,110.0
0.036721148,110.0
0.0367123,110.0
0.036700744,110.0
0.03669193,110.0
0.036683135,110.0
0.036672574,110.0
0.036661968,110.0
0.036653224,110.0
0.036643922,110.0
0.03663217,110.0
0.036623474,110.0
0.036614794,110.0
0.03660343,110.0
0.036594786,110.0
0.036586154,110.0
0.036574848,110.0
\ No newline at end of file
/*
* RadioStats provides the on and off-time of the radio in 32 bits.
* The counters are updated every millisecond. The counters can be
* reset if the reach their maximum.
*/
interface RadioStats
{
command uint32_t getOff();
command uint32_t getOn();
command uint8_t getStatus();
command void reset();
}
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* @author David Moss
* @author Tony O'Donovan
*/
#ifndef DEFAULTLPL_H
#define DEFAULTLPL_H
/**
* Low Power Listening Send States
*/
typedef enum {
S_LPL_NOT_SENDING, // DEFAULT
S_LPL_FIRST_MESSAGE, // 1. Sending the first message
S_LPL_SENDING, // 2. Sending all other messages
S_LPL_CLEAN_UP, // 3. Clean up the transmission
} lpl_sendstate_t;
/**
* This is a measured value of the time in ms the radio is actually on
* We round this up to err on the side of better performance ratios
* This includes the acknowledgement wait period and backoffs,
* which can typically be much longer than the transmission.
*
* Measured by Tony O'Donovan
*/
#ifndef DUTY_ON_TIME
#define DUTY_ON_TIME 11
#endif
/**
* The maximum number of CCA checks performed on each wakeup.
* If there are too few, the receiver may wake up between messages
* and not detect the transmitter.
*
* The on-time had to increase from the original version to allow multiple
* transmitters to co-exist. This is due to using ack's, which then requires us
* to extend the backoff period. In networks that transmit frequently, possibly
* with multiple transmitters, this power scheme makes sense.
*
* In networks that transmit very infrequently or without multiple transmitters,
* it makes more sense to go with no acks and no backoffs and make the
* receive check as short as possible.
*/
#ifndef MAX_LPL_CCA_CHECKS
#if defined(PLATFORM_TELOSB) || defined(PLATFORM_TMOTE)
#define MAX_LPL_CCA_CHECKS 400
#else
#define MAX_LPL_CCA_CHECKS 400
#endif
#endif
/**
* The minimum number of samples that must be taken in CC2420DutyCycleP
* that show the channel is not clear before a detection event is issued
*/
#ifndef MIN_SAMPLES_BEFORE_DETECT
#define MIN_SAMPLES_BEFORE_DETECT 3
#endif
#endif
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420
* @author David Moss
*/
#include "DefaultLpl.h"
#warning "*** USING DEFAULT LOW POWER COMMUNICATIONS ***"
configuration DefaultLplC {
provides {
interface LowPowerListening;
interface Send;
interface Receive;
interface SplitControl;
interface State as SendState;
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
interface SplitControl as SubControl;
}
}
implementation {
components MainC,
DefaultLplP,
PowerCycleC,
CC2420RadioC,
CC2420CsmaC,
CC2420TransmitC,
CC2420PacketC,
RandomC,
new StateC() as SendStateC,
new TimerMilliC() as OffTimerC,
new TimerMilliC() as SendDoneTimerC,
SystemLowPowerListeningC,
LedsC;
LowPowerListening = DefaultLplP;
Send = DefaultLplP;
Receive = DefaultLplP;
SplitControl = PowerCycleC;
SendState = SendStateC;
SubControl = DefaultLplP.SubControl;
SubReceive = DefaultLplP.SubReceive;
SubSend = DefaultLplP.SubSend;
MainC.SoftwareInit -> DefaultLplP;
DefaultLplP.SplitControlState -> PowerCycleC.SplitControlState;
DefaultLplP.RadioPowerState -> PowerCycleC.RadioPowerState;
DefaultLplP.SendState -> SendStateC;
DefaultLplP.OffTimer -> OffTimerC;
DefaultLplP.SendDoneTimer -> SendDoneTimerC;
DefaultLplP.PowerCycle -> PowerCycleC;
DefaultLplP.Resend -> CC2420TransmitC;
DefaultLplP.PacketAcknowledgements -> CC2420RadioC;
DefaultLplP.CC2420PacketBody -> CC2420PacketC;
DefaultLplP.RadioBackoff -> CC2420CsmaC;
DefaultLplP.Random -> RandomC;
DefaultLplP.Leds -> LedsC;
DefaultLplP.SystemLowPowerListening -> SystemLowPowerListeningC;
}
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420. This component is responsible for
* delivery of an LPL packet, and for turning off the radio when the radio
* has run out of tasks.
*
* The PowerCycle component is responsible for duty cycling the radio
* and performing receive detections.
*
* @author David Moss
*/
#include "Lpl.h"
#include "DefaultLpl.h"
#include "AM.h"
module DefaultLplP {
provides {
interface Init;
interface LowPowerListening;
interface Send;
interface Receive;
}
uses {
interface Send as SubSend;
interface CC2420Transmit as Resend;
interface RadioBackoff;
interface Receive as SubReceive;
interface SplitControl as SubControl;
interface PowerCycle;
interface CC2420PacketBody;
interface PacketAcknowledgements;
interface State as SendState;
interface State as RadioPowerState;
interface State as SplitControlState;
interface Timer<TMilli> as OffTimer;
interface Timer<TMilli> as SendDoneTimer;
interface Random;
interface Leds;
interface SystemLowPowerListening;
}
}
implementation {
/** The message currently being sent */
norace message_t *currentSendMsg;
/** The length of the current send message */
uint8_t currentSendLen;
/** TRUE if the radio is duty cycling and not always on */
bool dutyCycling;
/**
* Radio Power State
*/
enum {
S_OFF, // off by default
S_TURNING_ON,
S_ON,
S_TURNING_OFF,
};
/**
* Send States
*/
enum {
S_IDLE,
S_SENDING,
};
enum {
ONE_MESSAGE = 0,
};
/***************** Prototypes ***************/
task void send();
task void resend();
task void startRadio();
task void stopRadio();
void initializeSend();
void startOffTimer();
/***************** Init Commands ***************/
command error_t Init.init() {
dutyCycling = FALSE;
return SUCCESS;
}
/***************** LowPowerListening Commands ***************/
/**
* Set this this node's radio wakeup interval, in milliseconds.
* Once every interval, the node will sleep and perform an Rx check
* on the radio. Setting the wakeup interval to 0 will keep the radio
* always on.
*
* @param intervalMs the length of this node's wakeup interval, in [ms]
*/
command void LowPowerListening.setLocalWakeupInterval(uint16_t intervalMs) {
call PowerCycle.setSleepInterval(intervalMs);
}
/**
* @return the local node's wakeup interval, in [ms]
*/
command uint16_t LowPowerListening.getLocalWakeupInterval() {
return call PowerCycle.getSleepInterval();
}
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
* with the specified wakeup interval.
* @param msg Pointer to the message that will be sent
* @param intervalMs The receiving node's wakeup interval, in [ms]
*/
command void LowPowerListening.setRemoteWakeupInterval(message_t *msg,
uint16_t intervalMs) {
(call CC2420PacketBody.getMetadata(msg))->rxInterval = intervalMs;
}
/**
* @return the destination node's wakeup interval configured in this message
*/
command uint16_t LowPowerListening.getRemoteWakeupInterval(message_t *msg) {
return (call CC2420PacketBody.getMetadata(msg))->rxInterval;
}
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
* DSN that does not change for every copy of the message
* sent out. For messages that are not acknowledged, such as
* a broadcast address message, the receiving end does not
* signal receive() more than once for that message.
*/
command error_t Send.send(message_t *msg, uint8_t len) {
if(call SplitControlState.getState() == S_OFF) {
// Everything is off right now, start SplitControl and try again
return EOFF;
}
if(call SendState.requestState(S_LPL_SENDING) == SUCCESS) {
currentSendMsg = msg;
currentSendLen = len;
// In case our off timer is running...
call OffTimer.stop();
call SendDoneTimer.stop();
if(call RadioPowerState.getState() == S_ON) {
initializeSend();
return SUCCESS;
} else {
post startRadio();
}
return SUCCESS;
}
return EBUSY;
}
command error_t Send.cancel(message_t *msg) {
if(currentSendMsg == msg) {
call SendState.toIdle();
call SendDoneTimer.stop();
startOffTimer();
return call SubSend.cancel(msg);
}
return FAIL;
}
command uint8_t Send.maxPayloadLength() {
return call SubSend.maxPayloadLength();
}
command void *Send.getPayload(message_t* msg, uint8_t len) {
return call SubSend.getPayload(msg, len);
}
/***************** RadioBackoff Events ****************/
async event void RadioBackoff.requestInitialBackoff(message_t *msg) {
if((call CC2420PacketBody.getMetadata(msg))->rxInterval
> ONE_MESSAGE) {
call RadioBackoff.setInitialBackoff( call Random.rand16()
% (0x4 * CC2420_BACKOFF_PERIOD) + CC2420_MIN_BACKOFF);
}
}
async event void RadioBackoff.requestCongestionBackoff(message_t *msg) {
if((call CC2420PacketBody.getMetadata(msg))->rxInterval
> ONE_MESSAGE) {
call RadioBackoff.setCongestionBackoff( call Random.rand16()
% (0x3 * CC2420_BACKOFF_PERIOD) + CC2420_MIN_BACKOFF);
}
}
async event void RadioBackoff.requestCca(message_t *msg) {
}
/***************** DutyCycle Events ***************/
/**
* A transmitter was detected. You must now take action to
* turn the radio off when the transaction is complete.
*/
event void PowerCycle.detected() {
// At this point, the duty cycling has been disabled temporary
// and it will be this component's job to turn the radio back off
// Wait long enough to see if we actually receive a packet, which is
// just a little longer in case there is more than one lpl transmitter on
// the channel.
startOffTimer();
}
/***************** SubControl Events ***************/
event void SubControl.startDone(error_t error) {
if(!error) {
call RadioPowerState.forceState(S_ON);
if(call SendState.getState() == S_LPL_FIRST_MESSAGE
|| call SendState.getState() == S_LPL_SENDING) {
initializeSend();
}
}
}
event void SubControl.stopDone(error_t error) {
if(!error) {
if(call SendState.getState() == S_LPL_FIRST_MESSAGE
|| call SendState.getState() == S_LPL_SENDING) {
// We're in the middle of sending a message; start the radio back up
post startRadio();
} else {
call OffTimer.stop();
call SendDoneTimer.stop();
}
}
}
/***************** SubSend Events ***************/
event void SubSend.sendDone(message_t* msg, error_t error) {
switch(call SendState.getState()) {
case S_LPL_SENDING:
if(call SendDoneTimer.isRunning()) {
if(!call PacketAcknowledgements.wasAcked(msg)) {
post resend();
return;
}
}
break;
case S_LPL_CLEAN_UP:
/**
* We include this state so upper layers can't send a different message
* before the last message gets done sending
*/
break;
default:
break;
}
call SendState.toIdle();
call SendDoneTimer.stop();
startOffTimer();
signal Send.sendDone(msg, error);
}
/***************** SubReceive Events ***************/
/**
* If the received message is new, we signal the receive event and
* start the off timer. If the last message we received had the same
* DSN as this message, then the chances are pretty good
* that this message should be ignored, especially if the destination address
* as the broadcast address
*/
event message_t *SubReceive.receive(message_t* msg, void* payload,
uint8_t len) {
startOffTimer();
return signal Receive.receive(msg, payload, len);
}
/***************** Timer Events ****************/
event void OffTimer.fired() {
/*
* Only stop the radio if the radio is supposed to be off permanently
* or if the duty cycle is on and our sleep interval is not 0
*/
if(call SplitControlState.getState() == S_OFF
|| (call PowerCycle.getSleepInterval() > 0
&& call SplitControlState.getState() != S_OFF
&& call SendState.getState() == S_LPL_NOT_SENDING)) {
post stopRadio();
}
}
/**
* When this timer is running, that means we're sending repeating messages
* to a node that is receive check duty cycling.
*/
event void SendDoneTimer.fired() {
if(call SendState.getState() == S_LPL_SENDING) {
// The next time SubSend.sendDone is signaled, send is complete.
call SendState.forceState(S_LPL_CLEAN_UP);
}
}
/***************** Resend Events ****************/
/**
* Signal that a message has been sent
*
* @param p_msg message to send.
* @param error notifaction of how the operation went.
*/
async event void Resend.sendDone( message_t* p_msg, error_t error ) {
// This is actually caught by SubSend.sendDone
}
/***************** Tasks ***************/
task void send() {
if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {
post send();
}
}
task void resend() {
if(call Resend.resend(TRUE) != SUCCESS) {
post resend();
}
}
task void startRadio() {
if(call SubControl.start() != SUCCESS) {
post startRadio();
}
}
task void stopRadio() {
if(call SendState.getState() == S_LPL_NOT_SENDING) {
if(call SubControl.stop() != SUCCESS) {
post stopRadio();
}
}
}
/***************** Functions ***************/
void initializeSend() {
if(call LowPowerListening.getRemoteWakeupInterval(currentSendMsg)
> ONE_MESSAGE) {
if((call CC2420PacketBody.getHeader(currentSendMsg))->dest == IEEE154_BROADCAST_ADDR) {
call PacketAcknowledgements.noAck(currentSendMsg);
} else {
// Send it repetitively within our transmit window
call PacketAcknowledgements.requestAck(currentSendMsg);
}
call SendDoneTimer.startOneShot(
call LowPowerListening.getRemoteWakeupInterval(currentSendMsg) + 20);
}
post send();
}
void startOffTimer() {
call OffTimer.startOneShot(call SystemLowPowerListening.getDelayAfterReceive());
}
}
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Use this component to duty cycle the radio. When a message is heard,
* disable DutyCycling.
*
* @author David Moss dmm@rincon.com
*/
configuration PowerCycleC {
provides {
interface PowerCycle;
interface SplitControl;
interface State as SplitControlState;
interface State as RadioPowerState;
}
}
implementation {
components PowerCycleP,
CC2420TransmitC,
CC2420ReceiveC,
CC2420CsmaC,
LedsC,
new StateC() as RadioPowerStateC,
new StateC() as SplitControlStateC,
new TimerMilliC() as OnTimerC,
new TimerMilliC() as DutyCycleTimerC,
new TimerMilliC() as CheckTimerC;
#if defined(LOW_POWER_LISTENING) || defined(ACK_LOW_POWER_LISTENING)
components DefaultLplC as LplC;
#else
components DummyLplC as LplC;
#endif
PowerCycle = PowerCycleP;
SplitControl = PowerCycleP;
SplitControlState = SplitControlStateC;
RadioPowerState = RadioPowerStateC;
PowerCycleP.EnergyIndicator -> CC2420TransmitC.EnergyIndicator;
PowerCycleP.ByteIndicator -> CC2420TransmitC.ByteIndicator;
PowerCycleP.PacketIndicator -> CC2420ReceiveC.PacketIndicator;
PowerCycleP.SubControl -> CC2420CsmaC;
PowerCycleP.SendState -> LplC;
PowerCycleP.RadioPowerState -> RadioPowerStateC;
PowerCycleP.SplitControlState -> SplitControlStateC;
PowerCycleP.OnTimer -> OnTimerC;
PowerCycleP.Leds -> LedsC;
PowerCycleP.DutyCycleTimer -> DutyCycleTimerC;
}
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Module to duty cycle the radio on and off, performing CCA receive checks.
* When a carrier is sensed, this will leave the radio on. It is then up
* to higher layers to turn the radio off again. Once the radio is turned
* off, this module will automatically continue duty cycling and looking for
* a modulated signal.
*
* Suggested TODO's:
* > TransmitC and ReceiveC provide Energy, Byte, and Packet indicators.
* Tap into those to add more detection levels and granularity. Only let
* the radio turn off when we're not actively receiving bytes. Right now
* the packet indicator is a little backwards.
* > Let one component be in charge of maintaining State information about
* the power of the radio, probably lower in the stack.
* > Wire SplitControl, Send, and Receive through this component. Make it
* responsible for packet-level detections and being completely responsible
* for controlling the power of the radio without the use of upper layers
* > Remove unnecessary State components and Timers.
*
* @author David Moss
*/
#include "DefaultLpl.h"
module PowerCycleP {
provides {
interface PowerCycle;
interface SplitControl;
interface RadioStats;
}
uses {
interface Timer<TMilli> as OnTimer;
interface SplitControl as SubControl;
interface State as RadioPowerState;
interface State as SplitControlState;
interface State as SendState;
interface Leds;
interface ReceiveIndicator as EnergyIndicator;
interface ReceiveIndicator as ByteIndicator;
interface ReceiveIndicator as PacketIndicator;
interface Timer<TMilli> as DutyCycleTimer;
}
}
implementation {
uint32_t checktime=0,sleepTime=0;
uint8_t TimerStarted=0;
uint8_t statusLPL=0;//sleep=0,1,
/** The current period of the duty cycle, equivalent of wakeup interval */
uint16_t sleepInterval = LPL_DEF_LOCAL_WAKEUP;
/** The number of times the CCA has been sampled in this wakeup period */
uint16_t ccaChecks;
/**
* Radio Power, Check State, and Duty Cycling State
*/
enum {
S_OFF, // off by default
S_TURNING_ON,
S_ON,
S_TURNING_OFF,
};
/***************** Prototypes ****************/
task void stopRadio();
task void startRadio();
task void getCca();
bool finishSplitControlRequests();
bool isDutyCycling();
/***************** PowerCycle Commands ****************/
/**
* Set the sleep interval, in binary milliseconds
* @param sleepIntervalMs the sleep interval in [ms]
*/
command void PowerCycle.setSleepInterval(uint16_t sleepIntervalMs) {
if (!sleepInterval && sleepIntervalMs) {
// We were always on, now lets duty cycle
post stopRadio(); // Might want to delay turning off the radio
}
sleepInterval = sleepIntervalMs;
if(sleepInterval == 0 && call SplitControlState.isState(S_ON)) {
/*
* Leave the radio on permanently if sleepInterval == 0 and the radio is
* supposed to be enabled
*/
if(call RadioPowerState.getState() == S_OFF) {
call SubControl.start();
}
}
}
/**
* @return the sleep interval in [ms]
*/
command uint16_t PowerCycle.getSleepInterval() {
return sleepInterval;
}
/***************** SplitControl Commands ****************/
command error_t SplitControl.start() {
if(call SplitControlState.isState(S_ON)) {
return EALREADY;
} else if(call SplitControlState.isState(S_TURNING_ON)) {
return SUCCESS;
} else if(!call SplitControlState.isState(S_OFF)) {
return EBUSY;
}
// Radio was off, now has been told to turn on or duty cycle.
call SplitControlState.forceState(S_TURNING_ON);
if(sleepInterval > 0) {
// Begin duty cycling
post stopRadio();
return SUCCESS;
} else {
post startRadio();
return SUCCESS;
}
}
command error_t SplitControl.stop() {
if(call SplitControlState.isState(S_OFF)) {
return EALREADY;
} else if(call SplitControlState.isState(S_TURNING_OFF)) {
return SUCCESS;
} else if(!call SplitControlState.isState(S_ON)) {
return EBUSY;
}
call SplitControlState.forceState(S_TURNING_OFF);
post stopRadio();
return SUCCESS;
}
/***************** Timer Events ****************/
event void OnTimer.fired() {
if(isDutyCycling()) {
if(call RadioPowerState.getState() == S_OFF) {
ccaChecks = 0;
/*
* Turn on the radio only after the uC is fully awake. ATmega128's
* have this issue when running on an external crystal.
*/
post getCca();
} else {
// Someone else turned on the radio, try again in awhile
call OnTimer.startOneShot(sleepInterval);
}
}
}
event void DutyCycleTimer.fired()
{
if(call RadioPowerState.getState() == S_OFF){
sleepTime++;
statusLPL=0;
}
else {
checktime++;
statusLPL=1;
}
}
command uint32_t RadioStats.getOff()
{
return sleepTime;
}
command uint32_t RadioStats.getOn()
{
return checktime;
}
command uint8_t RadioStats.getStatus(){ return statusLPL;}
command void RadioStats.reset(){
checktime=0;
sleepTime=0;
}
/***************** SubControl Events ****************/
event void SubControl.startDone(error_t error) {
if(TimerStarted==0)
{
call DutyCycleTimer.startPeriodic(1);
TimerStarted=1;
}
call RadioPowerState.forceState(S_ON);
//call Leds.led2On();
if(finishSplitControlRequests()) {
return;
} else if(isDutyCycling()) {
post getCca();
}
}
event void SubControl.stopDone(error_t error) {
call RadioPowerState.forceState(S_OFF);
//call Leds.led2Off();
if(finishSplitControlRequests()) {
return;
} else if(isDutyCycling()) {
call OnTimer.startOneShot(sleepInterval);
}
}
/***************** Tasks ****************/
task void stopRadio() {
error_t error = call SubControl.stop();
if(error != SUCCESS) {
// Already stopped?
finishSplitControlRequests();
call OnTimer.startOneShot(sleepInterval);
}
}
task void startRadio() {
if(call SubControl.start() != SUCCESS) {
post startRadio();
}
}
task void getCca() {
uint8_t detects = 0;
if(isDutyCycling()) {
ccaChecks++;
if(ccaChecks == 1) {
// Microcontroller is ready, turn on the radio and sample a few times
post startRadio();
return;
}
atomic {
for( ; ccaChecks < MAX_LPL_CCA_CHECKS && call SendState.isIdle(); ccaChecks++) {
if(call PacketIndicator.isReceiving()) {
signal PowerCycle.detected();
return;
}
if(call EnergyIndicator.isReceiving()) {
detects++;
if(detects > MIN_SAMPLES_BEFORE_DETECT) {
signal PowerCycle.detected();
return;
}
// Leave the radio on for upper layers to perform some transaction
}
}
}
if(call SendState.isIdle()) {
post stopRadio();
}
}
}
/**
* @return TRUE if the radio should be actively duty cycling
*/
bool isDutyCycling() {
return sleepInterval > 0 && call SplitControlState.isState(S_ON);
}
/**
* @return TRUE if we successfully handled a SplitControl request
*/
bool finishSplitControlRequests() {
if(call SplitControlState.isState(S_TURNING_OFF)) {
call SplitControlState.forceState(S_OFF);
signal SplitControl.stopDone(SUCCESS);
return TRUE;
} else if(call SplitControlState.isState(S_TURNING_ON)) {
// Starting while we're duty cycling first turns off the radio
call SplitControlState.forceState(S_ON);
signal SplitControl.startDone(SUCCESS);
return TRUE;
}
return FALSE;
}
/**************** Defaults ****************/
default event void PowerCycle.detected() {
}
default event void SplitControl.startDone(error_t error) {
}
default event void SplitControl.stopDone(error_t error) {
}
}
ARCHITECTURE
=======================================================
The default LPL implementation uses a packet train with acknowledgements
enabled, shortened backoffs, and a spinning energy checking loop.
The default strategy can be improved by implementing a different architecture.
Right now the architecture looks like this:
+----------------------------------+
| DefaultLplP | -> To lower level Send
| Responsible for retransmissions | -> To lower level SplitControl
| and turning the radio off when | <- From lower level Receive
| done, or on when starting to |
| transmit |
+----------------------------------+
| PowerCycleP |
| Responsible for performing | -> To lower level SplitControl
| receive checks and leaving the |
| radio on |
+----------------------------------+
I think the architecture should be changed. If you're interested in doing work
in this area, there's lots of development and research to be done.
First, take a look at tinyos-2.x-contrib/wustl/upma. The architecture of the
CC2420 stack there is implemented to define a low-level abstraction layer
which separates radio-specific functionality from radio-independent
functionality. This is nice. By providing certain interfaces from the
radio-dependant functionality, it makes it easier to maintain MAC layer
stuff independent of the radio. And that includes LPL.
One of the things that radio stack uses is an Alarm instead of a spinning
task/while loop. Whereas the implementation here uses a static number of
loops to detect if energy is on the channel, we would be better able
to achieve the smallest radio asynchronous receive check on-time by using an
alarm. After all, the radio only has to be on to span the quiet gaps in a
transmitter's transmission, and we know approximately the duration of those
quiet gaps based on the backoff period, which the stack defines.
I recommend we redo some of the LPL architecture to look more like this:
+----------------------------------+
| DefaultLplP |
| Responsible for retransmissions |
+----------------------------------+
| | | (Send, Receive, SplitControl goes through PowerCycle)
+----------------------------------+
| PowerCycleP |
| Responsible for managing radio | -> To lower level Send
| on/off power, and telling | -> To lower level SplitControl
| PacketDetectP when to start/stop | <- From lower level Receive
| its job |
+----------------------------------+
| PacketDetectP |
| Responsible for detecting | <- EnergyIndicator
| energy, bytes, and/or packets. | <- ByteIndicator
| Notify PowerCycle when packets | <- PacketIndicator
| are detected |
+----------------------------------+
This is pretty radio independent.
OTHER LOW POWER LISTENING STRATEGIES
=============================================================
Other low power listening layers can be implemented as well:
* Continuous modulation / No Acknowledgements:
> Allows the receiver to achieve the lowest possible receive check
on time. It's shown to be several times more efficient on the receive
check than the default. This is a radio-dependent LPL strategy
and the CC2420 can acheive it by putting some transmit register into
test mode where it continually retransmits the contents of the TXFIFO.
The CRC of the packet must be uploaded into the TXFIFO because it won't
be calculated by the CC2420. Not sure if the preamble and sync bytes
need to be uploaded as well. The transmitter takes a hit because it
cannot receive acks in the middle of its packet train. But since
the receiver's energy consumption is so low, it's possible to increase
the number of receive checks in order to lower the duration of the
transmission.
> This strategy would be a good match for networks that must get data
through quickly when there is data, but doesn't see too many
transmissions in any given geographical area of the network. Also
a good strategy where your transmitters have more power.
* 802.15.4/ZigBee End Node:
> Queue up packets to Send to a particular destination until that node
checks in at some random time. Use fields in the ack frame to let the
node know that packets are available. Good match for networks where one
node has access to line power and other nodes are on batteries.
* Low throughput acknowledgement LPL:
> Just like the default, only it uses the ByteIndicator to turn off
the radio as soon as it stops receiving bytes and no packet was
received. Able to get a much shorter receive check at the expense
of decreased probability that you'll receive messages in a congested
network.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment