DUE PWM Frequency

dgelman: Has anyone found a solid way (preferably in sketch) to modify the output PWM frequency? Also changing variant.h from 1k to what ever you want isnt working for me. Changing it and saving doesn't change the output frequency.

Daniel

You have to restart the IDE if you make changes to the underlying libraries as they are compiled only once for the sketch "to save time".

you might look at PWMC_ConfigureClocks()

You have to restart the IDE if you make changes to the underlying libraries as they are compiled only once for the sketch "to save time".

you might look at PWMC_ConfigureClocks()

Hello,

I restarted my IDE to let it recompile, but I am still getting 1KHz PWM frequency, also I put the following line into setup but that did not do anything.

PWMC_ConfigureClocks(3922 * PWM_MAX_DUTY_CYCLE , 0, VARIANT_MCK);.

I wouldn't prefer either way since this micro is designated for motor control, if anything I would like to strictly change the variable in variant.h - if you know any reason why it is still not change, I would much appreciate it.

Daniel

Hello,

I have fixed the problem, somewhat.

Looking into variant.cpp

  { PIOB, PIO_PB25B_TIOA0,   ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC0_CHA0     }, // TIOA0
  { PIOC, PIO_PC28B_TIOA7,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHA7     }, // TIOA7
  { PIOC, PIO_PC26B_TIOB6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHB6     }, // TIOB6

  // 5
  { PIOC, PIO_PC25B_TIOA6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM,  TC2_CHA6     }, // TIOA6
  { PIOC, PIO_PC24B_PWML7,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH7,     NOT_ON_TIMER }, // PWML7
  { PIOC, PIO_PC23B_PWML6,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH6,     NOT_ON_TIMER }, // PWML6
  { PIOC, PIO_PC22B_PWML5,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH5,     NOT_ON_TIMER }, // PWML5
  { PIOC, PIO_PC21B_PWML4,   ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM),   NO_ADC, NO_ADC, PWM_CH4,

Notice that only pins 7, 6, 5 and 4 respond to the #define in the variant.h file. I am not sure how to configure the rest of the pins to act accordingly. I havent tried changing NOT_ON_PWM (highlighted in the other pin configurations) to PWM_CH#, if this is possible. I am assuming the architecture allocates pins 2-13 as PWM pins but on 5-7 as reconfigurable PWM pins.

If anyone would like to contribute why/how to reconfigure other pins - that would be helpful.

Daniel

Hi, after I read through the thread, I wanted to ask two things about PWM frequency on DUE:

  1. It seems the function for customizing PWM frequency (e.g. 100Hz on Pin 9, and 10kHz on pin 7) in the sketch isn't officially released yet, is it?? if not, do we have an expecting time on that?

  2. I'm wondering if we could just use the Servo library to adjust the PWM frequency to whatever we want? I did find the 20000 us time intervel being set for the servo to have a 50 Hz PWM output. It seems to me we don't have to get anything like analogWriteFrequency(). We could just generalize the Servo library to do that?

When this was discussed on the Arduino developers mail list, there was some agreement on analogWriteFrequency(pin, frequency).

About a week later, I implemented analogWriteFrequency() on Teensy 3.0, but I didn't create any documentation until only days ago. Here's the new page. Scroll down to "PWM Frequency".

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

One of the concerns with analogWriteFrequency() was possibly implying each pin can have a unique frequency. Now that both the function and documentation exist, I'd be really curious to hear any feedback?

Hopefully this will someday become implemented on Arduino Due?

Hello, I came up with a library for the Due specifically to setup PWM with unique frequencies (up to 2 for now) on different PWM pins. If you’d like, have a go and let me know how it goes.

The link below has an example Due program and the PWM library.

Your library works quite well!!!

Thanks a lot!!

randomvibe:
Hello, I came up with a library for the Due specifically to setup PWM with unique frequencies (up to 2 for now) on different PWM pins. If you’d like, have a go and let me know how it goes.

The link below has an example Due program and the PWM library.

http://arduino.cc/forum/index.php/topic,146947.msg1115263.html#msg1115263

Has anything progressed on this? I've not seen anything like analogWriteFrequency() for the Due and on another thread (http://forum.arduino.cc/index.php?topic=146947.msg1353829#msg1353829) someone has said that he is having problem's with randomvibe's pwm01 implementation.

