Teensy 3.6 native PWM frequency

Status
Not open for further replies.
The stars will go out, the sun will implode, and the sky will fall on our heads -
Nothing bad's gonna happen beyond that.
 
What's the question? You can use lower than the ideal frequencies, yes.

Edit: Some motors like way lower frequencies more. Below 1kHz.
 
@ilium007: just write some test code and observe what happens on the PWM pin with an oscilloscope and a logic analyser. This, in combination with reading thoroughly (and hopefully understanding) the FTM section of the MK66 reference manual, and looking at the implementation of analogWrite() in the Teensyduino core files should make you understand from where comes that idea of ideal PWM frequencies. It’s for people who are looking for maximum PWM speed, resolution, efficiency and (sub-microsecond) precision.
Using 8 bit resolution at 20kHz instead of the ideal 234375Hz means that internally, the Teensy will first set the PWM frequency to 20000Hz by setting the FTM mod value to 2999 (which gives a theoretical resolution of log2(3000)=11.55bits).
That means that if you want to analogWrite a value between 0 and 255 which is your desired 8bit resolution, he analogWrite() function will internally and transparently scale your value up to give corresponding channel compare register values between 0 and 2999, thus emulating your 8bit resolution on a native 11.55bit resolution (forced by your frequency requirement) engine.
 
I only need 8bit resolution and table gives me 234375 Hz. What will happen if I use 20000Hz ?

The PWM period will span 3000 clock cycles, rather than only 256 cycles. If the resolution of analogWrite is configured for 8 bits, which is the default, the code inside analogWrite will automatically scale your 0-255 numbers up to the 0-2999 range.

Usually this works perfectly fine. But if you're really concerned about having perfectly uniform increases in PWM steps, the downside of this scaling is some steps of 1 on the 0-255 scale will result in a step of 11 on the 0-2999 scale, but most will be a step of 12 of those 3000 clock cycles. On average, each increase of 1 on the 8 bit scale needs to translate to 11.71875 of those steps the actual hardware is using. The hardware of course is only capable of changing the PWM by integer increments of the clock it's using (on Teensy 3.6, that's F_BUS which defaults to 60 MHz).

For example, if you were to low pass filter the PWM and use it as a "poor man's DAC" (and ignoring the many other much worse issues of using PWM for a DAC) this non-uniform step size would correspond to what's commonly called differential non-linearity in DACs. The good news is the DNL will be at most 1/11th of one LSB (performance which would be considered excellent in any real DAC) in this case, since it's scaling up by such a large ratio. (but don't let this delude you into thinking low-pass filtered PWM makes a good DAC... there are so many other problems to overwhelm this DNL non-issue)

Those particular carrier frequencies are the "ideal" for a certain number of bits because the hardware actually is running with the exact number of clocks per PWM cycle so your values passed to analogWrite are a direct 1-to-1 mapping onto the hardware, without any scaling needed.

But if precisely 20 kHz is what really matters to you, analogWriteFrequency gives you the frequency you want. But it can't magically make the clock inside the chip be 256 times that frequency. The PWM is created by timers which run at 60 MHz, so when you choose any frequency that's not the "ideal" your writes need to be scaled to the actual numerical range the hardware is really using to generate the frequency you selected.

This issue is common to digital timer PWM on all microcontrollers. Most others don't give you support software a convenient frequency function and then automatically scale the data for you, but you'd encounter the same non-ideal issue when you go to do the scaling. It's just fundamentally how discrete time digital hardware creates PWM.
 
Last edited:
Thanks guys ! This definitely answers my question. I think it’s time I invested in an oscilloscope :(
 
Even with a very good oscilloscope, you'd be hard pressed to see these ~17 ns pulse width round-off differences within the span of a 50000 ns cycle of that waveform.
 
Just out of curiosity, I tried to measure it just now. Here's the code I run on a Teensy 3.6.

Code:
void setup() {
  analogWriteFrequency(3, 20000);
}

void loop() {
  for (int i=1; i <= 9; i++) {
    analogWrite(3, i);
    delay(55);
  }
}

Here's what my scope shows when I zoom in. The top half is the full PWM cycle, the bottom half is just the first small fraction for the first 9 of 256 PWM increments.

I turned on display persistence, so the locations of all the edges that occur over time remain visible.

file.png

If you stare at the full size image, can you notice if some of the slots are slightly smaller than the others?
 
In ever case, the motor driven by that PWM won’t care. Which proves that Frank B’s initial answer, which admittedly sounded more philosophical than technical, was already correct and exhaustive.
 
... Nevertheless, the "ideal" frequency for the motor can be lower - or even higher.
That depends on different factors, e.g. inductance, saturation current, etc.
Just try different frequencies that's the easiest way.
Nothing bad will happen :rolleyes:

edit: the smaller the motor the higher the frequency.
 
Last edited:
Status
Not open for further replies.
Back
Top