Skip to content

Commit bba346d

Browse files
committed
Adding parametrized callback functionality. With this functionality it is possible to call same callback function by different threads, and implement different functionality depending on the parameter.
1 parent ce6fea2 commit bba346d

5 files changed

Lines changed: 85 additions & 9 deletions

File tree

StaticThreadController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class StaticThreadController: public Thread{
4242
{
4343
// Run this thread before
4444
if(_onRun != nullptr && shouldRun())
45-
_onRun();
45+
_onRun(_param);
4646

4747
for(int i = 0; i < N; i++){
4848
// Is enabled? Timeout exceeded?

Thread.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include "Thread.h"
22

3-
Thread::Thread(void (*callback)(void), unsigned long _interval){
3+
Thread::Thread(void (*callback)(void*), unsigned long _interval, void *param){
44
enabled = true;
55
onRun(callback);
66
_cached_next_run = 0;
7+
_param = param;
78
last_run = millis();
89

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

42-
void Thread::onRun(void (*callback)(void)){
43-
_onRun = callback;
43+
void Thread::onRun(void (*callback)(void*)){
44+
_onRun = callback;
4445
}
4546

4647
void Thread::run(){
4748
if(_onRun != NULL)
48-
_onRun();
49+
_onRun(_param);
4950

5051
// Update last_run and _cached_next_run
5152
runned();

Thread.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ class Thread{
5353
void runned() { runned(millis()); }
5454

5555
// Callback for run() if not implemented
56-
void (*_onRun)(void);
56+
void (*_onRun)(void *);
57+
58+
// Pointer to a parameter used in callback
59+
void *_param;
5760

5861
public:
5962

@@ -68,7 +71,7 @@ class Thread{
6871
String ThreadName;
6972
#endif
7073

71-
Thread(void (*callback)(void) = NULL, unsigned long _interval = 0);
74+
Thread(void (*callback)(void*) = NULL, unsigned long _interval = 0, void *param = NULL);
7275

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

8285
// Callback set
83-
void onRun(void (*callback)(void));
86+
void onRun(void (*callback)(void *));
8487

8588
// Runs Thread
8689
virtual void run();

ThreadController.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ ThreadController::ThreadController(unsigned long _interval): Thread(){
2020
void ThreadController::run(){
2121
// Run this thread before
2222
if(_onRun != NULL)
23-
_onRun();
23+
_onRun(_param); // TODO #ivan, why is it needed?
2424

2525
unsigned long time = millis();
2626
int checks = 0;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
This example shows how to use a single callback function for multiple threads.
3+
Each of 5 threads lights up one of 5 LEDs in randomly selected intervals.
4+
Single callback function is called with a pointer to a data structure, which
5+
can be used for identifying a pin it needs to light up and thread point to set up
6+
a new waiting interval.
7+
8+
author: Ivan Koryakovskiy <i.koryakovskiy@gmail.com>
9+
date: 2017-07-29
10+
*/
11+
12+
#include <Thread.h>
13+
#include <ThreadController.h>
14+
15+
typedef struct blinkParam
16+
{
17+
Thread *th;
18+
int pin;
19+
};
20+
21+
ThreadController g_controller = ThreadController();
22+
23+
// Creating 5 controllers, each will call same callback function,
24+
// but with a different thread pointer as a parameter, and therefore different led
25+
const int g_th_num = 5;
26+
Thread *g_th[g_th_num];
27+
blinkParam *g_param[g_th_num];
28+
29+
int nextInterval()
30+
{
31+
// next time call thread after 1-5 seconds
32+
return 1000 + random(4000);
33+
}
34+
35+
void blinkLed(void *param)
36+
{
37+
// cast parameters to data structure
38+
blinkParam *bp = static_cast<blinkParam*>(param);
39+
40+
digitalWrite(bp->pin, HIGH);
41+
delayMicroseconds(10000);
42+
digitalWrite(bp->pin, LOW);
43+
44+
bp->th->setInterval(nextInterval());
45+
}
46+
47+
void setup()
48+
{
49+
randomSeed(analogRead(0));
50+
51+
// create five threads to light up pins D9-D13 (Arduino Nano)
52+
int pin = 9;
53+
for (int i = 0; i < g_th_num; i++)
54+
{
55+
g_param[i] = new blinkParam;
56+
57+
// note that parameter includes placeholders for thread pointer and pin number
58+
g_th[i] = new Thread(blinkLed, nextInterval(), static_cast<void*>(g_param[i]));
59+
60+
g_param[i]->th = g_th[i];
61+
g_param[i]->pin = pin + i;
62+
63+
g_controller.add(g_th[i]);
64+
65+
pinMode(g_param[i]->pin, OUTPUT);
66+
}
67+
}
68+
69+
void loop()
70+
{
71+
g_controller.run();
72+
}

0 commit comments

Comments
 (0)