Closed chess-levin closed 3 years ago
Thanks for your interests in the Library.
Your code did not initialize the ISR_Timer2 correctly.
I've just added example ISR_16_Timers_Array_Complex and ISR_Timers_Array_Simple to demonstrate the usage of 16 virtual ISR-based timers
The latter is modified from your code to illustrate what steps are missing.
#define TIMER_INTERRUPT_DEBUG 0
#define USE_TIMER_1 false
#define USE_TIMER_2 true
#define USE_TIMER_3 false
#define USE_TIMER_4 false
#define USE_TIMER_5 false
#include "TimerInterrupt.h"
#include "ISR_Timer.h"
#include <SimpleTimer.h> // https://github.com/schinken/SimpleTimer
ISR_Timer ISR_Timer2;
#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif
#define LED_TOGGLE_INTERVAL_MS 1000L
// You have to use longer time here if having problem because Arduino AVR clock is low, 16MHz => lower accuracy.
// Tested OK with 1ms when not much load => higher accuracy.
#define TIMER2_INTERVAL_MS 1L
volatile uint32_t startMillis = 0;
volatile uint32_t deltaMillis2s = 0;
volatile uint32_t deltaMillis5s = 0;
volatile uint32_t previousMillis2s = 0;
volatile uint32_t previousMillis5s = 0;
void TimerHandler2()
{
static bool toggle = false;
static int timeRun = 0;
ISR_Timer2.run();
// Toggle LED every LED_TOGGLE_INTERVAL_MS = 2000ms = 2s
if (++timeRun == ((LED_TOGGLE_INTERVAL_MS) / TIMER2_INTERVAL_MS) )
{
timeRun = 0;
//timer interrupt toggles pin LED_BUILTIN
digitalWrite(LED_BUILTIN, toggle);
toggle = !toggle;
}
}
void doingSomething2s()
{
unsigned long currentMillis = millis();
deltaMillis2s = currentMillis - previousMillis2s;
previousMillis2s = currentMillis;
}
void doingSomething5s()
{
unsigned long currentMillis = millis();
deltaMillis5s = currentMillis - previousMillis5s;
previousMillis5s = currentMillis;
}
/////////////////////////////////////////////////
#define SIMPLE_TIMER_MS 2000L
// Init SimpleTimer
SimpleTimer simpleTimer;
// Here is software Timer, you can do somewhat fancy stuffs without many issues.
// But always avoid
// 1. Long delay() it just doing nothing and pain-without-gain wasting CPU power.Plan and design your code / strategy ahead
// 2. Very long "do", "while", "for" loops without predetermined exit time.
void simpleTimerDoingSomething2s()
{
static unsigned long previousMillis = startMillis;
unsigned long currMillis = millis();
Serial.println("SimpleTimer : programmed " + String(SIMPLE_TIMER_MS) + "ms, current time ms : " + String(currMillis) + ", Delta ms : " + String(currMillis - previousMillis));
Serial.println("Timer2s actual : " + String(deltaMillis2s));
Serial.println("Timer5s actual : " + String(deltaMillis5s));
previousMillis = currMillis;
}
////////////////////////////////////////////////
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial);
Serial.println("\nStarting ISR_Timers_Array_Simple");
Serial.println("Version : " + String(TIMER_INTERRUPT_VERSION));
Serial.println("CPU Frequency = " + String(F_CPU / 1000000) + " MHz");
ITimer2.init();
if (ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2))
Serial.println("Starting ITimer2 OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer2. Select another freq., duration or timer");
ISR_Timer2.setInterval(2000L, doingSomething2s);
ISR_Timer2.setInterval(5000L, doingSomething5s);
// You need this timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary.
simpleTimer.setInterval(SIMPLE_TIMER_MS, simpleTimerDoingSomething2s);
}
#define BLOCKING_TIME_MS 10000L
void loop()
{
// This unadvised blocking task is used to demonstrate the blocking effects onto the execution and accuracy to Software timer
// You see the time elapse of ISR_Timer still accurate, whereas very unaccurate for Software Timer
// The time elapse for 2000ms software timer now becomes 3000ms (BLOCKING_TIME_MS)
// While that of ISR_Timer is still prefect.
delay(BLOCKING_TIME_MS);
// You need this Software timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary
// You don't need to and never call ISR_Timer.run() here in the loop(). It's already handled by ISR timer.
simpleTimer.run();
}
Although Serial.print() in Arduino Mega/UNO/Nano ISR is currently working, I advise not to do that way,. I've moved them to software timer's simpleTimerDoingSomething2s() to demonstrate how to use ISRs correctly.
Good Luck,
You can see in the following terminal output the accuracy if ISR-based Timers
Starting ISR_Timers_Array_Simple
Version : v1.0.3
CPU Frequency = 16 MHz
Starting ITimer2 OK, millis() = 1
SimpleTimer : programmed 2000ms, current time ms : 10004, Delta ms : 10004
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 20013, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 30021, Delta ms : 10008
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 40030, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 50038, Delta ms : 10008
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 60046, Delta ms : 10008
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 70054, Delta ms : 10008
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 80063, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 90072, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 100080, Delta ms : 10008
Timer2s actual : 2001
Timer5s actual : 5001
SimpleTimer : programmed 2000ms, current time ms : 110089, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 120097, Delta ms : 10008
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 130106, Delta ms : 10009
Timer2s actual : 2000
Timer5s actual : 5000
SimpleTimer : programmed 2000ms, current time ms : 140113, Delta ms : 10007
Timer2s actual : 2000
Timer5s actual : 5000
Hello Khoi Hoang, I like to try your new Library 1.0.2, but had no success with your new 16 ISR-based-timers. I want to work with several 'virtual timers' based on timer number two of my arduino nano board. Timer number one is used for a PWM-function / analogWrite() According to my sketch (see below) there should be some output every 2 and 5 seconds, but nothing happens. What do I wrong?
When I attach an ISR this way
ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, timer2HandlerDown)
it works. But my understanding is, that it is not possible to use more than one ISR this way.Thank you for your support.
Arduino IDE 1.8.13 VID: 1A86 PID: 7523