Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Teensy4 PWM frequency modulation and overhead questions

  1. #1

    Teensy4 PWM frequency modulation and overhead questions

    I presently have two pins on a Teensy 4 executing PWM at slightly different frequencies such that the voltage difference between the pins are essentially amplitude modulated at the difference in frequency when low-passed. I need to improve upon this by using PWM to frequency modulate a single pin instead.

    I am presently using analogwritefrequency to set the PWM frequency. If I can do an interrupt on output edge and call analogwritefrequency each time, I can adjust the PWM frequency once a cycle to implement FM by modulation each period length individually. I looked around and couldn't find cases where anybody had used PWM like this. I don't believe the compute overhead of analogwritefrequency is sufficient to preclude doing this or if there are other hangups. Does this sound feasible?

  2. #2
    Senior Member
    Join Date
    Aug 2019
    southwest USA
    seems feasible to me - give it a go. i had similar doubts about using Teensy LC to produce nice pseudo sine
    waves at up to 2 khz for modulation of an RF carrier (rather than sq waves to reduce occupied spectrum)
    using the built in DAC, with each burst of cycles starting/ending at or very near zero cross. managed to
    get it done by ignoring style and code size and just writing for speed.

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    How feasible 1 interrupt per waveform cycle is really depends on the frequency. It also depends heavily on what other libraries are using interrupts, and how much interrupt latency those libraries impose and how much latency they can tolerate from your use of interrupts.

    Teensy 4 is fast. 100,000 interrupts per second is usually "easy". Pushing past 1 million per second is possible, but probably requires more attention to writing efficient code. Somewhere around 10 to 20 million is the upper limit of what's possible, no matter how efficient your code.

    But again, it all depends on what other libs also need interrupts. Priority nesting is supported, so often times you can achieve much more by carefully choosing higher priority for more time sensitive interrupts. But some code, particularly Adafruit_NeoPixel, disables interrupts for lengthy times. Pretty much nothing like this will if you use that sort of interrupt blocking code.

  4. #4
    This basically works straight ahead. I'm using digital pins to feed ultrasonic transducers. I was able to modulate the PWM frequency with a sinusoid (to get PFM) and the signal came right through on the receiver as an FM modulated sinusoid centered at 40khz. I was also able to modulate the frequency with a sum of sinusoids...and everything checked out again. Sooo...yeah, Teensy4s can do ultrasonic PFM pretty much straight away...and with the available number of timers, quite a lot of it. If you have a stripped down design and do all the frequency adjustments within one interrupt there's not enough code to make it take long enough to get weird.

    The main thing making this hard is knowing the *exact* frequency the timers end up using when calling analogwritefrequency. I'm still unclear on how to make exact calculations. I was hoping I'd only have Teeny4 clock skews to through it off, but something extra is interfering.

    Specifically, PFM in this context requires the receiver to count clock edges (from the Tx) referenced to a center frequency (at the Rx). I have that mostly working but I have observed the center frequency needing to be configured by trial end error to get good demodulation. I suspect that this is due to 'notches' in frequency adjustment. I brought that up here:

    The notches may work out such that the positive and negative modulation phases are slightly askew and the edge count drifts positive or negative relative to the reference...thus making the centerfrequency adjustment required. If I can better calculate true output frequencies, I can properly match the center demodulation frequency and get better performance.

    A secondary issue is that in order to attempt to match PWM settings exactly, (and avoid timer opacity) I've been setting PWM on an output pin and wiring it to an input pin with an interrupt per this thread:
    If there is a way to lock identical PWM timing to that created with analogwritefrequency without using extra pins for external interrupts (and only a timer interrupt) it would really smooth the implementation, and for certain use cases (like mine) allow Teensy to function at ultrasonic as if it had as many DACs as digital pins and with no external components.

  5. #5
    I solved the external interrupts problem in this thread. This technique lets you run the PFM on a single pin instead of wiring two pins together.

    I still have some small ghosts running around, but presently single-pin PFM works pretty well and can be executed independently on 16 pins since there's that many FlexPWM timers. Furthermore, if implemented well, it can be robust to all those interrupts stepping one another.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts