PWM code


14 posts
by chris.meyers.fsu » Sun Jul 01, 2012 3:38 pm
Regarding the Gertboard PWM code ...

I am trying to control a servo that moves between 0 and 180 degrees given a single PWM at a particular duty cycle. i.e. Edge high =~ 3ms is 180 degrees, Edge high =~ .7ms is 0 degrees. 1 PWM at 50 % duty would result in the motor moving to 90 degrees.

I used the gertboard code to familiarize myself with PWM. The trouble is, I can't send a single PWM wave. This led me to look at the BCM2835 ARM Peripherals pdf. From the documentation I gather I can send a single PWM if use the FIFO mode. I, seemingly, successfully entered FIFO mode because writing to the FIFO queue changes the PWM frequency (debugging using poor mans audio). However, I am not able to configure the chip to send a single PWM. i.e. ensuring that RPTL1 = 0 doesn't have the effect of sending a single PWM.

Any advice on how to proceed? Am I understanding the FIFO queue correctly?
Posts: 27
Joined: Sat Jun 02, 2012 7:46 pm
by Gert van Loo » Sun Jul 01, 2012 6:41 pm
It is difficult to debug from a distance.

I have not much knowledge of servos, but I understand the signal into them is about 1KHz.
Somebody wrote a while ago that it is not so critical as the duty cycle is most important,
but it could be that the default PWM signal as used in the Gertboard example is just way to fast.
Try turning the PWM clock frequency down.

Oh, I think servos still need a continuous waveform. A single pulse will not work.
User avatar
Moderator
Moderator
Posts: 1843
Joined: Tue Aug 02, 2011 7:27 am
by chris.meyers.fsu » Sun Jul 01, 2012 7:41 pm
Somebody wrote a while ago that it is not so critical as the duty cycle is most important,

Correct, in my brief experience.

Try turning the PWM clock frequency down.

It feels like that is an issue. How do I go about turning down the PWM clock?

Oh, I think servos still need a continuous waveform. A single pulse will not work.

The servo has extra logic so that the duty cycle directly translates into a 0-180 degree position. Thus, a single PWM could potentially move the device 180 degrees.
Posts: 27
Joined: Sat Jun 02, 2012 7:46 pm
by Gert van Loo » Sun Jul 01, 2012 10:37 pm
chris.meyers.fsu wrote:.....
It feels like that is an issue. How do I go about turning down the PWM clock?


in setup_pwm read the comment :-)

