Index: OscilloscopeC.nc
===================================================================
--- OscilloscopeC.nc	(revision 5158)
+++ OscilloscopeC.nc	(working copy)
@@ -16,16 +16,28 @@
 #include "Timer.h"
 #include "Oscilloscope.h"
 
+enum
+{
+	MAX_CHANNELS=8
+};
+
 module OscilloscopeC @safe()
 {
   uses {
     interface Boot;
-    interface SplitControl as RadioControl;
+    interface SplitControl as CommunicationControl;
     interface AMSend;
     interface Receive;
     interface Timer<TMilli>;
-    interface Read<uint16_t>;
+#ifdef SENSOR_ARRAYS
+    interface Read<uint16_t> as ChannelRead[uint8_t];
+#else
+    interface Read<uint16_t> as ChannelRead0;
+    interface Read<uint16_t> as ChannelRead1;
+    interface Read<uint16_t> as ChannelRead2;
+#endif
     interface Leds;
+    interface GeneralIO as Enable;
   }
 }
 implementation
@@ -53,8 +65,10 @@
   event void Boot.booted() {
     local.interval = DEFAULT_INTERVAL;
     local.id = TOS_NODE_ID;
-    if (call RadioControl.start() != SUCCESS)
+//    local.channels = uniqueCount("Channel");
+    if (call CommunicationControl.start() != SUCCESS)
       report_problem();
+    call Enable.set();
   }
 
   void startTimer() {
@@ -62,11 +76,11 @@
     reading = 0;
   }
 
