GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

TimerMillis doesn't seem to work properly with 2 timers #162

Open Sistrum opened 4 years ago

Sistrum commented 4 years ago

Hello,

First, thanks for this useful work!

I have an issue with the TimerMillis library when I used 2 timers at the same time and restart those timers with different timing. Here a minimal sketch who shows the error:

#include <STM32L0.h>
#include "LoRaWAN.h"
#include "TimerMillis.h"

#define INT_FLAG_1 0x01
#define INT_FLAG_2 0x02

TimerMillis timer1, timer2;
uint32_t t1 = 60 * 1000;  // 1min
uint32_t t2 = 360 * 60 * 1000;  // 360min
uint8_t n1 = 3;
uint8_t n2 = 3;
uint8_t interruptFlags = 0x00;

void int_handler1 () {
  Serial.println("int_handler1");

  __disable_irq();
  interruptFlags |= INT_FLAG_1;
  __enable_irq();
}

void int_handler2 () {
  Serial.println("int_handler2");

  __disable_irq();
  interruptFlags |= INT_FLAG_2;
  __enable_irq();
}

void setup()
{
  // ------ SERIAL ------
  Serial.begin(9600);
  delay(3000);

  // ------ TIMERS ------
  timer1.start(int_handler1, 10000, 10000); // Set on 10sec
  timer2.start(int_handler2, 16000, 16000); // Set on 16sec
  Serial.println("Timers started");
}

void loop()
{
  if(interruptFlags & INT_FLAG_1) {
    __disable_irq();
    interruptFlags &= ~INT_FLAG_1;
    __enable_irq();
    if(n1) handler1();
  }

  if(interruptFlags & INT_FLAG_2) {
    __disable_irq();
    interruptFlags &= ~INT_FLAG_2;
    __enable_irq();
    if(n2) handler2();
  }
}

void handler1() {
  if (n1 == 1) {
    // After 3 interrupts of timer1
    timer1.restart(t1, t1); // t1 = 1min
    Serial.println("Timer 1 restarted");
  }

  n1--;
}

void handler2 () {
  if(n2 == 1) {
    // After 3 interrupts of timer2
    timer2.restart(t2, t2); // t2 = 360min
    Serial.println("Timer 2 restarted");
  }

  n2--;
}

And here the Serial output:

15:11:03.065 -> Timers started
15:11:13.077 -> int_handler1
15:11:19.072 -> int_handler2
15:11:23.076 -> int_handler1
15:11:33.052 -> int_handler1
15:11:33.052 -> Timer 1 restarted
15:11:35.074 -> int_handler2
15:11:51.076 -> int_handler2
15:11:51.076 -> Timer 2 restarted
15:12:01.059 -> int_handler1 // should have arrived 1 min after the restart of timer1 and not 10sec (old value) after the restart of timer2 !
15:13:33.059 -> int_handler1 // now it all good. The timer has "lost his lead"
15:14:33.051 -> int_handler1
15:15:33.057 -> int_handler1
...

I tried to replace "restart" with "stop" and "start" functions but it doesn't solve the issue. I tried to stop timer1 and start a new timer instance (like timer3) but it's doesn't solve the issue.

If I set "n2" to "5" in place of "3", everything works perfectly. The issue seems to occur when "timer2.restart()" runs after "timer1.restart()" but before the first interrupt of timer1 (with his new time values) occurs.

Moreover, the issue doesn't seem to come from the Arduino Serial timestamp.

Have someone an idea of what I can do to solve that or what I'm doing wrong?

Thanks

nelisse commented 4 years ago

We are also experiencing sometimes irregular timer behavior when using multiple timers. We had numerous code reviews, but nobody can pinpoint the cause. In our case the timer callback is also sometimes called to early, however it is hard to find a reproducible situation. In our timer callbacks we only set a global flag and wake up the processor (flag is polled and handled from loop()). Recently we found a reproducible situation that after an external interrupt occurs, the timer callback is called too early. This suggests that it is maybe not only timer handling related. When the external interrupts do no occur, timer behavior returns to normal....

GrumpyOldPizza commented 4 years ago

Is this on the downloadable version, or the latest code directly off GitHub ?

nelisse commented 4 years ago

Release 0.0.10 via Arduino Board Manager. Which is/looks identical to 0.0.10 from GitHub Releases (https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/releases)