//
void setup_pwm()
{
// Derive PWM clock direct from X-tal
// thus any system auto-slow-down-clock-to-save-power does not effect it
// The values below depends on the X-tal frequency!
PWMCLK_DIV = 0x5A000000 | (32<<12); // set pwm div to 32 (19.2/32 = 600KHz)
PWMCLK_CNTL = 0x5A000011; // Source=osc and enable
....

So how about:
PWMCLK_DIV = 0x5A000000 | (320<<12); // set pwm div to 320 (19.2/320= 60KHz)

You have 12 bits so the maximum is 0xFFF which gives 4688 Hz.
But then you have the PWM count limit as well so if you set that to e.g. 2047 you get a frequency of 2.2 Hz.
(Not 100% sure about the last statement, I have to check that tomorrow.)
User avatar
Moderator
Moderator
Posts: 1843
Joined: Tue Aug 02, 2011 7:27 am
by alanb » Wed Aug 01, 2012 9:48 pm
Gert van Loo wrote:You have 12 bits so the maximum is 0xFFF which gives 4688 Hz.
But then you have the PWM count limit as well so if you set that to e.g. 2047 you get a frequency of 2.2 Hz.
(Not 100% sure about the last statement, I have to check that tomorrow.)


Sorry to go digging up an ageing post but could you elaborate on that? I'm trying to better understand the PWM functionality.
My thinking currently is for a 50% duty cycle in PWM mode with MSEN=0 (no algorithm) the frequency is going to match (more or less) the clock frequency as the bits end up evenly spread out.
I'm thinking the lowest frequency with a 50% duty cycle you could achieve is ~147 Hz with the clock at 4688 Hz in MSEN=1 mode with a range of 64 bits and serial data to transmit being 0xFFFFFFFF. So unless my thinking is wrong this should give a 32 cycles high followed by 32 cycles low wave?

If I am wrong on this could someone provide a quick explanation?
Posts: 4
Joined: Wed Aug 01, 2012 9:19 pm
by Gert van Loo » Wed Aug 01, 2012 11:20 pm
With 50% duty cycle you will get HALF your clock frequency as the output will toggle every clock.
The 4688Hz clock is if you use the Xtal 19.2MHz as source. If you find a lower source the frequency will also be lower.
I have no idea what all the clocks are which are available during normal operation.

I have never looked into the details of the MSEN=1 mode.

Also if very low frequencies are required you can use SW running from the system timer.
User avatar
Moderator
Moderator
Posts: 1843
Joined: Tue Aug 02, 2011 7:27 am
by felixfurtak » Thu Aug 02, 2012 7:28 am
Hi Gert,

So in your code it seems that the PWM frequency will change depending on the duty cycle.

Is it possible to keep the PWM frequency the same, regardless of duty cycle?

This would be a preferred implementation for many people.

Felix
Posts: 47
Joined: Wed Nov 16, 2011 10:41 am
by Gert van Loo » Thu Aug 02, 2012 11:22 am
felixfurtak wrote:Hi Gert,

So in your code it seems that the PWM frequency will change depending on the duty cycle.

Is it possible to keep the PWM frequency the same, regardless of duty cycle?

This would be a preferred implementation for many people.

Felix


Sorry but that is not possible. A good PWM signal by definition will have a changing frequency.
User avatar
Moderator
Moderator
Posts: 1843
Joined: Tue Aug 02, 2011 7:27 am
by felixfurtak » Thu Aug 02, 2012 12:45 pm
Hi Gert,

Thanks for your reply. I thought PWM had constant frequency by definition. Maybe there are some variants?

I'm not sure I understand why this would be impossible to generate, but thanks for the info.

The problem that I have is that with a changing frequency, the switching losses in my transistors will also increase as the frequency increases, which will reduce linearity of the PWM. I guess, putting a larger clock divider would help.

Thanks again

Felix.
Posts: 47
Joined: Wed Nov 16, 2011 10:41 am
by jojopi » Thu Aug 02, 2012 1:22 pm
alanb wrote:I'm thinking the lowest frequency with a 50% duty cycle you could achieve is ~147 Hz with the clock at 4688 Hz in MSEN=1 mode with a range of 64 bits and serial data to transmit being 0xFFFFFFFF. So unless my thinking is wrong this should give a 32 cycles high followed by 32 cycles low wave?
I have not tested this, but I suspect when the data sheet says "M is the data to be sent", it means the number of bits, not the actual pattern.

So with MSEN=0, RANGE=8, DATA=3, you get a repeating pattern 00100101, and with MSEN=1, RANGE=8, DATA=3, you get repeating 11100000. To an application that cares only about the long-term average, these are the same output level: 3/8. Incidentally, MSEN=1 is what I would call PWM, and MSEN=0 is really Pulse Density Modulation.

In both cases, the output cycle time does not vary with duty cycle, as long as you adjust the duty cycle by changing DATA only and keeping RANGE constant.
User avatar
Posts: 1873
Joined: Tue Oct 11, 2011 8:38 pm
by texy » Thu Aug 02, 2012 5:58 pm
felixfurtak wrote:Hi Gert,

Thanks for your reply. I thought PWM had constant frequency by definition. Maybe there are some variants?

I'm not sure I understand why this would be impossible to generate, but thanks for the info.

The problem that I have is that with a changing frequency, the switching losses in my transistors will also increase as the frequency increases, which will reduce linearity of the PWM. I guess, putting a larger clock divider would help.

Thanks again

Felix.


I,m with you Felix - surely the frequency is the same, but its the mark/space ratio that changes with PWM ?

Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Moderator
Moderator
Posts: 2207
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by alanb » Thu Aug 02, 2012 8:33 pm
Gert van Loo wrote:With 50% duty cycle you will get HALF your clock frequency as the output will toggle every clock.
The 4688Hz clock is if you use the Xtal 19.2MHz as source. If you find a lower source the frequency will also be lower.
I have no idea what all the clocks are which are available during normal operation.

I have never looked into the details of the MSEN=1 mode.

Also if very low frequencies are required you can use SW running from the system timer.


Ah sorry a frequency of 1/2 makes sense, didn't think that one through properly :). I'm actually just attempting to put together a reasonable library for the GPIO pins and I'm trying to cover my bases so I don't leave anything desirable out. I came across this post and it got me thinking of ways to achieve this.
Posts: 4
Joined: Wed Aug 01, 2012 9:19 pm
by alanb » Thu Aug 02, 2012 8:43 pm
jojopi wrote:
alanb wrote:I'm thinking the lowest frequency with a 50% duty cycle you could achieve is ~147 Hz with the clock at 4688 Hz in MSEN=1 mode with a range of 64 bits and serial data to transmit being 0xFFFFFFFF. So unless my thinking is wrong this should give a 32 cycles high followed by 32 cycles low wave?
I have not tested this, but I suspect when the data sheet says "M is the data to be sent", it means the number of bits, not the actual pattern.

So with MSEN=0, RANGE=8, DATA=3, you get a repeating pattern 00100101, and with MSEN=1, RANGE=8, DATA=3, you get repeating 11100000. To an application that cares only about the long-term average, these are the same output level: 3/8. Incidentally, MSEN=1 is what I would call PWM, and MSEN=0 is really Pulse Density Modulation.

In both cases, the output cycle time does not vary with duty cycle, as long as you adjust the duty cycle by changing DATA only and keeping RANGE constant.


Thanks I wasn't sure if it meant what you suggested or treat the data register as actual data to be sent "serially". Reading over the data sheet again I would be inclined to agree with you here. I think I was combining PWM mode with MSEN=1 and Serialiser mode.
Cheers :D
Posts: 4
Joined: Wed Aug 01, 2012 9:19 pm
by honda4life » Fri Aug 31, 2012 9:57 pm
I don't get it how it works with changing frequency stuff,

Can someone explain :s
Posts: 70
Joined: Thu Mar 15, 2012 7:27 pm