Removed directory; contents are now under contikiprojects

This commit is contained in:
adamdunkels 2010-02-02 19:56:31 +00:00
parent 53d93eb83f
commit b8892a7be0
16 changed files with 0 additions and 1741 deletions

View file

@ -1,55 +0,0 @@
ifndef CONTIKI
CONTIKI = ../..
endif
zip: all jar
rm -rf contiki-energest-demo
mkdir contiki-energest-demo
cp nodeid/*.ihex contiki-energest-demo
cp energest-demo.ihex contiki-energest-demo
cp README contiki-energest-demo
cp -r handouts contiki-energest-demo/
mkdir contiki-energest-demo/tools
cp -r $(CONTIKI)/tools/sky contiki-energest-demo/tools
cp dist/*.jar contiki-energest-demo
cp Makefile.contiki-energest-demo contiki-energest-demo/Makefile
zip -r contiki-energest-demo.zip contiki-energest-demo
all: burn-nodeids javaapp energest-demo.ihex
upload: energest-demo.upload
burn-nodeids:
(cd nodeid; $(MAKE))
rundemo: zip
cd contiki-energest-demo; make rundemo
jar:
ant jar
javaapp:
ant compile
# Ensure that ./contiki-conf.h is included
CFLAGS+=-I.
ifndef TARGET
TARGET=sky
endif
ifdef UPDATE
CFLAGS += -DUPDATE_TICKS=CLOCK_SECOND*$(UPDATE)
else
CFLAGS += -DUPDATE_TICKS=CLOCK_SECOND
endif
ifdef CHANNEL
CFLAGS += -DRF_CHANNEL=$(CHANNEL)
else
CFLAGS += -DRF_CHANNEL=20
endif
include $(CONTIKI)/Makefile.include

View file

@ -1,13 +0,0 @@
CONTIKI=.
-include tools/sky/Makefile
upload-node-%:
$(MAKE) sky-reset burn-nodeid-$*.upload
$(MAKE) sky-reset
sleep 10
$(MAKE) sky-reset energest-demo.upload
upload-sink: upload-node-41
rundemo:
java -jar energest.jar /dev/com${firstword $(CMOTES)}

View file

@ -1,95 +0,0 @@
This directory contains the compiled code for the Contiki energy
estimation demonstration for ACM SenSys 2007. More information is
available in the handouts/ directory and at the Contiki website:
http://www.sics.se/contiki/
* INSTALLATION INSTRUCTIONS
Cygwin and Java (JRE) needs to be installed. The demo has been tested
on Microsoft Windows, but probably works under Linux too.
You need between two and eight Tmote Sky boards to run the demo: one
sink and between one and seven nodes. The nodes are numbered from 42
to 48, and 41 is the sink node.
Step 1: Unpack the zip file
unzip contiki-energest-demo.zip
Step 2: Change directory to the demo directory
cd contiki-energest-demo
Step 3: Connect the sink node to the PC. Remove all other Tmote Sky
nodes from the PC.
Step 4: Upload Contiki to the sink:
make upload-sink
Step 5: Remove the sink node from the PC.
Step 6: Connect one of the non-sink nodes to the PC
Step 7: Upload Contiki to the node:
make upload-node-42
This takes some time. The red LED should be lit when the
uploading is finished. We have found that in some cases brand
new Tmote Sky boards seem to cause a problem with Contiki and
the red LED does not light up. If so, try to wait a few
minutes (~10 minutes) with the Tmote Sky either inserted in
the PC, or powered with batteries. If the red LED goes on
after these minutes, repeat the "make upload-node-XX" to
upload Contiki again.
Step 8: Remove the Tmote Sky from the PC.
Step 9: Insert batteries into the Tmote Sky. The red LED should light
up.
Step 10: Repeat step 6 to step 9 for all non-sink nodes. Replace "make
upload-node-42" with "make upload-node-43", "make
upload-node-44", and so on.
Step 11: Insert the sink node to the PC again.
Step 12: Run the Java program:
make rundemo
NOTE: this uses the first Tmote Sky it finds as a
sink. Therefore, make sure that only one Tmote Sky (the sink) is
inserted.
Step 13: Push the "user" button on the Tmote Skys and watch their
power consumption go up and down.
* DEMO DESCRIPTION
Contiki continuously estimates the energy consumption of the
system. In this demonstration, seven Tmote Sky nodes, running Contiki,
estimates their energy consumption and send their power to a sink
node. The sink node is connected to the PC, and reports the nodes'
power to a Java program. The Java program shows the nodes' power
consumption for the last second.
When pushing the button on the nodes, they cycle through seven states
as below. This is reflected by their power consumption, as shown in
the Java program. The different states are:
* Red LED: sending one packet per second
* Green LED: radio listen 1% duty cycle
* Green, red LEDs: radio listen 10% duty cycle
* Blue LED: radio listen 100%
* Blue, red LEDs: radio listen 10%, CPU low-power mode disabled
* Blue, green LEDs: sending data 1.2 kilobytes/second
* Blue, green, red LEDs: sending data 12 kilobytes/second
When sending data, the radio is turned on for a while before the
transmission to check if it is possible to send the packet. This is
the reason why energy is spent on radio listening even when the nodes
are only sending data.

View file

@ -1,66 +0,0 @@
<?xml version="1.0"?>
<project name="Energy Assessment Demo" default="help" basedir=".">
<property name="java" location="src"/>
<property name="build" location="build"/>
<property name="lib" location="lib"/>
<property name="dist" location="dist"/>
<property name="args" value=""/>
<target name="init">
<tstamp/>
</target>
<target name="help">
<echo>
Examples:
> ant run -Dargs="com1"
Starts demo application listening on COM1 and tracking the first node.
</echo>
</target>
<target name="compile" depends="init">
<mkdir dir="${build}"/>
<javac srcdir="${java}" destdir="${build}" debug="on">
<classpath>
<pathelement path="."/>
<pathelement path="${lib}/jfreechart-1.0.6.jar"/>
<pathelement path="${lib}/jcommon-1.0.10.jar"/>
</classpath>
</javac>
</target>
<target name="clean" depends="init">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<target name="run" depends="init, compile">
<java fork="yes" dir="${build}" classname="Demo">
<arg line="${args}"/>
<classpath>
<pathelement path="${build}"/>
<pathelement path="${lib}/jfreechart-1.0.6.jar"/>
<pathelement path="${lib}/jcommon-1.0.10.jar"/>
</classpath>
</java>
</target>
<target name="jar" depends="clean, init, compile">
<mkdir dir="${dist}"/>
<jar destfile="${dist}/energest.jar" basedir="${build}">
<fileset dir="${build}"/>
<manifest>
<attribute name="Main-Class" value="Demo"/>
<attribute name="Class-Path" value=". jcommon-1.0.10.jar jfreechart-1.0.6.jar"/>
</manifest>
</jar>
<mkdir dir="${dist}"/>
<copy todir="${dist}">
<fileset dir="${lib}"/>
</copy>
</target>
</project>

View file

@ -1,190 +0,0 @@
/* -*- C -*- */
/* @(#)$Id: contiki-conf.h,v 1.6 2009/09/07 11:31:26 nifi Exp $ */
#ifndef CONTIKI_CONF_H
#define CONTIKI_CONF_H
#define SHELL_VARS_CONF_RAM_BEGIN 0x1100
#define SHELL_VARS_CONF_RAM_END 0x2000
#define TIMESYNCH_CONF_ENABLED 1
#define SIMPLE_CC2420_CONF_TIMESTAMPS 1
#define PROFILE_CONF_ON 1
#define ENERGEST_CONF_ON 1
#define HAVE_STDINT_H
#include "msp430def.h"
#ifndef RF_CHANNEL
#define RF_CHANNEL 26
#endif /* RF_CHANNEL */
#define ELFLOADER_CONF_DATAMEMORY_SIZE 0x1800
#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x1000
#define IRQ_PORT1 0x01
#define IRQ_PORT2 0x02
#define IRQ_ADC 0x03
#define CCIF
#define CLIF
#define CC_CONF_INLINE inline
#define AODV_COMPLIANCE
#define AODV_NUM_RT_ENTRIES 32
#define TMOTE_SKY 1
#define WITH_ASCII 1
/*#define PROCESS_CONF_FASTPOLL 4*/
/* CPU target speed in Hz */
#define F_CPU 2457600uL
/* Our clock resolution, this is the same as Unix HZ. */
#define CLOCK_CONF_SECOND 64
#define BAUD2UBR(baud) ((F_CPU/baud))
#define UIP_CONF_DHCP_LIGHT
#define UIP_CONF_LLH_LEN 0
#define UIP_CONF_BUFFER_SIZE 116
#define UIP_CONF_RECEIVE_WINDOW (UIP_CONF_BUFFER_SIZE - 40)
#define UIP_CONF_MAX_CONNECTIONS 4
#define UIP_CONF_MAX_LISTENPORTS 8
#define UIP_CONF_UDP_CONNS 12
#define UIP_CONF_FWCACHE_SIZE 30
#define UIP_CONF_BROADCAST 1
#define UIP_ARCH_IPCHKSUM 1
#define UIP_CONF_UDP_CHECKSUMS 1
#define UIP_CONF_PINGADDRCONF 0
#define UIP_CONF_LOGGING 0
/*
* Definitions below are dictated by the hardware and not really
* changeable!
*/
/* LED ports */
#define LEDS_PxDIR P5DIR
#define LEDS_PxOUT P5OUT
#define LEDS_CONF_RED 0x10
#define LEDS_CONF_GREEN 0x20
#define LEDS_CONF_YELLOW 0x40
/* Button sensors. */
#define IRQ_PORT2 0x02
typedef unsigned short uip_stats_t;
typedef unsigned short clock_time_t;
typedef unsigned long off_t;
#define ROM_ERASE_UNIT_SIZE 512
#define XMEM_ERASE_UNIT_SIZE (64*1024L)
#define XMAC_CONF_ON_TIME RTIMER_ARCH_SECOND / 100
#define XMAC_CONF_OFF_TIME RTIMER_ARCH_SECOND / 10
/* Use the first 64k of external flash for node configuration */
#define NODE_ID_XMEM_OFFSET (0 * XMEM_ERASE_UNIT_SIZE)
/* Use the second 64k of external flash for codeprop. */
#define EEPROMFS_ADDR_CODEPROP (1 * XMEM_ERASE_UNIT_SIZE)
#define CFS_XMEM_CONF_OFFSET (2 * XMEM_ERASE_UNIT_SIZE)
#define CFS_XMEM_CONF_SIZE (1 * XMEM_ERASE_UNIT_SIZE)
#define CFS_RAM_CONF_SIZE 4096
/*
* SPI bus configuration for the TMote Sky.
*/
/* SPI input/output registers. */
#define SPI_TXBUF U0TXBUF
#define SPI_RXBUF U0RXBUF
/* USART0 Tx ready? */
#define SPI_WAITFOREOTx() while ((U0TCTL & TXEPT) == 0)
/* USART0 Rx ready? */
#define SPI_WAITFOREORx() while ((IFG1 & URXIFG0) == 0)
/* USART0 Tx buffer ready? */
#define SPI_WAITFORTxREADY() while ((IFG1 & UTXIFG0) == 0)
#define SCK 1 /* P3.1 - Output: SPI Serial Clock (SCLK) */
#define MOSI 2 /* P3.2 - Output: SPI Master out - slave in (MOSI) */
#define MISO 3 /* P3.3 - Input: SPI Master in - slave out (MISO) */
/*
* SPI bus - M25P80 external flash configuration.
*/
#define FLASH_PWR 3 /* P4.3 Output */
#define FLASH_CS 4 /* P4.4 Output */
#define FLASH_HOLD 7 /* P4.7 Output */
/* Enable/disable flash access to the SPI bus (active low). */
#define SPI_FLASH_ENABLE() ( P4OUT &= ~BV(FLASH_CS) )
#define SPI_FLASH_DISABLE() ( P4OUT |= BV(FLASH_CS) )
#define SPI_FLASH_HOLD() ( P4OUT &= ~BV(FLASH_HOLD) )
#define SPI_FLASH_UNHOLD() ( P4OUT |= BV(FLASH_HOLD) )
/*
* SPI bus - CC2420 pin configuration.
*/
#define FIFO_P 0 /* P1.0 - Input: FIFOP from CC2420 */
#define FIFO 3 /* P1.3 - Input: FIFO from CC2420 */
#define CCA 4 /* P1.4 - Input: CCA from CC2420 */
#define SFD 1 /* P4.1 - Input: SFD from CC2420 */
#define CSN 2 /* P4.2 - Output: SPI Chip Select (CS_N) */
#define VREG_EN 5 /* P4.5 - Output: VREG_EN to CC2420 */
#define RESET_N 6 /* P4.6 - Output: RESET_N to CC2420 */
/* Pin status. */
#define FIFO_IS_1 (!!(P1IN & BV(FIFO)))
#define CCA_IS_1 (!!(P1IN & BV(CCA) ))
#define RESET_IS_1 (!!(P4IN & BV(RESET_N)))
#define VREG_IS_1 (!!(P4IN & BV(VREG_EN)))
#define FIFOP_IS_1 (!!(P1IN & BV(FIFO_P)))
#define SFD_IS_1 (!!(P4IN & BV(SFD)))
/* The CC2420 reset pin. */
#define SET_RESET_INACTIVE() ( P4OUT |= BV(RESET_N) )
#define SET_RESET_ACTIVE() ( P4OUT &= ~BV(RESET_N) )
/* CC2420 voltage regulator enable pin. */
#define SET_VREG_ACTIVE() ( P4OUT |= BV(VREG_EN) )
#define SET_VREG_INACTIVE() ( P4OUT &= ~BV(VREG_EN) )
/* CC2420 rising edge trigger for external interrupt 0 (FIFOP). */
#define FIFOP_INT_INIT() do {\
P1IES &= ~BV(FIFO_P);\
CLEAR_FIFOP_INT();\
} while (0)
/* FIFOP on external interrupt 0. */
#define ENABLE_FIFOP_INT() do { P1IE |= BV(FIFO_P); } while (0)
#define DISABLE_FIFOP_INT() do { P1IE &= ~BV(FIFO_P); } while (0)
#define CLEAR_FIFOP_INT() do { P1IFG &= ~BV(FIFO_P); } while (0)
/* Enables/disables CC2420 access to the SPI bus (not the bus).
*
* These guys should really be renamed but are compatible with the
* original Chipcon naming.
*
* SPI_CC2420_ENABLE/SPI_CC2420_DISABLE???
* CC2420_ENABLE_SPI/CC2420_DISABLE_SPI???
*/
#define SPI_ENABLE() ( P4OUT &= ~BV(CSN) ) /* ENABLE CSn (active low) */
#define SPI_DISABLE() ( P4OUT |= BV(CSN) ) /* DISABLE CSn (active low) */
#endif /* CONTIKI_CONF_H */

View file

@ -1,254 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR 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.
*
* @(#)$Id: contiki-sky-main.c,v 1.10 2010/01/15 11:02:18 nifi Exp $
*/
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <io.h>
#include "contiki.h"
#include "dev/battery-sensor.h"
#include "dev/button-sensor.h"
#include "dev/light-sensor.h"
#include "dev/sht11-sensor.h"
#include "dev/ds2411.h"
#include "dev/sht11.h"
#include "dev/leds.h"
#include "dev/light.h"
#include "dev/xmem.h"
#include "dev/cc2420.h"
#include "dev/slip.h"
#include "dev/uart1.h"
#include "net/mac/xmac.h"
#include "net/mac/nullmac.h"
#include "node-id.h"
#include "net/rime.h"
#include "sys/autostart.h"
/*#include "codeprop/codeprop.h"*/
SENSORS(&button_sensor, &light_sensor, &battery_sensor, &sht11_sensor);
extern int lpm_en;
#define WITH_UIP 0
#if WITH_UIP
static struct uip_fw_netif slipif =
{UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
#endif /* WITH_UIP */
/*---------------------------------------------------------------------------*/
#if 0
int
force_float_inclusion()
{
extern int __fixsfsi;
extern int __floatsisf;
extern int __mulsf3;
extern int __subsf3;
return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
}
#endif
/*---------------------------------------------------------------------------*/
void uip_log(char *msg) { puts(msg); }
/*---------------------------------------------------------------------------*/
/* Radio stuff in network byte order. */
static u16_t panId = 0x2024;
#ifndef RF_CHANNEL
#error define RF_CHANNEL!
#endif
/*---------------------------------------------------------------------------*/
void
force_inclusion(int d1, int d2)
{
snprintf(NULL, 0, "%d", d1 % d2);
}
/*---------------------------------------------------------------------------*/
static void
set_rime_addr(void)
{
rimeaddr_t addr;
addr.u8[0] = node_id & 0xff;
addr.u8[1] = node_id >> 8;
rimeaddr_set_node_addr(&addr);
}
/*---------------------------------------------------------------------------*/
static void
print_processes(struct process * const processes[])
{
printf("Starting");
while(*processes != NULL) {
printf(" '%s'", (*processes)->name);
processes++;
}
putchar('\n');
}
/*---------------------------------------------------------------------------*/
int
main(int argc, char **argv)
{
/*
* Initalize hardware.
*/
msp430_cpu_init();
clock_init();
leds_init();
leds_toggle(LEDS_RED | LEDS_GREEN | LEDS_BLUE);
#if WITH_UIP
slip_arch_init(BAUD2UBR(115200)); /* Must come before first printf */
#else /* WITH_UIP */
uart1_init(BAUD2UBR(115200)); /* Must come before first printf */
#endif /* WITH_UIP */
printf("Starting %s "
"($Id: contiki-sky-main.c,v 1.10 2010/01/15 11:02:18 nifi Exp $)\n", __FILE__);
ds2411_init();
xmem_init();
leds_toggle(LEDS_RED | LEDS_GREEN | LEDS_BLUE);
rtimer_init();
/*
* Hardware initialization done!
*/
/* Restore node id if such has been stored in external mem */
// node_id_burn(3);
node_id_restore();
printf("node_id : %hu\n", node_id);
printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
ds2411_id[0], ds2411_id[1], ds2411_id[2], ds2411_id[3],
ds2411_id[4], ds2411_id[5], ds2411_id[6], ds2411_id[7]);
#if WITH_UIP
uip_init();
uip_sethostaddr(&slipif.ipaddr);
uip_setnetmask(&slipif.netmask);
uip_fw_default(&slipif); /* Point2point, no default router. */
#endif /* WITH_UIP */
/*
* Initialize Contiki and our processes.
*/
process_init();
process_start(&etimer_process, NULL);
process_start(&sensors_process, NULL);
/*
* Initialize light and humidity/temp sensors.
*/
SENSORS_ACTIVATE(light_sensor);
SENSORS_ACTIVATE(sht11_sensor);
ctimer_init();
set_rime_addr();
cc2420_init();
cc2420_set_pan_addr(panId, 0 /*XXX*/, ds2411_id);
cc2420_set_channel(RF_CHANNEL);
cc2420_set_txpower(31);
nullmac_init(&cc2420_driver);
rime_init(&nullmac_driver);
// xmac_init(&cc2420_driver);
// rime_init(&xmac_driver);
/* rimeaddr_set_node_addr*/
#if WITH_UIP
process_start(&tcpip_process, NULL);
process_start(&uip_fw_process, NULL); /* Start IP output */
process_start(&slip_process, NULL);
#endif /* WITH_UIP */
SENSORS_ACTIVATE(button_sensor);
print_processes(autostart_processes);
autostart_start(autostart_processes);
energest_init();
/*
* This is the scheduler loop.
*/
printf("process_run()...\n");
ENERGEST_ON(ENERGEST_TYPE_CPU);
while (1) {
do {
/* Reset watchdog. */
} while(process_run() > 0);
/*
* Idle processing.
*/
if(lpm_en) {
int s = splhigh(); /* Disable interrupts. */
if(process_nevents() != 0) {
splx(s); /* Re-enable interrupts. */
} else {
static unsigned long irq_energest = 0;
/* Re-enable interrupts and go to sleep atomically. */
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_LPM);
/* We only want to measure the processing done in IRQs when we
are asleep, so we discard the processing time done when we
were awake. */
energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
_BIS_SR(GIE | SCG0 | /*SCG1 |*/ CPUOFF); /* LPM3 sleep. */
/* We get the current processing time for interrupts that was
done during the LPM and store it for next time around. */
dint();
irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
eint();
ENERGEST_OFF(ENERGEST_TYPE_LPM);
ENERGEST_ON(ENERGEST_TYPE_CPU);
}
}
}
return 0;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,359 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR 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.
*
* This file is part of the Contiki operating system.
*
* $Id: energest-demo.c,v 1.9 2010/01/15 11:02:18 nifi Exp $
*/
/**
* \file
* Contiki application sending estimated energy to a sink node
* \author
* Zhitao He <zhitao@sics.se>
*/
#include "contiki.h"
#include "net/rime.h"
#include "net/mac/mac.h"
#include "net/mac/nullmac.h"
#include "dev/button-sensor.h"
#include "dev/cc2420.h"
#include "dev/leds.h"
#include "node-id.h"
#include <stdio.h>
#define SINK_ID 41
/*---------------------------------------------------------------------------*/
PROCESS(output_process, "output energest");
PROCESS(user_process, "user input");
AUTOSTART_PROCESSES(
&output_process,
&user_process
);
/*---------------------------------------------------------------------------*/
static struct abc_conn abc;
static u16_t read = 0;
static u16_t send = 0;
int lpm_en;
static int radio_off;
static int computing;
static int sending;
enum states{
RADIO_OFF = 1,
RADIO_LOW,
RADIO_MID,
RADIO_FULL,
LPM_OFF,
SENDING1k,
SENDING12k,
};
struct energy_time {
unsigned short source;
long cpu;
long lpm;
long transmit;
long listen;
};
static struct energy_time last;
static struct energy_time diff;
// FIXME: workaround to turn on/off radio. Rime should export an MAC on/off interface to avoid forcing the user to do this explicitly
static const struct mac_driver *mac = &nullmac_driver;
static clock_time_t sleep_cycles;
static const char send_string[] = "I am a sending string.";
static int send_length = 10;
static int send_amount = 10;
/*---------------------------------------------------------------------------*/
static void
abc_recv(struct abc_conn *c)
{
struct energy_time *incoming= (struct energy_time *)packetbuf_dataptr();
read++;
if(node_id == SINK_ID) {
printf("%i SICS %i %u %li %li %li %li\n", node_id, read,
incoming->source, incoming->cpu, incoming->lpm,
incoming->transmit, incoming->listen);
}
}
/*---------------------------------------------------------------------------*/
const static struct abc_callbacks abc_call = {abc_recv};
/*---------------------------------------------------------------------------*/
static void
do_computing(void)
{
int i;
for(i = 0; i < 100; i++) {
clock_delay(1000);
}
}
/*---------------------------------------------------------------------------*/
static void
do_sending(void)
{
int i;
cc2420_set_channel(11);
cc2420_set_txpower(1);
for(i = 0;i < send_amount; i++) {
packetbuf_copyfrom(send_string, send_length);
mac->on();
abc_send(&abc);
mac->off(0);
}
cc2420_set_txpower(31);
cc2420_set_channel(RF_CHANNEL);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(output_process, ev, data)
{
static struct etimer et, et2;
PROCESS_EXITHANDLER(abc_close(&abc);)
PROCESS_BEGIN();
etimer_set(&et, 5*CLOCK_SECOND);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
/* Energy time init */
last.cpu = energest_type_time(ENERGEST_TYPE_CPU);
last.lpm = energest_type_time(ENERGEST_TYPE_LPM);
last.transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
last.listen = energest_type_time(ENERGEST_TYPE_LISTEN);
abc_open(&abc, 128, &abc_call);
if (node_id == SINK_ID) {
while(1) {
PROCESS_YIELD();
printf("I'm a sink. I'm doing nothing...");
}
}
etimer_set(&et, UPDATE_TICKS);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
if(computing) {
do_computing();
}
/* stop-start ongoing time measurements to retrieve the diffs
during last interval */
ENERGEST_OFF(ENERGEST_TYPE_CPU);
ENERGEST_ON(ENERGEST_TYPE_CPU);
mac->on();
mac->off(0);
/* Energy time diff */
diff.source = node_id;
diff.cpu = energest_type_time(ENERGEST_TYPE_CPU) - last.cpu;
diff.lpm = energest_type_time(ENERGEST_TYPE_LPM) - last.lpm;
diff.transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT) - last.transmit;
diff.listen = energest_type_time(ENERGEST_TYPE_LISTEN) - last.listen;
last.cpu = energest_type_time(ENERGEST_TYPE_CPU);
last.lpm = energest_type_time(ENERGEST_TYPE_LPM);
last.transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
last.listen = energest_type_time(ENERGEST_TYPE_LISTEN);
send++;
/* printf("%i SICS %i %i %li %li %li %li\n", node_id, send, */
/* diff.source, diff.cpu, diff.lpm, diff.transmit, diff.listen); */
packetbuf_copyfrom((char*)&diff, sizeof(diff));
mac->on();
abc_send(&abc);
if(sending) {
mac->off(0);
do_sending();
} else if(radio_off) {
mac->off(0);
} else {
mac->off(0);
etimer_set(&et2, sleep_cycles);
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et2));
mac->on();
}
etimer_reset(&et);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static enum states
next_state(enum states current_state)
{
return current_state == 7 ? current_state = 1 : current_state + 1;
}
/*---------------------------------------------------------------------------*/
static void
show_state(enum states current_state)
{
printf("state = %d\n", current_state);
switch(current_state) {
case 1:
leds_off(LEDS_BLUE);leds_off(LEDS_GREEN);leds_on(LEDS_RED);
break;
case 2:
leds_off(LEDS_BLUE);leds_on(LEDS_GREEN);leds_off(LEDS_RED);
break;
case 3:
leds_off(LEDS_BLUE);leds_on(LEDS_GREEN);leds_on(LEDS_RED);
break;
case 4:
leds_on(LEDS_BLUE);leds_off(LEDS_GREEN);leds_off(LEDS_RED);
break;
case 5:
leds_on(LEDS_BLUE);leds_off(LEDS_GREEN);leds_on(LEDS_RED);
break;
case 6:
leds_on(LEDS_BLUE);leds_on(LEDS_GREEN);leds_off(LEDS_RED);
break;
case 7:
leds_on(LEDS_BLUE);leds_on(LEDS_GREEN);leds_on(LEDS_RED);
break;
default:
printf("unknown state\n");
}
}
/*---------------------------------------------------------------------------*/
static void
run_state(enum states current_state)
{
switch(current_state) {
case RADIO_OFF:
lpm_en = 1;
radio_off = 1;
sleep_cycles = 0;
computing = 0;
sending = 0;
break;
case RADIO_LOW:
lpm_en = 1;
radio_off = 0;
sleep_cycles = UPDATE_TICKS * 99 / 100;
computing = 0;
sending = 0;
break;
case RADIO_MID:
lpm_en = 1;
radio_off = 0;
sleep_cycles = UPDATE_TICKS * 90 / 100;
computing = 0;
sending = 0;
break;
case RADIO_FULL:
lpm_en = 1;
radio_off = 0;
sleep_cycles = 0;
computing = 0;
sending = 0;
break;
case LPM_OFF:
lpm_en = 0;
radio_off = 0;
sleep_cycles = UPDATE_TICKS * 90 / 100;
computing = 0;
sending = 0;
break;
case SENDING1k:
lpm_en = 1;
radio_off = 0;
sleep_cycles = UPDATE_TICKS * 99 / 100;
computing = 0;
sending = 1;
send_amount = 10;
send_length = 100;
break;
case SENDING12k:
lpm_en = 1;
radio_off = 0;
sleep_cycles = UPDATE_TICKS * 90 / 100;
computing = 0;
sending = 1;
send_amount = 100;
send_length = 100;
break;
default:
;
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(user_process, ev, data)
{
static enum states state;
PROCESS_BEGIN();
printf("Node id %d\n", node_id);
SENSORS_ACTIVATE(button_sensor);
state = RADIO_OFF;
while(1) {
show_state(state);
run_state(state);
PROCESS_WAIT_EVENT();
if(ev == sensors_event && data == &button_sensor) {
state = next_state(state);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -1,15 +0,0 @@
burn-nodeid-%.ihex:
$(MAKE) nodeid=$* burn-nodeid.ihex && mv burn-nodeid.ihex $@
burn-nodeids: $(foreach NODEID, 41 42 43 44 45 46 47 48, burn-nodeid-$(NODEID).ihex)
ifndef CONTIKI
CONTIKI = ../../..
endif
ifndef TARGET
TARGET=sky
endif
include $(CONTIKI)/Makefile.include

View file

@ -1,694 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE OR 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.
*
* This file is part of the Contiki operating system.
*
* $Id: Demo.java,v 1.4 2008/07/02 14:12:48 adamdunkels Exp $
*/
/**
* \file
* Java program showing energy estimates from a Contiki app
* \author
* Fredrik Österlind <fros@sics.se>
*/
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
public class Demo extends JPanel {
public static final boolean REPLAY_TEMP_DATA = false;
public static final int TOTAL_HEIGHT = 300;
public static final int TOTAL_WIDTH = 900;
public static final String SERIALDUMP_WINDOWS = "./tools/sky/serialdump-windows.exe";
public static final String SERIALDUMP_LINUX = "./tools/sky/serialdump-linux";
public static final int HISTORY_MAX_SECONDS = 120;
public static final int NODE_HEIGHT = 300;
public static final int NODE_WIDTH = 450;
public static final int NUMBER_NODES = 7;
public static final int NODE_IDS[] = {42, 43, 44, 45, 46, 47, 48};
public static final String CATEGORIES[] = {"LPM", "CPU", "Radio listen", "Radio transmit"};
public static final int PARSE_NR_COMPONENTS = 8;
public static final int PARSE_POS_SINK_ID = 0;
public static final int PARSE_POS_SICS_ID = 1;
public static final int PARSE_POS_COUNT = 2;
public static final int PARSE_POS_SOURCE_ID = 3;
public static final int PARSE_POS_TIME_CPU = 4;
public static final int PARSE_POS_TIME_LPM = 5;
public static final int PARSE_POS_TIME_TRANSMIT = 6;
public static final int PARSE_POS_TIME_LISTEN = 7;
public static final String PARSE_SICS_ID = "SICS";
public static final double TICKS_PER_SECOND = 4096; /* TODO Convert from TimerB ticks to seconds */
public static final double UPDATE_PERIOD = 1; /* TODO Set update period (1 second?) */
/* CC2420 has 8.5 (-25dBm), 9.9 (-15dBm), 11 (-10dBm), 14 (-5dBm) and 17.4 (0dBm) */
public static final int CHARTS_MAX_MILLIWATTS = 70;
public static final double VOLTAGE = 3;
public static final double POWER_CPU = 1.800 * VOLTAGE; /* mW */
public static final double POWER_LPM = 0.0545 * VOLTAGE; /* mW */
public static final double POWER_TRANSMIT = 17.7 * VOLTAGE; /* mW */
public static final double POWER_LISTEN = 20.0 * VOLTAGE; /* mW */
public static final int MA_HISTORY_LENGTH = 40;
private Process serialDumpProcess;
private Vector<Double> historyLPM = new Vector<Double>();
private Vector<Double> historyCPU = new Vector<Double>();
private Vector<Double> historyListen = new Vector<Double>();
private Vector<Double> historyTransmit = new Vector<Double>();
private int trackedNodeIndex = 0; /* Currently tracked node index */
private String comPort;
private JFrame frame;
private TimeSeries nodeHistorySerie;
private JFreeChart nodeHistoryChart;
private JLabel nodeHistoryLabel;
private JFreeChart relativeChart;
private JLabel relativeLabel;
private DefaultPieDataset relativeDataset;
private JFreeChart totalChart;
private DefaultCategoryDataset totalDataset;
private JLabel totalLabel;
private int categoryOrder = 0;
public Demo(String comPort) {
this.comPort = comPort;
System.out.println("Demo application listening on COM port: " + comPort);
/* Make sure we have nice window decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
Rectangle maxSize = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getMaximumWindowBounds();
/* Create and set up the window */
frame = new JFrame("Sensor Node Power Profiling with Contiki (ACM SenSys 2007)");
if (maxSize != null) {
frame.setMaximizedBounds(maxSize);
}
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowListener() {
public void windowDeactivated(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
/* TODO Clean up resources */
if (serialDumpProcess != null) {
try {
serialDumpProcess.destroy();
} catch (Exception ex) {
System.err.println("Serialdump process exception: " + ex.getMessage());
}
}
System.exit(0);
}
});
frame.setContentPane(this);
/* Create charts */
createAllCharts();
/* Add charts */
this.setLayout(new BorderLayout());
JPanel contentPanel = new JPanel(new GridLayout(2, 1));
add(contentPanel);
JPanel upperPanel = new JPanel(new GridLayout());
totalLabel.setAlignmentX(JPanel.CENTER_ALIGNMENT);
upperPanel.add(totalLabel);
contentPanel.add(upperPanel);
JPanel lowerPanel = new JPanel(new GridLayout(1, 2));
relativeLabel.setAlignmentX(JPanel.CENTER_ALIGNMENT);
lowerPanel.add(relativeLabel);
nodeHistoryLabel.setAlignmentX(JPanel.CENTER_ALIGNMENT);
lowerPanel.add(nodeHistoryLabel);
contentPanel.add(lowerPanel);
JLabel advertisementLabel = new JLabel("Sensor Node Power Profiling with Contiki",
JLabel.CENTER);
advertisementLabel.setFont(new Font("Sans-serif", Font.BOLD, 40));
JLabel urlLabel = new JLabel("http://www.sics.se/contiki/",
JLabel.CENTER);
urlLabel.setFont(new Font("Monospace", Font.BOLD, 36));
add(advertisementLabel, BorderLayout.NORTH);
add(urlLabel, BorderLayout.SOUTH);
/* Display the window */
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
if (!REPLAY_TEMP_DATA) {
connectToCOMPort();
}
Timer updateTimer = new Timer(500, null);
updateTimer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// parseIncomingLine(TEMP_NODE_DATA[TEMP_COUNTER]);
// TEMP_COUNTER = (TEMP_COUNTER + 1) % TEMP_NODE_DATA.length;
try {
updateCharts();
} catch(Exception eeeee) {}
}
});
updateTimer.start();
if (REPLAY_TEMP_DATA) {
// Timer updateTimer = new Timer(1000, null);
updateTimer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
parseIncomingLine(TEMP_NODE_DATA[TEMP_COUNTER]);
TEMP_COUNTER = (TEMP_COUNTER + 1) % TEMP_NODE_DATA.length;
updateCharts();
}
});
updateTimer.start();
}
}
public void connectToCOMPort() {
/* Connect to COM using external serialdump application */
String osName = System.getProperty("os.name").toLowerCase();
String fullCommand;
if (osName.startsWith("win")) {
fullCommand = SERIALDUMP_WINDOWS + " " + "-b115200" + " " + comPort;
} else {
fullCommand = SERIALDUMP_LINUX + " " + "-b115200" + " " + comPort;
}
try {
String[] cmd = fullCommand.split(" ");
serialDumpProcess = Runtime.getRuntime().exec(cmd);
final BufferedReader input = new BufferedReader(new InputStreamReader(serialDumpProcess.getInputStream()));
final BufferedReader err = new BufferedReader(new InputStreamReader(serialDumpProcess.getErrorStream()));
/* Start thread listening on stdout */
Thread readInput = new Thread(new Runnable() {
public void run() {
String line;
try {
while ((line = input.readLine()) != null) {
parseIncomingLine(line);
}
input.close();
System.out.println("Serialdump process shut down, exiting");
System.exit(1);
} catch (IOException e) {
System.err.println("Exception when reading from serialdump");
e.printStackTrace();
System.exit(1);
}
}
}, "read input stream thread");
/* Start thread listening on stderr */
Thread readError = new Thread(new Runnable() {
public void run() {
String line;
try {
while ((line = err.readLine()) != null) {
System.err.println("Serialdump error stream> " + line);
}
err.close();
} catch (IOException e) {
System.err.println("Exception when reading from serialdump");
e.printStackTrace();
System.exit(1);
}
}
}, "read error stream thread");
readInput.start();
readError.start();
} catch (Exception e) {
System.err.println("Exception when executing '" + fullCommand + "'");
System.err.println("Exiting demo application");
e.printStackTrace();
System.exit(1);
}
}
public void createAllCharts() {
BufferedImage image;
/* Create total power history chart for tracked node */
nodeHistoryLabel = new JLabel();
createHistoryChartForNode(nodeHistoryLabel, trackedNodeIndex);
/* Create moving average relative power distribution chart */
relativeDataset = new DefaultPieDataset();
for (String category: CATEGORIES) {
relativeDataset.setValue(category, 0);
}
relativeChart = ChartFactory.createPieChart("Moving Average: Relative power distribution", relativeDataset, false, false, false);
image = relativeChart.createBufferedImage(NODE_WIDTH,NODE_HEIGHT);
relativeLabel = new JLabel();
relativeLabel.setIcon(new ImageIcon(image));
/* Create chart with power of all nodes */
totalDataset = new DefaultCategoryDataset();
for (int i=0; i < NUMBER_NODES; i++) {
for (String category: CATEGORIES) {
totalDataset.addValue(0, category, getNodeNameFromIndex(i));
}
}
totalChart = ChartFactory.createStackedBarChart(null, null, "Power (mW)", totalDataset, PlotOrientation.VERTICAL, true, true, true);
ValueAxis rangeAxis = totalChart.getCategoryPlot().getRangeAxis();
// rangeAxis.setRange(0, CHARTS_MAX_MILLIWATTS);
image = totalChart.createBufferedImage(TOTAL_WIDTH,TOTAL_HEIGHT);
totalLabel = new JLabel();
totalLabel.setIcon(new ImageIcon(image));
MouseListener categoryChangeListener = new MouseListener() {
public void mouseClicked(MouseEvent e) {
System.out.println("Toggling category order");
categoryOrder++;
totalDataset.clear();
for (int i=0; i < NUMBER_NODES; i++) {
for (int j=0; j < CATEGORIES.length; j++) {
totalDataset.addValue(0, CATEGORIES[(j + categoryOrder) % CATEGORIES.length], getNodeNameFromIndex(i));
}
}
totalChart = ChartFactory.createStackedBarChart(null, null, "Power (mW)", totalDataset, PlotOrientation.VERTICAL, true, true, true);
ValueAxis rangeAxis = totalChart.getCategoryPlot().getRangeAxis();
// rangeAxis.setRange(0, CHARTS_MAX_MILLIWATTS);
relativeDataset.clear();
for (int i=0; i < NUMBER_NODES; i++) {
for (int j=0; j < CATEGORIES.length; j++) {
relativeDataset.setValue(CATEGORIES[(j + categoryOrder) % CATEGORIES.length], 0.00001);
}
}
relativeChart = ChartFactory.createPieChart("Moving Average: Relative power distribution", relativeDataset, false, false, false);
updateCharts();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
};
totalLabel.addMouseListener(categoryChangeListener);
relativeLabel.addMouseListener(categoryChangeListener);
MouseListener toggleTrackedListener = new MouseListener() {
public void mouseClicked(MouseEvent e) {
trackedNodeIndex = (trackedNodeIndex + 1) % NODE_IDS.length;
System.out.println("Tracking " + getNodeNameFromIndex(trackedNodeIndex));
createHistoryChartForNode(nodeHistoryLabel, trackedNodeIndex);
updateCharts();
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
};
nodeHistoryLabel.addMouseListener(toggleTrackedListener);
}
public void createHistoryChartForNode(JLabel label, int index) {
BufferedImage image;
/* Create history */
nodeHistorySerie = new TimeSeries("", Second.class);
nodeHistorySerie.removeAgedItems(true);
nodeHistorySerie.setMaximumItemCount(HISTORY_MAX_SECONDS);
TimeSeriesCollection historyData = new TimeSeriesCollection(nodeHistorySerie);
nodeHistoryChart = ChartFactory.createTimeSeriesChart(getNodeNameFromIndex(index) + ": Total power (mW)", null, null, historyData, false, false, false);
ValueAxis rangeAxis = nodeHistoryChart.getXYPlot().getRangeAxis();
rangeAxis.setRange(0, CHARTS_MAX_MILLIWATTS);
image = nodeHistoryChart.createBufferedImage(NODE_WIDTH,NODE_HEIGHT);
label.setIcon(new ImageIcon(image));
}
public void addHistoryPower(double newPower) {
if (nodeHistorySerie != null) {
nodeHistorySerie.addOrUpdate(new Second(), newPower);
}
}
public void updateTotalPower(String category, String nodeName, double newValue) {
if (totalDataset != null) {
totalDataset.addValue(newValue, category, nodeName);
}
}
public void updateTotalPowers(String nodeName, double lpm, double cpu, double listen, double transmit) {
updateTotalPower(CATEGORIES[0], nodeName, lpm);
updateTotalPower(CATEGORIES[1], nodeName, cpu);
updateTotalPower(CATEGORIES[2], nodeName, listen);
updateTotalPower(CATEGORIES[3], nodeName, transmit);
}
public void setRelativePower(String category, double newVal) {
if (relativeDataset != null) {
relativeDataset.setValue(category, newVal);
}
}
public void setRelativePowers(double lpm, double cpu, double listen, double transmit) {
setRelativePower(CATEGORIES[0], lpm);
setRelativePower(CATEGORIES[1], cpu);
setRelativePower(CATEGORIES[2], listen);
setRelativePower(CATEGORIES[3], transmit);
}
public void updateMARelativePowers(double lpm, double cpu, double listen, double transmit) {
/* Add new values */
historyLPM.add(lpm);
historyCPU.add(cpu);
historyListen.add(listen);
historyTransmit.add(transmit);
/* Remove old values (if any) */
if (historyLPM.size() > MA_HISTORY_LENGTH) {
historyLPM.remove(0);
}
if (historyCPU.size() > MA_HISTORY_LENGTH) {
historyCPU.remove(0);
}
if (historyListen.size() > MA_HISTORY_LENGTH) {
historyListen.remove(0);
}
if (historyTransmit.size() > MA_HISTORY_LENGTH) {
historyTransmit.remove(0);
}
/* Calculate average */
double lpmMA = 0;
for (double power: historyLPM) {
lpmMA += power;
}
lpmMA /= historyLPM.size();
double cpuMA = 0;
for (double power: historyCPU) {
cpuMA += power;
}
cpuMA /= historyCPU.size();
double transmitMA = 0;
for (double power: historyTransmit) {
transmitMA += power;
}
transmitMA /= historyTransmit.size();
double listenMA = 0;
for (double power: historyListen) {
listenMA += power;
}
listenMA /= historyListen.size();
setRelativePowers(lpmMA, cpuMA, listenMA, transmitMA);
}
public void parseIncomingLine(String line) {
if (line == null) {
System.err.println("Parsing null line");
return;
}
/* Split line into components */
String[] components = line.split(" ");
if (components.length != PARSE_NR_COMPONENTS) {
System.err.println("Parsing wrong components count (" + components.length + "): '" + line + "'");
return;
}
/* Parse source and components times */
int sinkNodeID=-1, sourceNodeID=-1, timeCPU=-1, timeLPM=-1, timeTransmit=-1, timeListen=-1;
try {
sinkNodeID = Integer.parseInt(components[PARSE_POS_SINK_ID]);
if (!components[PARSE_POS_SICS_ID].equals(PARSE_SICS_ID)) {
throw new Exception("Parsing non-demo data: '" + line + "'");
}
/*Integer.parseInt(components[PARSE_POS_COUNT]);*/
sourceNodeID = Integer.parseInt(components[PARSE_POS_SOURCE_ID]);
timeCPU = Integer.parseInt(components[PARSE_POS_TIME_CPU]);
timeLPM = Integer.parseInt(components[PARSE_POS_TIME_LPM]);
timeTransmit = Integer.parseInt(components[PARSE_POS_TIME_TRANSMIT]);
/* TODO Too big transmit time? */
timeListen = Integer.parseInt(components[PARSE_POS_TIME_LISTEN]);
} catch (Exception e) {
System.err.println(e.getMessage());
return;
}
/* Validate parsed values */
String nodeName = getNodeNameFromId(sourceNodeID);
if (nodeName == null) {
System.err.println("No registered node with ID " + sourceNodeID + ": '" + line + "'");
return;
}
if (timeCPU < 0) {
System.err.println("Parsed negative CPU time (" + timeCPU + "): '" + line + "'");
return;
}
if (timeLPM < 0) {
System.err.println("Parsed negative LPM time (" + timeLPM + "): '" + line + "'");
return;
}
if (timeTransmit < 0) {
System.err.println("Parsed negative transmit time (" + timeTransmit + "): '" + line + "'");
return;
}
if (timeListen < 0) {
System.err.println("Parsed negative listen time (" + timeListen + "): '" + line + "'");
return;
}
/* Calculate component specific powers using parsed times */
double powerCPU = (timeCPU / TICKS_PER_SECOND) * POWER_CPU / UPDATE_PERIOD;
double powerLPM = (timeLPM / TICKS_PER_SECOND)* POWER_LPM / UPDATE_PERIOD;
double powerTransmit = (timeTransmit / TICKS_PER_SECOND)* POWER_TRANSMIT / UPDATE_PERIOD;
double powerListen = (timeListen / TICKS_PER_SECOND) * POWER_LISTEN / UPDATE_PERIOD;
/* Update node history */
if (getNodeNameFromId(sourceNodeID).equals(getNodeNameFromIndex(trackedNodeIndex))) {
System.out.println("Parsed data from tracked " + nodeName);
addHistoryPower(powerCPU + powerLPM + powerTransmit + powerListen);
} else {
System.out.println("Parsed data from " + nodeName);
}
updateMARelativePowers(powerLPM, powerCPU, powerListen, powerTransmit);
updateTotalPowers(nodeName, powerLPM, powerCPU, powerListen, powerTransmit);
// updateCharts();
}
public void updateCharts() {
BufferedImage image;
/* Recreate all label icons */
/* TODO Only update changed charts: i */
if (relativeLabel != null) {
image = relativeChart.createBufferedImage(NODE_WIDTH,NODE_HEIGHT);
relativeLabel.setIcon(new ImageIcon(image));
}
if (nodeHistoryLabel != null) {
image = nodeHistoryChart.createBufferedImage(NODE_WIDTH,NODE_HEIGHT);
nodeHistoryLabel.setIcon(new ImageIcon(image));
}
if (totalLabel != null) {
image = totalChart.createBufferedImage(TOTAL_WIDTH,TOTAL_HEIGHT);
totalLabel.setIcon(new ImageIcon(image));
}
repaint();
}
public String getNodeNameFromIndex(int index) {
return "Node " + NODE_IDS[index];
}
public static String getNodeNameFromId(int id) {
boolean exists = false;
for (int existingID: NODE_IDS) {
if (existingID == id) {
exists = true;
break;
}
}
if (!exists) {
System.err.println("Node " + id + " is not registered!");
return null;
}
return "Node " + id;
}
public static void main(final String[] args) {
if (args.length != 1) {
System.err.println("Usage: java Demo COMPORT [TRACK_NODE_ID]");
return;
}
final String comPort = args[0];
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Demo(comPort);
}
});
}
/* TEMPORARY DATA */
int TEMP_COUNTER = 0;
String[] TEMP_NODE_DATA = {
"33 S 1 33 3 0 4093 0",
"33 R 1 34 44 0 4052 0",
"33 S 2 33 77 0 4019 0",
"33 S 3 33 39 0 4057 0",
"33 R 2 34 39 0 4057 0",
"33 S 4 33 78 0 4018 0",
"33 R 3 34 80 0 4016 0",
"33 S 5 33 83 0 4013 0",
"33 R 4 34 80 0 4015 0",
"33 S 6 33 90 0 4006 0",
"33 S 7 33 40 0 4056 0",
"33 R 5 34 87 0 4009 0",
"33 S 8 33 80 0 4016 0",
"33 R 6 34 130 0 3965 0",
"33 S 9 33 81 0 4015 0",
"33 S 10 33 39 0 4057 0",
"33 R 7 34 87 0 4009 0",
"33 S 11 33 89 0 4007 0",
"33 R 8 34 94 0 4002 0",
"33 S 12 33 89 0 4007 0",
"33 R 9 34 47 0 4049 0",
"33 S 13 33 83 0 4013 0",
"33 R 10 34 82 0 4014 0",
"33 S 14 33 90 0 4006 0",
"33 R 11 34 94 0 3999 0",
"33 S 15 33 92 0 4004 0",
"33 S 16 33 46 0 4050 0",
"33 R 12 34 132 0 3964 0",
"33 R 13 34 46 0 4050 0",
"33 S 17 33 140 0 3956 0",
"33 R 14 34 86 0 4009 0",
"33 S 18 33 85 0 4010 0",
"33 R 15 34 94 0 4002 0",
"33 S 19 33 83 0 4013 0",
"33 S 20 33 41 0 4055 0",
"33 R 16 34 41 0 4055 0",
"33 S 21 33 86 0 4009 0",
"33 R 17 34 86 0 4010 0",
"33 R 18 34 84 0 4012 0",
"33 S 22 33 127 0 3969 0",
"33 R 19 34 84 0 4012 0",
"33 S 23 33 85 0 4011 0",
"33 S 24 33 44 0 4052 0",
"33 R 20 34 41 0 4055 0",
"33 S 25 33 86 0 4010 0",
"33 S 26 33 47 0 4048 0",
"33 R 21 34 94 0 4000 0",
"33 S 27 33 89 0 4004 0"
};
}