-  event void RadioControl.startDone(error_t error) {
+  event void CommunicationControl.startDone(error_t error) {
     startTimer();
   }
 
-  event void RadioControl.stopDone(error_t error) {
+  event void CommunicationControl.stopDone(error_t error) {
   }
 
   event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) {
@@ -99,6 +113,7 @@
   event void Timer.fired() {
     if (reading == NREADINGS)
       {
+//	local.readings = reading;
 	if (!sendBusy && sizeof local <= call AMSend.maxPayloadLength())
 	  {
 	    // Don't need to check for null because we've already checked length
@@ -111,16 +126,30 @@
 	  report_problem();
 
 	reading = 0;
+	{
+	    uint8_t cc;
+	    for (cc=0; cc < MAX_CHANNELS; cc++)
+	        local.readings[cc] = 0;
+	}
+
 	/* Part 2 of cheap "time sync": increment our count if we didn't
 	   jump ahead. */
 	if (!suppressCountChange)
 	  local.count++;
 	suppressCountChange = FALSE;
       }
-    if (call Read.read() != SUCCESS)
-      report_problem();
+
+    /* TODO: Start conversation for all channels when fired */
+#ifdef SENSOR_ARRAYS
+    if (call ChannelRead.read[0U]() != SUCCESS)
+#else
+    if (call ChannelRead0.read() != SUCCESS)
+#endif
+       report_problem();
   }
 
+
+
   event void AMSend.sendDone(message_t* msg, error_t error) {
     if (error == SUCCESS)
       report_sent();
@@ -130,13 +159,53 @@
     sendBusy = FALSE;
   }
 
-  event void Read.readDone(error_t result, uint16_t data) {
+  void readDone(uint8_t channel, error_t result, uint16_t data) {
+
     if (result != SUCCESS)
       {
 	data = 0xffff;
 	report_problem();
       }
-    if (reading < NREADINGS) 
-      local.readings[reading++] = data;
+
+    if (channel < MAX_CHANNELS) {
+       local.readings[channel] += data;
+    }
+
   }
+
+#if SENSOR_ARRAYS
+  event void ChannelRead.readDone[uint8_t channel](error_t result, uint16_t data) {
+    readDone(channel, result, data);
+
+    /* NEXT CHANNEL */
+    channel++;
+    if (channel == uniqueCount("Channel")) {
+       reading++;
+       return;
+    }
+    if (call ChannelRead.read[channel]() != SUCCESS)
+       report_problem();
+  }
+#else
+
+  event void ChannelRead0.readDone(error_t result, uint16_t data) {
+    readDone(0, result, data);
+    if (call ChannelRead1.read() != SUCCESS)
+       report_problem();
+  }
+
+  event void ChannelRead1.readDone(error_t result, uint16_t data) {
+    readDone(1, result, data);
+    if (call ChannelRead2.read() != SUCCESS)
+       report_problem();
+  }
+
+  event void ChannelRead2.readDone(error_t result, uint16_t data) {
+    readDone(2, result, data);
+    reading++;
+    // wait for next fire()
+  }
+#endif
+
 }
+
Index: java/Graph.java
===================================================================
--- java/Graph.java	(revision 5158)
+++ java/Graph.java	(working copy)
@@ -175,11 +175,11 @@
 
     /* Next point in mote's graph is at x value gx, screen coordinate sx */
     void nextPoint(Graphics g, int gx, int sx) {
-        int gy = parent.parent.data.getData(nodeId, gx);
+        int gy[] = parent.parent.data.getData(nodeId, gx);
         int sy = -1;
 
-        if (gy >= 0) { // Ignore missing values
-        double rsy = height - yscale * (gy - gy0);
+        if (gy != null && gy[0] >= 0) { // Ignore missing values
+        double rsy = height - yscale * (gy[0] - gy0);
 
         // Ignore problem values
         if (rsy >= -1e6 && rsy <= 1e6) {
Index: java/run
===================================================================
--- java/run	(revision 5158)
+++ java/run	(working copy)
@@ -1,4 +1,5 @@
 #!/bin/sh
+cd `dirname $0`
 if cygpath -w / >/dev/null 2>/dev/null; then
   CLASSPATH="oscilloscope.jar;$CLASSPATH"
 else
Index: java/Node.java
===================================================================
--- java/Node.java	(revision 5158)
+++ java/Node.java	(working copy)
@@ -8,6 +8,7 @@
  * 94704.  Attention:  Intel License Inquiry.
  */
 
+import java.util.*;
 /**
  * Class holding all data received from a mote.
  */
@@ -16,7 +17,9 @@
        INCREMENT itself must be a multiple of Constant.NREADINGS. This
        simplifies handling the extension and clipping of old data
        (see setEnd) */
-    final static int INCREMENT = 100 * Constants.NREADINGS;
+    final static int CHANNELS = Constants.NCHANNELS;
+    final static int WINDOW = 1;
+    final static int INCREMENT = 100 * Constants.NREADINGS/WINDOW;
     final static int MAX_SIZE = 100 * INCREMENT; // Must be multiple of INCREMENT
 
     /* The mote's identifier */
@@ -25,40 +28,37 @@
     /* Data received from the mote. data[0] is the dataStart'th sample
        Indexes 0 through dataEnd - dataStart - 1 hold data.
        Samples are 16-bit unsigned numbers, -1 indicates missing data. */
-    int[] data;
+    Vector data;
     int dataStart, dataEnd;
 
+    float[] window_func;
+
     Node(int _id) {
     id = _id;
+    window_func = new float[WINDOW];
+    for (int i=0; i<WINDOW; i++) {
+	window_func[i] = 1.0f; // rectangular
     }
+    }
 
     /* Update data to hold received samples newDataIndex .. newEnd.
        If we receive data with a lower index, we discard newer data
        (we assume the mote rebooted). */
     private void setEnd(int newDataIndex, int newEnd) {
+	
     if (newDataIndex < dataStart || data == null) {
-        /* New data is before the start of what we have. Just throw it
-           all away and start again */
+        // New data is before the start of what we have. Just throw it
+        //   all away and start again
         dataStart = newDataIndex;
-        data = new int[INCREMENT];
+        data = new Vector();
     }
-    if (newEnd > dataStart + data.length) {
-        /* Try extending first */
-        if (data.length < MAX_SIZE) {
-        int newLength = (newEnd - dataStart + INCREMENT - 1) / INCREMENT * INCREMENT;
-        if (newLength >= MAX_SIZE) {
-            newLength = MAX_SIZE;
-        }
+    data.ensureCapacity(newEnd - dataStart + 1);
 
-        int[] newData = new int[newLength];
-        System.arraycopy(data, 0, newData, 0, data.length);
-        data = newData;
-
-        }
+    /* TODO
         if (newEnd > dataStart + data.length) {
-        /* Still doesn't fit. Squish.
-           We assume INCREMENT >= (newEnd - newDataIndex), and ensure
-           that dataStart + data.length - INCREMENT = newDataIndex */
+        // Still doesn't fit. Squish.
+        //   We assume INCREMENT >= (newEnd - newDataIndex), and ensure
+        //   that dataStart + data.length - INCREMENT = newDataIndex
         int newStart = newDataIndex + INCREMENT - data.length;
 
         if (dataStart + data.length > newStart) {
@@ -68,10 +68,11 @@
         dataStart = newStart;
         }
     }
+	*/
     /* Mark any missing data as invalid */
     for (int i = dataEnd < dataStart ? dataStart : dataEnd;
          i < newDataIndex; i++) {
-        data[i - dataStart] = -1;
+	// TODO        data.removeElementAt(i - dataStart);
     }
 
     /* If we receive a count less than the old count, we assume the old
@@ -83,19 +84,41 @@
     /* Data received containing NREADINGS samples from messageId * NREADINGS 
        onwards */
     void update(int messageId, int[] readings) {
-    int start = messageId * Constants.NREADINGS;
-    setEnd(start, start + Constants.NREADINGS);
+	int len = 1; // Use all payload (readings.length-CHANNELS+1)/CHANNELS;
+    int start = messageId * len;
+    setEnd(start, start + len);
+
+    for (int i = 0; i < len; i++) {
+	int sample[] = new int[CHANNELS];
+	for (int channel = 0; channel < CHANNELS; channel++)
+	    sample[channel] = readings[CHANNELS*i + channel];
+	data.add(start - dataStart + i, sample);
+    }
+
+    /*
+    // Start simple - rectangular window
+    int sum=0;
     for (int i = 0; i < readings.length; i++) {
-        data[start - dataStart + i] = readings[i];
+         sum += readings[i];
     }
+    */
+
+    /*
+    float sum=0.0f;
+    for (int i = 0; i < readings.length; i++) {
+	sum += readings[i]*window_func[i];
     }
+    
+    data[start - dataStart + 0] = Math.round(sum);
+    */
+    }
 
     /* Return value of sample x, or -1 for missing data */
-    int getData(int x) {
+    int[] getData(int x) {
     if (x < dataStart || x >= dataEnd) {
-        return -1;
+        return null;
     } else {
-        return data[x - dataStart];
+        return (int[])data.get(x - dataStart);
     }
     }
 
Index: java/Data.java
===================================================================
--- java/Data.java	(revision 5158)
+++ java/Data.java	(working copy)
@@ -24,6 +24,7 @@
     /* Data received from mote nodeId containing NREADINGS samples from
        messageId * NREADINGS onwards. Tell parent if this is a new node. */
     void update(int nodeId, int messageId, int readings[]) {
+	/* TODO: rewrite to use Vector */
     if (nodeId >= nodes.length) {
         int newLength = nodes.length * 2;
         if (nodeId >= newLength) {
@@ -43,9 +44,9 @@
     }
 
     /* Return value of sample x for mote nodeId, or -1 for missing data */
-    int getData(int nodeId, int x) {
+    int[] getData(int nodeId, int x) {
     if (nodeId >= nodes.length || nodes[nodeId] == null)
-        return -1;
+        return new int[0];
     return nodes[nodeId].getData(x);
     }
 
Index: OscilloscopeAppC.nc
===================================================================
--- OscilloscopeAppC.nc	(revision 5158)
+++ OscilloscopeAppC.nc	(working copy)
@@ -19,17 +19,39 @@
 configuration OscilloscopeAppC { }
 implementation
 {
-  components OscilloscopeC, MainC, ActiveMessageC, LedsC,
-    new TimerMilliC(), new DemoSensorC() as Sensor, 
-    new AMSenderC(AM_OSCILLOSCOPE), new AMReceiverC(AM_OSCILLOSCOPE);
+  components DelugeC;
+  components LedsC;
 
+  DelugeC.Leds -> LedsC;
+
+  components OscilloscopeC, MainC,
+    new TimerMilliC(), HplMMA7261QTC as Accel;
+#ifdef DELUGE_BASESTATION
+  components SerialActiveMessageC as ActiveMessageC_,
+    new SerialAMSenderC(AM_OSCILLOSCOPE) as AMSenderC_,
+    new SerialAMReceiverC(AM_OSCILLOSCOPE) as AMReceiverC_;
+#else
+  components ActiveMessageC as ActiveMessageC_,
+    new AMSenderC(AM_OSCILLOSCOPE) as AMSenderC_,
+    new AMReceiverC(AM_OSCILLOSCOPE) as AMReceiverC_;
+#endif
+
+
   OscilloscopeC.Boot -> MainC;
-  OscilloscopeC.RadioControl -> ActiveMessageC;
-  OscilloscopeC.AMSend -> AMSenderC;
-  OscilloscopeC.Receive -> AMReceiverC;
+  OscilloscopeC.CommunicationControl -> ActiveMessageC_;
+  OscilloscopeC.AMSend -> AMSenderC_;
+  OscilloscopeC.Receive -> AMReceiverC_;
   OscilloscopeC.Timer -> TimerMilliC;
-  OscilloscopeC.Read -> Sensor;
+#ifdef SENSOR_ARRAYS
+  OscilloscopeC.ChannelRead[unique("Channel")] -> Accel.AccelX;
+  OscilloscopeC.ChannelRead[unique("Channel")] -> Accel.AccelY;
+  OscilloscopeC.ChannelRead[unique("Channel")] -> Accel.AccelZ;
+#else
+  OscilloscopeC.ChannelRead0 -> Accel.AccelX;
+  OscilloscopeC.ChannelRead1 -> Accel.AccelY;
+  OscilloscopeC.ChannelRead2 -> Accel.AccelZ;
+#endif
   OscilloscopeC.Leds -> LedsC;
-
+  OscilloscopeC.Enable -> Accel.Sleep; /* Sleep is active low */ 
   
 }
Index: Makefile
===================================================================
--- Makefile	(revision 5158)
+++ Makefile	(working copy)
@@ -1,3 +1,6 @@
 COMPONENT=OscilloscopeAppC
+BOOTLOADER=tosboot
 
+#CFLAGS += -DDELUGE_LIGHT_BASESTATION
+
 include $(MAKERULES)
