diff --git a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp
index 5c92ce9ba18ade2d128aac36a5928b50616d2851..ed6186c52cf747776b34b073c0a4d3338461da8c 100644
--- a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp
+++ b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.cpp
@@ -31,9 +31,20 @@
 
 
 /////
-// Local variables
+// Static variables
 
-static const struct device* timer6 = NULL;
+const struct device* Scheduling::timer6 = NULL;
+
+const int Scheduling::DEFAULT_PRIORITY = 5;
+
+k_tid_t Scheduling::communicationThreadTid;
+k_tid_t Scheduling::applicationThreadTid;
+
+k_thread Scheduling::communicationThreadData;
+k_thread Scheduling::applicationThreadData;
+
+K_THREAD_STACK_DEFINE(communication_thread_stack, 512);
+K_THREAD_STACK_DEFINE(application_thread_stack,   512);
 
 
 /////
@@ -42,10 +53,20 @@ static const struct device* timer6 = NULL;
 Scheduling scheduling;
 
 
+/////
+// Private API
+
+void Scheduling::threadEntryPoint(void* thread_function_p, void*, void*)
+{
+	thread_function_t thread_function = (thread_function_t)thread_function_p;
+	thread_function();
+}
+
+
 /////
 // Public API
 
-void Scheduling::controlTaskInit(void (*periodic_task)(), uint32_t task_period_us)
+void Scheduling::startControlTask(void (*periodic_task)(), uint32_t task_period_us)
 {
 	if (periodic_task != NULL)
 	{
@@ -58,10 +79,30 @@ void Scheduling::controlTaskInit(void (*periodic_task)(), uint32_t task_period_u
 		timer_cfg.timer_irq_t_usec   = task_period_us;
 
 		timer_config(timer6, &timer_cfg);
+		timer_start(timer6);
 	}
 }
 
-void Scheduling::controlTaskLaunch()
+void Scheduling::startCommunicationTask(thread_function_t routine, int priority)
+{
+	communicationThreadTid = k_thread_create(&communicationThreadData,
+                                             communication_thread_stack,
+                                             K_THREAD_STACK_SIZEOF(communication_thread_stack),
+                                             threadEntryPoint,
+                                             (void*)routine, NULL, NULL,
+                                             priority,
+                                             0,
+                                             K_NO_WAIT);
+}
+
+void Scheduling::startApplicationTask(thread_function_t routine, int priority)
 {
-	timer_start(timer6);
+	applicationThreadTid = k_thread_create(&applicationThreadData,
+                                           application_thread_stack,
+                                           K_THREAD_STACK_SIZEOF(application_thread_stack),
+                                           threadEntryPoint,
+                                           (void*)routine, NULL, NULL,
+                                           priority,
+                                           0,
+                                           K_NO_WAIT);
 }
diff --git a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h
index fd8e93237731a0756c152feef754e0fe02def5fe..99b807c20be71b64850eda9e2a8ef12beefc7ff7 100644
--- a/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h
+++ b/zephyr/modules/owntech_scheduling/zephyr/public_api/Scheduling.h
@@ -28,17 +28,22 @@
 
 #include <stdint.h>
 
+#include <zephyr.h>
+
+typedef void (*thread_function_t)();
 
 /////
 // Static class definition
 
 class Scheduling
 {
+private:
+	static void threadEntryPoint(void* thread_function_p, void*, void*);
+
 public:
 	/**
-	 * @brief Library initialization function.
-	 *        This function uses Timer 6 to execute the periodic
-	 *        user task.
+	 * @brief This function uses Timer 6 to execute the periodic user task.
+	 *        The task is immediately started.
 	 *
 	 * @param periodic_task Pointer to the void(void) function
 	 *        to be executed periodically.
@@ -47,12 +52,41 @@ public:
 	 *        Allowed range: 1 to 6553 µs.
 	 *        Value is ignored if first parameter is NULL.
 	 */
-	void controlTaskInit(void (*periodic_task)(), uint32_t task_period_us);
+	static void startControlTask(void (*periodic_task)(), uint32_t task_period_us);
+
+	/**
+	 * @brief Schedule the communication thread.
+	 *        The task is immediately started.
+	 *
+	 * @param routine Pointer to the void(void) function
+	 *        that will act as the thread main function.
+	 * @param priority Priority of the thread. This
+	 *        parameter can be omitted and will take
+	 *        its default value.
+	 */
+	static void startCommunicationTask(thread_function_t routine, int priority = DEFAULT_PRIORITY);
 
 	/**
-	 * @brief Begins the periodic run of the task.
+	 * @brief Schedule the application thread.
+	 *        The task is immediately started.
+	 *
+	 * @param routine Pointer to the void(void) function
+	 *        that will act as the thread main function.
+	 * @param priority Priority of the thread. This
+	 *        parameter can be omitted and will take
+	 *        its default value.
 	 */
-	void controlTaskLaunch();
+	static void startApplicationTask(thread_function_t routine, int priority = DEFAULT_PRIORITY);
+
+private:
+	static const struct device* timer6;
+	static const int DEFAULT_PRIORITY;
+
+	static k_tid_t communicationThreadTid;
+	static k_tid_t applicationThreadTid;
+
+	static k_thread communicationThreadData;
+	static k_thread applicationThreadData;
 };