Passing variables to fuction in timer function, gives error

Hi,

Please tell me how to do this correctly.

Passing variables in function I have defined(test), works as expected, but when I put it in to the Ticker function, it does not work.
Have not found an answer this far, and all my ideas to make this work, have failed.

#include <Ticker.h>
Ticker timer;

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
//
}

Error: invalid use of void expression

void loop() {
  // put your main code here, to run repeatedly:
//test(1,2);
timer.attach (2000, test(1,2));
}

void test(int c, int d)
{
  Serial.println(c+d);
}

Look at the examples with the library. You need to provide a callback function with optional argument when you attach. You're calling your test function in the attach where you should be passing a pointer to it. Also, your test function can only have a single argument, not two.

What are you trying to do?

timer.attach (2000, test(1,2));

This is not how the library expects the constructor.

The callback function is presented first, and then the time.

Ticker(fptr callback, uint32_t timer, uint32_t repeat = 0, resolution_t resolution = MICROS);

As a separate issue, you have a callback function with parameters. I'm not certain how to do that as I haven't studied the library and how it sets up the callback functions.

Using ticker.h instead of basic millis() timers has added a layer of complexity.

wildbill:
Also, your test function can only have a single argument, not two.

But this works fine when I call function without timer!?

What are you trying to do?

This is my test sketch taken from the project where I need this feature.
Fading the led stripe in or out, with given speed. Two arguments that is.

Searching the solution for a some time. Maybe I lack with the right search words.
Could you give me a working code sample, please.

WemosAlaPlaya:
But this works fine when I call function without timer!?

Sure it does, but the library expects a function with no more than a single parameter. That parameter could be a pointer to a struct with two fields though.

WemosAlaPlaya:
Fading the led stripe in or out, with given speed. Two arguments that is.

What are those arguments?

As Cattledog says, it would probably be easier to do this without the ticker library. Apparently neither he nor I has used it, so I suspect that you would get better assistance just using millis.

The attach function requires a function pointer.
Right now, you're passing it the result of a call to the "test" function, not the function itself.

Try this:

timer.attach (2000, []{ test(1,2); });

It wraps the function call in a lambda function: Lambda expressions (since C++11) - cppreference.com

Pieter

The attach function requires a function pointer.

There is no .attach() function in https://github.com/sstaub/Ticker

I am not aware of other libraries with the same name. I think that the OP has wandered onto swampy ground, and is stuck for a variety of reasons. Wrong library syntax, and use of a callback function with parameters without using a function pointer.

It is a part of the Arduino ESP8266 core:

There are overloads that take function pointers, and overloads that take std::function objects.

timer.attach (2000, []{ test(1,2); });

This is good if used correctly. +1 on how to handle the function pointer. (Lambda function) :slight_smile:

EDIT: This runs on a UNO.

#include <Ticker.h>

void test(const int c, const int d)
{
  Serial.println(c + d); 
}

Ticker timer([]{test(1,2);},2000);

void setup() {
  Serial.begin(9600);
   timer.start();
}

void loop() {
  timer.update();
}

Yes, I have come across at least two "Ticker" libraries, which is more than a bit confusing.
As I know, one works only in Arduino (clone) board, when other "Ticker" in ESP8266.

This same thing is also with BH1750 libraries. All of them have same name, but some of them work with me, some don't.

So the actual version of test function fades an LED strip in or out. Are the parameters it takes the pin number of the strip and whether to fade in or out?

How do you envisage using the ticker functionality to use test?

I do know milliseconds, but my thought was that with Ticker I do not have to worry about roll overs and restart, etc.
With making function that would be for my needs, takes some time. That does not matter, but why write a code when it's already done? Or have I missed something here.

What I'm poking at is how you will use the ticker(s). If you pass the callback function as a lambda as shown earlier, you will always call test with parameters 1,2. If that's ok, you're done. But I suspect it isn't. Maybe it would be enough to call another function that calls test and has some extra logic to determine what parameters to pass it.

In any event, it seems that Ticker really doesn't do much for you in this scenario. YMMV.

Try this for multiple arguments to your callback function (compiles but untested):

#include <Ticker.h>

Ticker timer;

struct FunctParameters {
  int32_t c;
  int32_t d;
};

FunctParameters params;

void test(FunctParameters *p);

void setup() {
  Serial.begin(115200);
  delay(1000);
  params.c = 100;
  params.d = 50;
  timer.attach (2000, test, &params);
}

void loop() {
}

void test(FunctParameters *p) {
  Serial.println(p->c + p->d);
  p->c += 10;
  p->d -= 5;
}
1 Like

Try this for multiple arguments to your callback function (compiles but untested):

I tried to run this on a Wemos D1 mini, but saw no output.

This is what I managed on a UNO with the syntax of the avr library and the lamda function for the callback. I have done versions which pass the arguments by value and by reference following gfvalvo's model.

#include <Ticker.h>

struct FunctParameters {
  int32_t c;
  int32_t d;
};

FunctParameters params;

void test(FunctParameters *p) {
  Serial.println(p->c + p->d);
  p->c += 10;
  p->d -= 5;
}

Ticker timer([] {test(&params);}, 2000);

void setup() {
  params.c = 100;
  params.d = 50;
  Serial.begin(115200);
  Serial.println("Starting Ticker.h callback function test");
  Serial.println("parameters by reference");
  timer.start();
}
void loop() {
  timer.update();
}
#include <Ticker.h>

int32_t c = 100;
int32_t d = 50;

void test(int32_t a, int32_t b)
{
 Serial.println(a + b);
 c += 10;
 d -= 5;
}
Ticker timer([]{test(c,d);},2000);

void setup() {
Serial.begin(115200);
Serial.println("Starting Ticker.h callback function test");
Serial.println("parameters by value");
timer.start(); 
}
void loop() {
timer.update();
}

cattledog:
I tried to run this on a Wemos D1 mini, but saw no output.

Hmmm ... perhaps it was the Serial.println() in the callback? The ESP version doesn't declare an update() function, so I'm guessing the callback runs in an interrupt context. Anyway, all my ESP's are otherwise occupied right now so I can't test. I'm sure I could make it work after banging on it a little while.