Why can't I do this:... with IntervalTimer

Status
Not open for further replies.

ceremona

Well-known member
void Speak(int pin){
if (count1%2) analogWrite(pin,0); else analogWrite(pin,255); //set the PWM to the just-read sample, this will average out because of the speaker’s inertia to a position
count1++; // increment sample
}

Speak4Timer.begin(Speak, 700);

Compiler gives me hell about not being of type void, but it IS of type void, it's just that the argument to the Speak function isn't a void.

I didn't see anything in the documentation (which is sparse for IntervalTimer) saying I couldn't do this.


Thanks.
 
IntervalTimer requires the function to be defined this way:

void Spaek(void)

But your function is:

void Speak(int pin)

IntervalTimer can only call functions which do not take any input. Your's takes an integer.
 
IntervalTimer wouldn't know what argument to use for pin when calling "void Speak(int pin)". With C++11 (Arduino 1.6.x), you could use a lambda adapter and write:

const int pin = 7;
Speak4Timer.begin([]{Speak(pin);}, 700);

"pin" must be a compile time constant.
 
Thanks tni. I'll try this if what your suggesting is true. It's annoying to have to write separate functions for each different pin, when I am only doing the same thing over and over.

So I need to address this as a kind of array like you have it?
Speak4Timer.begin([]{Speak(pin);}, 700);


I already am using a const input as the pin argument but the compiler still balks.

To clarify, I was doing:
const int pin7 = 7;
Speak4Timer.begin(Speak(pin7), 700);

...and it still hated that.
 
It's annoying to have to write separate functions for each different pin, when I am only doing the same thing over and over.

Are you aware there are only 4 timers available in the hardware for IntervalTimer to use? At most you'd be writing the same thing 4 times.
 
To clarify, I was doing:
const int pin7 = 7;
Speak4Timer.begin(Speak(pin7), 700);

...and it still hated that.
IntervalTimer::begin() takes a function pointer as argument. "Speak(pin7)" is not a function pointer, not even an incompatible one. In "Speak4Timer.begin(Speak(pin7), 700)" the compiler will try to call "Speak(pin7)" which returns "void" and try to use that as argument to "Speak4Timer.begin()" - it can't convert "void" to a function pointer.

"[]{Speak(7);}" is a lambda function and can be transformed by the compiler into a function pointer.

"Speak4Timer.begin([]{Speak(7);}, 700);" is equivalent to:
Code:
void adapterFunction() {
    Speak(7);
}
Speak4Timer.begin(adapterFunction, 700);

A lambda function is the easiest way in C++ to get a function pointer to something where you need to pass a parameter. Your "Speak(int)" function is incompatible with "function(void)" (which IntervalTimer expects) and you need an indirection/translation layer.
 
Thanks tni for that bit of c++ wizardry. I'll store that in my brain somewhere and hope it stays.

Paul. Yes, I know there's only 4 timers, I just wanted to pinch on code space. Also, it seems that there are 4 possible physical FTM channels amongst the pins for the 3.6 teensy (which isn't sadly isn't a huge improvement from 3.2), but what will be the max number of IntervalTimer calls I can make in the code for 3.6?
 
Status
Not open for further replies.
Back
Top