PaulStoffregen / TimerOne

TimerOne Library with optimization and expanded hardware support
http://www.pjrc.com/teensy/td_libs_TimerOne.html
470 stars 209 forks source link

probably flaw of start() #46

Open 5chufti opened 4 years ago

5chufti commented 4 years ago

Description

At least on UNO with latest Arduino IDE and lib git version timer.start() probably not working as seen in sketches developed with older version. after a timer.stop() a timer.start() immediately calls ISR (not delayed by set interval)

(maybe it is just an undocumented sideeffect of recent version that stop() clears the set interval?)

Steps To Reproduce Problem

modified example shows problem: see below

Hardware & Software

Board UNO Arduino IDE version Version info & package name (from Tools > Boards > Board Manager) git version as of 21.Nov.2020 Operating system & version Win7

Arduino Sketch

#include <TimerOne.h>

const int led = LED_BUILTIN;  // the pin with a LED

void setup(void)
{
  pinMode(led, OUTPUT);
  Timer1.initialize(150000);
  Timer1.attachInterrupt(blinkLED); // blinkLED to run every 0.15 seconds
  Serial.begin(9600);
}

int ledState = LOW;
volatile unsigned long blinkCount = 0; // use volatile for shared variables

void blinkLED(void)
{
  Timer1.stop();
  if (ledState == LOW) {
    ledState = HIGH;
    blinkCount = blinkCount + 1;  // increase when LED turns on
  } else {
    ledState = LOW;
  }
  digitalWrite(led, ledState);
  Timer1.start();        //Timer1.initialize(150000); works in sketches w older version of lib
}

void loop(void)
{
  unsigned long blinkCopy;  // holds a copy of the blinkCount
  noInterrupts();
  blinkCopy = blinkCount;
  interrupts();

  Serial.print("blinkCount = ");
  Serial.println(blinkCopy);
  delay(100);
}

Errors or Incorrect Output

not blinking, counter increasing much too fast w/o blink

vjenne commented 3 years ago

Yes, I just ran into this problem too. My solution is as follows: In timerOne.h, i changed line 85. TCNT1 = 0; I changed 0 to 1. I think preloading this timer generates an interrupt the same as when an overflow happens like when the timer goes from 0xFFFF to 0x0000. Thus generating an overflow interrupt. So if you change line 85 to TCNT1 = 1; No interrupt will happen. Your timing will be 1 clock tick faster than expected....

jbidinger commented 2 years ago

I changed the Timer1.start() call to Timer1.resume() in blinkLED() and your sketch seems to be working. I'm testing on a Mega though. Having said that I did have problems with Timer1.start().

Looks like I'm nekrothreading here. Maybe it will help someone.