My understanding is we agreed, at least in principle, on the analogWriteFrequency() function after much discussion on the Arduino Developers mail list.

So far, it looks like the Arduino team hasn't worked on this, and nobody appears to have tried to contribute it. Perhaps this library could be used as a basis for making such a contribution? Odds seem good Cristian might merge it into Arduino 1.5.5 or some future version, since we all basically agreed on the API many months ago.

I implemented analogWriteFrequency() on Teensy 3.0, but that code is specific to the timer peripherals on the Freescale Kinetis chip. It won't work on Due's SAM3X chip.

I'd be very thankful if somebody finally accomplished this. :)

Rigth now I am using the fix of changing variant.h file to change PWM frequency, but on my due board it only affects PWM frequency of pins 6,7,8 and 9. Others keep working at 1KHz.

It would be great to be able to change all pins' PWM frequency and more important, changing it from IDE (not asking to have different frequencies in every pin, maybe 2 frequencies would be enough).

Thank you very much!

Luis

It's unfortunate these new API ideas, which have been agreed upon in principle (usually after much conversation on the developer mail list) don't get implemented or even documented in the official Arduino software.

If this had been a documented part of the API, even as "coming in a future version", odds are good Intel would have incorporated variable frequency into their I/O scheme on the new Galileo board. Looking through their code, it seems they did special support for the pulse generation for Servo.

Then again, I could do far better at documenting stuff for Teensy. Maybe next year I ought to slow down on the tech side and focus on that?

Hi there

can you please post your software with the 3 sinwaves as an output

thanks in advance

to change the PWM frequency of all pins.. that means also the ones not in range 6,7,8,9.. you should change also TC_FREQUENCY in variant.h.

this works perfectly. i get a nice 330 kHz period for all pins now.

Hi check the pwm01.h you can change the PWM frequency with it

Do you know how to generate a SINE PWM ?

earx: to change the PWM frequency of all pins.. that means also the ones not in range 6,7,8,9.. you should change also TC_FREQUENCY in variant.h.

this works perfectly. i get a nice 330 kHz period for all pins now.

How did you do it in detail?

void setup() {

// PWM Pulsbreite eingeben uint32_t pwm_duty_u= 0.75*65536;//2^16 =65536 also maximaler Wert fuer duty cycle ist 65536-1 uint32_t pwm_duty_v= 0.75*65536; uint32_t pwm_duty_w= 0.75*65536;

// PWM Frequenz in HZ eingeben

uint32_t pwm_freq1 = 300000;

//PWM Auflösung

pwm_set_resolution(16);

//Hardware Ausgabe

pwm_setup( 7, pwm_freq1, 2); //pwm_setup (pin,freq,iclock 2 ist Clock B) pwm_setup( 8, pwm_freq1, 2); pwm_setup( 9, pwm_freq1, 2);

pwm_write_duty( 7, pwm_duty_u ); // pin, duty_cycle_pro_phase pwm_write_duty( 8, pwm_duty_v ); pwm_write_duty( 9, pwm_duty_w );

// Verzögerung in uS

delay(30000);

// PWM Stop

// pwm_stop( 7 ); //pwm_stop( 8 ); //pwm_stop( 9 );

the header file pwm01.h is here :http://forum.arduino.cc/index.php?PHPSESSID=povm0bi5ipfp6s6o33a226h4s0&topic=144446.msg1149044#msg1149044

in variant.h: change the line:

define TC_FREQUENCY 1000

to

define TC_FREQUENCY 300000

and as said previously:

define PWM_FREQUENCY 1000

to

define PWM_FREQUENCY 300000

the frequency doesn't have to match exactly. it's governed by the mother clock divided by the pwm resolution (256 steps) divided by a power of two. the max would be 84 MHz / 256 = 328.125 kHz.

hope that clears things up. there could be more elegant ways and i still have to test what this does to micros() and delay().. on AVR-based Arduino that issue exists.

Hi what about my question :( how can I modify thisd code to get a SINE PWM wave ?

What exactly is a "SINE PWM" wave?

This is a sine pwm

http://www.pstracks.com/wp-content/uploads/2012/12/fig4.gif

It enabels you to re build a sine wave throught your pwm signal