Kanarie
Kanarie

Reputation: 183

Passing a struct by reference/pointer using arduino-timer.h for Arduino

I'm building an arduino project with various leds that have to blink. I've decided to use [arduino-timer.h] (https://www.arduino.cc/reference/en/libraries/arduino-timer/). I do not know C++. I know javascript.

The arduino-timer.h functions (.in, .at, .every) allow for an third argument to be passed to the timerfunction that is being called. I want this third argument to be a struct for more flexibility.

See below code that shows a basic example of what I'm trying. The variable colourCount is not changing however. From what I've gathered, to be able to do this I'm supposed to pass the struct variable either by reference or by pointer.

In the function calls I've tried stuff like

bool genericOn(TimerStruct &obj) { 

but that is throwing errors :

In function 'void setup()':
timer_struct_test:27:58: error: no matching function for 
call to 'Timer<3u, millis, TimerStruct>::every(const int&, bool (&)(TimerStruct&), TimerStruct*)'
   repeatTask = u_timer.every(Interval, genericOn, &timerC);

So.... can someone help?

Below is the code that is working except for the colorCount that stays the same.

#include <arduino-timer.h>

Timer<>::Task repeatTask;
Timer<>::Task blinkTask;

const int DIO_GREEN = 17; 
const int Interval = 1000;
struct TimerStruct
{
    int total;
    int color;
    int colorCount;
    int inBetween;
};

Timer<3, millis, struct TimerStruct> u_timer;
Timer<10, millis, struct TimerStruct> b_timer;
void setup (){
  Serial.begin(9600);   // Initialize serial communications with the PC
  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
  pinMode (DIO_GREEN, OUTPUT);
  struct TimerStruct timerC;
  timerC.total = 10;
  timerC.color = DIO_GREEN;
  timerC.colorCount = 0;
  timerC.inBetween = 500;
  repeatTask = u_timer.every(Interval, genericOn, timerC);
}

void loop() {
  u_timer.tick(); 
  b_timer.tick(); 
}

bool genericOn(TimerStruct obj) {
  digitalWrite(obj.color, LOW);
   Serial.print(obj.colorCount);
   Serial.print(" - color ");
   Serial.print(obj.color);
   Serial.print(" - total ");
  Serial.print(obj.total);
  Serial.print("- inbetween");
   Serial.println(obj.inBetween);
  blinkTask = b_timer.in(obj.inBetween, genericOff, obj);
  if (obj.colorCount< obj.total){
   obj.colorCount++;
   return true;
  }
  return false;
}

bool genericOff(TimerStruct obj) {
  digitalWrite(obj.color, HIGH);
  return true;
}

Upvotes: 0

Views: 493

Answers (1)

Kanarie
Kanarie

Reputation: 183

My dear friend Ant#1 solved it by putting the & and * in the right places:

    #include <arduino-timer.h>

 Timer<>::Task repeatTask;
 Timer<>::Task blinkTask;

const int DIO_GREEN = 17;
const unsigned long Interval = 1000;
struct TimerStruct
{
  int total;
  int color;
  int colorCount;
  int inBetween;
};

TimerStruct timerC;


Timer<3, millis, TimerStruct*> u_timer;
Timer<10, millis, TimerStruct*> b_timer;

void setup () {
  Serial.begin(9600);
  while (!Serial);
  pinMode (DIO_GREEN, OUTPUT);
  timerC.total = 10;
  timerC.color = DIO_GREEN;
  timerC.colorCount = 0;
  timerC.inBetween = 500;
  u_timer.every(Interval, genericOn, &timerC);
}

void loop() {
  u_timer.tick();
  b_timer.tick();
}

bool genericOn(TimerStruct *obj) {
  digitalWrite(obj->color, LOW);
  Serial.print(obj->colorCount);
  Serial.print(" - color ");
  Serial.print((*obj).color);
  Serial.print(" - total ");
  Serial.print(obj->total);
  Serial.print("- inbetween");
  Serial.println(obj->inBetween);
  b_timer.in(obj->inBetween, genericOff, obj);
  if (obj->colorCount < obj->total) {
    Serial.println("inside if");
    obj->colorCount++;
    return true;
  }
  return false;
}

bool genericOff(TimerStruct *obj) {
  digitalWrite(obj->color, HIGH);
  return true;
}

Upvotes: 0

Related Questions