I'm attempting to write a timer function for my class. The basic function is to wait n seconds, then execute some arbitrary code entered by the user. An example below:
int state = OFF;
int stateTwo = OFF;
void wait_test() { state = (state == OFF) ? ON : OFF; board.writeLED(0, state); }
void wait_test_2() { stateTwo = (stateTwo == OFF) ? ON : OFF; board.writeLED(1, stateTwo); }
NeuroBoard board;
void loop() {
board.wait(1000, wait_test);
}
Every second the function is called which turns on/off the first led on the board. However, if I add this to the next line in the loop:
board.wait(2000, wait_test_2);
It doesn't work, and only the first led is turned on/off.
For the wait function, I use an instance variable to hold the milliseconds, then calculate the difference in the function. I've seen other questions with inquiries about multiple timers, but I haven't found any that relate to class functions. Below is my function:
Surely if you need to use two "timers" then you need separate "timer" objects so that the values associated with them are encapsulated in each instance
Obviously, you have a bug in your code. You only provided half, or less, of your code. So don't be surprised if you only get half of an answer to your question....
Yes, I tried going that approach. However, I don't know how many times the user will use our wait function, so I don't know how many timer objects to create to handle each delay.
I would like to roll by myself and see if I could do it, but if you'd like to share what you've used in the past to help me that would be greatly appreciated!
Yes, I tried going that approach. However, I don't know how many times the user will use our wait function, so I don't know how many timer objects to create to handle each delay.
You don't need to create a timer object every time you need to run the timer. Typically, each timer object would be created and exist for the lifetime of the program. It would have some kind of "start" method, and would be automatically or explicitly be reset by a reset method after registering the expiry of an interval.
If you don't know where the problem lies in the section you posted, how can you be so sure it's there, and not somewhere else?
Here's my take on multiple timer objects that can "wait n seconds, then execute some arbitrary code".
#include "timeObj.h"
#include "idlers.h"
// **************************************************************
// delayTrigger is your base class. Inherit this to make your
// actual triggered classes.
// **************************************************************
class delayTrigger : public timeObj,
public idler {
public:
delayTrigger(float delayTime);
virtual ~delayTrigger(void);
virtual void doAction(void); // Derived classes inherit this and fill it out.
// Probably ignore these.. (under hood kind of stuff)
virtual void start(void);
virtual void stepTime(void);
virtual void idle(void);
bool mTriggered;
};
delayTrigger::delayTrigger(float delayTime)
: timeObj(delayTime),
idler() { mTriggered = false; }
delayTrigger::~delayTrigger(void) { }
// This one is filled out by the inherited class.
void delayTrigger::doAction(void) { }
// These next few are just for tying all the bits together.
// We need to add the hookup() call and to clear the triggered flag.
void delayTrigger::start(void) {
hookup();
mTriggered = false;
timeObj::start();
}
// Also need to clear the triggered flag here as well.
void delayTrigger::stepTime(void) {
mTriggered = false;
timeObj::stepTime();
}
// This thing runs behind in the background. Think of this
// as your own private slice of loop().
void delayTrigger::idle(void) {
if (!mTriggered && ding()) {
mTriggered = true;
doAction();
}
}
// **************************************************************
// A couple exampples of delay trigger classes.
// **************************************************************
class liteOn : public delayTrigger {
public:
liteOn(float delayMs);
virtual ~liteOn(void);
virtual void doAction(void);
};
liteOn::liteOn(float delayMs)
: delayTrigger(delayMs) { }
liteOn::~liteOn(void) { }
void liteOn::doAction(void) { digitalWrite(13, HIGH); }
// ************
class liteOff : public delayTrigger {
public:
liteOff(float delayMs);
virtual ~liteOff(void);
virtual void doAction(void);
};
liteOff::liteOff(float delayMs)
: delayTrigger(delayMs) { }
liteOff::~liteOff(void) { }
void liteOff::doAction(void) { digitalWrite(13, LOW); }
// **************************************************************
// And we let the run..
// **************************************************************
liteOn MrOn(1000);
liteOff MrOff(2000);
void setup() {
pinMode(13, OUTPUT); // Make LED pin output.
MrOn.start(); // Start the call to turn on the LED
MrOff.start(); // Start the call to turn off the LED
}
void loop() {
idle(); //Let the idlers have their time in the sun.
}
Each different function call would need to be "wrapped"in its own class. But, you can make as many of the same function at different times as you'd like.
void setup() {
pinMode(13, OUTPUT); // Make LED pin output.
MrOn1.start(); // Start the call to turn on the LED
MrOff1.start(); // Start the call to turn off the LED
MrOn2.start(); // Start the call to turn on the LED
MrOff2.start(); // Start the call to turn off the LED
}