aboutsummaryrefslogtreecommitdiff
path: root/Arduino
diff options
context:
space:
mode:
Diffstat (limited to 'Arduino')
-rw-r--r--Arduino/Queue.cpp147
-rw-r--r--Arduino/Queue.h39
-rw-r--r--Arduino/Tests/arduinoTests.ino185
3 files changed, 371 insertions, 0 deletions
diff --git a/Arduino/Queue.cpp b/Arduino/Queue.cpp
new file mode 100644
index 0000000..f428228
--- /dev/null
+++ b/Arduino/Queue.cpp
@@ -0,0 +1,147 @@
+#include "Queue.h"
+
+Queue::Queue()
+{
+ _itemsInQueue = 0;
+ _queueStart = 0;
+ _queueEnd = 0;
+}
+
+int Queue::scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur)
+{
+ int rv = 0;
+
+ if(strlen(id) > 7)
+ {
+ rv = -1;
+ } else {
+
+ queueItem newItem;
+ newItem.fPtr = func;
+ memset(newItem.itemName, 0, 8);
+ memcpy(newItem.itemName, id, strlen(id));
+ newItem.recur = recur;
+ newItem.next = initialRun;
+
+ rv = _addToQueue(newItem);
+ }
+
+ return rv;
+}
+
+int Queue::scheduleRemoveFunction(const char * id)
+{
+ queueItem target;
+ int rv = -1;
+ for (int i = 0; i < _itemsInQueue; ++i)
+ {
+ if(_queueGetTop(target) == 0)
+ {
+ if(strcmp(target.itemName, id) == 0)
+ {
+ rv = 0;
+ } else {
+ _addToQueue(target);
+ }
+ } else {
+ rv = -1;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+int Queue::scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur)
+{
+ queueItem target;
+ int rv = -1;
+ for (int i = 0; i < _itemsInQueue; ++i)
+ {
+ if(_queueGetTop(target) == 0)
+ {
+ if(strcmp(target.itemName, id) == 0)
+ {
+ target.next = nextRunTime;
+ target.recur = newRecur;
+ rv = 0;
+ }
+ _addToQueue(target);
+ } else {
+ rv = -1;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+int Queue::Run(unsigned long now)
+{
+ queueItem target;
+ int rv = 0;
+ if(_itemsInQueue == 0)
+ {
+ rv = -1;
+ }
+ for (int i = 0; i < _itemsInQueue; ++i)
+ {
+ if(_queueGetTop(target)==0)
+ {
+ if(target.next <= now)
+ {
+ int tRv;
+ tRv = (target.fPtr)(now);
+ if(tRv == 0)
+ {
+ rv++;
+ }
+ if(target.recur != 0)
+ {
+ target.next = now + target.recur;
+ _addToQueue(target);
+ }
+ } else {
+ _addToQueue(target);
+ }
+ } else {
+ rv = -1;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+int Queue::_queueGetTop(queueItem &item)
+{
+ int rv = 0;
+ //Remove the top item, stuff it into item
+ if (_queueEnd != _queueStart) {
+ queueItem tempQueueItem = _schedule[_queueStart];
+ //This Algorithm also from Wikipedia.
+ _queueStart = (_queueStart + 1) % QueueScheduleSize;
+ item = tempQueueItem;
+ _itemsInQueue--;
+ } else {
+ //if the buffer is empty, return an error code
+ rv = -1;
+ }
+
+ return rv;
+}
+
+int Queue::_addToQueue(queueItem item)
+{
+ //This is just a circular buffer, and this algorithm is stolen from wikipedia
+ int rv = 0;
+ if ((_queueEnd + 1) % QueueScheduleSize != _queueStart) {
+ _schedule[_queueEnd] = item;
+ _queueEnd = (_queueEnd + 1) % QueueScheduleSize;
+ _itemsInQueue++;
+ } else {
+ //if buffer is full, error
+ rv = -1;
+ }
+ return rv;
+} \ No newline at end of file
diff --git a/Arduino/Queue.h b/Arduino/Queue.h
new file mode 100644
index 0000000..d23afb3
--- /dev/null
+++ b/Arduino/Queue.h
@@ -0,0 +1,39 @@
+#ifndef QUEUE_H
+#define QUEUE_H
+
+#include "Arduino.h"
+
+typedef int (*queuedFunction)(unsigned long);
+
+#define QueueScheduleSize 11
+
+struct queueItem {
+ queuedFunction fPtr;
+ unsigned long next;
+ unsigned long recur;
+ char itemName[8];
+};
+
+class Queue
+{
+private:
+ unsigned int _queueStart;
+ unsigned int _queueEnd;
+ unsigned int _itemsInQueue;
+ queueItem _schedule[QueueScheduleSize];
+
+ int _queueGetTop(queueItem &item);
+ int _addToQueue(queueItem item);
+
+public:
+ Queue();
+
+ int scheduleFunction(queuedFunction func, const char * id, unsigned long initialRun, unsigned long recur);
+ int scheduleRemoveFunction(const char * id);
+ int scheduleChangeFunction(const char * id, unsigned long nextRunTime, unsigned long newRecur);
+
+ int Run(unsigned long now);
+ /* data */
+};
+
+#endif \ No newline at end of file
diff --git a/Arduino/Tests/arduinoTests.ino b/Arduino/Tests/arduinoTests.ino
new file mode 100644
index 0000000..653ae5f
--- /dev/null
+++ b/Arduino/Tests/arduinoTests.ino
@@ -0,0 +1,185 @@
+#include <Queue.h>
+
+/*
+ Blink
+ Turns on an LED on for one second, then off for one second, repeatedly.
+
+ This example code is in the public domain.
+ */
+
+void setup() {
+ // initialize the digital pin as an output.
+ // Pin 13 has an LED connected on most Arduino boards:
+ pinMode(13, OUTPUT);
+ Serial.begin(9600);
+ Serial.println("Alive");
+
+ int testStatus = 0;
+ testStatus |= test_addTooMany();
+ testStatus |= test_removeNonExistent();
+ testStatus |= test_tooManyCharacters();
+ testStatus |= test_changeNonExistent();
+ testStatus |= test_runEmpty();
+
+ if(testStatus == 0)
+ {
+ Serial.println("All tests passed.");
+ } else {
+ Serial.println("Something Failed.");
+ }
+
+}
+
+void loop() {
+ delay(1000);
+}
+
+int testFunction(unsigned long now)
+{
+ Serial.print("Hello: ");
+ Serial.print(now);
+ Serial.println();
+}
+
+int test_addTooMany(void)
+{
+ Queue testQueue;
+ int rv;
+ int testStatus = 0;
+ rv = testQueue.scheduleFunction(testFunction, "Test1", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test2", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test3", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test4", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test5", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test6", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test7", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test8", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test9", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test10", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleFunction(testFunction, "Test11", 5000, 1000);
+ if(rv != -1)
+ {
+ Serial.println("test_addTooMany failed.");
+ testStatus = -1;
+ }
+
+ return testStatus;
+}
+
+int test_removeNonExistent(void)
+{
+ Queue testQueue;
+ int rv;
+ int testStatus = 0;
+ rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_removeNonExistent failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleRemoveFunction("Fail");
+ if(rv != -1)
+ {
+ Serial.println("test_removeNonExistent failed.");
+ testStatus = -1;
+ }
+ return testStatus;
+}
+
+int test_tooManyCharacters(void)
+{
+ Queue testQueue;
+ int rv;
+ int testStatus = 0;
+ rv = testQueue.scheduleFunction(testFunction, "ReallyLongName", 5000, 1000);
+ if(rv != -1)
+ {
+ Serial.println("test_tooManyCharacters failed.");
+ testStatus = -1;
+ }
+ return testStatus;
+}
+
+int test_changeNonExistent(void)
+{
+ Queue testQueue;
+ int rv;
+ int testStatus = 0;
+ rv = testQueue.scheduleFunction(testFunction, "Test", 5000, 1000);
+ if(rv != 0)
+ {
+ Serial.println("test_changeNonExistent failed.");
+ testStatus = -1;
+ }
+ rv = testQueue.scheduleChangeFunction("Fail", 1000, 1000);
+ if(rv != -1)
+ {
+ Serial.println("test_changeNonExistent failed.");
+ testStatus = -1;
+ }
+ return testStatus;
+}
+
+int test_runEmpty(void)
+{
+ Queue myQueue;
+ int rv = 0;
+ int testStatus = 0;
+ rv = myQueue.Run(10);
+ if (rv != -1)
+ {
+ Serial.println("test_runEmpty failed.");
+ testStatus = -1;
+ }
+ return testStatus;
+} \ No newline at end of file