Skip to content

Commit

Permalink
[SCHEDULER] Scheduler and Tasks
Browse files Browse the repository at this point in the history
Correct Scheduler and first Tasks
  • Loading branch information
aleemont1 authored Nov 25, 2023
2 parents e1123eb + 75acd7f commit 613943b
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 60 deletions.
2 changes: 2 additions & 0 deletions smart_bridge/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
; https://docs.platformio.org/page/projectconf.html

[env:uno]
monitor_speed = 9600
monitor_filters = direct
platform = atmelavr
board = uno
framework = arduino
Expand Down
2 changes: 1 addition & 1 deletion smart_bridge/src/components/api/Sonar.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class Sonar
/**
* @brief Constant representing no object detected by the sonar sensor.
*/
static const float NO_OBJECT_DETECTED = -1.0f;
static constexpr float NO_OBJECT_DETECTED = -1.0f;
};

#endif // __SONAR__
6 changes: 5 additions & 1 deletion smart_bridge/src/config/config.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef __CONFIG__
#define __CONFIG__

//DEBUG
//#define __DEBUG

// LED
#define L1_PIN 7 // Green diode led
#define L2_PIN 6 // Red diode led
Expand All @@ -26,7 +29,8 @@
/**
* TODO: TIMING, time constants for example N4.... etc
*/
#define N1 10 // Time for the gate to open after car presence (in seconds)
#define N1 2
// Time for the gate to open after car presence (in seconds)
#define MINDIST 10 // Minimum distance for car fully entering (in cm)
#define N2 10 // Time to consider car fully entered (in seconds)
#define N3 15 // Time for the washing process (in seconds)
Expand Down
67 changes: 20 additions & 47 deletions smart_bridge/src/kernel/Scheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,57 +1,30 @@
#include "Scheduler.h"
#include <TimerOne.h>

volatile bool timerFlag = false;
Scheduler::Scheduler() : numTasks(0), lastMillis(0) {}

