The hardware has 6 PWM channels, and the PwmOut Interface can be used on mbed pins p21-p26.
The default period is 0.020s, and the default pulsewidth is 0.
The PwmOut interface can express the pulse train in many ways depening on how it is to be used. The period and pulse width can be expressed directly in units of seconds, millisecond or microseconds. The pulsewidth can also be expressed as a percentage of the the period.
You can also specify the LED1-LED4 as PwmOut. Note that these are just different pinout options for the same underlying PWM hardware, so they are just alternative routing rather than extra PWM channels. So you can pin them out can't be used at the same time:
PWM H/W Channel
Pinout Options
PWM_1
P2_0/p26 or P1_18/LED1
PWM_2
P2_1/p25 or P1_20/LED2
PWM_3
P2_2/p24 or P1_21/LED3
PWM_4
P2_3/p23 or P1_23/LED4
PWM_5
P2_4/p22
PWM_6
P2_5/p21
On the mbed LPC2368 and LPC1768, the PwmOut hardware is limited to share the period value between all outputs. Therefore, if you change the period of one output, you change them all. The pulsewidth can be set independently for each output.
#include "mbed.h"
PwmOut servo(p21);
int main() {
servo.period(0.020); // servo requires a 20ms period
while (1) {
for(float offset=0.0; offset<0.001; offset+=0.0001) {
servo.pulsewidth(0.001 + offset); // servo position determined by a pulsewidth between 1-2ms
wait(0.25);
}
}
}
if I try to set the period with the above statement servo.period(0.020); I get an error statement
"This declaration has no storage class or type specifier (E77-D)"
any idea what is wrong?
Lothar
if I try to set the period with the above statement servo.period(0.020); I get an error statement
"This declaration has no storage class or type specifier (E77-D)"
any idea what is wrong?
Lothar
I'm going to have to guess as you haven't provided much details of the code that is giving you problems, but for example:
#include "mbed.h"
PwmOut servo(p21);
int main() {
servo.period(0.020); // servo requires a 20ms period
}
is valid code, whereas something like:
#include "mbed.h"
PwmOut servo(p21);
servo.period(0.020); // servo requires a 20ms period
int main() {
}
would give the error you describe. Program code must be within a function (such as main).
Hope that helps!
Simon
Hi Lothar,
I'm going to have to guess as you haven't provided much details of the code that is giving you problems, but for example:
<<code>>
#include "mbed.h"
PwmOut servo(p21);
int main() {
servo.period(0.020); // servo requires a 20ms period
}
<</code>>
is valid code, whereas something like:
<<code>>
#include "mbed.h"
PwmOut servo(p21);
servo.period(0.020); // servo requires a 20ms period
int main() {
}
<</code>>
would give the error you describe. Program code must be within a function (such as main).
Hope that helps!
Simon
I have 4 PWM channels controlling motor ESCs for a quadrotor and 2 servo channels for controlling a camera platform. I am attempting to reduce the period of the two camera servo PWM channels by setting the pulse width of these two channels to zero for 4 out 5 of the cycles. The motor updates are at 200Hz.
The synchronisation is performed by capturing a motor pulse edge and then setting the masking conditional which in turn is used to set the widths to zero for the camera channels.
So the questions:
1) are the pulse width updates guaranteed to occur within one cycle?
2) is there an easier way to detect when the positive pulse edge occurs without wiring the output pin to an detection input using an interrupt (an internal event perhaps)?
Thanks
Greg
I have 4 PWM channels controlling motor ESCs for a quadrotor and 2 servo channels for controlling a camera platform. I am attempting to reduce the period of the two camera servo PWM channels by setting the pulse width of these two channels to zero for 4 out 5 of the cycles. The motor updates are at 200Hz.
The synchronisation is performed by capturing a motor pulse edge and then setting the masking conditional which in turn is used to set the widths to zero for the camera channels.
So the questions:
1) are the pulse width updates guaranteed to occur within one cycle?
2) is there an easier way to detect when the positive pulse edge occurs without wiring the output pin to an detection input using an interrupt (an internal event perhaps)?
Thanks
Greg
1) When you set the pulsewidth, it is placed in a holding register in the pwm hardware which automatically updates the pulswidth at the start of the next period (so, yes)
2) The mbed APIs don't provide anything, so that may well be the easiest way. You may be able to find some specific features of the LPC1768 pwm hardware that gives you what you want (reading the counter registers? some form of interrupt?), but you'd need to investigate the LPC1768 manual here.
Sounds like an interesting project!
Simon
Hi Greg,
1) When you set the pulsewidth, it is placed in a holding register in the pwm hardware which automatically updates the pulswidth at the start of the next period (so, yes)
2) The mbed APIs don't provide anything, so that may well be the easiest way. You may be able to find some specific features of the LPC1768 pwm hardware that gives you what you want (reading the counter registers? some form of interrupt?), but you'd need to investigate the LPC1768 manual here.
Sounds like an interesting project!
Simon
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
Hello all,
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
mbed is quite versatile with regards to assigning outputs to various pins; however it doesn't like it if you assign an output that *must* go through certain pins to a different one. It probably tries to output what it would do if it was going through the PWM circuitry that applies to p21-26?
<<quote mtl1>>
Hello all,
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
<</quote>>
mbed is quite versatile with regards to assigning outputs to various pins; however it doesn't like it if you assign an output that *must* go through certain pins to a different one. It probably tries to output what it would do if it was going through the PWM circuitry that applies to p21-26?
Probably could be simpler (do I need the detach or does this just happen after the timeout for example?) but seems to work fine with now visible performance impact on anything else.
Greg
<<quote simon>>
Hi Greg,
....
Sounds like an interesting project!
Simon
<</quote>>
Thanks Simon,
I finally went for a software solution (below) and will now use all six PWM outputs for the motors allowing hexacopters etc.
I must put something up here but the Wiki is at:
http://code.google.com/p/uavp-mods/wiki/UAVXArm
For others the code I used is:
CameraTicker.attach_us(&CamPWMOnISR, 22000);
void CamPWMOnISR(void) {
PWMCamRoll.write(1);
CamRollTimeout.attach_us(&CamRollPWMOffISR, 1000 + PWM[CamRollC]);
PWMCamPitch.write(1);
CamPitchTimeout.attach_us(&CamPitchPWMOffISR, 1000 + PWM[CamPitchC]);
}
void CamRollPWMOffISR(void) {
PWMCamRoll.write(0);
CamRollTimeout.detach(); // redundant?
}
void CamPitchPWMOffISR(void) {
PWMCamPitch.write(0);
CamPitchTimeout.detach(); // redundant?
}
Probably could be simpler (do I need the detach or does this just happen after the timeout for example?) but seems to work fine with now visible performance impact on anything else.
Greg
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
You are probably seeing mbed's "Blue Lights of Death" flashing pattern, as described in the handbook debugging page. This indicates a runtime error, such as trying to use a pin assignment not available for a certain interface. Sometimes an error message will also be printed on the usb serial port to help track it down.
Hope that makes things clear.
Simon
Hi Michael,
<<quote mtl1>>
I was just experimenting with the PwmOut function a moment ago. It seems that the function has some odd behavior when the PWM output pin is set to something other than p21-26 or LED1-4. I tried it with p20, and it seemed to affect all LED pins. I did not check the other PWM pins to see if they were affected. This result was unexpected as I thought the output would just not occur.
<</quote>>
You are probably seeing mbed's "Blue Lights of Death" flashing pattern, as described in the handbook [[http://mbed.org/handbook/Debugging|debugging]] page. This indicates a runtime error, such as trying to use a pin assignment not available for a certain interface. Sometimes an error message will also be printed on the usb serial port to help track it down.
Hope that makes things clear.
Simon
Does PWM operate using timers & interrupts? If I use PWM for several output pins, each with different duty cycles, are different timers involved, and does each different PWM output use/generate a different interrupt? Or is a single timer used along with a list of times to generate interrupts?
Bill
Does PWM operate using timers & interrupts? If I use PWM for several output pins, each with different duty cycles, are different timers involved, and does each different PWM output use/generate a different interrupt? Or is a single timer used along with a list of times to generate interrupts?
Bill
PWM outputs does not use any kind of interrupts. For generating PWM is used a dedicated timer.
You don't have to worry about interrupts when using PWM outputs.
PWM outputs does not use any kind of interrupts. For generating PWM is used a dedicated timer.
You don't have to worry about interrupts when using PWM outputs.
My frail understanding of USB is that there needs to be some housekeeping/maintenance between the OS and a USB device so that the OS knows the device is still present. This has to happen from time to time. I'm wondering whether a program that is running on the device for a while is able to fulfill this maintenance while it's executing its code. Interrupt driven techniques mean that this code can perform these maintenance calls in between interrupt driven code execution (like toggling pins involved in PWM). I want my embedded device to stay connected to a host throughout so the host can send it commands, data, etc., and I fear that while the device is running its internal stuff it may not be available to service this OS maintenance.
No doubt I have a muddy view; can anyone straighten me out?
Thanks.
Bill
Ok, another question about PWM, sort of.
My frail understanding of USB is that there needs to be some housekeeping/maintenance between the OS and a USB device so that the OS knows the device is still present. This has to happen from time to time. I'm wondering whether a program that is running on the device for a while is able to fulfill this maintenance while it's executing its code. Interrupt driven techniques mean that this code can perform these maintenance calls in between interrupt driven code execution (like toggling pins involved in PWM). I want my embedded device to stay connected to a host throughout so the host can send it commands, data, etc., and I fear that while the device is running its internal stuff it may not be available to service this OS maintenance.
No doubt I have a muddy view; can anyone straighten me out?
Thanks.
Bill
I've gotten a variant of one of the PWM examples going on my mbed. When I plug it into my Mac, a new device shows up in my /dev folder, and after I bring up a terminal and identify which device the mbed is. I can command the LEDs in my test circuit fine.
On a Windows 7 machine, when I plug in the mbed it shows up as a removable device like a thumb drive in the Device Manager. If I then bring up a terminal program, all I see are com ports, none of which is any use. Any pointers on this?
Thanks,
equipoise
And another thing...
I've gotten a variant of one of the PWM examples going on my mbed. When I plug it into my Mac, a new device shows up in my /dev folder, and after I bring up a terminal and identify which device the mbed is. I can command the LEDs in my test circuit fine.
On a Windows 7 machine, when I plug in the mbed it shows up as a removable device like a thumb drive in the Device Manager. If I then bring up a terminal program, all I see are com ports, none of which is any use. Any pointers on this?
Thanks,
-- equipoise
I found out how to get my mbed recognized and working on WIndows 7 - amazing how this "instructions" concept works. Still have questions about how or if there is a need to maintain a USB connection while code is running on the mbed.
Bill
I found out how to get my mbed recognized and working on WIndows 7 - amazing how this "instructions" concept works. Still have questions about how or if there is a need to maintain a USB connection while code is running on the mbed.
Bill
I wonder why there is not a function to GET the period... only one to get the dutycycle?
Or is there something I am missing?
Tue
The default period is 0.020s. Presumably if you changed it to something other than this you would know what you changed it to and so a function to GET the period would be redundant?
<<quote myren>>
I wonder why there is not a function to GET the period... only one to get the dutycycle?
Or is there something I am missing?
Tue
<</quote>>
The default period is 0.020s. Presumably if you changed it to something other than this you would know what you changed it to and so a function to GET the period would be redundant?
Hello from Switzerland
I need 4 PWM-outputs, all of the same base frequency. Now my problem: Each of the 4 PWM should have a delay one to each other. So the PWMs are not synchronous anymore. Can someone give me a tip, how to resolve this in a efficient way? Grazie Mille.
Hello Titi Tix; Thank you for your hardware-solution with external RC's and Schmitt-triggers. What i am looking for, is a solution by software. Looking at the user manual of the m-controller, you can find in the chapter PWM (page 511 / fig. 119) , that you can preset the different match registers... just i did not get a working result yet.
Hello from Switzerland
I need 4 PWM-outputs, all of the same base frequency. Now my problem: Each of the 4 PWM should have a delay one to each other. So the PWMs are not synchronous anymore. Can someone give me a tip, how to resolve this in a efficient way? Grazie Mille.
Hello Titi Tix; Thank you for your hardware-solution with external RC's and Schmitt-triggers. What i am looking for, is a solution by software. Looking at the user manual of the m-controller, you can find in the chapter PWM (page 511 / fig. 119) , that you can preset the different match registers... just i did not get a working result yet.
It depends on the delays. Try this way:
FirstPwmOut - R1- C2 to GND - triggerschmidt (74hc14) - out
This introduces a delay determined by RC . Use biger delay for SecondPwmOut and so on.
Also instead of 74hc14 you can use CD4093. Pay attention in software that the PWM obtained this way is inverted hardware or use another inverter for the output.
It depends on the delays. Try this way:
FirstPwmOut - R1- C2 to GND - triggerschmidt (74hc14) - out
This introduces a delay determined by RC . Use biger delay for SecondPwmOut and so on.
Also instead of 74hc14 you can use CD4093. Pay attention in software that the PWM obtained this way is inverted hardware or use another inverter for the output.
Hi there, I'm having some trouble understanding what happens when you set the PwmOut itself to a value. For example:
include "mbed.h"
PwmOut led(p21);
AnalogIn ain(p20);
main(){
while (1){
led=ain;
}
}
We are setting the 'led' to a value. But what in particular are we changing? The output voltage? Or some percentage?
Sorry if it's a stupid question, I'm new at this!
Thanks
Hi there, I'm having some trouble understanding what happens when you set the PwmOut itself to a value. For example:
#include "mbed.h"
PwmOut led(p21);
AnalogIn ain(p20);
main(){
while (1){
led=ain;
}
}
We are setting the 'led' to a value. But what in particular are we changing? The output voltage? Or some percentage?
Sorry if it's a stupid question, I'm new at this!
Thanks
Please login to post comments.