Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterized #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion StaticThreadController.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class StaticThreadController: public Thread{
{
// Run this thread before
if(_onRun != nullptr && shouldRun())
_onRun();
_onRun(_param);

for(int i = 0; i < N; i++){
// Is enabled? Timeout exceeded?
Expand Down
9 changes: 5 additions & 4 deletions Thread.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "Thread.h"

Thread::Thread(void (*callback)(void), unsigned long _interval){
Thread::Thread(void (*callback)(void*), unsigned long _interval, void *param){
enabled = true;
onRun(callback);
_cached_next_run = 0;
_param = param;
last_run = millis();

ThreadID = (int)this;
Expand Down Expand Up @@ -39,13 +40,13 @@ bool Thread::shouldRun(unsigned long time){
return !time_remaining && enabled;
}

void Thread::onRun(void (*callback)(void)){
_onRun = callback;
void Thread::onRun(void (*callback)(void*)){
_onRun = callback;
}

void Thread::run(){
if(_onRun != NULL)
_onRun();
_onRun(_param);

// Update last_run and _cached_next_run
runned();
Expand Down
9 changes: 6 additions & 3 deletions Thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ class Thread{
void runned() { runned(millis()); }

// Callback for run() if not implemented
void (*_onRun)(void);
void (*_onRun)(void *);

// Pointer to a parameter used in callback
void *_param;

public:

Expand All @@ -68,7 +71,7 @@ class Thread{
String ThreadName;
#endif

Thread(void (*callback)(void) = NULL, unsigned long _interval = 0);
Thread(void (*callback)(void*) = NULL, unsigned long _interval = 0, void *param = NULL);

// Set the desired interval for calls, and update _cached_next_run
virtual void setInterval(unsigned long _interval);
Expand All @@ -80,7 +83,7 @@ class Thread{
bool shouldRun() { return shouldRun(millis()); }

// Callback set
void onRun(void (*callback)(void));
void onRun(void (*callback)(void *));

// Runs Thread
virtual void run();
Expand Down
2 changes: 1 addition & 1 deletion ThreadController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ThreadController::ThreadController(unsigned long _interval): Thread(){
void ThreadController::run(){
// Run this thread before
if(_onRun != NULL)
_onRun();
_onRun(_param); // TODO #ivan, why is it needed?

unsigned long time = millis();
int checks = 0;
Expand Down
72 changes: 72 additions & 0 deletions examples/ParameterizedCallback/ParameterizedCallback.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
This example shows how to use a single callback function for multiple threads.
Each of 5 threads lights up one of 5 LEDs in randomly selected intervals.
Single callback function is called with a pointer to a data structure, which
can be used for identifying a pin it needs to light up and thread point to set up
a new waiting interval.

author: Ivan Koryakovskiy <[email protected]>
date: 2017-07-29
*/

#include <Thread.h>
#include <ThreadController.h>

typedef struct blinkParam
{
Thread *th;
int pin;
};

ThreadController g_controller = ThreadController();

// Creating 5 controllers, each will call same callback function,
// but with a different thread pointer as a parameter, and therefore different led
const int g_th_num = 5;
Thread *g_th[g_th_num];
blinkParam *g_param[g_th_num];

int nextInterval()
{
// next time call thread after 1-5 seconds
return 1000 + random(4000);
}

void blinkLed(void *param)
{
// cast parameters to data structure
blinkParam *bp = static_cast<blinkParam*>(param);

digitalWrite(bp->pin, HIGH);
delayMicroseconds(10000);
digitalWrite(bp->pin, LOW);

bp->th->setInterval(nextInterval());
}

void setup()
{
randomSeed(analogRead(0));

// create five threads to light up pins D9-D13 (Arduino Nano)
int pin = 9;
for (int i = 0; i < g_th_num; i++)
{
g_param[i] = new blinkParam;

// note that parameter includes placeholders for thread pointer and pin number
g_th[i] = new Thread(blinkLed, nextInterval(), static_cast<void*>(g_param[i]));

g_param[i]->th = g_th[i];
g_param[i]->pin = pin + i;

g_controller.add(g_th[i]);

pinMode(g_param[i]->pin, OUTPUT);
}
}

void loop()
{
g_controller.run();
}