UNO R4 Wifi two 0.5 usec timers possible?

I want to use UNO R4 WIFI on a 2-wheel balance robot. It's potentially great because it is fast, has onboard IMU for balance, and it has WIFI / BT.

Usually, a 2-wheel robot uses two 1 usec or 0.5 usec timers to control the motor speed. The problem is I don't see documentation on using the timers.

Is it possible to get two 0.5 usec timers with this board?
Is there documentation somewhere for how to use the timers?
Are there examples somewhere on how to use them?

Sure would be a nice little robot controller with something like a motor shield or CNC shield on top for stepper motors.

Got my boards mixed up.

There is no onboard IMU on the R4.

I wonder if you mean that the timer has 0.5usec resolution, with maybe a count to 256 and repeat. That would give you a period of 128usec, or about 8KHz. So the PWM output would go high at time 0 (unless a duty cycle of 0 was being called for) and then it would stay high for any number of intervals up to 255. Perhaps that means there need to be 255 intervals total, not 256. But anyway, not a 2MHz frequency.

Here is clock code for a Leonardo board that claims it is 2 MHZ. That would be a period of .5 usec, yes?

// STEPPER MOTORS INITIALIZATION
  Serial.println("Stepers init");
  // MOTOR1 => TIMER1
  TCCR1A = 0;                       // Timer1 CTC mode 4, OCxA,B outputs disconnected
  TCCR1B = (1 << WGM12) | (1 << CS11); // Prescaler=8, => 2Mhz
  OCR1A = ZERO_SPEED;               // Motor stopped
  dir_M1 = 0;
  TCNT1 = 0;

I'll do a little research on the exact timing needed.

The actual speed needed to drive the steppers is 180usec to 2000usec.
With step pulses at 180usec intervals the robot will be moving quite fast.
with 2000usec (2ms), it will be crawling.

So, my revised questions are:
Is it possible to get two timers that can be varied from 200usec to 2000usec?
Is there documentation somewhere for how to use the timers on this board?
Are there examples somewhere on how to use them?

I found this on the web: Under the Hood: Arduino UNO R4 - Timers - Phil Schatzmann
It seems to work just fine.

This is how I implemented it:

#include "FspTimer.h"
#define ENABLE_PIN  4
#define STEP1_PIN   7
#define DIR1_PIN    8
#define STEP2_PIN  12
#define DIR2_PIN    5

FspTimer M1_timer;
FspTimer M2_timer;
uint64_t count = 0;
uint64_t start_time = 0;

// callback method used by M1_timer
void M1_callback(timer_callback_args_t __attribute((unused)) *p_args) {
  digitalWrite(STEP1_PIN, LOW);
  delayMicroseconds(1);
  digitalWrite(STEP1_PIN, HIGH);
}

// callback method used by M2_timer
void M2_callback(timer_callback_args_t __attribute((unused)) *p_args) {
  digitalWrite(STEP2_PIN, LOW);
  delayMicroseconds(1);
  digitalWrite(STEP2_PIN, HIGH);
}

bool beginTimerM1(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;
  }

  FspTimer::force_use_of_pwm_reserved_timer();

  if (!M1_timer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, rate, 0.0f, M1_callback)) {
    return false;
  }

  if (!M1_timer.setup_overflow_irq()) {
    return false;
  }

  if (!M1_timer.open()) {
    return false;
  }

  if (!M1_timer.start()) {
    return false;
  }
  return true;
}

bool beginTimerM2(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;
  }

  FspTimer::force_use_of_pwm_reserved_timer();

  if (!M2_timer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, rate, 0.0f, M2_callback)) {
    return false;
  }

  if (!M2_timer.setup_overflow_irq()) {
    return false;
  }

  if (!M2_timer.open()) {
    return false;
  }

  if (!M2_timer.start()) {
    return false;
  }
  return true;
}

void setup() {
  Serial.begin(115200);
  pinMode(ENABLE_PIN, OUTPUT);
  pinMode(STEP1_PIN, OUTPUT);
  pinMode(DIR1_PIN, OUTPUT);
  pinMode(STEP2_PIN, OUTPUT);
  pinMode(DIR2_PIN, OUTPUT);

  digitalWrite(ENABLE_PIN, LOW);         // enable steppers
  digitalWrite(STEP1_PIN, HIGH);
  digitalWrite(STEP2_PIN, HIGH);
  digitalWrite(DIR1_PIN, HIGH);
  digitalWrite(DIR2_PIN, LOW);

  beginTimerM1(5555);       // 180usec
  beginTimerM2(500);        // 2000usec
  start_time = millis();
}

void loop() {
 
}

And this is the result:

IMG_6793.zip (597.8 KB)

I'm actually updating my MobaTools library to support the UNO R4. It will be definitely able to create stepper pulses up to 180µs ( probaly even a bit faster ). It will be able to drive up to 6 steppers with that speed.
So how urgent do you need it ? I may still need a bit time to get it released. ( Beta testers are always welcome :wink: )

I'm using the FSP to select a free timer, but then i configure it directly, because the FSPTimer class doesn't support the needed timer mode.

Well, I only use the static methods to select a free timer and reserve it. I think, when implementing a library that maybe better, to coexist with other libraries that may use the FSP. I don't create any FSPTimer object.

No, I'm using the GPT timer just like I use the timers in other supported boards. I need a completely unbuffered mode for the compare registers to create compare interrupts at any time.

Delta_G,
as long as you can choose 2 timers without interrupting millis() and micros(), I'm good with it.

I noticed how easy it was for people to respond once I said what I wanted to do with this.

That made me think a spec for exactly what a 2-wheeled stepper-based library ought to do to would be helpful. That would help in creating the library and simplify creating these robots for beginners. It would obviously be initially focused on the R4 WIFI because it is a good platform to use as a starting point and might later expand to other boards. These robots also need a shield with 2 stepper drivers, an IMU for the angles and acceleration, and a PID controller. Servos are a good way to get the robot to stand up on its own when it falls down.

Such a library would start with everything necessary to control the steppers and possibly expand to a library that includes what is needed for the IMU, steppers, servos, and communications.

Right now, I know of a couple choices for the stepper shield, but none that I know of that include an IMU so that would be a simple add-on to the design.

I am very interested in balancing things and have has some past marginal success, the problem is I am only a hacker type programmer, but I understand fairly well what is needed to make these work. Perhaps, if anyone else on here is interested in balancing objects, they could help.

I could take a stab at such a spec, and perhaps open a new post to gather corrections and updates.

Does this sound like a good idea to anyone else?

If you are interested I can upload the development2.6.0 branch on GitHub, so that it reflects the current development state. With e.g. the GPT configuration.
It's definitely 'in development' with a lot of debugging features enabled. But stepper and servo should basically work on R4 already.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.