void timeHandler(void)
{
timerFlag = true;
void Scheduler::init(int intervalMillis) {
// Set up the interval for the scheduler
// You may want to use a timer or other mechanisms for more accurate timing
// For simplicity, using millis() in this example
this->intervalMillis = intervalMillis;
lastMillis = millis() - intervalMillis;
}

void Scheduler::init(int period)
{
this->period = period;
timerFlag = false;
long u_period = 1000L * period;
Timer1.initialize(u_period);
Timer1.attachInterrupt(timeHandler);
this->numTasks = 0;
}

bool Scheduler::addTask(Task *task)
{
if (this->numTasks < MAX_TASKS - 1)
{
this->tasks[this->numTasks++] = task;
return true;
void Scheduler::addTask(Task *task) {
if (numTasks < sizeof(tasks) / sizeof(tasks[0])) {
tasks[numTasks++] = task;
}
return false;
}

void Scheduler::schedule()
{
while (!timerFlag);
timerFlag = false;

for (int i = 0; i < this->numTasks; i++)
{
if (this->tasks[i]->isActive())
{
if (this->tasks[i]->isPeriodic())
{
if (this->tasks[i]->updateAndCheckTime(this->period))
{
this->tasks[i]->tick();
}
}
else
{
this->tasks[i]->tick();
}
if (this->tasks[i]->isCompleted())
{
this->tasks[i]->setActive(false);
}
}
void Scheduler::schedule() {
unsigned long currentMillis = millis();
if (currentMillis - lastMillis >= intervalMillis) { // Adjust the interval as needed
for (int i = 0; i < numTasks; ++i) {
if (tasks[i] != nullptr && tasks[i]->isActive()) {
tasks[i]->tick();
}
}
}
lastMillis = currentMillis;
}
}
19 changes: 10 additions & 9 deletions smart_bridge/src/kernel/Scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@

#include "Task.h"

#define MAX_TASKS 30
class Scheduler {
//A simple cooperative scheduler to execute tasks
Task *tasks[MAX_TASKS];
int numTasks;
int period;
private:
Task *tasks[10]; // Adjust the size based on the number of tasks
int numTasks;
unsigned long lastMillis;
int intervalMillis;

public:
void init(int period);
virtual bool addTask(Task *task);
virtual void schedule();
public:
Scheduler();
void init(int intervalMillis);
void addTask(Task *task);
void schedule();
};

#endif
10 changes: 9 additions & 1 deletion smart_bridge/src/kernel/TaskWithState.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include "Task.h"
#include <Arduino.h>

// TODO: Check if state managing is necessary
// TODO: Create a stateless timed task class

class TaskWithState : public Task
{
public:
Expand All @@ -15,7 +18,12 @@ class TaskWithState : public Task
this->stateTimestamp = millis();
}

long timeInState()
int getState()
{
return this->state;
}

long elapsedTime()
{
return millis() - stateTimestamp;
}
Expand Down
21 changes: 21 additions & 0 deletions smart_bridge/src/kernel/TaskWithTimer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef __TASK_WITH_TIMER__
#define __TASK_WITH_TIMER__

#include "Task.h"
#include <Arduino.h>

class TaskWithTimer : public Task
{
public:
TaskWithTimer() : Task(){
this->timerTimestamp = millis();
}; // Default constructor

long elapsedTime()
{
return millis() - timerTimestamp;
}
private:
long timerTimestamp;
};
#endif
18 changes: 17 additions & 1 deletion smart_bridge/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
#include "Arduino.h"
#include "kernel/Scheduler.h"
#include "tasks/BlinkTask.h"
#include "tasks/CheckInTask.h"
#include "config/config.h"

Scheduler scheduler;

void setup()
{
Serial.begin(9600);
scheduler.init(500);
//NOTE: THIS IS JUST A TEST TASK
BlinkTask *blinkTask = new BlinkTask(L3_PIN);
blinkTask->init(500);
blinkTask->setActive(true);
//NOTE: THIS IS THE REAL TASK
CheckInTask *checkInTask = new CheckInTask();
checkInTask->init();
checkInTask->setActive(true);
scheduler.addTask(checkInTask);
scheduler.addTask(blinkTask);
}

void loop()
{

scheduler.schedule();
}
28 changes: 28 additions & 0 deletions smart_bridge/src/tasks/BlinkTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "BlinkTask.h"

BlinkTask::BlinkTask(int pin)
{
this->pin = pin;
}

void BlinkTask::init(int period)
{
Task::init(period);
led = new Led(pin);
state = OFF;
}

void BlinkTask::tick()
{
switch (state)
{
case OFF:
led->switchOn();
state = ON;
break;
case ON:
led->switchOff();
state = OFF;
break;
}
}
20 changes: 20 additions & 0 deletions smart_bridge/src/tasks/BlinkTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __BLINK_TASK__
#define __BLINK_TASK__

#include "kernel/Task.h"
#include "components/api/Led.h"

class BlinkTask: public Task {

int pin;
Light* led;
enum { ON, OFF} state;

public:

BlinkTask(int pin);
void init(int period);
void tick();
};

#endif
32 changes: 32 additions & 0 deletions smart_bridge/src/tasks/CheckInTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "CheckInTask.h"

// Implement the CheckInTask class that executes the checkin process.
// The checkin process is as follows:
// 1. Turn on the L1 led.
// 2. Wait for N1 seconds.
// 3. Turn on the L2 led.
// 4. Open the gate.

void CheckInTask::tick()
{
Serial.println("CheckInTask::started");
switch(this->getState()) {

case STARTED:
L1->switchOn(); // Turn on L1
Serial.println("CheckInTask::Turned on L1");
this->setState(WAITING); // Set the state to STATE1
break;
case WAITING:
if (this->elapsedTime() >= (N1 * 1000)) // After N1 seconds have elapsed
{
L1->switchOff(); // Turn off L1
Serial.println("CheckInTask::Turned off L1");
L2->switchOn(); // Turn on L2
Serial.println("CheckInTask::Turned on L2");
gate->write(90); // Open the gate
Serial.println("CheckInTask::Opened the gate");
this->setCompleted(); // Mark the task as completed
}
}
}
34 changes: 34 additions & 0 deletions smart_bridge/src/tasks/CheckInTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifndef __CHECK_IN_TASK__
#define __CHECK_IN_TASK__

#include "kernel/TaskWithState.h"
#include "components/api/Led.h"
#include "config/config.h"
#include <Servo.h>

class CheckInTask : public TaskWithState
{
public:
CheckInTask() : TaskWithState()
{
this->L1 = new Led(L1_PIN);
this->L2 = new Led(L2_PIN);
this->gate = new Servo();
gate->attach(SERVO_PIN);
Serial.println("CheckInTask created");
this->setState(STARTED);
};
void tick() override;

private:
enum states
{
STARTED,
WAITING
};
Led *L1;
Led *L2;
Servo *gate;
};

#endif

0 comments on commit 613943b

Please sign in to comment.