Removed directory; contents are now under contikiprojects
This commit is contained in:
parent
53d93eb83f
commit
b8892a7be0
|
@ -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
|
|
|
@ -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)}
|
|
|
@ -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.
|
|
|
@ -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>
|
|
|
@ -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 */
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
|
@ -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"
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in a new issue