GrumpyOldPizza commented 4 years ago

I meant the sources off GitHub directly.

On Fri, Nov 27, 2020, 6:25 AM nelisse notifications@github.com wrote:

Release 0.0.10 via Arduino Board Manager. Which is/looks identical to 0.0.10 from GitHub Releases (https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/releases) https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/releases

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/162#issuecomment-734833899, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7GNFNHL34JGJO6EP5LSR6SEVANCNFSM4SZYWBTQ .

nelisse commented 3 years ago

The current GitHub state is incompatible on an application level with the 0.0.10 release, so I have not been doing much testing with the current GitHub state.

I will need to have some way in my applications, to be able to distinguish between the 2 code lines (therefore my other question regarding the version literals).

Furthermore the Arduino IDE/CLI unfortunately does not have an easy way to switch between various package releases, so it requires some careful administration on my side….

I will come back to this later with updates!

Martin

From: Thomas Roell notifications@github.com Sent: Friday, 27 November, 2020 14:27 To: GrumpyOldPizza/ArduinoCore-stm32l0 ArduinoCore-stm32l0@noreply.github.com Cc: nelisse mwnelisse@gmail.com; Comment comment@noreply.github.com Subject: Re: [GrumpyOldPizza/ArduinoCore-stm32l0] TimerMillis doesn't seem to work properly with 2 timers (#162)

I meant the sources off GitHub directly.

On Fri, Nov 27, 2020, 6:25 AM nelisse <notifications@github.com mailto:notifications@github.com > wrote:

Release 0.0.10 via Arduino Board Manager. Which is/looks identical to 0.0.10 from GitHub Releases (https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/releases) https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/releases

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/162#issuecomment-734833899, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7GNFNHL34JGJO6EP5LSR6SEVANCNFSM4SZYWBTQ .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/162#issuecomment-734834464 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AEMXJOHQJUNA5YPFJKWAGQTSR6SKBANCNFSM4SZYWBTQ . https://github.com/notifications/beacon/AEMXJOBX7CTSQMSVGYVQ7S3SR6SKBA5CNFSM4SZYWBT2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOFPGK6IA.gif

hallard commented 3 years ago

I already faced out this, here what I've done (on mac os so may be you need to adjust some folder names) to switch between version. Assuming you installed the repo from arduino IDE the package on MacOs are under ~/Library/Arduino15/packages/TleraCorp/hardware/stm32l0/0.0.10

Then I got on my home dir both version named 0.0.10-gitand 0.0.10-release and a script to switch from one to other

charles@mac-office:stm32l0$ pwd
/Users/charles/Devt/stm32l0
charles@mac-office:stm32l0$ ls -lA
total 24
-rw-r--r--@  1 charles  staff  10244 13 jul 14:27 .DS_Store
drwxr-xr-x  15 charles  staff    480  4 mai  2020 0.0.10-git
drwxrwxr-x@ 14 charles  staff    448 13 jul 11:24 0.0.10-release
lrwxr-xr-x   1 charles  staff     39  4 jui  2020 set_stm.sh -> /Users/charles/OneDrive/devt/set_stm.sh
charles@mac-office:stm32l0$ 

The trick is to link in the packages folder the git version or release version, it's done by a basic script

#/bin/bash

echo "Select environement for STM32L0"
echo "1) latest release"
echo "2) git"
echo -n "Input Selection : "
read version

if [ "$version" = "1" ]; then
        folder="release/"
elif [ "$version" = "2" ]; then
        folder="git/"
else
        echo "You have entered an invalid selection!"
fi

echo "Setting folder to $folder"

if [ "$folder" != "" ]; then
    echo "unlink ~/Library/Arduino15/packages/TleraCorp/hardware/stm32l0/0.0.10"
    unlink ~/Library/Arduino15/packages/TleraCorp/hardware/stm32l0/0.0.10
    echo "linking ~/devt/stm32l0/0.0.10-$folder to ~/Library/Arduino15/packages/TleraCorp/hardware/stm32l0/0.0.10"
    ln -sFf ~/devt/stm32l0/0.0.10-$folder ~/Library/Arduino15/packages/TleraCorp/hardware/stm32l0/0.0.10
fi

Of course close Arduino IDE before switching and open back after

Hope this helps