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

Thread: analogWriteFrequency() causes glitches output

  1. #1
    Junior Member
    Join Date
    Aug 2013
    Posts
    7

    analogWriteFrequency() causes glitches output

    Click image for larger version. 

Name:	24521158202_da6ca965e0_z_d.jpg 
Views:	99 
Size:	77.2 KB 
ID:	6203
    Is there a way to avoid glitches caused by changing the output frequency with analogWriteFrequency()? It appears to force a reset of the counter when it is called, which causes a transition earlier than it should. In this example the same frequency value is written (when trace 2 goes high), so the square wave should be constant, but instead it has a truncated pulse on the PWM output.

    Code:
    void setup()
    {
      pinMode(10, OUTPUT);
      pinMode(13, OUTPUT);
    }
    
    void loop()
    {
      analogWriteFrequency(10, 666);
      analogWrite(10, 128);
    
      digitalWrite(13, 1);
      delay(90);
      digitalWrite(13, 0);
      delay(10);
    }

  2. #2
    Junior Member
    Join Date
    Aug 2013
    Posts
    7
    The offending code appears to be in pins_teensy.c:
    Code:
            } else if (pin == 5 || pin == 6 || pin == 9 || pin == 10 ||
              (pin >= 20 && pin <= 23)) {
                    FTM0_SC = 0;
                    FTM0_CNT = 0;
                    FTM0_MOD = mod;
                    FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
            }
    Is it necessary to set FTM0_CNT=0 for a reason that I'm missing?

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,173
    I believe it was done this way based on these words from section 36.3.5 from the reference manual.

    Initialize the FTM counter, by writing to CNT, before writing to the MOD register to
    avoid confusion about when the first counter overflow will occur.
    However, reading the rest of 36.3.5 and 36.4.10.2, it looks like that's not really necessary. But if you write a new MOD value that's smaller, at a moment when the current count is equal or greater, then you can end up the counter going all the way to 0xFFFF before wrapping over to 0. Or in other words, it looks like the hardware only checks equals, not greater-than, and the counter increments.

    I appreciate your effort to make this a small, very reproducible example. But for real-world use, are you changing the frequency? In other words, just reading the MOD value and doing nothing would fix this example, but do nothing for a real usage that's actually calling analogWriteFrequency() to change the setting.

  4. #4
    Junior Member
    Join Date
    Aug 2013
    Posts
    7
    Yes, the example is quite simplified -- I'm using the PWM output to drive a stepper motor and controlling the velocity with the frequency. The occasional short pulses were causing the stepper to skip steps at certain speeds.

    I'll copy the code out of analogWriteFrequency() into my own routine and have it check FTM0_CNT after writing to FTM0_MOD to see if it needs to force a reset when adjusting the frequency. This will cause a mid-length pulse during the transition, which is acceptable. Thanks for the clarification!

  5. #5
    Junior Member
    Join Date
    Aug 2018
    Location
    Paris, France
    Posts
    17
    Hello Hudson, I am interested by your attempt to modify analogWriteFrequency so that there is no glitch when it is called. Did you succeed ?

  6. #6
    Junior Member
    Join Date
    Aug 2018
    Location
    Paris, France
    Posts
    17
    Hello Paul,
    I am wondering why you say that "But if you write a new MOD value that's smaller, at a moment when the current count is equal or greater, then you can end up the counter going all the way to 0xFFFF before wrapping over to 0.* since 36.4.10.2 says *If the selected mode is not CPWM then MOD register is updated after MOD register was written and the FTM counter changes from MOD to CNTIN*.
    What do you think ?

  7. #7
    Junior Member
    Join Date
    Aug 2018
    Location
    Paris, France
    Posts
    17
    For those interested, I have solved the glitch issue by writing my own changeFrequency function as a replacement for the library analogWriteFrequency.
    See this post :
    https://forum.pjrc.com/threads/53334...requency-issue

Posting Permissions

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