I was wondering how to use the timers in the new Arduino UNO R4. Unfortunately I did not find any documentation, so I decided to document my findings here.

The UNO R4 has two timer peripherals: the General PWM Timer (GPT) and the Asynchronous General Purpose Timer (AGT).

There are only 2 16 bit AGT timers (but one is already used to provide the Arduino millis() and microseconds() methods) and there are 7 GPT timers which are also used by PWM. To increase the flexibility you can explicitly request a timer which has been reserved for PWM.

The Arduino API implements the FspTimer class which provides all the necessary functionality.

Here is a test sketch that is setting up a GPT timer with a corresponding interrupt which executes a callback method at a defined interval rate e.g. 8000 hz.

#include "FspTimer.h"

FspTimer audio_timer;
uint64_t count=0;
uint64_t start_time=0;

// callback method used by timer
void timer_callback(timer_callback_args_t __attribute((unused)) *p_args) {

bool beginTimer(float rate) {
  uint8_t timer_type = GPT_TIMER;
  int8_t tindex = FspTimer::get_available_timer(timer_type);
  if (tindex < 0){
    tindex = FspTimer::get_available_timer(timer_type, true);
  if (tindex < 0){
    return false;


  if(!audio_timer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, rate, 0.0f, timer_callback)){
    return false;

  if (!audio_timer.setup_overflow_irq()){
    return false;

  if (!audio_timer.open()){
    return false;

  if (!audio_timer.start()){
    return false;
  return true;

void setup() {
  start_time = millis();

void loop() {
  // calculate the effective frequency
  int freq = 1000 * count / (millis()-start_time);
  count = 0;
  start_time = millis();

This is pretty straight forward!

The cool thing, which is no shown here, is that you can add a final parameter to the audio_timer.begin() method which will end up as parameter value which is passed to the timer_callback!

Categories: Arduino


han · 22. May 2024 at 15:55

hello. My name is Seungmin Han. I want to control a BLDC motor. The frequency starts at 1666hz. But Arduino R4 cannot control the motor. Maybe it’s my fault. Because I am a beginner. So I want control MCU register control. help me!!

    pschatzmann · 22. May 2024 at 17:13

    I never tried this but Google gives the following information: The frame rate of these pulses is usually between 50Hz to 490Hz
    So you seem to be much too high. The speed is controlled by setting the duty cycle

Anonymous · 6. November 2023 at 21:25

Thank you for this information. Very helpful.

ArminJo · 26. July 2023 at 22:18

Hi Phil,
thanks for the code, but it is somehow incorrect, especially

if (tindex==0){


tindex = FspTimer::get_available_timer(timer_type);

at least for the 1.02 version of the FspTimer library

A correct version (with different variable names) should be:

uint8_t tTimerType = GPT_TIMER;
int8_t tIndex = FspTimer::get_available_timer(tTimerType); // Get first unused channel. Here we need the address of tTimerType
if (tIndex < 0 || tTimerType != GPT_TIMER){
// here we found no unused GPT channel
tIndex = FspTimer::get_available_timer(tTimerType, true); // true to force use of already used PWM channel
// If we already get an tIndex < 0 we have an error, but do not know how to handle :-(
FspTimer::force_use_of_pwm_reserved_timer(); // enable usage of channel for use in begin()

it is used here: https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/private/IRTimer.hpp#L1110

    pschatzmann · 26. July 2023 at 22:59

    Thanks for your feed-back

Doug · 3. July 2023 at 20:09

Thanks a lot for this posting. I just got an UNO r4, and quickly realized I had no idea how to implement a times ISR. Could find anything anywhere, and then saw this. Thanks again!!

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *