Setting PWM resolution and frequency on Nano 33 IoT

Hi all,

I’m trying to figure out the maximum actual PWM resolution of the Arduino Nano 33 IoT, and I must admit I’m a bit confused. I’ve searched around, but the results I’m finding are quite inconclusive.

My end goal is to dim three LED strips as smoothly as possible (using MOSFETs), which would involve a high PWM resolution (12 bits or better) at at least approx. 1000Hz, but ideally as high a frequency as possible to avoid flicker when filmed with a video camera.

I take it the possible approaches are either using AnalogWriteResolution() or the Arduino_SAMD21_turbo_PWM library. The latter seems to allow easily setting both frequency and resolution, whereas the former allows for setting resolution, while setting frequency is a bit more involved.

However, there are a few things about the Turbo PWM lib I don’t understand:

  • It seems to allow PWM on pins 4, 7 and 8, which are not PWM pins at all in the official pinout, is this correct?
  • MaxSteps is 0xFFFFFF for (24-bits) timers 0 and 1, and 0xFFFF for (16 bits) timer 2, whereas AnalogWriteResolution() tops out at 12 bit, what gives?
  • I assume there must be some kind of limitations in possible combinations of resolutions and frequencies, i.e. higher resolutions don’t work at higher frequencies, but I can’t seem to figure out exactly what these limitations would be.
    [/list]

From previous experience with other Arduini I remember that messing with timers to change PWM frequencies could lead to all sorts of weird effects on millis() and delay(). Are there any such effects I would be aware of with the Nano 33 IoT?

For this appplication I’ll be using the IMU, WiFi for OTA firmware upload, plus SPI to talk to a LumenRadio module using the CRMX TimoTwo library. If messing with the PWM wreaks havok to any of that, it would be useful to know.

I’ll experiment a bit when I get my Nano 33 IoT boards, but they haven’t arrived yet, and my research in anticipation of their arrival has stagnated …

TIA

-G

Hi G,

It seems to allow PWM on pins 4, 7 and 8, which are not PWM pins at all in the official pinout, is this correct?

Yes, the SAMD21 microcontroller has a peripheral multiplexer that allows TCC (and TC) timer outputs to be routed to many more pins than the official pinout.

MaxSteps is 0xFFFFFF for (24-bits) timers 0 and 1, and 0xFFFF for (16 bits) timer 2, whereas AnalogWriteResolution() tops out at 12 bit, what gives?

I assume there must be some kind of limitations in possible combinations of resolutions and frequencies, i.e. higher resolutions don't work at higher frequencies

Yes, the 24-bit resolution for timers TCC0 and TCC1, plus the 16-bit resolution for timer TCC2 are the maximum resolutions possible. However, increasing the PWM frequency by reducing the value of the timer's period (PER) register, in turn reduces the resolution. This happens because reducing the period means the timer has less ticks to count before it overflows.

The formula for calculating single slope PWM frequency is:

PWM frequency = (frequency GCLK) / (N * PER + 1)

where:
frequency GCLK = generic clock frequency (usually 48MHz, but can be other frequencies)
N = timer prescaler (can be 1, 2, 4, 8, 16, 64, 256 & 1024)
PER = value of the timer's period register

The formula for calculating the timer's resolution is:

Timer resolution = log(PER + 1) / log(2)

where:
log = log to the base 10

For this appplication I'll be using the IMU, WiFi for OTA firmware upload, plus SPI to talk to a LumenRadio module using the CRMX TimoTwo library. If messing with the PWM wreaks havok to any of that, it would be useful to know.

The Arduino timing functions such as delay(), millis(), etc... use the SAMD21's system tick (systick) timer. Therefore using the TCC or TC timers won't adversely affect these functions in any way.