- Why do we need this TimerInterrupt_Generic library
- Changelog
- Prerequisites
- Installation
- Packages' Patches
- 1. For Adafruit nRF52840 and nRF52832 boards
- 2. For Teensy boards
- 3. For Arduino SAM DUE boards
- 4. For Arduino SAMD boards
- 5. For Adafruit SAMD boards
- 6. For Seeeduino SAMD boards
- 7. For STM32 boards
- 8. For RP2040-based boards using Earle Philhower arduino-pico core
- 9. For Portenta_H7 boards using Arduino IDE in Linux
- Libraries' Patches
- HOWTO Fix
Multiple Definitions
Linker Error - HOWTO Use analogRead() with ESP32 running WiFi and/or BlueTooth (BT/BLE)
- HOWTO Use PWM analogWrite() with ESP8266 running Timer1 Interrupt
- More useful Information
- New from v1.1.0
- Usage for ESP32
- Usage for NRF52
- Usage for SAMD
- Usage for SAM DUE
- Usage for Teensy
- Usage for STM32F/L/H/G/WB/MP1
- Usage for NRF52840-based board using mbed-RTOS such as Nano-33-BLE.
- Usage for Arduino AVR
- Usage for Arduino megaAVR
- Examples
- Example ISR_16_Timers_Array_Complex for MBED RP2040 boards
- Debug Terminal Output Samples
- 1. ISR_Timer_Complex_Ethernet on Arduino SAM DUE
- 2. ISR_Timer_Complex_Ethernet on Adafruit NRF52840_FEATHER EXPRESS
- 3. ISR_16_Timers_Array_Complex on Arduino SAMD21 SAMD_NANO_33_IOT
- 4. TimerInterruptTest on Teensy 4.1
- 5. ISR_16_Timers_Array_Complex on ESP32_DEV
- 6. ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E
- 7. ISR_16_Timers_Array_Complex on STM32F7 Nucleo-144 F767ZI
- 8. TimerInterruptTest on STM32F7 Nucleo-144 F767ZI
- 9. ISR_16_Timers_Array_Complex on Nano 33 BLE
- 10. ISR_16_Timers_Array_Complex on Arduino megaAVR Nano Every to show accuracy difference
- Debug
- Troubleshooting
- Issues
- TO DO
- DONE
- Contributions and Thanks
- Contributing
- License
- Copyright
Why do we need this TimerInterrupt_Generic library
This library enables you to use Interrupt from Hardware Timers on supported Arduino boards such as AVR, Mega-AVR, ESP8266, ESP32, SAMD, SAM DUE, nRF52, STM32F/L/H/G/WB/MP1, Teensy, Nano-33-BLE, etc.
As Hardware Timers are rare, and very precious assets of any board, this library now enables you to use up to 16 ISR-based Timers, while consuming only 1 Hardware Timer. Timers' interval is very long (ulong millisecs).
Imagine you have a system with a mission-critical function, measuring water level and control the sump pump or doing something much more important. You normally use a software timer to poll, or even place the function in loop(). But what if another function is blocking the loop() or setup().
So your function might not be executed on-time or not at all, and the result would be disastrous.
You'd prefer to have your function called, no matter what happening with other functions (busy loop, bug, etc.).
The correct choice is to use a Hardware Timer with Interrupt to call your function.
These hardware timers, using interrupt, still work even if other functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software timers using millis() or micros(). That's necessary if you need to measure some data requiring better accuracy.
Functions using normal software timers, relying on loop() and calling millis(), won't work if the loop() or setup() is blocked by certain operation. For example, certain function is blocking while it's connecting to WiFi or some services.
The catch is your function is now part of an ISR (Interrupt Service Routine), and must be lean / mean, and follow certain rules. More to read on:
You'd certainly experienced that if using other Hardware Timer Libraries, such as TimerOne or TimerThree, the interval is short, in milliseconds range.
For example, Teensy 4.x, with super-high clock frequency of 600MHz and Timer1 and Timer3 clock of 150MHz, the maximum interval / frequency is only 55922.3467 us / 17.881939 Hz. This Teensy_TimerInterrupt library will provide you up to 16 super-long (ulong millisecs) ISR Timers for each used Timer1 or Timer3.
For Teensy 4.x, this library will be expanded to use other available hardware timers, such as FTM, GPT, QUAD, PIT, in addition to current Timer1 and Timer3.
-
ESP8266
-
ESP32, ESP32-S2
-
AdaFruit Feather nRF52832, nRF52840 Express, BlueFruit Sense, Itsy-Bitsy nRF52840 Express, Metro nRF52840 Express, NINA_B302_ublox, NINA_B112_ublox etc..
-
Arduino SAMD21 (ZERO, MKR, NANO_33_IOT, etc.).
-
Adafruit SAM21 (Itsy-Bitsy M0, Metro M0, Feather M0, Gemma M0, etc.).
-
Adafruit SAM51 (Itsy-Bitsy M4, Metro M4, Grand Central M4, Feather M4 Express, etc.).
-
Seeeduino SAMD21/SAMD51 boards (SEEED_WIO_TERMINAL, SEEED_FEMTO_M0, SEEED_XIAO_M0, Wio_Lite_MG126, WIO_GPS_BOARD, SEEEDUINO_ZERO, SEEEDUINO_LORAWAN, SEEED_GROVE_UI_WIRELESS, etc.)
-
Sparkfun SAMD21 boards such as SparkFun_RedBoard_Turbo, SparkFun_Qwiic_Micro, etc.
-
Sparkfun SAMD51 boards such as SparkFun_SAMD51_Thing_Plus, SparkFun_SAMD51_MicroMod, etc.
-
STM32 (Nucleo-144, Nucleo-64, Nucleo-32, Discovery, STM32F1, STM32F3, STM32F4, STM32H7, STM32L0, etc.).
-
STM32F/L/H/G/WB/MP1 (Nucleo-64 L053R8,Nucleo-144, Nucleo-64, Nucleo-32, Discovery, STM32Fx, STM32H7, STM32Lx, STM32Gx, STM32WB, STM32MP1, etc.) having 64K+ Flash program memory.
-
Teensy boards such as :
- Teensy 4.1, 4.0
- Teensy 3.6, 3.5, 3.2/3.1, 3.0
- Teensy LC
- Teensy++ 2.0 and Teensy 2.0
-
Arduino, Adafruit, Sparkfun, Generic AVR boards such as :
- Arduino Uno / Mega / Duemilanove / Diecimila / LilyPad / Mini / Fio / Nano, etc.
- Arduino ATMega 16U4, 32U4 such as AVR Leonardo, Leonardo ETH, YUN, Esplora, LILYPAD_USB, AVR_ROBOT_CONTROL, AVR_ROBOT_MOTOR, AVR_INDUSTRIAL101, etc.
- Adafruit ATMega 32U4 such as AVR_FLORA8, AVR_FEATHER32U4, AVR_CIRCUITPLAY, AVR_ITSYBITSY32U4_5V, AVR_ITSYBITSY32U4_3V, AVR_BLUEFRUITMICRO, AVR_ADAFRUIT32U4, etc.
- Adafruit ATMega 328(P) such as AVR_METRO, AVR_FEATHER328P, AVR_PROTRINKET5, AVR_PROTRINKET3, AVR_PROTRINKET5FTDI, AVR_PROTRINKET3FTDI, etc.
- Generic or Sparkfun AVR ATmega_32U4 such as AVR_MAKEYMAKEY, AVR_PROMICRO, etc.
- Generic or Sparkfun AVR ATmega_328(P) such as ARDUINO_REDBOT, ARDUINO_AVR_DIGITAL_SANDBOX, etc.
- Generic or Sparkfun AVR ATmega128RFA1 such as ATMEGA128RFA1_DEV_BOARD, etc.
-
Arduino Nano-33-BLE
-
Arduino SAM DUE.
-
ATmega4809-based boards such as :
- Arduino UNO WiFi Rev2, AVR_NANO_EVERY, etc.
-
RP2040-based boards such as RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040 and GENERIC_RP2040, etc. using Earle Philhower's arduino-pico core
-
RP2040-based boards such as Nano_RP2040_Connect, RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040 and GENERIC_RP2040, etc. using Arduino-mbed RP2040 core
-
Inside the attached function, delay() won’t work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function.
-
Typically global variables are used to pass data between an ISR and the main program. To make sure variables shared between an ISR and the main program are updated correctly, declare them as volatile.
ESP32 Core 2.0.1+
for ESP32-based boards.ESP8266 Core 3.0.2+
for ESP8266-based boards. . To use ESP8266 core 2.7.1+ for LittleFS.Arduino AVR core 1.8.3+
for Arduino (Use Arduino Board Manager) for AVR boards.Adafruit AVR core 1.4.13+
for Adafruit AVR boards. Use Arduino Board Manager to install.Sparkfun AVR core 1.1.13+
for Sparkfun AVR boards. Use Arduino Board Manager to install.Teensy core v1.55+
for Teensy (4.1, 4.0, 3.6, 3.5, 3,2, 3.1, 3.0) boards.Arduino SAM DUE core v1.6.12+
for SAM DUE ARM Cortex-M3 boards.Arduino SAMD core 1.8.12+
for SAMD ARM Cortex-M0+ boards.Adafruit SAMD core 1.7.5+
for SAMD ARM Cortex-M0+ and M4 boards (Nano 33 IoT, etc.).Seeeduino SAMD core 1.8.2+
for SAMD21/SAMD51 boards (XIAO M0, Wio Terminal, etc.).Sparkfun SAMD core 1.8.1+
for SAMD21/SAMD51 boards (SparkFun_RedBoard_Turbo, SparkFun_SAMD51_Thing_Plus, etc.).Adafruit nRF52 v1.1.0+
for nRF52 boards such as Adafruit NRF52840_FEATHER, NRF52832_FEATHER, NRF52840_FEATHER_SENSE, NRF52840_ITSYBITSY, NRF52840_CIRCUITPLAY, NRF52840_CLUE, NRF52840_METRO, NRF52840_PCA10056, PARTICLE_XENON, NINA_B302_ublox, etc.Arduino Core for STM32 v2.1.0+
for STM32F/L/H/G/WB/MP1 boards.Arduino megaAVR core 1.8.7+
for Arduino megaAVR boards. Use Arduino Board Manager to install.Arduino mbed_rp2040 core 2.6.1+
for Arduino (Use Arduino Board Manager) RP2040-based boards, such as Arduino Nano RP2040 Connect, RASPBERRY_PI_PICO, etc..Earle Philhower's arduino-pico core v1.9.6+
for RP2040-based boards such as RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040 and GENERIC_RP2040, etc.
Blynk library 1.0.1
. to use with certain examples.
- For built-in LAN8742A Ethernet:
STM32Ethernet library v1.2.0+
for built-in LAN8742A Ethernet on (Nucleo-144, Discovery).LwIP library v2.1.2+
for built-in LAN8742A Ethernet on (Nucleo-144, Discovery).
- For W5x00 Ethernet:
Ethernet library v2.0.0+
for W5100, W5200 and W5500.EthernetLarge library v2.0.0+
for W5100, W5200 and W5500.Ethernet2 library v1.0.4+
for W5500.Ethernet3 library v1.5.5+
for W5500/WIZ550io/WIZ850io/USR-ES1 with Wiznet W5500 chip.
- For ENC28J60 Ethernet:
EthernetENC library v2.0.1+
for ENC28J60. . New and BetterUIPEthernet library v2.0.10+
for ENC28J60.
-
WiFiNINA_Generic library v1.8.13+
to use WiFiNINA modules/shields. To install. check if using WiFiNINA for boards such as Nano 33 IoT, nRF52, Teensy, etc. -
Blynk_WiFiNINA_WM library 1.1.2+
to use with Blynk-WiFiNINA-related example. To install. check -
To use with certain examples
SimpleTimer library
forISR_16_Timers_Array examples
The best and easiest way is to use Arduino Library Manager
. Search for TimerInterrupt_Generic, then select / install the latest version.
You can also use this link for more detailed instructions.
Another way to install is to:
- Navigate to TimerInterrupt_Generic page.
- Download the latest release
TimerInterrupt_Generic-master.zip
. - Extract the zip file to
TimerInterrupt_Generic-master
directory - Copy whole
TimerInterrupt_Generic-master
folder to Arduino libraries' directory such as~/Arduino/libraries/
.
- Install VS Code
- Install PlatformIO
- Install TimerInterrupt_Generic library or TimerInterrupt_Generic library by using Library Manager. Search for TimerInterrupt_Generic in Platform.io Author's Libraries
- Use included platformio.ini file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at Project Configuration File
To be able to compile, run and automatically detect and display BOARD_NAME on nRF52840/nRF52832 boards, you have to copy the whole nRF52 Packages_Patches directory into Adafruit nRF52 directory (~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0).
Supposing the Adafruit nRF52 version is 1.1.0. These files must be copied into the directory:
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/platform.txt
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/boards.txt
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/cores/nRF5/Udp.h
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/cores/nRF5/Print.h
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/cores/nRF5/Print.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/variants/NINA_B302_ublox/variant.h
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/variants/NINA_B302_ublox/variant.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/variants/NINA_B112_ublox/variant.h
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/variants/NINA_B112_ublox/variant.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/1.1.0/cores/nRF5/Udp.h
Whenever a new version is installed, remember to copy these files into the new version directory. For example, new version is x.yy.z These files must be copied into the directory:
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/platform.txt
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/boards.txt
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/cores/nRF5/Udp.h
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/cores/nRF5/Print.h
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/cores/nRF5/Print.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/variants/NINA_B302_ublox/variant.h
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/variants/NINA_B302_ublox/variant.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/variants/NINA_B112_ublox/variant.h
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/variants/NINA_B112_ublox/variant.cpp
~/.arduino15/packages/adafruit/hardware/nrf52/x.yy.z/cores/nRF5/Udp.h
To be able to compile and run on Teensy boards, you have to copy the files in Packages_Patches for Teensy directory into Teensy hardware directory (./arduino-1.8.15/hardware/teensy/avr/boards.txt).
Supposing the Arduino version is 1.8.15. These files must be copied into the directory:
./arduino-1.8.15/hardware/teensy/avr/boards.txt
./arduino-1.8.15/hardware/teensy/avr/cores/teensy/Stream.h
./arduino-1.8.15/hardware/teensy/avr/cores/teensy3/Stream.h
./arduino-1.8.15/hardware/teensy/avr/cores/teensy4/Stream.h
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz These files must be copied into the directory:
./arduino-x.yy.zz/hardware/teensy/avr/boards.txt
./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy/Stream.h
./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy3/Stream.h
./arduino-x.yy.zz/hardware/teensy/avr/cores/teensy4/Stream.h
To be able to compile and run on SAM DUE boards, you have to copy the whole SAM DUE directory into Arduino sam directory (~/.arduino15/packages/arduino/hardware/sam/1.6.12).
Supposing the Arduino SAM core version is 1.6.12. This file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/sam/1.6.12/platform.txt
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz This file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/sam/x.yy.zz/platform.txt
To be able to compile, run and automatically detect and display BOARD_NAME on Arduino SAMD (Nano-33-IoT, etc) boards, you have to copy the whole Arduino SAMD Packages_Patches directory into Arduino SAMD directory (~/.arduino15/packages/arduino/hardware/samd/1.8.11).
Supposing the Arduino SAMD version is 1.8.11. Now only one file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/samd/1.8.11/platform.txt
Whenever a new version is installed, remember to copy this files into the new version directory. For example, new version is x.yy.zz
This file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/samd/x.yy.zz/platform.txt
Supposing the Arduino SAMD version is 1.8.9. These files must be copied into the directory:
~/.arduino15/packages/arduino/hardware/samd/1.8.9/platform.txt
~/.arduino15/packages/arduino/hardware/samd/1.8.9/cores/arduino/Arduino.h
Whenever a new version is installed, remember to copy these files into the new version directory. For example, new version is x.yy.z
These files must be copied into the directory:
~/.arduino15/packages/arduino/hardware/samd/x.yy.z/platform.txt
~/.arduino15/packages/arduino/hardware/samd/x.yy.z/cores/arduino/Arduino.h
This is mandatory to fix the notorious Arduino SAMD compiler error. See Improve Arduino compatibility with the STL (min and max macro)
...\arm-none-eabi\include\c++\7.2.1\bits\stl_algobase.h:243:56: error: macro "min" passed 3 arguments, but takes just 2
min(const _Tp& __a, const _Tp& __b, _Compare __comp)
Whenever the above-mentioned compiler error issue is fixed with the new Arduino SAMD release, you don't need to copy the Arduino.h
file anymore.
To be able to compile, run and automatically detect and display BOARD_NAME on Adafruit SAMD (Itsy-Bitsy M4, etc) boards, you have to copy the whole Adafruit SAMD Packages_Patches directory into Adafruit samd directory (~/.arduino15/packages/adafruit/hardware/samd/1.7.5).
Supposing the Adafruit SAMD core version is 1.7.5. This file must be copied into the directory:
~/.arduino15/packages/adafruit/hardware/samd/1.7.5/platform.txt
~/.arduino15/packages/adafruit/hardware/samd/1.7.5/cores/arduino/Print.h
~/.arduino15/packages/adafruit/hardware/samd/1.7.5/cores/arduino/Print.cpp
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz This file must be copied into the directory:
~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/platform.txt
~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/cores/arduino/Print.h
~/.arduino15/packages/adafruit/hardware/samd/x.yy.zz/cores/arduino/Print.cpp
To be able to compile, run and automatically detect and display BOARD_NAME on Seeeduino SAMD (XIAO M0, Wio Terminal, etc) boards, you have to copy the whole Seeeduino SAMD Packages_Patches directory into Seeeduino samd directory (~/.arduino15/packages/Seeeduino/hardware/samd/1.8.2).
Supposing the Seeeduino SAMD core version is 1.8.2. This file must be copied into the directory:
~/.arduino15/packages/Seeeduino/hardware/samd/1.8.2/platform.txt
~/.arduino15/packages/Seeeduino/hardware/samd/1.8.2/cores/arduino/Arduino.h
~/.arduino15/packages/Seeeduino/hardware/samd/1.8.2/cores/arduino/Print.h
~/.arduino15/packages/Seeeduino/hardware/samd/1.8.2/cores/arduino/Print.cpp
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz This file must be copied into the directory:
~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/platform.txt
~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Arduino.h
~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Print.h
~/.arduino15/packages/Seeeduino/hardware/samd/x.yy.zz/cores/arduino/Print.cpp
To use LAN8720 on some STM32 boards
- Nucleo-144 (F429ZI, NUCLEO_F746NG, NUCLEO_F746ZG, NUCLEO_F756ZG)
- Discovery (DISCO_F746NG)
- STM32F4 boards (BLACK_F407VE, BLACK_F407VG, BLACK_F407ZE, BLACK_F407ZG, BLACK_F407VE_Mini, DIYMORE_F407VGT, FK407M1)
you have to copy the files stm32f4xx_hal_conf_default.h and stm32f7xx_hal_conf_default.h into STM32 stm32 directory (~/.arduino15/packages/STM32/hardware/stm32/2.1.0/system) to overwrite the old files.
Supposing the STM32 stm32 core version is 2.1.0. These files must be copied into the directory:
~/.arduino15/packages/STM32/hardware/stm32/2.1.0/system/STM32F4xx/stm32f4xx_hal_conf_default.h
for STM32F4.~/.arduino15/packages/STM32/hardware/stm32/2.1.0/system/STM32F7xx/stm32f7xx_hal_conf_default.h
for Nucleo-144 STM32F7.
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz, theses files must be copied into the corresponding directory:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F4xx/stm32f4xx_hal_conf_default.h
- `~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/system/STM32F7xx/stm32f7xx_hal_conf_default.h
To use Serial1 on some STM32 boards without Serial1 definition (Nucleo-144 NUCLEO_F767ZI, Nucleo-64 NUCLEO_L053R8, etc.) boards, you have to copy the files STM32 variant.h into STM32 stm32 directory (~/.arduino15/packages/STM32/hardware/stm32/2.1.0). You have to modify the files corresponding to your boards, this is just an illustration how to do.
Supposing the STM32 stm32 core version is 2.1.0. These files must be copied into the directory:
~/.arduino15/packages/STM32/hardware/stm32/2.1.0/variants/STM32F7xx/F765Z(G-I)T_F767Z(G-I)T_F777ZIT/NUCLEO_F767ZI/variant.h
for Nucleo-144 NUCLEO_F767ZI.~/.arduino15/packages/STM32/hardware/stm32/2.1.0/variants/STM32L0xx/L052R(6-8)T_L053R(6-8)T_L063R8T/NUCLEO_L053R8/variant.h
for Nucleo-64 NUCLEO_L053R8.
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz, theses files must be copied into the corresponding directory:
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/STM32F7xx/F765Z(G-I)T_F767Z(G-I)T_F777ZIT/NUCLEO_F767ZI/variant.h
~/.arduino15/packages/STM32/hardware/stm32/x.yy.zz/variants/STM32L0xx/L052R(6-8)T_L053R(6-8)T_L063R8T/NUCLEO_L053R8/variant.h
8. For RP2040-based boards using Earle Philhower arduino-pico core
To be able to automatically detect and display BOARD_NAME on RP2040-based boards (RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040, GENERIC_RP2040, etc) boards, you have to copy the file RP2040 platform.txt into rp2040 directory (~/.arduino15/packages/rp2040/hardware/rp2040/1.4.0).
Supposing the rp2040 core version is 1.4.0. This file must be copied into the directory:
~/.arduino15/packages/rp2040/hardware/rp2040/1.4.0/platform.txt
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz This file must be copied into the directory:
~/.arduino15/packages/rp2040/hardware/rp2040/x.yy.zz/platform.txt
With core after v1.5.0, this step is not necessary anymore thanks to the PR Add -DBOARD_NAME="{build.board}" #136.
Some libraries, such as Adafruit DHT-sensor-library, require the definition of microsecondsToClockCycles(). To be able to compile and run on RP2040-based boards, you have to copy the files in RP2040 Arduino.h into rp2040 directory (~/.arduino15/packages/rp2040/hardware/rp2040/1.4.0).
Supposing the rp2040 core version is 1.4.0. This file must be copied to replace:
~/.arduino15/packages/rp2040/hardware/rp2040/1.4.0/cores/rp2040/Arduino.h
Whenever a new version is installed, remember to copy this file into the new version directory. For example, new version is x.yy.zz This file must be copied to replace:
~/.arduino15/packages/rp2040/hardware/rp2040/x.yy.zz/cores/rp2040/Arduino.h
With core after v1.5.0, this step is not necessary anymore thanks to the PR Add defs for compatibility #142.
To be able to upload firmware to Portenta_H7 using Arduino IDE in Linux (Ubuntu, etc.), you have to copy the file portenta_post_install.sh into mbed_portenta directory (~/.arduino15/packages/arduino/hardware/mbed_portenta/2.5.2/portenta_post_install.sh).
Then run the following command using sudo
$ cd ~/.arduino15/packages/arduino/hardware/mbed_portenta/2.5.2
$ chmod 755 portenta_post_install.sh
$ sudo ./portenta_post_install.sh
This will create the file /etc/udev/rules.d/49-portenta_h7.rules
as follows:
# Portenta H7 bootloader mode UDEV rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="035b", GROUP="plugdev", MODE="0666"
Supposing the ArduinoCore-mbed core version is 2.5.2. Now only one file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/mbed_portenta/2.5.2/portenta_post_install.sh
Whenever a new version is installed, remember to copy this files into the new version directory. For example, new version is x.yy.zz
This file must be copied into the directory:
~/.arduino15/packages/arduino/hardware/mbed_portenta/x.yy.zz/portenta_post_install.sh
If your application requires 2K+ HTML page, the current Ethernet library
must be modified if you are using W5200/W5500 Ethernet shields. W5100 is not supported for 2K+ buffer. If you use boards requiring different CS/SS pin for W5x00 Ethernet shield, for example ESP32, ESP8266, nRF52, etc., you also have to modify the following libraries to be able to specify the CS/SS pin correctly.
To fix Ethernet library
, just copy these following files into the Ethernet library
directory to overwrite the old files:
To fix EthernetLarge library
, just copy these following files into the EthernetLarge library
directory to overwrite the old files:
To fix Ethernet2 library
, just copy these following files into the Ethernet2 library
directory to overwrite the old files:
To add UDP Multicast support, necessary for the UPnP_Generic library:
- To fix
Ethernet3 library
, just copy these following files into theEthernet3 library
directory to overwrite the old files:
To be able to compile and run on nRF52 boards with ENC28J60 using UIPEthernet library, you have to copy these following files into the UIPEthernet utility
directory to overwrite the old files:
To fix ESP32 compile error
, just copy the following file into the ESP32
cores/esp32 directory (e.g. ./arduino-1.8.13/hardware/espressif/cores/esp32) to overwrite the old file:
To fix ESP8266 compile error
such as
error: 'class EthernetClass' has no member named 'init'
Ethernet.init (USE_THIS_SS_PIN);
just rename the following file in ./arduino-1.8.16/hardware/esp8266com/esp8266/libraries/Ethernet directory
- From
Ethernet.h
toEthernet_ESP8266.h
Check if you need to install the UIPEthernet patch new STM32 core F3/F4 compatibility to avoid errors #include HardwareSPI.h
on some STM32 boards (Nucleo-32 F303K8, etc.)
The current library implementation, using xyz-Impl.h instead of standard xyz.cpp, possibly creates certain Multiple Definitions
Linker error in certain use cases. Although it's simple to just modify several lines of code, either in the library or in the application, the library is adding 2 more source directories
- scr_h for new h-only files
- src_cpp for standard h/cpp files
besides the standard src directory.
To use the old standard cpp way, locate this library' directory, then just
- Delete the all the files in src directory.
- Copy all the files in src_cpp directory into src.
- Close then reopen the application code in Arduino IDE, etc. to recompile from scratch.
To re-use the new h-only way, just
- Delete the all the files in src directory.
- Copy the files in src_h directory into src.
- Close then reopen the application code in Arduino IDE, etc. to recompile from scratch.
Please have a look at ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to have more detailed description and solution of the issue.
- ADC1 controls ADC function for pins GPIO32-GPIO39
- ADC2 controls ADC function for pins GPIO0, 2, 4, 12-15, 25-27
Look in file adc_common.c
In ADC2, there're two locks used for different cases:
lock shared with app and Wi-Fi: ESP32: When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed. ESP32S2: The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
lock shared between tasks: when several tasks sharing the ADC2, we want to guarantee all the requests will be handled. Since conversions are short (about 31us), app returns the lock very soon, we use a spinlock to stand there waiting to do conversions one by one.
adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
- In order to use ADC2 for other functions, we have to acquire complicated firmware locks and very difficult to do
- So, it's not advisable to use ADC2 with WiFi/BlueTooth (BT/BLE).
- Use ADC1, and pins GPIO32-GPIO39
- If somehow it's a must to use those pins serviced by ADC2 (GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27), use the fix mentioned at the end of ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example to work with ESP32 WiFi/BlueTooth (BT/BLE).
Please have a look at ESP8266TimerInterrupt Issue 8: ESP8266Timer and PWM --> wdt reset to have more detailed description and solution of the issue.
- Timer0 has been used for WiFi and it's not advisable to use while using WiFi (if not using WiFi, why select ESP8266 ??)
- Timer1 is used by this ESP8266TimerInterrupt Library
- If possible, use software timer instead of ESP8266TimerInterrupt Hardware Timer1
- If using ESP8266TimerInterrupt Hardware Timer1 is a must, you can either
- use external DAC such as AD5662, AD5667, AD5696.
- use software PWM such as mentioned in ESP8266 PWM REVISITED (AND REIMPLEMENTED)
The ESP32 has two timer groups, each one with two general purpose hardware timers. All the timers are based on 64 bits counters and 16 bit prescalers.
The timer counters can be configured to count up or down and support automatic reload and software reload.
They can also generate alarms when they reach a specific value, defined by the software. The value of the counter can be read by the software program.
The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short. Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
The timer1 counters can be configured to support automatic reload.
From Arduino 101: Timers and Interrupts
Timer0 is a 8-bit timer.
In the Arduino world timer0 is been used for the timer functions, like delay(), millis() and micros(). If you change Timer0 registers, this may influence the Arduino timer function. So you should know what you are doing.
Timer1 is a 16-bit timer. In the Arduino world the Servo library uses timer1 on Arduino Uno (Timer5 on Arduino Mega).
Timer2 is a 8-bit timer like Timer0. In the Arduino work the tone() function uses Timer2.
Timer 3,4,5 are only available on Arduino Mega boards. These timers are all 16-bit timers.
The Timers of STM32s are numerous, yet very sophisticated and powerful.
In general, across the STM32 microcontrollers families, the timer peripherals that have the same name also have the same features set, but there are a few exceptions.
For example, the TIM1 timer peripheral is shared across the STM32F1 Series, STM32F2 Series and STM32F4 Series, but for the specific case of STM32F30x microcontrollers family, the TIM1 timer peripheral features a bit richer features set than the TIM1 present in the other families.
The general purpose timers embedded by the STM32 microcontrollers share the same backbone structure; they differ only on the level of features embedded by a given timer peripheral.
The level of features integration for a given timer peripheral is decided based on the applications field that it targets.
The timer peripherals can be classified as: • Advanced-configuration timers like TIM1 and TIM8 among others. • General-purpose configuration timers like TIM2 and TIM3 among others • Lite-configuration timers like TIM9, TIM10, TIM12 and TIM16 among others • Basic-configuration timers like TIM6 and TIM7 among others.
For example, STM32F103C8T6 has one advance timer, while STM32F103VET6 has two advanced timers. Nucleo-144 STM32F767ZI boards have 14 Timers, TIM1-TIM14.
More information can be found at Embedded-Lab STM32 TIMERS
To be sure which Timer is available for the board you're using, check the Core Package's related files. For example, for Nucleo-144 STM32F767ZI, check these files:
~/.arduino15/packages/STM32/hardware/stm32/1.9.0/system/Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f7xx.h
~/.arduino15/packages/STM32/hardware/stm32/1.9.0/system/Drivers/CMSIS/Device/ST/STM32F7xx/Include/stm32f767xx.h
The information will be as follows:
typedef struct
{
__IO uint32_t CR1; /*!< TIM control register 1, Address offset: 0x00 */
__IO uint32_t CR2; /*!< TIM control register 2, Address offset: 0x04 */
__IO uint32_t SMCR; /*!< TIM slave mode control register, Address offset: 0x08 */
__IO uint32_t DIER; /*!< TIM DMA/interrupt enable register, Address offset: 0x0C */
__IO uint32_t SR; /*!< TIM status register, Address offset: 0x10 */
__IO uint32_t EGR; /*!< TIM event generation register, Address offset: 0x14 */
__IO uint32_t CCMR1; /*!< TIM capture/compare mode register 1, Address offset: 0x18 */
__IO uint32_t CCMR2; /*!< TIM capture/compare mode register 2, Address offset: 0x1C */
__IO uint32_t CCER; /*!< TIM capture/compare enable register, Address offset: 0x20 */
__IO uint32_t CNT; /*!< TIM counter register, Address offset: 0x24 */
__IO uint32_t PSC; /*!< TIM prescaler, Address offset: 0x28 */
__IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
__IO uint32_t RCR; /*!< TIM repetition counter register, Address offset: 0x30 */
__IO uint32_t CCR1; /*!< TIM capture/compare register 1, Address offset: 0x34 */
__IO uint32_t CCR2; /*!< TIM capture/compare register 2, Address offset: 0x38 */
__IO uint32_t CCR3; /*!< TIM capture/compare register 3, Address offset: 0x3C */
__IO uint32_t CCR4; /*!< TIM capture/compare register 4, Address offset: 0x40 */
__IO uint32_t BDTR; /*!< TIM break and dead-time register, Address offset: 0x44 */
__IO uint32_t DCR; /*!< TIM DMA control register, Address offset: 0x48 */
__IO uint32_t DMAR; /*!< TIM DMA address for full transfer, Address offset: 0x4C */
__IO uint32_t OR; /*!< TIM option register, Address offset: 0x50 */
__IO uint32_t CCMR3; /*!< TIM capture/compare mode register 3, Address offset: 0x54 */
__IO uint32_t CCR5; /*!< TIM capture/compare mode register5, Address offset: 0x58 */
__IO uint32_t CCR6; /*!< TIM capture/compare mode register6, Address offset: 0x5C */
__IO uint32_t AF1; /*!< TIM Alternate function option register 1, Address offset: 0x60 */
__IO uint32_t AF2; /*!< TIM Alternate function option register 2, Address offset: 0x64 */
} TIM_TypeDef;
and
#define PERIPH_BASE 0x40000000UL /*!< Base address of : AHB/ABP Peripherals
/*!< Peripheral memory map */
#define APB1PERIPH_BASE PERIPH_BASE
/*!< APB1 peripherals */
#define TIM2_BASE (APB1PERIPH_BASE + 0x0000UL)
#define TIM3_BASE (APB1PERIPH_BASE + 0x0400UL)
#define TIM4_BASE (APB1PERIPH_BASE + 0x0800UL)
#define TIM5_BASE (APB1PERIPH_BASE + 0x0C00UL)
#define TIM6_BASE (APB1PERIPH_BASE + 0x1000UL)
#define TIM7_BASE (APB1PERIPH_BASE + 0x1400UL)
#define TIM12_BASE (APB1PERIPH_BASE + 0x1800UL)
#define TIM13_BASE (APB1PERIPH_BASE + 0x1C00UL)
#define TIM14_BASE (APB1PERIPH_BASE + 0x2000UL)
/*!< APB2 peripherals */
#define TIM1_BASE (APB2PERIPH_BASE + 0x0000UL)
#define TIM8_BASE (APB2PERIPH_BASE + 0x0400UL)
#define TIM9_BASE (APB2PERIPH_BASE + 0x4000UL)
#define TIM10_BASE (APB2PERIPH_BASE + 0x4400UL)
#define TIM11_BASE (APB2PERIPH_BASE + 0x4800UL)
...
#define TIM2 ((TIM_TypeDef *) TIM2_BASE)
#define TIM3 ((TIM_TypeDef *) TIM3_BASE)
#define TIM4 ((TIM_TypeDef *) TIM4_BASE)
#define TIM5 ((TIM_TypeDef *) TIM5_BASE)
#define TIM6 ((TIM_TypeDef *) TIM6_BASE)
#define TIM7 ((TIM_TypeDef *) TIM7_BASE)
#define TIM12 ((TIM_TypeDef *) TIM12_BASE)
#define TIM13 ((TIM_TypeDef *) TIM13_BASE)
#define TIM14 ((TIM_TypeDef *) TIM14_BASE)
...
#define TIM1 ((TIM_TypeDef *) TIM1_BASE)
#define TIM8 ((TIM_TypeDef *) TIM8_BASE)
...
#define TIM9 ((TIM_TypeDef *) TIM9_BASE)
#define TIM10 ((TIM_TypeDef *) TIM10_BASE)
#define TIM11 ((TIM_TypeDef *) TIM11_BASE)
TCB0-TCB3 are 16-bit timers.
Now with these new 16 ISR-based timers
(while consuming only 1 hardware timer), the maximum interval is practically unlimited (limited only by unsigned long miliseconds). The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
The ISR_16_Timers_Array_Complex and ISR_16_Timers_Array_Complex examples will demonstrate the nearly perfect accuracy compared to software timers by printing the actual elapsed millisecs of each type of timers.
Being ISR-based timers, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet and Blynk services. You can also have many (up to 16)
timers to use.
This non-being-blocked important feature is absolutely necessary for mission-critical tasks.
You'll see blynkTimer Software is blocked while system is connecting to WiFi / Internet / Blynk, as well as by blocking task
in loop(), using delay() function as an example. The elapsed time then is very unaccurate
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
Timer0, Timer1, Timer2 and Timer3
are supported for ESP32.
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_1-NRF_TIMER_4 (1 to 4)
// If you select the already-used NRF_TIMER_0, it'll be auto modified to use NRF_TIMER_1
// Init NRF52 timer NRF_TIMER1
NRF52Timer ITimer(NRF_TIMER_1);
void TimerHandler(void)
{
// Doing something here inside ISR
}
#define TIMER_INTERVAL_MS 1000 // 1s = 1000ms
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler0))
Serial.println("Starting ITimer OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer. Select another freq. or timer");
}
/// Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_1-NRF_TIMER_4 (1 to 4)
// If you select the already-used NRF_TIMER_0, it'll be auto modified to use NRF_TIMER_1
// Init NRF52 timer NRF_TIMER2
NRF52Timer ITimer(NRF_TIMER_2);
// Init NRF52_ISR_Timer
// Each NRF52_ISR_Timer can service 16 different ISR-based timers
ISR_Timer NRF52_ISR_Timer;
void TimerHandler(void)
{
NRF52_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_MS 50L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In NRF52, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
{
lastMillis = millis();
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
}
else
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// Depending on the board, you can select SAMD21 Hardware Timer from TC3-TCC
// SAMD21 Hardware Timer from TC3 or TCC
// SAMD51 Hardware Timer only TC3
SAMDTimer ITimer0(TIMER_TC3);
void TimerHandler0(void)
{
// Doing something here inside ISR
}
#define TIMER0_INTERVAL_MS 1000 // 1s = 1000ms
void setup()
{
....
// Interval in microsecs
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0))
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer0. Select another freq. or timer");
}
// Depending on the board, you can select SAMD21 Hardware Timer from TC3-TCC
// SAMD21 Hardware Timer from TC3 or TCC
// SAMD51 Hardware Timer only TC3
SAMDTimer ITimer0(TIMER_TC3);
// Init SAMD_ISR_Timer
// Each SAMD_ISR_Timer can service 16 different ISR-based timers
ISR_Timer SAMD_ISR_Timer;
void TimerHandler(void)
{
SAMD_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_MS 50L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In SAMD, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
{
lastMillis = millis();
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
}
else
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
SAMD_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
SAMD_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
SAMD_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
SAMD_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// Interval in microsecs
attachDueInterrupt(TIMER1_INTERVAL_MS * 1000, TimerHandler1, "ITimer1");
void TimerHandler(void)
{
// Doing something here inside ISR
}
#define TIMER_INTERVAL_MS 1000 // 1s = 1000ms
uint16_t attachDueInterrupt(double microseconds, timerCallback callback, const char* TimerName)
{
DueTimerInterrupt dueTimerInterrupt = DueTimer.getAvailable();
dueTimerInterrupt.attachInterruptInterval(microseconds, callback);
uint16_t timerNumber = dueTimerInterrupt.getTimerNumber();
Serial.print(TimerName);
Serial.print(" attached to Timer(");
Serial.print(timerNumber);
Serial.println(")");
return timerNumber;
}
void setup()
{
....
// Interval in microsecs
attachDueInterrupt(TIMER_INTERVAL_MS * 1000, TimerHandler, "ITimer");
}
// Interval in microsecs
attachDueInterrupt(TIMER1_INTERVAL_MS * 1000, TimerHandler1, "ITimer1");
// Init SAMDUE_ISR_Timer
// Each SAMDUE_ISR_Timer can service 16 different ISR-based timers
ISR_Timer SAMDUE_ISR_Timer;
void TimerHandler(void)
{
SAMDUE_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_MS 1L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In SAM DUE, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
uint16_t attachDueInterrupt(double microseconds, timerCallback callback, const char* TimerName)
{
DueTimerInterrupt dueTimerInterrupt = DueTimer.getAvailable();
dueTimerInterrupt.attachInterruptInterval(microseconds, callback);
uint16_t timerNumber = dueTimerInterrupt.getTimerNumber();
Serial.print(TimerName);
Serial.print(" attached to Timer(");
Serial.print(timerNumber);
Serial.println(")");
return timerNumber;
}
void setup()
{
....
// Interval in microsecs
attachDueInterrupt(HW_TIMER_INTERVAL_MS * 1000, TimerHandler, "ITimer");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
SAMDUE_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
SAMDUE_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
SAMDUE_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
SAMDUE_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// You can select Teensy Hardware Timer from TEENSY_TIMER_1 or TEENSY_TIMER_3
// Init Teensy timer TEENSY_TIMER_1
TeensyTimer ITimer0(TEENSY_TIMER_1);
void TimerHandler0(void)
{
// Doing something here inside ISR
}
// For Teensy 4.0/4.1, F_BUS_ACTUAL = 150 MHz => max period is only 55922 us (~17.9 Hz)
#define TIMER0_INTERVAL_MS 50L
void setup()
{
....
// Interval in microsecs
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0))
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer0. Select another freq. or timer");
}
// You can select Teensy Hardware Timer from TEENSY_TIMER_1 or TEENSY_TIMER_3
// Init Teensy timer TEENSY_TIMER_1
TeensyTimer ITimer(TEENSY_TIMER_1);
// Init Teensy_ISR_Timer
// Each Teensy_ISR_Timer can service 16 different ISR-based timers
ISR_Timer Teensy_ISR_Timer;
void TimerHandler(void)
{
Teensy_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_MS 50L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In Teensy, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR every 2 seconds
}
void doingSomething5s()
{
// Doing something here inside ISR every 5 seconds
}
void doingSomething11s()
{
// Doing something here inside ISR every 11 seconds
}
void doingSomething101s()
{
// Doing something here inside ISR every 101 seconds
}
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
{
lastMillis = millis();
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
}
else
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
Teensy_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
Teensy_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
Teensy_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
Teensy_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// Init STM32 timer TIM1
STM32Timer ITimer0(TIM1);
void TimerHandler0(void)
{
// Doing something here inside ISR
}
#define TIMER0_INTERVAL_MS 1000 // 1s = 1000ms
void setup()
{
....
// Interval in microsecs
if (ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * 1000, TimerHandler0))
Serial.println("Starting ITimer0 OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer0. Select another freq. or timer");
}
// Init STM32 timer TIM1
STM32Timer ITimer(TIM1);
// Init STM32_ISR_Timer
// Each STM32_ISR_Timer can service 16 different ISR-based timers
ISR_Timer STM32_ISR_Timer;
void TimerHandler(void)
{
STM32_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_US 100L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In STM32, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
{
lastMillis = millis();
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
}
else
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
STM32_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
STM32_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
STM32_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
STM32_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
// For core mbed core 1.3.2-
// Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_1,NRF_TIMER_3,NRF_TIMER_4 (1,3 and 4)
// If you select the already-used NRF_TIMER_0 or NRF_TIMER_2, it'll be auto modified to use NRF_TIMER_1
// For core mbed core 2.0.0-
// Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_3,NRF_TIMER_4 (3 and 4)
// If you select the already-used NRF_TIMER_0, NRF_TIMER_1 or NRF_TIMER_2, it'll be auto modified to use NRF_TIMER_3
// Init NRF52 timer NRF_TIMER4
NRF52_MBED_Timer ITimer0(NRF_TIMER_4);
void TimerHandler(void)
{
// Doing something here inside ISR
}
#define TIMER_INTERVAL_MS 1000 // 1s = 1000ms
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler0))
Serial.println("Starting ITimer OK, millis() = " + String(millis()));
else
Serial.println("Can't set ITimer. Select another freq. or timer");
}
/// Depending on the board, you can select NRF52 Hardware Timer from NRF_TIMER_1-NRF_TIMER_4 (1 to 4)
// If you select the already-used NRF_TIMER_0, it'll be auto modified to use NRF_TIMER_1
// Init NRF52 timer NRF_TIMER2
NRF52_MBED_Timer ITimer(NRF_TIMER_2);
// Init NRF52_ISR_Timer
// Each NRF52_ISR_Timer can service 16 different ISR-based timers
ISR_Timer NRF52_ISR_Timer;
void TimerHandler(void)
{
NRF52_ISR_Timer.run();
}
#define HW_TIMER_INTERVAL_MS 50L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// In NRF52, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
void setup()
{
....
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_MS * 1000, TimerHandler))
{
lastMillis = millis();
Serial.println("Starting ITimer OK, millis() = " + String(lastMillis));
}
else
Serial.println("Can't set ITimer correctly. Select another freq. or interval");
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
NRF52_ISR_Timer.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
Only Timer1 and Timer2 are supported for Nano, UNO, etc. boards possessing 3 timers.
Timer3, Timer4 and Timer5 are only available for Arduino Mega boards.
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
Timer0, Timer1, Timer2 and Timer3 (TCB0-TCB3) are supported for Nano Every, UNO WiFi Rev2, etc. boards.
Before using any Timer, you have to make sure the Timer has not been used by any other purpose.
#define USE_TIMER_0 false
#define USE_TIMER_1 true // <======== This will enable ITimer1
#define USE_TIMER_2 false
#define USE_TIMER_3 false
void TimerHandler1(void)
{
// Doing something here inside ISR
}
#define TIMER_INTERVAL_MS 1000 // 1s = 1000ms
void setup()
{
....
// ITimer1 is initialized here
ITimer1.init();
// Interval in millisecs
if (ITimer1.attachInterruptInterval(TIMER1_INTERVAL_MS, TimerHandler1))
{
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(millis());
}
else
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
...
}
// Init ISR_Timer ISR_Timer1 to permit using 16 ISR_based Timers from 1 Hardware Timers (ITimer1)
ISR_Timer ISR_Timer1;
#define USE_TIMER_0 false
#define USE_TIMER_1 true // <======== This will enable ITimer1
#define USE_TIMER_2 false
#define USE_TIMER_3 false
void TimerHandler1(void)
{
ISR_Timer1.run();
}
#define HW_TIMER_INTERVAL_MS 50L
#define TIMER_INTERVAL_2S 2000L
#define TIMER_INTERVAL_5S 5000L
#define TIMER_INTERVAL_11S 11000L
#define TIMER_INTERVAL_101S 101000L
// Avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething2s()
{
// Doing something here inside ISR
}
void doingSomething5s()
{
// Doing something here inside ISR
}
void doingSomething11s()
{
// Doing something here inside ISR
}
void doingSomething101s()
{
// Doing something here inside ISR
}
void setup()
{
....
// ITimer1 is initialized here
ITimer1.init();
// Interval in millisecs
if (ITimer1.attachInterruptInterval(HW_TIMER_INTERVAL_MS, TimerHandler1))
{
Serial.print(F("Starting ITimer1 OK, millis() = ")); Serial.println(millis());
}
else
Serial.println(F("Can't set ITimer1. Select another freq. or timer"));
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each ISR_Timer
ISR_Timer1.setInterval(TIMER_INTERVAL_2S, doingSomething2s);
ISR_Timer1.setInterval(TIMER_INTERVAL_5S, doingSomething5s);
ISR_Timer1.setInterval(TIMER_INTERVAL_11S, doingSomething11s);
ISR_Timer1.setInterval(TIMER_INTERVAL_101S, doingSomething101s);
}
- Argument_None
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- Change_Interval.
- ISR_16_Timers_Array
- ISR_16_Timers_Array_Complex.
- Argument_None
- ISR_RPM_Measure
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- Change_Interval.
- ISR_16_Timers_Array New
- ISR_16_Timers_Array_Complex New
- Argument_None
- ISR_16_Timers_Array
- ISR_RPM_Measure
- ISR_Timer_Complex_Ethernet
- ISR_Timer_Complex_WiFiNINA
- RPM_Measure
- SwitchDebounce
- TimerInterruptLEDDemo.
- TimerInterruptTest
- ISR_16_Timers_Array_Complex.
- Change_Interval.
- FakeAnalogWrite.
- Argument_None
- ISR_16_Timers_Array
- ISR_RPM_Measure
- ISR_Timer_Complex_Ethernet
- ISR_Timer_Complex_WiFiNINA
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- TimerInterruptLEDDemo
- ISR_16_Timers_Array_Complex.
- Change_Interval.
- Argument_None
- ISR_16_Timers_Array
- ISR_RPM_Measure
- ISR_Timer_Complex_Ethernet
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- TimerInterruptLEDDemo
- ISR_16_Timers_Array_Complex.
- Change_Interval.
- Argument_None
- ISR_16_Timers_Array
- ISR_RPM_Measure
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- TimerInterruptLEDDemo
- ISR_16_Timers_Array_Complex.
- Change_Interval.
- Argument_None
- ISR_16_Timers_Array
- ISR_RPM_Measure
- ISR_Timer_Complex
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- TimerInterruptLEDDemo
- ISR_16_Timers_Array_Complex.
- Change_Interval.
- Argument_Complex
- Argument_None
- Argument_Simple
- Change_Interval
- FakeAnalogWrite
- ISR_16_Timers_Array_Complex
- ISR_RPM_Measure
- ISR_Timers_Array_Simple
- RPM_Measure
- SwitchDebounce
- TimerDuration
- TimerInterruptTest
- Change_Interval_HF. New.
- Argument_None
- ISR_16_Timers_Array
- ISR_16_Timers_Array_Complex
- SwitchDebounce
- TimerInterruptLEDDemo
- TimerInterruptTest
- FakeAnalogWrite.
- Change_Interval.
- Argument_Complex
- Argument_None
- Argument_Simple
- Change_Interval.
- FakeAnalogWrite.
- ISR_16_Timers_Array_Complex.
- ISR_RPM_Measure
- Change_Interval_HF
- ISR_Timers_Array_Simple.
- RPM_Measure
- SwitchDebounce
- TimerDuration
- TimerInterruptTest
- Argument_Complex
- Argument_None
- Argument_Simple
- Change_Interval
- ISR_16_Timers_Array_Complex
- ISR_Timers_Array_Simple
- RPM_Measure
- SwitchDebounce
- TimerInterruptTest
- Argument_Complex
- Argument_None
- Argument_Simple
- Change_Interval
- ISR_16_Timers_Array_Complex
- ISR_Timers_Array_Simple
- SwitchDebounce
- TimerInterruptTest
Example ISR_16_Timers_Array_Complex for MBED RP2040 boards
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)
#define USING_MBED_RPI_PICO_TIMER_INTERRUPT true
#else
#error This code is intended to run on the MBED RASPBERRY_PI_PICO platform! Please check your Tools->Board setting.
#endif
// These define's must be placed at the beginning before #include "TimerInterrupt_Generic.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
#define _TIMERINTERRUPT_LOGLEVEL_ 4
#include "TimerInterrupt_Generic.h"
#include "ISR_Timer_Generic.h"
#include <SimpleTimer.h> // https://github.com/jfturcot/SimpleTimer
#ifndef LED_BUILTIN
#define LED_BUILTIN 25
#endif
#ifndef LED_BLUE
#define LED_BLUE 10
#endif
#ifndef LED_RED
#define LED_RED 11
#endif
#define HW_TIMER_INTERVAL_US 10000L
volatile uint32_t startMillis = 0;
// You can select MBED_RPI_PICO_Timer from 0 to 3
// Init MBED_RPI_PICO_Timer
MBED_RPI_PICO_Timer ITimer(0);
// Init MBED_RPI_PICO_ISRTimer
// Each MBED_RPI_PICO_ISRTimer can service 16 different ISR-based timers
ISR_Timer MBED_RPI_PICO_ISRTimer;
#define LED_TOGGLE_INTERVAL_MS 2000L
// Never use Serial.print inside this mbed ISR. Will hang the system
void TimerHandler(uint alarm_num)
{
static bool toggle = false;
static int timeRun = 0;
//////////////////////////////////////////////////////////
// Always call this for MBED RP2040 before processing ISR
TIMER_ISR_START(alarm_num);
///////////////////////////////////////////////////////////
MBED_RPI_PICO_ISRTimer.run();
// Toggle LED every LED_TOGGLE_INTERVAL_MS = 2000ms = 2s
if (++timeRun == ((LED_TOGGLE_INTERVAL_MS * 1000) / HW_TIMER_INTERVAL_US) )
{
timeRun = 0;
//timer interrupt toggles pin LED_BUILTIN
digitalWrite(LED_BUILTIN, toggle);
toggle = !toggle;
}
////////////////////////////////////////////////////////////
// Always call this for MBED RP2040 after processing ISR
TIMER_ISR_END(alarm_num);
////////////////////////////////////////////////////////////
}
/////////////////////////////////////////////////
#define NUMBER_ISR_TIMERS 16
typedef void (*irqCallback) ();
/////////////////////////////////////////////////
#define USE_COMPLEX_STRUCT true
#if USE_COMPLEX_STRUCT
typedef struct
{
irqCallback irqCallbackFunc;
uint32_t TimerInterval;
unsigned long deltaMillis;
unsigned long previousMillis;
} ISRTimerData;
// In NRF52, avoid doing something fancy in ISR, for example Serial.print()
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
// Or you can get this run-time error / crash
void doingSomething(int index);
#else
volatile unsigned long deltaMillis [NUMBER_ISR_TIMERS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
volatile unsigned long previousMillis [NUMBER_ISR_TIMERS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// You can assign any interval for any timer here, in milliseconds
uint32_t TimerInterval[NUMBER_ISR_TIMERS] =
{
5000L, 10000L, 15000L, 20000L, 25000L, 30000L, 35000L, 40000L,
45000L, 50000L, 55000L, 60000L, 65000L, 70000L, 75000L, 80000L
};
void doingSomething(int index)
{
unsigned long currentMillis = millis();
deltaMillis[index] = currentMillis - previousMillis[index];
previousMillis[index] = currentMillis;
}
#endif
////////////////////////////////////
// Shared
////////////////////////////////////
void doingSomething0()
{
doingSomething(0);
}
void doingSomething1()
{
doingSomething(1);
}
void doingSomething2()
{
doingSomething(2);
}
void doingSomething3()
{
doingSomething(3);
}
void doingSomething4()
{
doingSomething(4);
}
void doingSomething5()
{
doingSomething(5);
}
void doingSomething6()
{
doingSomething(6);
}
void doingSomething7()
{
doingSomething(7);
}
void doingSomething8()
{
doingSomething(8);
}
void doingSomething9()
{
doingSomething(9);
}
void doingSomething10()
{
doingSomething(10);
}
void doingSomething11()
{
doingSomething(11);
}
void doingSomething12()
{
doingSomething(12);
}
void doingSomething13()
{
doingSomething(13);
}
void doingSomething14()
{
doingSomething(14);
}
void doingSomething15()
{
doingSomething(15);
}
#if USE_COMPLEX_STRUCT
ISRTimerData curISRTimerData[NUMBER_ISR_TIMERS] =
{
//irqCallbackFunc, TimerInterval, deltaMillis, previousMillis
{ doingSomething0, 5000L, 0, 0 },
{ doingSomething1, 10000L, 0, 0 },
{ doingSomething2, 15000L, 0, 0 },
{ doingSomething3, 20000L, 0, 0 },
{ doingSomething4, 25000L, 0, 0 },
{ doingSomething5, 30000L, 0, 0 },
{ doingSomething6, 35000L, 0, 0 },
{ doingSomething7, 40000L, 0, 0 },
{ doingSomething8, 45000L, 0, 0 },
{ doingSomething9, 50000L, 0, 0 },
{ doingSomething10, 55000L, 0, 0 },
{ doingSomething11, 60000L, 0, 0 },
{ doingSomething12, 65000L, 0, 0 },
{ doingSomething13, 70000L, 0, 0 },
{ doingSomething14, 75000L, 0, 0 },
{ doingSomething15, 80000L, 0, 0 }
};
void doingSomething(int index)
{
unsigned long currentMillis = millis();
curISRTimerData[index].deltaMillis = currentMillis - curISRTimerData[index].previousMillis;
curISRTimerData[index].previousMillis = currentMillis;
}
#else
irqCallback irqCallbackFunc[NUMBER_ISR_TIMERS] =
{
doingSomething0, doingSomething1, doingSomething2, doingSomething3,
doingSomething4, doingSomething5, doingSomething6, doingSomething7,
doingSomething8, doingSomething9, doingSomething10, doingSomething11,
doingSomething12, doingSomething13, doingSomething14, doingSomething15
};
#endif
///////////////////////////////////////////
#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.print(F("SimpleTimer : ")); Serial.print(SIMPLE_TIMER_MS / 1000);
Serial.print(F(", ms : ")); Serial.print(currMillis);
Serial.print(F(", Dms : ")); Serial.println(currMillis - previousMillis);
for (uint16_t i = 0; i < NUMBER_ISR_TIMERS; i++)
{
#if USE_COMPLEX_STRUCT
Serial.print(F("Timer : ")); Serial.print(i);
Serial.print(F(", programmed : ")); Serial.print(curISRTimerData[i].TimerInterval);
Serial.print(F(", actual : ")); Serial.println(curISRTimerData[i].deltaMillis);
#else
Serial.print(F("Timer : ")); Serial.print(i);
Serial.print(F(", programmed : ")); Serial.print(TimerInterval[i]);
Serial.print(F(", actual : ")); Serial.println(deltaMillis[i]);
#endif
}
previousMillis = currMillis;
}
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial);
delay(100);
Serial.print(F("\nStarting ISR_16_Timers_Array_Complex on ")); Serial.println(BOARD_NAME);
Serial.println(MBED_RPI_PICO_TIMER_INTERRUPT_VERSION);
Serial.println(TIMER_INTERRUPT_GENERIC_VERSION);
// Interval in microsecs
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
{
startMillis = millis();
Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(startMillis);
}
else
Serial.println(F("Can't set ITimer. Select another freq. or timer"));
startMillis = millis();
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
// You can use up to 16 timer for each MBED_RPI_PICO_ISRTimer
for (uint16_t i = 0; i < NUMBER_ISR_TIMERS; i++)
{
#if USE_COMPLEX_STRUCT
curISRTimerData[i].previousMillis = startMillis;
MBED_RPI_PICO_ISRTimer.setInterval(curISRTimerData[i].TimerInterval, curISRTimerData[i].irqCallbackFunc);
#else
previousMillis[i] = millis();
MBED_RPI_PICO_ISRTimer.setInterval(TimerInterval[i], irqCallbackFunc[i]);
#endif
}
// 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 MBED_RPI_PICO_ISRTimer still accurate, whereas very unaccurate for Software Timer
// The time elapse for 2000ms software timer now becomes 3000ms (BLOCKING_TIME_MS)
// While that of MBED_RPI_PICO_ISRTimer 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 MBED_RPI_PICO_ISRTimer.run() here in the loop(). It's already handled by ISR timer.
simpleTimer.run();
}
The following is the sample terminal output when running example ISR_Timer_Complex_Ethernet on Arduino SAM DUE to demonstrate the accuracy of ISR Hardware Timer, especially when system is very busy. The ISR timer is programmed for 2s, is activated exactly after 2.000s !!!
While software timer, programmed for 2s, is activated after 10.917s !!!. Then in loop(), it's also activated every 3s.
Starting ISR_Timer_Complex_Ethernet on SAM DUE
SAMDUETimerInterrupt v1.2.0
TimerInterrupt_Generic v1.8.0
Using Timer(0) = TC0, channel = 0, IRQ = TC0_IRQn
Timer(0), us = 50000.00
ITimer attached to Timer(0)
[5] Getting IP...
[7] MAC: FE-8A-F1-EA-DE-82
_pinCS = 0
W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5100, SSIZE =4096
2s: Delta ms = 2000
2s: Delta ms = 2000
[7728] IP:192.168.2.134
[7728]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ v0.6.1 on Arduino Due
[7732] BlynkArduinoClient.connect: Connecting to account.duckdns.org:8080
[7849] Ready (ping: 6ms).
IP = 192.168.2.134
2s: Delta ms = 2000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 10917
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
11s: Delta ms = 11000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
11s: Delta ms = 11000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
11s: Delta ms = 11000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
11s: Delta ms = 11000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
The following is the sample terminal output when running example ISR_Timer_Complex_Ethernet on *Adafruit NRF52840_FEATHER EXPRESS using W5500 Ethernet to demonstrate the accuracy of ISR Hardware Timer, especially when system is very busy. The ISR timer is programmed for 2s, is activated exactly after 2.000s !!!
While software timer, programmed for 2s, is activated after 4.867s !!!. Then in loop(), it's also activated every 3s.
Starting ISR_Timer_Complex_Ethernet on NRF52840_FEATHER
NRF52TimerInterrupt v1.3.0
TimerInterrupt_Generic v1.8.0
NRF52TimerInterrupt: F_CPU (MHz) = 64, Timer = NRF_TIMER2
NRF52TimerInterrupt: _fre = 1000000.00, _count = 50000
Starting ITimer OK, millis() = 1419
[1419] Getting IP...
[1419] MAC: FE-BE-97-DA-C3-EA
_pinCS = 0
W5100 init, using SS_PIN_DEFAULT = 10, new ss_pin = 10, W5100Class::ss_pin = 10
W5100::init: W5500, SSIZE =4096
[3104] IP:192.168.2.129
[3104]
___ __ __
/ _ )/ /_ _____ / /__
/ _ / / // / _ \/ '_/
/____/_/\_, /_//_/_/\_\
/___/ v0.6.1 on ARDUINO_NRF52_ADAFRUIT
[3106] BlynkArduinoClient.connect: Connecting to account.duckdns.org:8080
[3218] Ready (ping: 8ms).
IP = 192.168.2.129
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 4867
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
11s: Delta ms = 11000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
11s: Delta ms = 11000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
2s: Delta ms = 2000
5s: Delta ms = 5000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
21s: Delta ms = 21000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
11s: Delta ms = 11000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
2s: Delta ms = 2000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
2s: Delta ms = 2000
5s: Delta ms = 5000
11s: Delta ms = 11000
blynkDoingSomething2s: Delta programmed ms = 2000, actual = 3000
The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on Arduino SAMD21 SAMD_NANO_33_IOT to demonstrate the accuracy of ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!
In this example, 16 independent ISR Timers are used, yet utilized just one Hardware Timer. The Timer Intervals and Function Pointers are stored in arrays to facilitate the code modification.
Starting ISR_16_Timers_Array_Complex on SAMD_NANO_33_IOT
SAMDTimerInterrupt v1.5.0
TimerInterrupt_Generic v1.8.0
CPU Frequency = 48 MHz
Starting ITimer OK, millis() = 1180
SimpleTimer : 2, ms : 11180, Dms : 10000
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 21184, Dms : 10004
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 31187, Dms : 10003
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 41190, Dms : 10003
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 51194, Dms : 10004
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 61197, Dms : 10003
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 71200, Dms : 10003
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 81203, Dms : 10003
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80000
SimpleTimer : 2, ms : 91206, Dms : 10003
The following is the sample terminal output when running example TimerInterruptTest on Teensy 4.1 to demonstrate how to start/stop and the accuracy of Hardware Timers.
Starting TimerInterruptTest on Teensy 4.0/4.1
Teensy_TimerInterrupt v1.2.0
TimerInterrupt_Generic v1.8.0
CPU Frequency = 600 MHz
TEENSY_TIMER_1, F_BUS_ACTUAL (MHz) = 150, request interval = 30000, actual interval (us) = 29999
Prescale = 7, _timerCount = 17578
Starting ITimer0 OK, millis() = 1128
Stop ITimer0, millis() = 5001
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
Start ITimer0, millis() = 10002
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
TeensyTimerInterrupt:resumeTimer TEENSY_TIMER_1
Stop ITimer0, millis() = 15003
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
Start ITimer0, millis() = 20004
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
TeensyTimerInterrupt:resumeTimer TEENSY_TIMER_1
Stop ITimer0, millis() = 25005
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
Start ITimer0, millis() = 30006
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
TeensyTimerInterrupt:resumeTimer TEENSY_TIMER_1
Stop ITimer0, millis() = 35007
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
Start ITimer0, millis() = 40008
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
TeensyTimerInterrupt:resumeTimer TEENSY_TIMER_1
Stop ITimer0, millis() = 45009
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
Start ITimer0, millis() = 50010
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
TeensyTimerInterrupt:resumeTimer TEENSY_TIMER_1
Stop ITimer0, millis() = 55011
TeensyTimerInterrupt:stopTimer TEENSY_TIMER_1
The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on ESP32_DEV to demonstrate the accuracy of ISR Hardware Timer.
Starting ISR_16_Timers_Array_Complex on ESP32_DEV
ESP32_New_TimerInterrupt v1.0.1
TimerInterrupt_Generic v1.8.0
CPU Frequency = 240 MHz
Starting ITimer OK, millis() = 2045
SimpleTimer : 2, ms : 12044, Dms : 9999
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 22097, Dms : 10053
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 32160, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 42223, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 52286, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 62349, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 72412, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 82475, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80000
SimpleTimer : 2, ms : 92538, Dms : 10063
The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E to demonstrate of ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!
Starting ISR_16_Timers_Array_Complex on ESP8266_NODEMCU_ESP12E
ESP8266TimerInterrupt v1.4.1
TimerInterrupt_Generic v1.8.0
CPU Frequency = 160 MHz
Starting ITimer OK, millis() = 177
SimpleTimer : 2, ms : 10179, Dms : 10000
Timer : 0, programmed : 5000, actual : 5008
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 20232, Dms : 10053
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15008
Timer : 3, programmed : 20000, actual : 20008
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 30286, Dms : 10054
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20008
Timer : 4, programmed : 25000, actual : 25008
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 40341, Dms : 10055
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25008
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 50396, Dms : 10055
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 60452, Dms : 10056
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35008
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 70509, Dms : 10057
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 65008
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 80566, Dms : 10057
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45008
Timer : 9, programmed : 50000, actual : 50008
Timer : 10, programmed : 55000, actual : 55008
Timer : 11, programmed : 60000, actual : 60008
Timer : 12, programmed : 65000, actual : 65008
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 75008
Timer : 15, programmed : 80000, actual : 80008
The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on STM32F7 Nucleo-144 F767ZI to demonstrate of ISR Hardware Timer, especially when system is very busy or blocked. The 16 independent ISR timers are programmed to be activated repetitively after certain intervals, is activated exactly after that programmed interval !!!
Starting ISR_16_Timers_Array_Complex on NUCLEO_F767ZI
STM32_TimerInterrupt v1.2.1
TimerInterrupt_Generic v1.8.0
CPU Frequency = 216 MHz
Starting ITimer OK, millis() = 105
SimpleTimer : 2, ms : 10110, Dms : 10005
Timer : 0, programmed : 5000, actual : 5010
Timer : 1, programmed : 10000, actual : 10010
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 20169, Dms : 10059
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15010
Timer : 3, programmed : 20000, actual : 20010
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 30230, Dms : 10061
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20010
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30010
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 40293, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30010
Timer : 6, programmed : 35000, actual : 35010
Timer : 7, programmed : 40000, actual : 40010
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 50357, Dms : 10064
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30010
Timer : 6, programmed : 35000, actual : 35010
Timer : 7, programmed : 40000, actual : 40010
Timer : 8, programmed : 45000, actual : 45010
Timer : 9, programmed : 50000, actual : 50010
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 60421, Dms : 10064
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35010
Timer : 7, programmed : 40000, actual : 40010
Timer : 8, programmed : 45000, actual : 45010
Timer : 9, programmed : 50000, actual : 50010
Timer : 10, programmed : 55000, actual : 55010
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 70484, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40010
Timer : 8, programmed : 45000, actual : 45010
Timer : 9, programmed : 50000, actual : 50010
Timer : 10, programmed : 55000, actual : 55010
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65010
Timer : 13, programmed : 70000, actual : 70010
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 80552, Dms : 10068
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45010
Timer : 9, programmed : 50000, actual : 50010
Timer : 10, programmed : 55000, actual : 55010
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65010
Timer : 13, programmed : 70000, actual : 70010
Timer : 14, programmed : 75000, actual : 75010
Timer : 15, programmed : 80000, actual : 80010
SimpleTimer : 2, ms : 90618, Dms : 10066
The following is the sample terminal output when running example TimerInterruptTest on STM32F7 Nucleo-144 F767ZI to demonstrate how to start/stop Hardware Timers.
Starting TimerInterruptTest on NUCLEO_F767ZI
STM32_TimerInterrupt v1.2.1
TimerInterrupt_Generic v1.8.0
CPU Frequency = 216 MHz
STM32TimerInterrupt: Timer Input Freq (Hz) = 216000000, _fre = 1000000.00, _count = 1000000
Starting ITimer0 OK, millis() = 108
STM32TimerInterrupt: Timer Input Freq (Hz) = 108000000, _fre = 1000000.00, _count = 3000000
Starting ITimer1 OK, millis() = 119
Stop ITimer0, millis() = 5001
Start ITimer0, millis() = 10002
Stop ITimer1, millis() = 15001
Stop ITimer0, millis() = 15003
Start ITimer0, millis() = 20004
Stop ITimer0, millis() = 25005
Start ITimer1, millis() = 30002
Start ITimer0, millis() = 30006
Stop ITimer0, millis() = 35007
Start ITimer0, millis() = 40008
Stop ITimer1, millis() = 45003
Stop ITimer0, millis() = 45009
Start ITimer0, millis() = 50010
Stop ITimer0, millis() = 55011
Start ITimer1, millis() = 60004
Start ITimer0, millis() = 60012
Stop ITimer0, millis() = 65013
Start ITimer0, millis() = 70014
Stop ITimer1, millis() = 75005
Stop ITimer0, millis() = 75015
Start ITimer0, millis() = 80016
Stop ITimer0, millis() = 85017
Start ITimer1, millis() = 90006
Start ITimer0, millis() = 90018
Stop ITimer0, millis() = 95019
Start ITimer0, millis() = 100020
Stop ITimer1, millis() = 105007
Stop ITimer0, millis() = 105021
Start ITimer0, millis() = 110022
Stop ITimer0, millis() = 115023
Start ITimer1, millis() = 120008
Start ITimer0, millis() = 120024
Stop ITimer0, millis() = 125025
Start ITimer0, millis() = 130026
Stop ITimer1, millis() = 135009
Stop ITimer0, millis() = 135027
Start ITimer0, millis() = 140028
The following is the sample terminal output when running example ISR_16_Timers_Array_Complex on Nano 33 BLE to demonstrate the accuracy of ISR Hardware Timer, especially when system is very busy. The ISR timer is programmed for 2s, is activated exactly after 2.000s !!!
While software timer, **programmed for 2s, is activated after more than 3.000s in loop().
Starting ISR_16_Timers_Array_Complex on Nano 33 BLE
NRF52_MBED_TimerInterrupt v1.3.0
TimerInterrupt_Generic v1.8.0
Starting ITimer OK, millis() = 810
SimpleTimer : 2, ms : 3810, Dms : 3000
Timer : 0, programmed : 5000, actual : 0
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 6822, Dms : 3012
Timer : 0, programmed : 5000, actual : 5006
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 9834, Dms : 3012
Timer : 0, programmed : 5000, actual : 5006
Timer : 1, programmed : 10000, actual : 0
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 12845, Dms : 3011
Timer : 0, programmed : 5000, actual : 4995
Timer : 1, programmed : 10000, actual : 10001
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 15857, Dms : 3012
Timer : 0, programmed : 5000, actual : 5006
Timer : 1, programmed : 10000, actual : 10001
Timer : 2, programmed : 15000, actual : 15007
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 18868, Dms : 3011
Timer : 0, programmed : 5000, actual : 5006
Timer : 1, programmed : 10000, actual : 10001
Timer : 2, programmed : 15000, actual : 15007
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 21880, Dms : 3012
Timer : 0, programmed : 5000, actual : 4997
Timer : 1, programmed : 10000, actual : 10003
Timer : 2, programmed : 15000, actual : 15007
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 24892, Dms : 3012
Timer : 0, programmed : 5000, actual : 4997
Timer : 1, programmed : 10000, actual : 10003
Timer : 2, programmed : 15000, actual : 15007
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 27903, Dms : 3011
Timer : 0, programmed : 5000, actual : 5006
Timer : 1, programmed : 10000, actual : 10003
Timer : 2, programmed : 15000, actual : 15007
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 30914, Dms : 3011
Timer : 0, programmed : 5000, actual : 4992
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14995
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 33926, Dms : 3012
Timer : 0, programmed : 5000, actual : 4992
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14995
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 36938, Dms : 3012
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14995
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 39950, Dms : 3012
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14995
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 42961, Dms : 3011
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 14995
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 45972, Dms : 3011
Timer : 0, programmed : 5000, actual : 4993
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 14999
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 48983, Dms : 3011
Timer : 0, programmed : 5000, actual : 4993
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 14999
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 25010
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 51994, Dms : 3011
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9996
Timer : 2, programmed : 15000, actual : 14999
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 55006, Dms : 3012
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9996
Timer : 2, programmed : 15000, actual : 14999
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 58017, Dms : 3011
Timer : 0, programmed : 5000, actual : 5002
Timer : 1, programmed : 10000, actual : 9996
Timer : 2, programmed : 15000, actual : 14999
Timer : 3, programmed : 20000, actual : 20004
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30002
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 61029, Dms : 3012
Timer : 0, programmed : 5000, actual : 5004
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 15009
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 64040, Dms : 3011
Timer : 0, programmed : 5000, actual : 5004
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 15009
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 67051, Dms : 3011
Timer : 0, programmed : 5000, actual : 4995
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 15009
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 70062, Dms : 3011
Timer : 0, programmed : 5000, actual : 4995
Timer : 1, programmed : 10000, actual : 10006
Timer : 2, programmed : 15000, actual : 15009
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35005
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 73073, Dms : 3011
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 15009
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24994
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35003
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 76085, Dms : 3012
Timer : 0, programmed : 5000, actual : 4994
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14992
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24998
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35003
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 75002
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 79096, Dms : 3011
Timer : 0, programmed : 5000, actual : 4994
Timer : 1, programmed : 10000, actual : 9998
Timer : 2, programmed : 15000, actual : 14992
Timer : 3, programmed : 20000, actual : 20002
Timer : 4, programmed : 25000, actual : 24998
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35003
Timer : 7, programmed : 40000, actual : 40008
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 75002
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 82107, Dms : 3011
Timer : 0, programmed : 5000, actual : 5003
Timer : 1, programmed : 10000, actual : 9997
Timer : 2, programmed : 15000, actual : 14992
Timer : 3, programmed : 20000, actual : 19995
Timer : 4, programmed : 25000, actual : 24998
Timer : 5, programmed : 30000, actual : 30008
Timer : 6, programmed : 35000, actual : 35003
Timer : 7, programmed : 40000, actual : 39997
Timer : 8, programmed : 45000, actual : 45001
Timer : 9, programmed : 50000, actual : 50004
Timer : 10, programmed : 55000, actual : 55006
Timer : 11, programmed : 60000, actual : 60010
Timer : 12, programmed : 65000, actual : 65005
Timer : 13, programmed : 70000, actual : 70008
Timer : 14, programmed : 75000, actual : 75002
Timer : 15, programmed : 80000, actual : 80005
SimpleTimer : 2, ms : 85118, Dms : 3011
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
megaAVR_TimerInterrupt v1.4.0
TimerInterrupt_Generic v1.8.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 16MHz for highest accuracy
[TISR] TCB 1
[TISR] ==================
[TISR] Init, Timer = 1
[TISR] CTRLB = 0
[TISR] CCMP = 65535
[TISR] INTCTRL = 0
[TISR] CTRLA = 1
[TISR] ==================
[TISR] Frequency = 200.00 , CLK_TCB_FREQ = 16000000
[TISR] setFrequency: _CCMPValueRemaining = 80000
Starting ITimer1 OK, millis() = 15
SimpleTimer : 2, ms : 10016, Dms : 10016
Timer : 0, programmed : 5000, actual : 5018
Timer : 1, programmed : 10000, actual : 10018
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 20075, Dms : 10059
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10001
Timer : 2, programmed : 15000, actual : 15019
Timer : 3, programmed : 20000, actual : 20019
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 30135, Dms : 10060
Timer : 0, programmed : 5000, actual : 5000 <========== Very accurate @ clock 16MHz
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20019
Timer : 4, programmed : 25000, actual : 25019
Timer : 5, programmed : 30000, actual : 30019
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 40195, Dms : 10060
...
Timer : 0, programmed : 5000, actual : 4996
Timer : 1, programmed : 10000, actual : 9996
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20001
Timer : 4, programmed : 25000, actual : 25001
Timer : 5, programmed : 30000, actual : 30001
Timer : 6, programmed : 35000, actual : 34997
Timer : 7, programmed : 40000, actual : 40019
Timer : 8, programmed : 45000, actual : 45020
Timer : 9, programmed : 50000, actual : 50020
Timer : 10, programmed : 55000, actual : 55020
Timer : 11, programmed : 60000, actual : 60020
Timer : 12, programmed : 65000, actual : 65020
Timer : 13, programmed : 70000, actual : 70016
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 80442, Dms : 10063
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 14996
Timer : 3, programmed : 20000, actual : 19996
Timer : 4, programmed : 25000, actual : 24996
Timer : 5, programmed : 30000, actual : 30001
Timer : 6, programmed : 35000, actual : 34997
Timer : 7, programmed : 40000, actual : 39997
Timer : 8, programmed : 45000, actual : 45020
Timer : 9, programmed : 50000, actual : 50020
Timer : 10, programmed : 55000, actual : 55020
Timer : 11, programmed : 60000, actual : 60020
Timer : 12, programmed : 65000, actual : 65020
Timer : 13, programmed : 70000, actual : 70016
Timer : 14, programmed : 75000, actual : 75016
Timer : 15, programmed : 80000, actual : 80016
SimpleTimer : 2, ms : 90506, Dms : 10064
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
megaAVR_TimerInterrupt v1.4.0
TimerInterrupt_Generic v1.8.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 8MHz for very high accuracy
Starting ITimer1 OK, millis() = 10
SimpleTimer : 2, ms : 10011, Dms : 10011
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10011
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
...
SimpleTimer : 2, ms : 160949, Dms : 10064
Timer : 0, programmed : 5000, actual : 5000 <========== Very accurate @ clock 8MHz
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80000
SimpleTimer : 2, ms : 171013, Dms : 10064
Timer : 0, programmed : 5000, actual : 5000
Timer : 1, programmed : 10000, actual : 10000
Timer : 2, programmed : 15000, actual : 15000
Timer : 3, programmed : 20000, actual : 20000
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30000
Timer : 6, programmed : 35000, actual : 35000
Timer : 7, programmed : 40000, actual : 40000
Timer : 8, programmed : 45000, actual : 45000
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55000
Timer : 11, programmed : 60000, actual : 60000
Timer : 12, programmed : 65000, actual : 65000
Timer : 13, programmed : 70000, actual : 70000
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80000
Starting ISR_16_Timers_Array_Complex on megaAVR Nano Every
megaAVR_TimerInterrupt v1.4.0
TimerInterrupt_Generic v1.8.0
CPU Frequency = 16 MHz
TCB Clock Frequency = 250KHz for lower accuracy but longer time
Starting ITimer1 OK, millis() = 11
SimpleTimer : 2, ms : 10012, Dms : 10012
Timer : 0, programmed : 5000, actual : 5021
Timer : 1, programmed : 10000, actual : 10015
Timer : 2, programmed : 15000, actual : 0
Timer : 3, programmed : 20000, actual : 0
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
SimpleTimer : 2, ms : 20071, Dms : 10059
Timer : 0, programmed : 5000, actual : 4994
Timer : 1, programmed : 10000, actual : 9999
Timer : 2, programmed : 15000, actual : 15020
Timer : 3, programmed : 20000, actual : 20014
Timer : 4, programmed : 25000, actual : 0
Timer : 5, programmed : 30000, actual : 0
Timer : 6, programmed : 35000, actual : 0
Timer : 7, programmed : 40000, actual : 0
Timer : 8, programmed : 45000, actual : 0
Timer : 9, programmed : 50000, actual : 0
Timer : 10, programmed : 55000, actual : 0
Timer : 11, programmed : 60000, actual : 0
Timer : 12, programmed : 65000, actual : 0
Timer : 13, programmed : 70000, actual : 0
Timer : 14, programmed : 75000, actual : 0
Timer : 15, programmed : 80000, actual : 0
...
SimpleTimer : 2, ms : 845278, Dms : 10063
Timer : 0, programmed : 5000, actual : 4994 <========== Less accurate @ clock 250KHz
Timer : 1, programmed : 10000, actual : 9997
Timer : 2, programmed : 15000, actual : 15001
Timer : 3, programmed : 20000, actual : 20005
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30004
Timer : 6, programmed : 35000, actual : 34998
Timer : 7, programmed : 40000, actual : 40001
Timer : 8, programmed : 45000, actual : 44995
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55004
Timer : 11, programmed : 60000, actual : 59998
Timer : 12, programmed : 65000, actual : 64992
Timer : 13, programmed : 70000, actual : 70005
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80004
SimpleTimer : 2, ms : 855342, Dms : 10064
Timer : 0, programmed : 5000, actual : 5004
Timer : 1, programmed : 10000, actual : 9999
Timer : 2, programmed : 15000, actual : 15003
Timer : 3, programmed : 20000, actual : 20005
Timer : 4, programmed : 25000, actual : 25000
Timer : 5, programmed : 30000, actual : 30004
Timer : 6, programmed : 35000, actual : 34998
Timer : 7, programmed : 40000, actual : 40001
Timer : 8, programmed : 45000, actual : 45007
Timer : 9, programmed : 50000, actual : 50000
Timer : 10, programmed : 55000, actual : 55004
Timer : 11, programmed : 60000, actual : 59998
Timer : 12, programmed : 65000, actual : 64992
Timer : 13, programmed : 70000, actual : 70005
Timer : 14, programmed : 75000, actual : 75000
Timer : 15, programmed : 80000, actual : 80004
Debug is enabled by default on Serial.
You can also change the debugging level (TIMERINTERRUPT_LOGLEVEL) from 0 to 4
// These define's must be placed at the beginning before #include "TimerInterrupt_Generic.h"
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
#define TIMER_INTERRUPT_DEBUG 0
#define _TIMERINTERRUPT_LOGLEVEL_ 0
If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards.
Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions.
Submit issues to: TimerInterrupt_Generic issues
- Search for bug and improvement.
- Basic hardware timers for
- AVR
- megaAVR
- ESP8266
- ESP32
- ESP32-S2
- SAMD
- SAM DUE
- nRF52
- Teensy
- Mbed-OS Nano-33-BLE
- STM32F/L/H/G/WB/MP1
- Raspberry Pi pico
- MBED Raspberry Pi pico
- Portenta H7
- RTL8720DN
- More hardware-initiated software-enabled timers
- Longer time interval
- Clean-up all compiler warnings possible.
- Add Table of Contents
- Add Version String
- Add
changelog.md
Many thanks for everyone for bug reporting, new feature suggesting, testing and contributing to the development of this library.
- Use some code from the Ivan Seidel's DueTimer Library.
- Use some code from the Tamasa's ZeroTimer Library.
- Use some code from the Dennis van Gils' SAMD51_InterruptTimer Library.
- Thanks to good work of Miguel Wisintainer for working with, developing, debugging and testing.
- Thanks to Holger Lembke to report ESP8266TimerInterrupt Issue 8: ESP8266Timer and PWM --> wdt reset, leading to the HOWTO Use PWM analogWrite() with ESP8266 running Timer1 Interrupt notes.
- Thanks to Jelmer to report and make PR in Moved the implementation header file to a separate .cpp file.
- Thanks to Django0 to provide the following PR Fixed warnings from cppcheck (platformio) and -Wall arduino-cli. PR#10.
⭐️ Ivan Seidel |
⭐️ Tamasa |
Dennis van Gils |
Miguel Wisintainer |
Holger Lembke |
Jelmer |
Django0 |
If you want to contribute to this project:
- Report bugs and errors
- Ask for enhancements
- Create issues and pull requests
- Tell other people about this library
- The library is licensed under MIT
Copyright 2020- Khoi Hoang