diff --git a/LeonardoMixerIO/doc/Dokumentation_Systemtechnik.pdf b/LeonardoMixerIO/doc/Dokumentation_Systemtechnik.pdf
index e3bc35ae922d1c6e4c35b27a9324d4f1425c8866..fc73855e358c18006ebb4bde331466095077cc2c 100644
Binary files a/LeonardoMixerIO/doc/Dokumentation_Systemtechnik.pdf and b/LeonardoMixerIO/doc/Dokumentation_Systemtechnik.pdf differ
diff --git a/LeonardoMixerIO/src/LeonardoMixer.cpp b/LeonardoMixerIO/src/LeonardoMixer.cpp
index c5ebd12c66784e5b84c42302fad4a6ecad8410db..669c6b4c8b852193abc0d98c89a31efc5b58b5db 100644
--- a/LeonardoMixerIO/src/LeonardoMixer.cpp
+++ b/LeonardoMixerIO/src/LeonardoMixer.cpp
@@ -1,3 +1,4 @@
+
 // LeonardoMixer.cpp
 // Copyright 2016, 2017 Lukas Friedrichsen, Philipp Stenkamp
 // License: Modified BSD-License
diff --git a/LeonardoMixerIO/src/Scheduler.cpp b/LeonardoMixerIO/src/Scheduler.cpp
index 5bdb1aba430013701a17a532539fac9d56926836..36f10e1375016c52e8081da22a74cbaf4da45bfd 100644
--- a/LeonardoMixerIO/src/Scheduler.cpp
+++ b/LeonardoMixerIO/src/Scheduler.cpp
@@ -226,8 +226,8 @@ unsigned long Scheduler::getTaskTimerDiff (task *taskToGet) {
 // Handles the functions excluding send
 void Scheduler::perform (void) {
   if (taskCounter && *taskCounter) {
-    (*taskCounter)->activity();
     updateTaskTimer((task *) *taskCounter);
+    (*taskCounter)->activity();
     taskCounter++;
   }
   else if (nRtTasks) {
@@ -245,6 +245,8 @@ void Scheduler::exterminate (void){
 
 // Scheduler, called cyclical in the loop-function
 void Scheduler::schedule (void) {
+  long diff;
+  long schedTime = micros();
   if (rtTasks) {
     unsigned long timerDiff = getTaskTimerDiff(rtTasks->listElement);
     unsigned long cycleTime = getTaskCycleTime((rtTask *) rtTasks->listElement);
@@ -258,13 +260,14 @@ void Scheduler::schedule (void) {
           exterminate();
         }
       }
-      rtTasks->listElement->activity();
       updateTaskTimer(rtTasks->listElement);
+      rtTasks->listElement->activity();
       rtTasks = sortRtTasks(rtTasks);
       if (nRtTasks){
         setPriorities();
         taskCounter = nRtTasks;
       }
+      diff = micros()-schedTime;
     }
     else if (nRtTasks) {
       perform();
@@ -279,4 +282,9 @@ void Scheduler::schedule (void) {
     }
     // No tasks... Nothing to do!
   }
+
+  if (debugger) {
+    debugger->print("schedule runtime: ");
+    debugger->println(diff);
+  }
 }
diff --git a/SchedulerPerformance/.gitignore b/SchedulerPerformance/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..934359b46eeaa32338143ad01df78b353ffad436
--- /dev/null
+++ b/SchedulerPerformance/.gitignore
@@ -0,0 +1,5 @@
+.pioenvs
+.clang_complete
+.gcc-flags.json
+.piolibdeps
+.pioenvs
diff --git a/SchedulerPerformance/.travis.yml b/SchedulerPerformance/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2c4ff5c9885cd682b31b389d63a97cf8cee91f55
--- /dev/null
+++ b/SchedulerPerformance/.travis.yml
@@ -0,0 +1,65 @@
+# Continuous Integration (CI) is the practice, in software
+# engineering, of merging all developer working copies with a shared mainline
+# several times a day < http://docs.platformio.org/page/ci/index.html >
+#
+# Documentation:
+#
+# * Travis CI Embedded Builds with PlatformIO
+#   < https://docs.travis-ci.com/user/integration/platformio/ >
+#
+# * PlatformIO integration with Travis CI
+#   < http://docs.platformio.org/page/ci/travis.html >
+#
+# * User Guide for `platformio ci` command
+#   < http://docs.platformio.org/page/userguide/cmd_ci.html >
+#
+#
+# Please choice one of the following templates (proposed below) and uncomment
+# it (remove "# " before each line) or use own configuration according to the
+# Travis CI documentation (see above).
+#
+
+
+#
+# Template #1: General project. Test it using existing `platformio.ini`.
+#
+
+# language: python
+# python:
+#     - "2.7"
+#
+# sudo: false
+# cache:
+#     directories:
+#         - "~/.platformio"
+#
+# install:
+#     - pip install -U platformio
+#
+# script:
+#     - platformio run
+
+
+#
+# Template #2: The project is intended to by used as a library with examples
+#
+
+# language: python
+# python:
+#     - "2.7"
+#
+# sudo: false
+# cache:
+#     directories:
+#         - "~/.platformio"
+#
+# env:
+#     - PLATFORMIO_CI_SRC=path/to/test/file.c
+#     - PLATFORMIO_CI_SRC=examples/file.ino
+#     - PLATFORMIO_CI_SRC=path/to/test/directory
+#
+# install:
+#     - pip install -U platformio
+#
+# script:
+#     - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/SchedulerPerformance/LICENSE.txt b/SchedulerPerformance/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fab0530340b8ab7bef448b8a291d075ef5cf4ea4
--- /dev/null
+++ b/SchedulerPerformance/LICENSE.txt
@@ -0,0 +1,7 @@
+LeonardoMixerIO
+Copyright 2016, 2017 Lukas Friedrichsen, Philipp Stenkamp
+License: Modified BSD-License
+
+Realtime RC mixer for Arduino-devices
+
+2017-02-10
diff --git a/SchedulerPerformance/Pseudocode.txt b/SchedulerPerformance/Pseudocode.txt
new file mode 100644
index 0000000000000000000000000000000000000000..68f233e9a1a75b1f1a83a670d9d42edaa5145c1b
--- /dev/null
+++ b/SchedulerPerformance/Pseudocode.txt
@@ -0,0 +1,91 @@
+r timer;
+int taskCounter = 1;
+int priorityCounter = 1;
+
+Tasks senden = new Task(
+  void *send (void){
+    ...
+  }
+  , 0);
+
+Tasks mischen = new Task(
+  void *mix (void){
+    ...
+  }
+  , 2);
+
+Tasks empfangen = new Task(
+  void receive (void){
+    ...
+  }
+  , 1);
+
+Tasks *tasks = {senden, mischen, empfangen};  //Jedem Task muss eine eindeutige, fortlaufende Priorität gegeben werden!
+
+struct {
+  boolean empfangen;
+  int data;
+  input protocol;
+} signal;
+
+signal *inputs = {...};
+
+void scheduler (void){
+  switch timer:
+    case >20ms:
+      resetTimer();
+      task[0].activity();
+      setPriorities();
+    case <20ms:
+      perform();
+}
+
+void resetTimer (void){
+  timer = 0;
+}
+
+void aktualisiereTimer (void){
+  timer += ticksseitletztemaktualisieren/tickfrequenz
+}
+
+void setPriorities (void){
+  if (alleEmpfangen()){
+    task[1].priority = 1;
+    tasks[2].priority = 2;
+  }
+  else {
+    task[1].priority = 2;
+    tasks[2].priority = 1;
+  }
+  taskCounter = 1;
+  priorityCounter = 1;
+}
+
+void perform (void){
+  if (taskCounter > tasks.length()){
+    taskCounter = 1;
+    priorityCounter++;
+  }
+  if (priorityCounter > tasks.length(){
+    priorityCounter = 1;
+  }
+  if (tasks[taskCounter].priority == priorityCounter){
+    tasks[taskCounter].activity();
+  }
+  taskCounter++;
+}
+
+boolean alleEmpfangen (void){
+  boolean ready = true;
+  for (int i = 0; i <= input.length(); i++){
+    ready = ready & input[i].empfangen;
+  }
+  return empfangen;
+}
+
+void main (void){
+  while (true){
+    aktualisiereTimer();
+    scheduler();
+  }
+}
diff --git a/SchedulerPerformance/lib/readme.txt b/SchedulerPerformance/lib/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c196e2868378cc663483751768b0f8165ca8648
--- /dev/null
+++ b/SchedulerPerformance/lib/readme.txt
@@ -0,0 +1,36 @@
+
+This directory is intended for the project specific (private) libraries.
+PlatformIO will compile them to static libraries and link to executable file.
+
+The source code of each library should be placed in separate directory, like
+"lib/private_lib/[here are source files]".
+
+For example, see how can be organized `Foo` and `Bar` libraries:
+
+|--lib
+|  |--Bar
+|  |  |--docs
+|  |  |--examples
+|  |  |--src
+|  |     |- Bar.c
+|  |     |- Bar.h
+|  |--Foo
+|  |  |- Foo.c
+|  |  |- Foo.h
+|  |- readme.txt --> THIS FILE
+|- platformio.ini
+|--src
+   |- main.c
+
+Then in `src/main.c` you should use:
+
+#include <Foo.h>
+#include <Bar.h>
+
+// rest H/C/CPP code
+
+PlatformIO will find your libraries automatically, configure preprocessor's
+include paths and build them.
+
+More information about PlatformIO Library Dependency Finder
+- http://docs.platformio.org/page/librarymanager/ldf.html
diff --git a/SchedulerPerformance/platformio.ini b/SchedulerPerformance/platformio.ini
new file mode 100644
index 0000000000000000000000000000000000000000..29dafa993fdb962570170d3a20734172717ae96d
--- /dev/null
+++ b/SchedulerPerformance/platformio.ini
@@ -0,0 +1,14 @@
+; PlatformIO Project Configuration File
+;
+;   Build options: build flags, source filter
+;   Upload options: custom upload port, speed and extra flags
+;   Library options: dependencies, extra library storages
+;   Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; http://docs.platformio.org/page/projectconf.html
+
+[env:leonardo]
+platform = atmelavr
+board = leonardo
+framework = arduino
diff --git a/SchedulerPerformance/src/PerformanceTest.cpp b/SchedulerPerformance/src/PerformanceTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e437c4f636c6111bbfdc5b35d0a73fc2510db943
--- /dev/null
+++ b/SchedulerPerformance/src/PerformanceTest.cpp
@@ -0,0 +1,95 @@
+// PerformanceTest.cpp
+// Copyright 2017 Lukas Friedrichsen, Philipp Stenkamp
+// License: Modified BSD-License
+//
+// Test-Application for the Scheduler
+//
+// 2017-01-06
+
+
+#include <Arduino.h>
+#include "Scheduler.h"
+
+Scheduler *scheduler;
+rtTask rt1, rt2, rt3;
+rtTask *rtTasks[] = { &rt1, &rt2, &rt3, NULL };
+nRtTask nrt1, nrt2;
+//nRtTask *nRtTasks[] = { &nrt1, &nrt2,  NULL };
+nRtTask *nRtTasks[] = { NULL };
+
+long lastTime;
+
+void no_Function (void)
+{
+  return;
+}
+
+void nrt1_Function (void)
+  {
+    //return;// do nothing
+
+    long tmpTime = micros();
+
+    Serial.print("Timestamp nrt1: ");
+    Serial.print(tmpTime);
+    Serial.print(", Diff: ");
+    Serial.println(tmpTime - lastTime);
+    lastTime = micros();
+
+  }
+
+void nrt2_Function (void)
+  {
+    //return;// do nothing
+
+    long tmpTime = micros();
+
+    Serial.print("Timestamp nrt2: ");
+    Serial.print(tmpTime);
+    Serial.print(", Diff (us): ");
+    Serial.println(tmpTime - lastTime);
+    lastTime = micros();
+
+  }
+
+void send_Function (void)
+  {
+    return;
+    long tmpTime = micros()-lastTime;
+    lastTime = micros();
+    Serial.print("Cycletime send: ");
+    Serial.print(tmpTime);
+    Serial.print(", Diff (us): ");
+    Serial.println(tmpTime - rt1.cycleTime);
+  }
+
+void setup()
+  {
+    Serial.begin(9600);
+    nrt1.priority = 1;
+    nrt1.activity = nrt1_Function;
+    nrt1.timestamp = 0;
+
+    nrt1.priority = 2;
+    nrt2.activity = nrt2_Function;
+    nrt2.timestamp = 0;
+
+    rt1.activity = no_Function;
+    rt1.timestamp = 0;
+    rt1.cycleTime = 50000;
+
+    rt2.activity = no_Function;
+    rt2.timestamp = 0;
+    rt2.cycleTime = 20000;
+
+    rt3.activity = no_Function;
+    rt3.timestamp = 0;
+    rt3.cycleTime = 100000;
+
+    lastTime = micros();
+
+    scheduler = new Scheduler(rtTasks, nRtTasks);
+    scheduler->setDebugger(&Serial);
+  }
+
+void loop() { scheduler->schedule(); }
diff --git a/SchedulerPerformance/src/Scheduler.cpp b/SchedulerPerformance/src/Scheduler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..341af42ab7a2019d4b69e72b0a6f71d37904428c
--- /dev/null
+++ b/SchedulerPerformance/src/Scheduler.cpp
@@ -0,0 +1,290 @@
+// Scheduler.cpp
+// Copyright 2016, 2017 Lukas Friedrichsen, Philipp Stenkamp
+// License: Modified BSD-License
+//
+// Implementation of a cooperative multitasking based scheduler for Arduino-devices
+//
+// 2017-02-10
+
+
+#include "Scheduler.h"
+
+// Constructor with task-array as input-argument
+Scheduler::Scheduler (rtTask **newRtTasks, nRtTask **newNRtTask) {
+  rtTasks = NULL;
+  nRtTasks = NULL;
+  taskCounter = NULL;
+  debugger = NULL;
+  listStoragePointer = NULL;
+  overloadCounter = 0;
+  nRtTaskCounter = 0;
+  setRtTasks(newRtTasks);
+  setNRtTasks(newNRtTask);
+}
+
+// Sorts and sets the input-array as the new non-realtime-task-array; the last element of newNRtTasks HAS TO BE A NULLPOINTER to mark the end of the array
+void Scheduler::setNRtTasks (nRtTask **newNRtTasks) {
+  if (newNRtTasks && newNRtTasks[0]) {
+    nRtTaskCounter = 0;
+    while (newNRtTasks[nRtTaskCounter]) {
+      nRtTaskCounter++;
+      if (nRtTaskCounter >= MAX_TASK_THRESHOLD) {
+        if (debugger) {
+          debugger->println("Number of non-realtime-tasks exceeds task threshold or nullpointer at the end of the array missing! Shutting down scheduler!");
+        }
+        exterminate();
+      }
+    }
+    nRtTasks = newNRtTasks;
+    sortTasks((task **) nRtTasks, 0, nRtTaskCounter-1);
+    taskCounter = nRtTasks;
+  }
+  else {
+    nRtTasks = NULL;
+  }
+}
+
+// Sorts the realtime-task-array and converts it to a linked list; the last element of newRtTask HAS TO BE A NULLPOINTER to mark the end of the array
+void Scheduler::setRtTasks (rtTask **newRtTasks) {
+  if (newRtTasks && newRtTasks[0]) {
+    listStoragePointer = listStorage;
+    int counter = 0;
+    while (newRtTasks[counter]) {
+      counter++;
+      if (counter >= MAX_TASK_THRESHOLD) {
+        if (debugger) {
+          debugger->println("Number of realtime-tasks exceeds task threshold or nullpointer at the end of the array missing! Shutting down scheduler!");
+        }
+        exterminate();
+      }
+    }
+    task **temp = (task **) newRtTasks;
+    sortTasks(temp, 0, counter-1);
+    rtTasks = convertToLinkedList(temp);
+  }
+  else {
+    rtTasks = NULL;
+  }
+}
+
+// Sets a serial-port for debugging; error-messages will be printed there
+void Scheduler::setDebugger (Serial_ *serial){
+  debugger = serial;
+}
+
+// Sorts the task-array so that the tasks are in order of their cycle-time / priority (if a non-realtime-task-array is given, getTaskCycleTime will return the tasks priority); left is the first, right the last position in the array to be sorted
+void Scheduler::sortTasks(task **tasks, int left, int right) {
+  if (left < right && (right-left+1) > 1 && tasks && *tasks) {
+
+    // Quicksort (O(n*log(n)) on average; recursive)
+    /*int middle = left+rand()%(right-left+1);
+    unsigned long test = getTaskCycleTime((rtTask *) tasks[middle]);
+    int l = left;
+    int r = right;
+    while (l <= r) {
+      while (getTaskCycleTime((rtTask *) tasks[l]) < test) {
+        l++;
+      }
+      while (getTaskCycleTime((rtTask *) tasks[r]) > test) {
+        r--;
+      }
+      if (l <= r) {
+        task *temp = tasks[l];
+        tasks[l] = tasks[r];
+        tasks[r] = temp;
+        l++;
+        r--;
+      }
+    }
+    sortTasks(tasks, left, r);
+    sortTasks(tasks, l, right);*/
+
+    // Heapsort (allways O(n*log(n)); iterative)
+    int length, start, heapLength, i, j;
+    task *reference;
+
+    start = left;
+    heapLength = right-left+1;
+    length = heapLength/2+1;
+
+    while (heapLength > 1) {
+      if (length > 1) {
+        reference = tasks[start+(--length-1)];
+      }
+      else {
+        reference = tasks[start+heapLength-1];
+        tasks[start+heapLength-1] = tasks[start];
+        heapLength--;
+      }
+      i = length;
+      j = length*2;
+      while (j <= heapLength && heapLength > 1) {
+        if (j < heapLength && getTaskCycleTime((rtTask *) tasks[start+j-1]) < getTaskCycleTime((rtTask *) tasks[start+j])) {
+          j++;
+        }
+        if (getTaskCycleTime((rtTask *) reference) < getTaskCycleTime((rtTask *) tasks[start+j-1])) {
+          tasks[start+i-1] = tasks[start+j-1];
+          i = j;
+          j *= 2;
+        }
+        else {
+          j = heapLength + 1; // Terminates the shift-down
+        }
+      }
+      tasks[start+i-1] = reference;
+    }
+  }
+}
+
+// Places the given element in the linked list based on when it has to be called next; if only one realtime-task exists, the list isn't modified
+linkedListElement * Scheduler::sortRtTasks (linkedListElement *tasks) {
+  linkedListElement *reference = tasks;
+  linkedListElement *counter = (linkedListElement *) reference->next;
+  if (counter && (signed long)(getTaskCycleTime((rtTask *) reference->listElement)-getTaskTimerDiff(reference->listElement)) > (signed long)(getTaskCycleTime((rtTask *) counter->listElement)-getTaskTimerDiff(counter->listElement))) {
+    while (counter->next && (signed long)(getTaskCycleTime((rtTask *) reference->listElement)-getTaskTimerDiff(reference->listElement)) > (signed long)(getTaskCycleTime((rtTask *) counter->listElement)-getTaskTimerDiff(counter->listElement))){
+      counter = (linkedListElement *) counter->next;
+    }
+    linkedListElement *temp = (linkedListElement *) reference->next;
+    reference->next = counter->next;
+    counter->next = reference;
+    return temp;
+  }
+  else {
+    return reference;
+  }
+}
+
+// Converts the given realtime-task-array to a bidirectional linked list element
+linkedListElement * Scheduler::convertToLinkedList (task **taskArray) {
+  linkedListElement *firstElement = NULL;
+  linkedListElement *listElementPointer = NULL;
+  while (*taskArray) {
+    linkedListElement *new_pointer = newLinkedListElement();
+    new_pointer->listElement = *taskArray;
+    new_pointer->next = NULL;
+    if (listElementPointer) {
+      listElementPointer->next = new_pointer;
+    }
+    else {
+      firstElement = new_pointer;
+    }
+    listElementPointer = new_pointer;
+    taskArray++;
+  }
+  return firstElement;
+}
+
+// Returns a pointer to a new linked list element from the array listStorage
+linkedListElement * Scheduler::newLinkedListElement (void){
+  if (listStoragePointer){
+    return listStoragePointer++;
+  }
+  else {
+    if (debugger) {
+      debugger->println("Can't initialize any more linked list elements! Shutting down scheduler!");
+    }
+    exterminate();
+  }
+}
+
+// Sets the timer of the given task to the current time in microseconds
+void Scheduler::updateTaskTimer (task *taskToUpdate) {
+  taskToUpdate->timestamp = micros();
+}
+
+// Dynamic prioritiy-allocation to prevent starvation
+void Scheduler::setPriorities (void) {
+  sortTasks((task **) nRtTasks, 0, nRtTaskCounter-1);
+  taskCounter = nRtTasks;
+  int counter = 0;
+  while (taskCounter && *taskCounter){
+    if (getTaskTimerDiff((task *) *taskCounter) >= STARVATION_THRESHOLD){
+      nRtTask *temp = *taskCounter;
+      memmove(nRtTasks+1, nRtTasks, counter*sizeof(void *));
+      *nRtTasks = temp;
+    }
+    counter++;
+    taskCounter++;
+  }
+}
+
+// Returns the cycle time of the given realtime-task
+unsigned long Scheduler::getTaskCycleTime (rtTask *taskToGet) {
+  return taskToGet->cycleTime;
+}
+
+// Returns the priority of the given non-realtime-task
+unsigned long Scheduler::getTaskPriority(nRtTask *taskToGet) {
+  return taskToGet->priority;
+}
+
+// Returns the difference between the value of timestamp of the given task and the current time in microseconds
+unsigned long Scheduler::getTaskTimerDiff (task *taskToGet) {
+  return (micros() - taskToGet->timestamp);
+}
+
+// Handles the functions excluding send
+void Scheduler::perform (void) {
+  if (taskCounter && *taskCounter) {
+    updateTaskTimer((task *) *taskCounter);
+    (*taskCounter)->activity();
+    taskCounter++;
+  }
+  else if (nRtTasks) {
+    taskCounter = nRtTasks;
+  }
+}
+
+// The system switches to a defined state (do nothing) in case of a error.
+void Scheduler::exterminate (void){
+  if (debugger) {
+    debugger->println("An error occured! Programm terminated!");
+  }
+  while (true);
+}
+
+// Scheduler, called cyclical in the loop-function
+void Scheduler::schedule (void) {
+  long diff;
+  long schedTime = micros();
+  if (rtTasks) {
+    unsigned long timerDiff = getTaskTimerDiff(rtTasks->listElement);
+    unsigned long cycleTime = getTaskCycleTime((rtTask *) rtTasks->listElement);
+    if (timerDiff >= cycleTime) {
+      if (((timerDiff-cycleTime)*100/cycleTime) > OVERLOAD_THRESHOLD_PERCENT) {
+        overloadCounter++;
+        if (overloadCounter > OVERLOAD_THRESHOLD_TIMES) {
+          if (debugger) {
+            debugger->println("Capacity overload! Delay between theoretical and practical cycle-time exceeds threshold! Shutting down scheduler!");
+          }
+          exterminate();
+        }
+      }
+      updateTaskTimer(rtTasks->listElement);
+      rtTasks->listElement->activity();
+      rtTasks = sortRtTasks(rtTasks);
+      if (nRtTasks){
+        setPriorities();
+        taskCounter = nRtTasks;
+      }
+      diff = micros()-schedTime;
+      if (debugger) {
+        debugger->println("Scheduler::schedule runtime (us): ");
+        debugger->println(diff);
+      }
+    }
+    else if (nRtTasks) {
+      perform();
+    }
+  }
+  else if (nRtTasks) {
+    perform();
+  }
+  else {
+    if (debugger) {
+      debugger->println("No tasks... Nothing to do!");
+    }
+    // No tasks... Nothing to do!
+  }
+
+}
diff --git a/SchedulerPerformance/src/Scheduler.h b/SchedulerPerformance/src/Scheduler.h
new file mode 100644
index 0000000000000000000000000000000000000000..324e773637aed645178434c4655b4602f6f3b0b7
--- /dev/null
+++ b/SchedulerPerformance/src/Scheduler.h
@@ -0,0 +1,66 @@
+// Scheduler.h
+// TODO License
+// Lukas Friedrichsen, 2016-12-
+//
+
+#ifndef Scheduler_h
+#define Scheduler_h
+
+#include <Arduino.h>
+#include "Scheduler.h"
+
+#define MAX_TASK_THRESHOLD 10
+#define OVERLOAD_THRESHOLD_PERCENT 10
+#define OVERLOAD_THRESHOLD_TIMES 1000
+#define STARVATION_THRESHOLD 100000
+
+struct task
+{
+  void (*activity) (void);  // The schedulers only purpose is scheduling the tasks, not to process any data. Therefor the function doesn't accept input-arguments nor returns any value.
+  unsigned long timestamp;
+};
+
+struct rtTask: task
+{
+  unsigned long cycleTime;
+};
+
+struct nRtTask: task
+{
+  unsigned long priority;
+};
+
+struct linkedListElement
+{
+  task *listElement;
+  void *next;
+};
+
+class Scheduler
+{
+  public:
+    Scheduler (rtTask **newRtTasks, nRtTask **newNRtTask);
+    void schedule (void);
+    void setRtTasks (rtTask **newRtTasks);
+    void setNRtTasks (nRtTask **newNRtTasks);
+    void setDebugger (Serial_ *debugger);
+
+  private:
+    linkedListElement *rtTasks, *listStoragePointer, listStorage[MAX_TASK_THRESHOLD];
+    nRtTask **nRtTasks, **taskCounter;
+    unsigned int overloadCounter, nRtTaskCounter;
+    Serial_ *debugger;
+    void sortTasks (task **tasks, int left, int right);
+    linkedListElement * sortRtTasks (linkedListElement *tasks);
+    linkedListElement * convertToLinkedList (task **tasks);
+    linkedListElement * newLinkedListElement (void);
+    void updateTaskTimer (task *taskToUpdate);
+    void setPriorities (void);
+    unsigned long getTaskCycleTime (rtTask *taskToGet);
+    unsigned long getTaskPriority (nRtTask *taskToGet);
+    unsigned long getTaskTimerDiff (task *taskToGet);
+    void perform (void);
+    void exterminate (void);
+};
+
+#endif