added demo files
This commit is contained in:
parent
e0f3025752
commit
abaffc7b30
7
Coursework-Demo/Makefile
Normal file
7
Coursework-Demo/Makefile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CONTIKI_PROJECT = coursework
|
||||||
|
all: $(CONTIKI_PROJECT)
|
||||||
|
|
||||||
|
#UIP_CONF_IPV6=1
|
||||||
|
|
||||||
|
CONTIKI = ../..
|
||||||
|
include $(CONTIKI)/Makefile.include
|
141
Coursework-Demo/buffer.h
Normal file
141
Coursework-Demo/buffer.h
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#ifndef _BUFFER_GUARD
|
||||||
|
#define _BUFFER_GUARD
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
typedef struct Buffer {
|
||||||
|
float* items;
|
||||||
|
int length;
|
||||||
|
Stats stats;
|
||||||
|
} Buffer;
|
||||||
|
|
||||||
|
Buffer
|
||||||
|
getBuffer(int size) // retrieve new buffer with malloc-ed memory space
|
||||||
|
{
|
||||||
|
float* memSpace = (float*) malloc(size * sizeof(float));
|
||||||
|
Buffer buffer = {memSpace, size, };
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
freeBuffer(Buffer buffer) // little abstraction function to act as buffer destructor
|
||||||
|
{
|
||||||
|
free(buffer.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
swapBufferMemory(Buffer *first, Buffer *second) // swap memspaces between buffers
|
||||||
|
{
|
||||||
|
float* firstItems = first->items; // swap input buffer and output buffer item pointers
|
||||||
|
first->items = second->items;
|
||||||
|
second->items = firstItems;
|
||||||
|
|
||||||
|
int firstLength = first->length; // swap lengths to iterate correctly
|
||||||
|
first->length = second->length;
|
||||||
|
second->length = firstLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
void // perform aggregation into groupSize (4 in the spec)
|
||||||
|
aggregateBuffer(Buffer bufferIn, Buffer bufferOut, int groupSize)
|
||||||
|
{
|
||||||
|
int requiredGroups = ceil((float)bufferIn.length/groupSize); // number of groups
|
||||||
|
int finalGroupSize = bufferIn.length % groupSize; // work out length of final group if bufferIn not of length that divides nicely
|
||||||
|
|
||||||
|
if(requiredGroups > bufferOut.length) // error check
|
||||||
|
{
|
||||||
|
putFloat((float)bufferIn.length/groupSize); printf(" length out buffer required, %i provided\n", bufferOut.length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int g; // for group number
|
||||||
|
float *inputPtr = bufferIn.items; // cursor for full buffer
|
||||||
|
float *outputPtr = bufferOut.items; // cursor for output buffer
|
||||||
|
for(g = 0; g < requiredGroups; g++)
|
||||||
|
{
|
||||||
|
int length = groupSize; // length of this group's size
|
||||||
|
if(g == requiredGroups - 1 && finalGroupSize != 0) length = finalGroupSize; // shorten if necessary
|
||||||
|
|
||||||
|
*outputPtr = calculateMean(inputPtr, length); // SET OUTPUT VALUE
|
||||||
|
|
||||||
|
inputPtr += length; // increment both cursors
|
||||||
|
outputPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
calculateBufferEMA(Buffer inBuffer, Buffer outBuffer, float smooth)
|
||||||
|
{
|
||||||
|
if(smooth < 0 || smooth > 1) // VALIDATE SMOOTH VALUE
|
||||||
|
{
|
||||||
|
printf("Smoothing value of %f not valid, between 0 and 1 required", smooth);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inBuffer.length > outBuffer.length) // OUTPUT BUFFER LONG ENOUGH
|
||||||
|
{
|
||||||
|
printf("Out buffer not big enough to hold items");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
float *inputPtr = inBuffer.items; // cursor for full buffer
|
||||||
|
float *outputPtr = outBuffer.items; // cursor for output buffer
|
||||||
|
|
||||||
|
float emaLast;
|
||||||
|
for(i = 0; i < inBuffer.length; i++)
|
||||||
|
{
|
||||||
|
if(i == 0)
|
||||||
|
{
|
||||||
|
*outputPtr = *inputPtr; //first ema is first value
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*outputPtr = calculateEMA(*inputPtr, emaLast, smooth);
|
||||||
|
}
|
||||||
|
emaLast = *outputPtr; // keep this ema for next round
|
||||||
|
|
||||||
|
inputPtr++;
|
||||||
|
outputPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clearBuffer(Buffer buffer)
|
||||||
|
{
|
||||||
|
int length = buffer.length;
|
||||||
|
if(length > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float *bufferPtr = buffer.items;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
*bufferPtr = 0.0;
|
||||||
|
bufferPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
printBuffer(Buffer buffer)
|
||||||
|
{
|
||||||
|
putchar('[');
|
||||||
|
|
||||||
|
int length = buffer.length;
|
||||||
|
if(length > 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float *ptr = buffer.items;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if(i > 0) printf(", ");
|
||||||
|
|
||||||
|
putFloat(*ptr);
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
BIN
Coursework-Demo/contiki-sky.a
Normal file
BIN
Coursework-Demo/contiki-sky.a
Normal file
Binary file not shown.
2951
Coursework-Demo/contiki-sky.map
Normal file
2951
Coursework-Demo/contiki-sky.map
Normal file
File diff suppressed because it is too large
Load Diff
163
Coursework-Demo/cooja_coursework.csc
Normal file
163
Coursework-Demo/cooja_coursework.csc
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<simconf>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mrm</project>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/mspsim</project>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/avrora</project>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/serial_socket</project>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/collect-view</project>
|
||||||
|
<project EXPORT="discard">[CONTIKI_DIR]/tools/cooja/apps/powertracker</project>
|
||||||
|
<simulation>
|
||||||
|
<title>Aggregator Coursework</title>
|
||||||
|
<speedlimit>1.0</speedlimit>
|
||||||
|
<randomseed>123464</randomseed>
|
||||||
|
<motedelay_us>1000000</motedelay_us>
|
||||||
|
<radiomedium>
|
||||||
|
se.sics.cooja.radiomediums.UDGM
|
||||||
|
<transmitting_range>50.0</transmitting_range>
|
||||||
|
<interference_range>100.0</interference_range>
|
||||||
|
<success_ratio_tx>1.0</success_ratio_tx>
|
||||||
|
<success_ratio_rx>1.0</success_ratio_rx>
|
||||||
|
</radiomedium>
|
||||||
|
<events>
|
||||||
|
<logoutput>40000</logoutput>
|
||||||
|
</events>
|
||||||
|
<motetype>
|
||||||
|
se.sics.cooja.mspmote.SkyMoteType
|
||||||
|
<identifier>sky1</identifier>
|
||||||
|
<description>Sky Mote Type #sky1</description>
|
||||||
|
<source EXPORT="discard">[CONTIKI_DIR]/surrey/Coursework-Demo/coursework.c</source>
|
||||||
|
<commands EXPORT="discard">make coursework.sky TARGET=sky</commands>
|
||||||
|
<firmware EXPORT="copy">[CONTIKI_DIR]/surrey/Coursework-Demo/coursework.sky</firmware>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Position</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.RimeAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.IPAddress</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.interfaces.MoteAttributes</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspClock</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspMoteID</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyButton</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyFlash</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyCoffeeFilesystem</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.Msp802154Radio</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspSerial</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyLED</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.MspDebugOutput</moteinterface>
|
||||||
|
<moteinterface>se.sics.cooja.mspmote.interfaces.SkyTemperature</moteinterface>
|
||||||
|
</motetype>
|
||||||
|
<mote>
|
||||||
|
<breakpoints />
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.interfaces.Position
|
||||||
|
<x>29.99841204907099</x>
|
||||||
|
<y>-115.95137024353158</y>
|
||||||
|
<z>0.0</z>
|
||||||
|
</interface_config>
|
||||||
|
<interface_config>
|
||||||
|
se.sics.cooja.mspmote.interfaces.MspMoteID
|
||||||
|
<id>1</id>
|
||||||
|
</interface_config>
|
||||||
|
<motetype_identifier>sky1</motetype_identifier>
|
||||||
|
</mote>
|
||||||
|
</simulation>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.SimControl
|
||||||
|
<width>321</width>
|
||||||
|
<z>0</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>37</location_x>
|
||||||
|
<location_y>57</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.Visualizer
|
||||||
|
<plugin_config>
|
||||||
|
<skin>se.sics.cooja.plugins.skins.IDVisualizerSkin</skin>
|
||||||
|
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 153.72871631902638 172.41033658502872</viewport>
|
||||||
|
</plugin_config>
|
||||||
|
<width>314</width>
|
||||||
|
<z>6</z>
|
||||||
|
<height>179</height>
|
||||||
|
<location_x>40</location_x>
|
||||||
|
<location_y>20</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.TimeLine
|
||||||
|
<plugin_config>
|
||||||
|
<mote>0</mote>
|
||||||
|
<showRadioRXTX />
|
||||||
|
<showRadioHW />
|
||||||
|
<showLEDs />
|
||||||
|
<split>-1</split>
|
||||||
|
<zoomfactor>500.0</zoomfactor>
|
||||||
|
</plugin_config>
|
||||||
|
<width>1217</width>
|
||||||
|
<z>5</z>
|
||||||
|
<height>183</height>
|
||||||
|
<location_x>424</location_x>
|
||||||
|
<location_y>852</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.Notes
|
||||||
|
<plugin_config>
|
||||||
|
<notes>Enter notes here</notes>
|
||||||
|
<decorations>true</decorations>
|
||||||
|
</plugin_config>
|
||||||
|
<width>6</width>
|
||||||
|
<z>7</z>
|
||||||
|
<height>160</height>
|
||||||
|
<location_x>680</location_x>
|
||||||
|
<location_y>0</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.MoteInterfaceViewer
|
||||||
|
<mote_arg>0</mote_arg>
|
||||||
|
<plugin_config>
|
||||||
|
<interface>Serial port</interface>
|
||||||
|
<scrollpos>0,0</scrollpos>
|
||||||
|
</plugin_config>
|
||||||
|
<width>1201</width>
|
||||||
|
<z>1</z>
|
||||||
|
<height>706</height>
|
||||||
|
<location_x>408</location_x>
|
||||||
|
<location_y>15</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.MoteInterfaceViewer
|
||||||
|
<mote_arg>0</mote_arg>
|
||||||
|
<plugin_config>
|
||||||
|
<interface>Temperature and Light</interface>
|
||||||
|
<scrollpos>0,0</scrollpos>
|
||||||
|
</plugin_config>
|
||||||
|
<width>340</width>
|
||||||
|
<z>2</z>
|
||||||
|
<height>179</height>
|
||||||
|
<location_x>28</location_x>
|
||||||
|
<location_y>227</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.MoteInterfaceViewer
|
||||||
|
<mote_arg>0</mote_arg>
|
||||||
|
<plugin_config>
|
||||||
|
<interface>Sky LED</interface>
|
||||||
|
<scrollpos>0,0</scrollpos>
|
||||||
|
</plugin_config>
|
||||||
|
<width>317</width>
|
||||||
|
<z>4</z>
|
||||||
|
<height>206</height>
|
||||||
|
<location_x>28</location_x>
|
||||||
|
<location_y>445</location_y>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
se.sics.cooja.plugins.MoteInterfaceViewer
|
||||||
|
<mote_arg>0</mote_arg>
|
||||||
|
<plugin_config>
|
||||||
|
<interface>Button</interface>
|
||||||
|
<scrollpos>0,0</scrollpos>
|
||||||
|
</plugin_config>
|
||||||
|
<width>296</width>
|
||||||
|
<z>3</z>
|
||||||
|
<height>115</height>
|
||||||
|
<location_x>54</location_x>
|
||||||
|
<location_y>699</location_y>
|
||||||
|
</plugin>
|
||||||
|
</simconf>
|
||||||
|
|
248
Coursework-Demo/coursework.c
Normal file
248
Coursework-Demo/coursework.c
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
#define READING_INTERVAL 2 //in Hz
|
||||||
|
#define BUFFER_SIZE 12 // length of buffer to populate
|
||||||
|
|
||||||
|
// below thresholds are calibrated for the cooja slider
|
||||||
|
// they are likely not suitable for using on the mote
|
||||||
|
#define SD_THRESHOLD_SOME 400 // some activity, 4-to-1 above, 12-to-1 below
|
||||||
|
#define SD_THRESHOLD_LOTS 1000 // lots of activity, don't aggregate
|
||||||
|
|
||||||
|
#define AGGREGATION_GROUP_SIZE 4 // group size to aggregate (4 in spec)
|
||||||
|
|
||||||
|
#define INITIAL_STATE true // whether begins running or not
|
||||||
|
|
||||||
|
//#define SAX // use sax aggregation and transform instead of simple average aggregation
|
||||||
|
#define SAX_BREAKPOINTS 4 // number of characters to be used
|
||||||
|
|
||||||
|
#define EMA
|
||||||
|
#define EMA_SMOOTH 0.7 // smoothing factor
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
|
||||||
|
#include <stdio.h> /* For printf() */
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
#include "util.h" // for print methods
|
||||||
|
#include "math.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "sax.h"
|
||||||
|
|
||||||
|
static process_event_t event_buffer_full;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS(sensing_process, "Sensing process"); // collect data
|
||||||
|
PROCESS(aggregator_process, "Aggregator process"); // receive full data buffers for processing
|
||||||
|
|
||||||
|
AUTOSTART_PROCESSES(&sensing_process, &aggregator_process);
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(sensing_process, ev, data)
|
||||||
|
{
|
||||||
|
/*INIT*/
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
static bool isRunning = INITIAL_STATE;
|
||||||
|
static struct etimer timer;
|
||||||
|
if(isRunning) etimer_set(&timer, CLOCK_SECOND/READING_INTERVAL); // start timer if running
|
||||||
|
|
||||||
|
event_buffer_full = process_alloc_event(); // event for passing full buffers away for processing
|
||||||
|
initIO();
|
||||||
|
|
||||||
|
static Buffer buffer;
|
||||||
|
buffer = getBuffer(BUFFER_SIZE);
|
||||||
|
/*END INIT*/
|
||||||
|
|
||||||
|
static int counter = 0;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
PROCESS_WAIT_EVENT();
|
||||||
|
|
||||||
|
if (ev == PROCESS_EVENT_TIMER){
|
||||||
|
leds_off(LEDS_RED);
|
||||||
|
|
||||||
|
float light_lx = getLight(); // GET
|
||||||
|
|
||||||
|
buffer.items[counter] = light_lx; // STORE
|
||||||
|
|
||||||
|
printf("%2i/%i: ", counter + 1, buffer.length);putFloat(light_lx);putchar('\n'); // DISPLAY CURRENT VALUE
|
||||||
|
//printBuffer(buffer);putchar('\n'); // DISPLAY CURRENT BUFFER
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
if(counter == buffer.length) // CHECK WHETHER FULL
|
||||||
|
{
|
||||||
|
process_post(&aggregator_process, event_buffer_full, &buffer); // pass buffer to processing thread
|
||||||
|
counter = 0;
|
||||||
|
buffer = getBuffer(BUFFER_SIZE); // get new buffer for next data, no freeing in this thread
|
||||||
|
}
|
||||||
|
|
||||||
|
etimer_reset(&timer);
|
||||||
|
}
|
||||||
|
/* BUTTON CLICKED */
|
||||||
|
else if (ev == sensors_event && data == &button_sensor)
|
||||||
|
{
|
||||||
|
isRunning = !isRunning;
|
||||||
|
if (isRunning == true)
|
||||||
|
{
|
||||||
|
printf("Starting...\n");
|
||||||
|
etimer_set(&timer, CLOCK_SECOND/READING_INTERVAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Stopping, clearing buffer...\n");
|
||||||
|
etimer_stop(&timer);
|
||||||
|
counter = 0; // just reset counter, used as index on buffer items, will overwrite
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
PROCESS_THREAD(aggregator_process, ev, data)
|
||||||
|
{
|
||||||
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
PROCESS_WAIT_EVENT_UNTIL(ev == event_buffer_full);
|
||||||
|
leds_on(LEDS_RED);
|
||||||
|
|
||||||
|
Buffer fullBuffer = *(Buffer *)data;
|
||||||
|
/*********************/
|
||||||
|
#ifdef EMA
|
||||||
|
handleEMABufferRotation(&fullBuffer);
|
||||||
|
#elif SAX
|
||||||
|
handleSAXBufferRotation(&fullBuffer);
|
||||||
|
#else
|
||||||
|
handleSimpleBufferRotation(&fullBuffer); // pass by reference, edited if lots of activity
|
||||||
|
#endif
|
||||||
|
freeBuffer(fullBuffer);
|
||||||
|
/*********************/
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_END();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
// Buffer filled with readings, process and aggregate
|
||||||
|
void
|
||||||
|
handleSimpleBufferRotation(Buffer *inBufferPtr)
|
||||||
|
{
|
||||||
|
printf("Buffer full, aggregating\n\n");
|
||||||
|
|
||||||
|
Buffer inBuffer = *inBufferPtr;
|
||||||
|
Buffer outBuffer; // OUTPUT BUFFER HOLDER
|
||||||
|
// above pointer is assigned a buffer in either of the below cases
|
||||||
|
|
||||||
|
Stats sd = calculateStdDev(inBuffer.items, inBuffer.length); // GET BUFFER STATISTICS
|
||||||
|
|
||||||
|
printf("B = ");printBuffer(inBuffer);putchar('\n');
|
||||||
|
printf("StdDev = ");putFloat(sd.std);putchar('\n');
|
||||||
|
printf("Aggregation = ");
|
||||||
|
|
||||||
|
/* LOTS OF ACTIVITY - LEAVE */
|
||||||
|
if(sd.std > SD_THRESHOLD_LOTS)
|
||||||
|
{
|
||||||
|
//printf("Lots of activity, std. dev.: ");putFloat(sd.std);printf(", leaving as-is\n");
|
||||||
|
puts("None");
|
||||||
|
|
||||||
|
outBuffer = getBuffer(1); // get a dummy buffer, will swap items for efficiency
|
||||||
|
|
||||||
|
swapBufferMemory(inBufferPtr, &outBuffer); // ensures both are freed but no need to copy items
|
||||||
|
|
||||||
|
}
|
||||||
|
/* SOME ACTIVITY - AGGREGATE */
|
||||||
|
else if(sd.std > SD_THRESHOLD_SOME)
|
||||||
|
{
|
||||||
|
//printf("Some activity, std. dev.: ");putFloat(sd.std);printf(", compressing buffer\n");
|
||||||
|
puts("4-into-1");
|
||||||
|
|
||||||
|
int outLength = ceil((float)inBuffer.length/AGGREGATION_GROUP_SIZE); // CALCULATE NUMBER OF OUTPUT ELEMENTS
|
||||||
|
outBuffer = getBuffer(outLength); // CREATE OUTPUT BUFFER
|
||||||
|
|
||||||
|
aggregateBuffer(inBuffer, outBuffer, AGGREGATION_GROUP_SIZE);
|
||||||
|
|
||||||
|
}
|
||||||
|
/* NO ACTIVITY - FLATTEN */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//printf("Insignificant std. dev.: ");putFloat(sd.std);printf(", squashing buffer\n");
|
||||||
|
puts("12-into-1");
|
||||||
|
|
||||||
|
outBuffer = getBuffer(1); // CREATE OUTPUT BUFFER
|
||||||
|
|
||||||
|
outBuffer.items[0] = sd.mean;
|
||||||
|
}
|
||||||
|
outBuffer.stats = sd; // final compressed buffer has stats for uncompressed data in case of further interest
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
handleFinalBuffer(outBuffer); // PASS FINAL BUFFER
|
||||||
|
freeBuffer(outBuffer); // RELEASE ITEMS
|
||||||
|
/*********************/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handleSAXBufferRotation(Buffer *inBufferPtr)
|
||||||
|
{
|
||||||
|
printf("Buffer full, SAX-ing\n\n");
|
||||||
|
|
||||||
|
Buffer inBuffer = *inBufferPtr;
|
||||||
|
Buffer outBuffer; // OUTPUT BUFFER HOLDER
|
||||||
|
// above pointer is assigned a buffer in either of the below cases
|
||||||
|
|
||||||
|
int outLength = ceil((float)inBuffer.length/AGGREGATION_GROUP_SIZE); // CALCULATE NUMBER OF OUTPUT ELEMENTS
|
||||||
|
outBuffer = getBuffer(outLength); // CREATE OUTPUT BUFFER
|
||||||
|
|
||||||
|
inBuffer.stats = calculateStdDev(inBuffer.items, inBuffer.length); // GET BUFFER STATISTICS
|
||||||
|
outBuffer.stats = inBuffer.stats;
|
||||||
|
|
||||||
|
normaliseBuffer(inBuffer); // Z NORMALISATION
|
||||||
|
aggregateBuffer(inBuffer, outBuffer, AGGREGATION_GROUP_SIZE); // PAA
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
handleFinalBuffer(outBuffer); // PASS FINAL BUFFER
|
||||||
|
freeBuffer(outBuffer); // RELEASE ITEMS
|
||||||
|
/*********************/
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
handleEMABufferRotation(Buffer *inBufferPtr)
|
||||||
|
{
|
||||||
|
printf("Buffer full, EMA-ing\n\n");
|
||||||
|
|
||||||
|
Buffer inBuffer = *inBufferPtr;
|
||||||
|
Buffer outBuffer; // OUTPUT BUFFER HOLDER
|
||||||
|
// above pointer is assigned a buffer in either of the below cases
|
||||||
|
|
||||||
|
outBuffer = getBuffer(inBuffer.length); // CREATE OUTPUT BUFFER
|
||||||
|
|
||||||
|
calculateBufferEMA(inBuffer, outBuffer, EMA_SMOOTH);
|
||||||
|
|
||||||
|
printf("X: ");printBuffer(inBuffer);putchar('\n');
|
||||||
|
printf("Smoothing factor: ");putFloat(EMA_SMOOTH);putchar('\n');putchar('\n');
|
||||||
|
|
||||||
|
/*********************/
|
||||||
|
handleFinalBuffer(outBuffer); // PASS FINAL BUFFER
|
||||||
|
freeBuffer(outBuffer); // RELEASE ITEMS
|
||||||
|
/*********************/
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process final buffer following aggregation
|
||||||
|
void
|
||||||
|
handleFinalBuffer(Buffer buffer)
|
||||||
|
{
|
||||||
|
#ifdef EMA
|
||||||
|
printf("EMA: ");printBuffer(buffer);putchar('\n');
|
||||||
|
#elif SAX
|
||||||
|
printf("X: ");printBuffer(buffer);putchar('\n');
|
||||||
|
printf("Mean: ");putFloat(buffer.stats.mean);putchar('\n');
|
||||||
|
printf("Std Dev: ");putFloat(buffer.stats.std);putchar('\n');putchar('\n');
|
||||||
|
|
||||||
|
char* saxString = stringifyBuffer(buffer);
|
||||||
|
printf("SAX: %s\n", saxString);
|
||||||
|
|
||||||
|
free(saxString);
|
||||||
|
#else
|
||||||
|
printf("X: ");printBuffer(buffer);putchar('\n');
|
||||||
|
#endif
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
BIN
Coursework-Demo/coursework.sky
Normal file
BIN
Coursework-Demo/coursework.sky
Normal file
Binary file not shown.
28
Coursework-Demo/io.h
Normal file
28
Coursework-Demo/io.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef _IO_GUARD
|
||||||
|
#define _IO_GUARD
|
||||||
|
|
||||||
|
#include "dev/light-sensor.h"
|
||||||
|
#include "dev/button-sensor.h"
|
||||||
|
#include "dev/leds.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
initIO()
|
||||||
|
{
|
||||||
|
SENSORS_ACTIVATE(light_sensor);
|
||||||
|
SENSORS_ACTIVATE(button_sensor);
|
||||||
|
leds_off(LEDS_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get float from light sensor including transfer function
|
||||||
|
float
|
||||||
|
getLight(void)
|
||||||
|
{
|
||||||
|
int lightData = light_sensor.value(LIGHT_SENSOR_PHOTOSYNTHETIC);
|
||||||
|
|
||||||
|
float V_sensor = 1.5 * lightData / 4096;
|
||||||
|
float I = V_sensor/1e5;
|
||||||
|
float light = 0.625 * 1e6 * I * 1000;
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
88
Coursework-Demo/math.h
Normal file
88
Coursework-Demo/math.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef _MATH_GUARD
|
||||||
|
#define _MATH_GUARD
|
||||||
|
|
||||||
|
typedef struct Stats {
|
||||||
|
float mean;
|
||||||
|
float std;
|
||||||
|
} Stats;
|
||||||
|
|
||||||
|
float
|
||||||
|
calculateEMA(float nextValue, float emaLast, float smooth)
|
||||||
|
{
|
||||||
|
if(smooth < 0 || smooth > 1) // validate smooth value
|
||||||
|
{
|
||||||
|
printf("Smoothing value of %f not valid, between 0 and 1 required", smooth);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (smooth * nextValue) + ((1 - smooth) * emaLast);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ceil(float in) // self-implement ceil func, no math.h
|
||||||
|
{
|
||||||
|
int num = (int) in;
|
||||||
|
if(in - num > 0) num++;
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
sqrt(float in) // self-implement sqrt func, no math.h
|
||||||
|
{
|
||||||
|
float sqrt = in/2;
|
||||||
|
float temp = 0;
|
||||||
|
|
||||||
|
while(sqrt != temp)
|
||||||
|
{
|
||||||
|
temp = sqrt;
|
||||||
|
sqrt = (in/temp + temp) / 2;
|
||||||
|
}
|
||||||
|
return sqrt;
|
||||||
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
calculateMean(float buffer[], int length)
|
||||||
|
{
|
||||||
|
if(length <= 0)
|
||||||
|
{
|
||||||
|
printf("%i items is not valid length\n", length);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SUM */
|
||||||
|
float sum = 0;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
sum += buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum / length; // DIVIDE ON RETURN
|
||||||
|
}
|
||||||
|
|
||||||
|
Stats
|
||||||
|
calculateStdDev(float buffer[], int length)
|
||||||
|
{
|
||||||
|
Stats stats;
|
||||||
|
if(length <= 0)
|
||||||
|
{
|
||||||
|
printf("%i items is not valid length\n", length);
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.mean = calculateMean(buffer, length);
|
||||||
|
|
||||||
|
float sum = 0;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
float diffFromMean = buffer[i] - stats.mean; // (xi - mu)
|
||||||
|
sum += diffFromMean*diffFromMean; // Sum(diff squared)
|
||||||
|
}
|
||||||
|
|
||||||
|
stats.std = sqrt(sum/length);
|
||||||
|
|
||||||
|
return stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
92
Coursework-Demo/sax.h
Normal file
92
Coursework-Demo/sax.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#ifndef _SAX_GUARD
|
||||||
|
#define _SAX_GUARD
|
||||||
|
|
||||||
|
#define SAX_CHAR_START 'a'
|
||||||
|
|
||||||
|
#ifndef SAX_BREAKPOINTS
|
||||||
|
#define SAX_BREAKPOINTS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Could have used a 2d array for breakpoints, index by number of breakpoints
|
||||||
|
|
||||||
|
// Since the number of boundaries is known at compile-time, save these lookup calls by
|
||||||
|
// defining as as constant 1D arrays
|
||||||
|
|
||||||
|
#if SAX_BREAKPOINTS == 3
|
||||||
|
const float breakPoints[] = {-0.43, 0.43};
|
||||||
|
#elif SAX_BREAKPOINTS == 4
|
||||||
|
const float breakPoints[] = {-0.67, 0, 0.67};
|
||||||
|
#elif SAX_BREAKPOINTS == 5
|
||||||
|
const float breakPoints[] = {-0.84, -0.25, 0.25, 0.84};
|
||||||
|
#elif SAX_BREAKPOINTS == 6
|
||||||
|
const float breakPoints[] = {-0.97, -0.43, 0, 0.43, 0.97};
|
||||||
|
#elif SAX_BREAKPOINTS == 7
|
||||||
|
const float breakPoints[] = {-1.07, -0.57, -0.18, 0.18, 0.57, 1.07};
|
||||||
|
#elif SAX_BREAKPOINTS == 8
|
||||||
|
const float breakPoints[] = {-1.15, -0.67, -0.32, 0, 0.32, 0.67, 1.15};
|
||||||
|
#elif SAX_BREAKPOINTS == 9
|
||||||
|
const float breakPoints[] = {-1.22, -0.76, -0.43, -0.14, 0.14, 0.43, 0.76, 1.22};
|
||||||
|
#elif SAX_BREAKPOINTS == 10
|
||||||
|
const float breakPoints[] = {-1.28, -0.84, -0.52, -0.25, 0, 0.25, 0.52, 0.84, 1.28};
|
||||||
|
#else
|
||||||
|
#define SAX_BREAKPOINTS 4
|
||||||
|
const float breakPoints[] = {-0.67, 0, 0.67};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
normaliseBuffer(Buffer bufferIn) // z normalise buffer for SAX
|
||||||
|
{
|
||||||
|
if(bufferIn.stats.std == 0) // error check, don't divide by 0
|
||||||
|
{
|
||||||
|
printf("Standard deviation of zero, unable to normalise\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int i;
|
||||||
|
float *inputPtr = bufferIn.items; // cursor
|
||||||
|
for(i = 0; i < bufferIn.length; i++)
|
||||||
|
{
|
||||||
|
*inputPtr = (*inputPtr - bufferIn.stats.mean) / bufferIn.stats.std;
|
||||||
|
|
||||||
|
inputPtr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
valueToSAXChar(float inputValue)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < SAX_BREAKPOINTS; i++)
|
||||||
|
{
|
||||||
|
if(i == 0) // first iter, is less than first breakpoint
|
||||||
|
{
|
||||||
|
if(inputValue < breakPoints[i]) return SAX_CHAR_START + i;
|
||||||
|
}
|
||||||
|
else if(i == SAX_BREAKPOINTS - 1) // last iter, is more than last breakpoint
|
||||||
|
{
|
||||||
|
if(breakPoints[i - 1] < inputValue) return SAX_CHAR_START + i;
|
||||||
|
}
|
||||||
|
else // in between check interval of two breakpoints
|
||||||
|
{
|
||||||
|
if((breakPoints[i - 1] < inputValue) && (inputValue < breakPoints[i])) return SAX_CHAR_START + i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char* // map buffer of normalised floats into SAX chars
|
||||||
|
stringifyBuffer(Buffer bufferIn)
|
||||||
|
{
|
||||||
|
char* outputString = (char*) malloc((bufferIn.length + 1) * sizeof(char)); // +1 for null terminator
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < bufferIn.length; i++)
|
||||||
|
{
|
||||||
|
outputString[i] = valueToSAXChar(bufferIn.items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputString[bufferIn.length] = '\0'; // add null terminator
|
||||||
|
return outputString;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
4
Coursework-Demo/symbols.c
Normal file
4
Coursework-Demo/symbols.c
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include "symbols.h"
|
||||||
|
|
||||||
|
const int symbols_nelts = 0;
|
||||||
|
const struct symbols symbols[] = {{0,0}};
|
3
Coursework-Demo/symbols.h
Normal file
3
Coursework-Demo/symbols.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include "loader/symbols.h"
|
||||||
|
|
||||||
|
extern const struct symbols symbols[1];
|
37
Coursework-Demo/util.h
Normal file
37
Coursework-Demo/util.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef _UTIL_GUARD
|
||||||
|
#define _UTIL_GUARD
|
||||||
|
|
||||||
|
typedef unsigned short USHORT;
|
||||||
|
|
||||||
|
//print a unsigned short picewise char by char
|
||||||
|
void
|
||||||
|
putShort(USHORT in)
|
||||||
|
{
|
||||||
|
// recursively shift each digit of the int to units from most to least significant
|
||||||
|
if (in >= 10)
|
||||||
|
{
|
||||||
|
putShort(in / 10);
|
||||||
|
}
|
||||||
|
// isolate unit digit from each number by modulo and add '0' char to turn integer into corresponding ascii char
|
||||||
|
putchar((in % 10) + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
putFloat(float in)
|
||||||
|
{
|
||||||
|
if(in < 0)
|
||||||
|
{
|
||||||
|
putchar('-'); // print negative sign if required
|
||||||
|
in = -in;
|
||||||
|
}
|
||||||
|
|
||||||
|
USHORT integerComponent = (USHORT) in; // truncate float to integer
|
||||||
|
float fractionComponent = (in - integerComponent) * 1000; // take fraction only and promote to integer
|
||||||
|
if (fractionComponent - (USHORT)fractionComponent >= 0.5) fractionComponent++; // round
|
||||||
|
|
||||||
|
putShort(integerComponent);
|
||||||
|
putchar('.');
|
||||||
|
putShort((USHORT) fractionComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user