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

Thread: PWM Frequency (was: TimerOne on Teensy 3)

  1. #1

    PWM Frequency (was: TimerOne on Teensy 3)

    This Teensy is great!! Thanks for all the hard work Paul!

    Is there currently a way to alter the PWM frequency without setting up a timer interrupt? I used TimerOne on my Uno, though I can't get it to work on the Teensy 3. I'm using PWM to drive an LED in a guitar pedal so I have to get it over 20kHz. Right now I'm using beta7. I will set up an ISR if needed, though if there is a simpler method like TimerOne, or if it will be supported soon, that would be helpful.

  2. #2
    Alright... the lack of responses leads me to believe one thing... time to jump into some interrupts!

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Actually, I've been considering adding a function to set the PWM frequency. It's being discussed today on the Arduino developers mail list, hopefully to agree on the name and parameters, Teensy and Arduino can be compatible when/if they also add it.

  4. #4
    That would be great if they added it. TimerOne is so flexible and easy to use, I'd love to see it come standard.

  5. #5
    Re-posting as suggested. Many of our motor drivers (combat robots) require a PWM pulse of 32Khz and some older ones use 20Khz and hence the requirement. Sometimes we run different motors on the same robot. The Arduino playground turned up with some simple way of setting PWM frequencies -
    http://arduino.cc/playground/Code/PwmFrequency

    and this: http://arduino.cc/forum/index.php/topic,117425.0.html

    But I'm not sure if this can be used within the Teensy 3 environment. Given the additional number of pins available for PWM, a library would be extremely useful to have if someone has adapted this. In any case, what is the simplest way to set pin (5 or 6) to 32Khz ?
    Last edited by vspear; 11-22-2012 at 05:42 PM.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    I started a discussion on the Arduino developer list 6 days ago, regarding this feature and (hopefully) agreeing on a common definition when/if Arduino adds it, so code can be compatible between Teensy and regular Arduino.

    Since then, a huge amount of discussion has happened, with all sorts of ideas posted. I'm still holding out hope there may be some agreement to standardize this function, and I'm hoping in the future to collaborate more with the Arduino team so new features are compatible for sharing code between Teensy and Arduino.

    However, yesterday... after 5 days of wandering discussion, I finally posted this message:

    http://arduino.cc/pipermail/develope...er/007333.html

    I'm going to work on "analogWriteFrequency" this weekend or early next week. I'll post updates on this thread as I have something for you, and as the situation with collaborating with Arduino develops.
    Last edited by PaulStoffregen; 11-28-2012 at 04:42 PM.

  7. #7
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,112
    request for functionality, followed by wide ranging and ultimately endless conversation, followed by a concrete and well documented suggestion, followed by implementation. Sounds like a familiar standardization pattern.

    Reporting on either sucesses or problems, on user feedback, and a second developer saying they implemented the same thing 'for compatibility' are the usual next steps

  8. #8
    Quote Originally Posted by Nantonos View Post
    request for functionality, followed by wide ranging and ultimately endless conversation, followed by a concrete and well documented suggestion, followed by implementation. Sounds like a familiar standardization pattern.

    Reporting on either sucesses or problems, on user feedback, and a second developer saying they implemented the same thing 'for compatibility' are the usual next steps
    What is the point of your post ? It offers no value to anyone seeking help here.

  9. #9
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,112
    If you don't value coordination and communication in the wider Arduino community then I guess it would have no value to you, no. Edit: Those things do have value to me, though.

    A desire for interoperable solutions can often be blocked by some well-known anti-patterns; equally, there are techniques to counter that. Hence my post. I agree that its a divergence from 'Project guidance'. If I had been starting a new thread it would probably have best been in 'General discussion'. I posted here as it was a direct response to Paul's comment.
    Last edited by Nantonos; 11-24-2012 at 04:39 PM. Reason: Explanation

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    I personally find the Arduino developers mail list frustrating. It seems like "wide ranging and ultimately endless conversation" is more common than any of those other steps... especially the implementation part. Limor Fried (aka "Lady Ada") recently called it "bikeshedding". I love that term.

    http://www.urbandictionary.com/defin...m=bikeshedding

    I suspect the point of the message above was cynical humor, but with impersonal text-only communication it's always hard to tell for sure. Let's not get nasty here, ok?

    Yesterday I took a break from USB stuff and worked on improving analogRead speed. This morning I'm going to look into analogWriteRes and analogWriteFrequency. Will update here soon....

  11. #11
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,112
    Quote Originally Posted by PaulStoffregen View Post
    I personally find the Arduino developers mail list frustrating. It seems like "wide ranging and ultimately endless conversation" is more common than any of those other steps... especially the implementation part.
    Yup. That pattern is familiar to me from other standardization efforts. There are ways to un-deadlock it though, hence my comment.

    Quote Originally Posted by PaulStoffregen View Post
    Limor Fried (aka "Lady Ada") recently called it "bikeshedding". I love that term.

    http://www.urbandictionary.com/defin...m=bikeshedding
    Yup. Another one is 'boiling the ocean' aka solving all the world's problems as a prerequisite for solving the original one.

    Quote Originally Posted by PaulStoffregen View Post
    I suspect the point of the message above was cynical humor, but with impersonal text-only communication it's always hard to tell for sure.
    Sorry if it came over as sarcasm; that wasn't the intent at all. It was actually an honest suggestion on how to get forward momentum again on the specific problem.

    Quote Originally Posted by PaulStoffregen View Post
    Let's not get nasty here, ok?
    Agreed; edited my response.

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Here is a copy of my work-in-progress code. It has my first attempt at analogWriteResolution() and analogWriteFrequency(). It also has speedups to analogRead(), USB mouse (probably working) and USB joystick (probably not working).

    http://www.pjrc.com/teensy/beta/teensy3_24nov12.zip

    To use this, just replace your hardware/teensy/cores/teensy3 folder with the contents of this zip file.

    Please report any bugs... think "reproducible bug report"

  13. #13
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Has anyone (other than me) tried this yet?

  14. #14
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    700
    Using the Examples/Basics/Fade sketch, without calling analogWriteFrequency(), it seems to change default PWM frequency from 1.8 kHz to 490 Hz. Using the code below, I do indeed see a PWM frequency of 32 kHz as expected, and the PWM frequency remains the same at all three T3 clock settings (24,48,96 MHz). Nice work!

    I also tried setting higher frequencies: up to 2 MHz it still looks reasonable. At 10 MHz there are such big quantization errors that I get only about 3 distinct frequencies, which are actually around 11 or 12 MHz, but obviously that's pushing it with only a 48 MHz system clock.

    Code:
    // Test Teensy 3 (Ard 1.0.2 Beta 8) using Paul's new alpha PWM code, Nov. 27 2012
    int ledPin = 9;    // LED connected to digital pin 9
    
    void setup(){
      analogWriteFrequency(ledPin, 32000);  // set PWM frequency (pin, Hz)
    }
    
    void loop()  { 
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
        analogWrite(ledPin, fadeValue);         
        delay(30);                            
      } 
      for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
        analogWrite(ledPin, fadeValue);         
        delay(30);                            
      } 
    }
    Last edited by JBeale; 11-27-2012 at 07:49 PM.

  15. #15
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    700
    I see that the T3 has 10 PWM output pins, and I confirmed that the PWM values can be controlled independently on each pin. However from trying the below code, I see it will only generate two different base frequencies at once; setting a third frequency also changes one or both of the first two. I presume there are only two clock generators available. Also, it seems the pins work in pairs, so pins 3 and 4 are always working at the same frequency, pins 5 & 6, etc.

    Code:
    #define STEP 10    // pwm value ramp step size
    #define NPINS 10
    int pins[10] = {3,4,5,6,9,10,20,21,22,23};  // PWM pins on Teensy 3
    int freq[10] = {262,294,330,349,392,440,494,523,587,659}; // whole tones
    
    void setup(){
      for (int i=0;i<NPINS;i++) {
        analogWriteFrequency(pins[i], freq[i]);  // set PWM frequency (pin, Hz)
      }
    } // end setup()
    
    void loop()  { 
     for (int i=0;i<NPINS;i++) {
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=STEP) { 
        analogWrite(pins[i], fadeValue);         
        delay(30);                            
      } 
    
      for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=STEP) { 
        analogWrite(pins[i], fadeValue);         
        delay(30);                            
      } 
      
     } // for (i..)
    } // end loop()
    Last edited by JBeale; 11-27-2012 at 09:13 PM.

  16. #16
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Thanks for testing! Would be believe that version had a bunch of debugging code left in? I've commented it out. Everything else should still be the same.

    http://www.pjrc.com/teensy/beta/teensy3_27nov12.zip

  17. #17
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    700
    Actually, the new Nov.27 version does not seem to work as before. The below code was working earlier today to set the PWM frequency on pin 9 to 32 kHz, but now it stays at the default value of 490 Hz.
    To confirm, I swapped back to the previous teensy/cores/teensy3 folder (from Nov.24 zip file) and it worked again.

    Code:
    // Test Teensy 3 (Ard 1.0.2 Beta 8) using Paul's new alpha PWM code, Nov. 27 2012
    int ledPin = 9;    // LED connected to digital pin 9
    
    void setup(){
      analogWriteFrequency(ledPin, 32000);  // set PWM frequency (pin, Hz)
    }
    
    void loop()  { 
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
        analogWrite(ledPin, fadeValue);         
        delay(30);                            
      } 
      for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
        analogWrite(ledPin, fadeValue);         
        delay(30);                            
      } 
    }
    Looks like, in addition to commenting out the print statements, also this changed in pins_teensy.c at analogWriteFrequency():
    Code:
    	if (pin == 3 || pin == 4) {
    		FTM1_SC = 0;
    		FTM1_CNT = 0;
    		FTM1_MOD = mod;
    		FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
    	} else if (pin == 5 || pin == 6 || pin == 10 || pin == 11 ||
    	  (pin >= 20 && pin <= 23)) {
    		FTM0_SC = 0;
    		FTM0_CNT = 0;
    		FTM0_MOD = mod;
    		FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
    	}
    }

    ...because in the previous Nov.24 version that does set PWM frequency on pin 9, it looked like this:
    Code:
    	if (pin == 3 || pin == 4) {
    		FTM1_SC = 0;
    		FTM1_CNT = 0;
    		FTM1_MOD = mod;
    		FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
    	} else {
    		FTM0_SC = 0;
    		FTM0_CNT = 0;
    		FTM0_MOD = mod;
    		FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
    	}
    }
    Is it a typo to be including pin 11 and neglecting pin 9? According to my Teensy 3 pinout card, pin 11 is not a PWM pin. By pure chance, my test program used the one pin (#9) that the new Nov.27 code does not enable frequency selection for.
    Last edited by JBeale; 11-28-2012 at 05:30 AM.

  18. #18
    Have to get my scope out and test this coming weekend with the ultrasonic motor drivers. Looks very promising indeed....
    Last edited by vspear; 11-28-2012 at 03:22 AM.

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Opps, sorry. I see what went wrong. I added a check to make sure the pin number was valid, but the check is incorrect. It's looking for pin 11 instead of 9. I've updated the code. I'm going to work on the joystick code today and hopefully make a beta release this weeks when I get it working.

    Though perhaps somewhat off-topic, maybe this is a good moment to mention a sneak-peek at something I've been working on the last couple days. It's a circuit board (actually a stack of circuit boards) intended to someday allow me to build fully automated regression testing for Teensy. I just sent the first PCB attempt to iTead yesterday. Here's what it looks like:

    Click image for larger version. 

Name:	t_regresstest.png 
Views:	322 
Size:	63.3 KB 
ID:	67

    This is actually a few different designs on a single board, depending on which parts are soldered. They're meant to stack on top of each other, with a 40 pin ribbon cable forming a bus between them. The top board has just a Teensy 2.0 and that little power supply part in the upper left. It's the master control board that configures up to 8 slave boards which actually run the regression tests. Each slave board is meant to have one Teensy, either a 2.0, ++2.0 or 3.0 (but only 1 per PCB). The master is able to pulse the PROG/RST pin on the Teensy on any slave board, so I can make a script which controls which slave board gets reprogrammed. Those big square chips are bidirectional crosspoint switch chips which allow any combination all 46 pins to connect to any combination of 16 bus lines that connect to all boards. So I can have the master controller connect any pins together on any Teensy, or any combination of pins from any other Teensy on any board, with the limitation only up to 16 total signals (I considered more, but those chips are spendy and I can easily work within the scope of 16 signals and just break large tests into multiple pieces).

    At least that's the idea. Right now it's just a grand idea and a design file I sent off to make the first attempt at a PCB.

    Software-wise, years ago, Mark Sproul and Rick Anderson did a lot of work to make an Arduino Test Suite. I contributed code. I've exchanged emails with them recently about this effort. They intended to do something similar (perhaps not with extravagant crosspoint switches) with a set of Arduino boards connected to a server to automatically test the Arduino software. Many of the tests are already written and much of the framework for doing this is already in place.

    Eventually this system is going to let me write functionality tests. Most of Mark and Rick's work was using a single board at a time, but this way will let me design automated tests using 2 or more boards. For analogWriteFrequency, I'll probably build a test where one board runs a sketch that outputs several different frequencies and perhaps the signal will be routed to another board running the FreqMeasure or FreqCounter library, to check the frequency is correct. The test would them repeat for each PWM capable pin.
    Last edited by PaulStoffregen; 11-28-2012 at 04:43 PM.

  20. #20
    Wow. That's like > $200 in switch parts if I understand you right. Really cool! Thanks Paul!

    -c

  21. #21
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Yup, closer to $300. I used sockets, so if the PCB needs a rev (very likely) I can pull the chips.

  22. #22
    Fascinating. Battle testing will certainly yield a superior product. There is no substitute (yet) for hard core regression testing.

    Cheers.

  23. #23
    Senior Member
    Join Date
    Oct 2012
    Location
    Portland OR
    Posts
    700
    Nice looking test fixture. But "...been working on the last couple of days..." !? I want to know how one person gets so much done. We need someone like you at our company. Then the rest of the engineers could go home :-)

    On the other hand, don't accept any job offers, because you're doing great stuff with Teensys!

  24. #24
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,285
    Here's a new page, documenting the PWM functions.

    http://www.pjrc.com/teensy/td_pulse.html

Posting Permissions

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