Can someone explain why the tsp timer overflow callback is not called

hello,

I just started on Arduino and made a cool heartbeat pulse on the RGB led,
this is my hello world and want to figure out all the things I can do.
just like the timer interrupt callback.
I cannot seem to get the timer overflow going or at least cannot hit the callback.
can someone give me a hint since I am lost at this point :slight_smile:

BR Henkjan

/// here is my hello world code:

#include <FspTimer.h>

int TimerInitDone;

void setup() {

  Serial.begin(9600);

  FspTimer fspTimer;

  uint8_t type = GPT_TIMER;
  int8_t channel = fspTimer.get_available_timer(type);

  if (type != GPT_TIMER || channel == -1)
    return;

  if (!fspTimer.begin(TIMER_MODE_PERIODIC, type, channel, 10.0, STANDARD_DUTY_CYCLE_PERC, Timer_Callback, nullptr))
    return;

 if (!fspTimer.setup_overflow_irq())
    return;

  if (!fspTimer.open())
    return;

  if (!fspTimer.start())
    return;


 

  TimerInitDone = 1;
  interrupts();
}

const int HeartBeatArray[] = { 1, 4, 16, 32, 64, 255, 64, 32, 16,
                               0, 0, 0, 0, 0, 0, 0,
                               1, 4, 32, 16, 4, 1,
                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                               0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int i, j = 1;

void loop() {

  Serial.println("Beat  " + String(i++) + " - " + String(j));

  if (!TimerInitDone) return;

  for (int i = 0; i < (sizeof(HeartBeatArray) / sizeof(int)); i++) {

    analogWrite(LEDR, 255 - HeartBeatArray[i]);  // Red is fully on
    delay(15);
  }
}


void Timer_Callback(st_timer_callback_args* timer_args) {
  j = 42;
}

I don’t know that library but intuitively I would say that your FspTimer fspTimer object is local to the setup() function. As soon as setup() ends, that object is destroyed, so the timer never runs and the overflow interrupt never occurs.

May be It’s time to read about scope

➜ To fix this, define the timer outside of setup() as a global variable.

What is your Arduino board?

Hi, that might be it :slight_smile:
I was kind of expecting such hardware related stuff to have class functions but maybe indeed the thing seizes to exist immediately .
gonna try that today, thx

BR Henkjan

hello,

I just have an Arduino nano R4

BR henkjan

It is a class/object. Classes are a software thing, not a hardware thing.

If an object is declared locally, inside a function, it will only exist locally, like any other type of variable. It is possible to create objects dynamically, so they continue to exist after the function that created them ends, but that's not happening here.

As a beginner, you probably won't have the experience to know when it's appropriate to use a particular class or library. I suspect that's the case here.

So why are you using this library? Why not just use millis()?

yes, I am definitely new to this.
the reason I am using this library is I want to have an actual callback from a timer interrupt so I can build things with a foreground and background task.
maybe the millis() can do the same, or is this a way to create timed loops where you implement everything from the background?

yeah, that was exactly the problem. thanks for helping out :slight_smile:
my lack of understanding created an object that was destroyed again.
now the callback is called.

thanks

I think @ketelbinkie73 was thinking that whatever the instance was configuring at hardware level, it would stay active after the object disappeared (assuming its destructor would not clean up).

For example when you call attachInterrupt() inside a local object in setup() , the object itself may go out of scope and be destroyed at the end of setup() , but the interrupt configuration on the hardware remains.
➜ The MCU has already registered the ISR function in its interrupt vector table, so the pin will still trigger the ISR when an event occurs

Same would be true for pure hardware stuff, if you set a pin mode, a certain pwm etc...

I think that's what he meant.

great - have fun!

You don't generally need interrupts to achieve that, or any number of apparently simultaneous tasks, if you code the right way and use millis().

An example of a good reason for using timer interrupts is when you need to achieve very high accuracy in the timing of something and with a low "jitter". If you tried to do that with millis() you might get a significant jitter. Not something a human would generally notice or be concerned about, except in certain circumstances.

For example if your code is multiplexing an LED matrix, even a small jitter in the timing would be noticeable to a human because it would make the display flicker and appear uneven in it's brightness.

But for most tasks, a little jitter isn't noticeable to humans, so it's fine to use millis().

The advantage of using millis() is that it will run on any model of Arduino without modification. Your code, using that library, may only run on Uno R4, I'm not sure.

hi,

thanks for that I will take into consideration. especially the hardware independence.

br