#1
  1. <?PHP user_title("gimp"); ?>
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2005
    Location
    Internet
    Posts
    7,652
    Rep Power
    6084

    Pulse Width Modulation (PWM) for dummies


    Let me explain PWM as I understand it.

    PWM stands for pulse width modulation.

    Consider a square wave. You send a HIGH pulse followed by a LOW pulse. To put it more simply, you turn a pin on, then you turn it off.


    Credit http://enginova.com/RMS_fig_2.jpg

    Now, let's say that we keep sending this over and over. Let's say that we have 500 HIGH and 500 LOW signals per second. What happens?

    Well, since we have a duty cycle of 50%, most of your components will read that as 50% of the max voltage. If you were to have a duty cycle of 10%, that would be 10% of the max voltage.

    So, with PWM you can specify basically how much voltage you want to send on a regulated voltage line. The values range from 0 to some value that depends on the brand of microprocessor you have (for example, Arduino goes to 255), with the maximum being the max output value (HIGH) and 0 being 0V (LOW or off).


    If you're using an arduino, you can go File -> Examples -> Analog -> Fading for a quick example.
    Chat Server Project & Tutorial | WiFi-remote-control sailboat (building) | Joke Thread
    “Rational thinkers deplore the excesses of democracy; it abuses the individual and elevates the mob. The death of Socrates was its finest fruit.”
    Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken. Use TODO to leave yourself reminders. Calling a program finished before all these points are checked off is lazy.
    -Partial Credit: Sun

    If I ask you to redescribe your problem, it's because when you describe issues in detail, you often get a *click* and you suddenly know the solutions.
    Ches Koblents
  2. #2
  3. <?PHP user_title("gimp"); ?>
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2005
    Location
    Internet
    Posts
    7,652
    Rep Power
    6084
    But let's say you don't have any PWM outputs, or you're already using all of them. Well, this requires a slight change in the logic of your program to accommodate your own PWM.

    Consider again how PWM works. You can do one of two things:
    1) Send a pattern where HIGH and LOW signals are the same length, but send more HIGH than LOW signals or vice versa, or
    2) Send a pattern where each cycle is one HIGH and LOW but one of them can be longer than the other.

    Example for 1) If your microprocessor sends a pulse for precisely 1 ms, you can send a HIGH and then a LOW pulse for a 50% duty cycle, or nine HIGH pulses and a LOW pulse for a 90% duty cycle, or you can send three HIGHs and a LOW for 75%. You get the point.

    Example for 2) You can send a HIGH pulse for 9 ms and a LOW pulse for 1 ms for a 50% duty cycle, or a HIGH pulse for 1 ms and a LOW for 333 us (microseconds) for a 75% duty cycle, etc.

    Which method you choose is up to you, but take a quick look at the note on the bottom of this post if you're using an arduino. But there you have it, your own PWM pin with no hardware modification.

    However, take note of what I said about changing your program's logic. If you use this method you're either going to have to put it on a different thread using interrupts - which I'm not sure how well they work - or if it's in your loop() method you're going to have to take out any delay at the end of it, otherwise your components will just turn on and off. This works great when the delay between one iteration and the next of the loop is 5 ms or less - my current program is about 1 ms. Also, if you're writing to serial - don't, because that slows everything down immensely and it's the same as having a 30 ms delay after every iteration.





    *As of right now, the arduino has a bug where delaying for microseconds using delayMicroseconds causes time drift - or incorrect time - in the Arduino. If I remember correctly, the pattern is that the microseconds that you delay for don't get added on to the clock. Therefore, DO NOT USE delayMicroseconds! Instead, use something like this
    Code:
    int delayFor = 100; // microseconds you want to delay for
    long time = micros();
    while (micros() - time < delayFor) {}
    Seriously, for anyone directed here from google, this bug nearly gave me a heart attack me a few months back. I just could not for the life of me figure it out. This function is a workaround that works 100%. You'll often want to use it if controlling something with pulses measured in the us (like a motor controller that wants 1500 us, for example.)
    Last edited by gimp; October 27th, 2009 at 02:41 PM.
    Chat Server Project & Tutorial | WiFi-remote-control sailboat (building) | Joke Thread
    “Rational thinkers deplore the excesses of democracy; it abuses the individual and elevates the mob. The death of Socrates was its finest fruit.”
    Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken. Use TODO to leave yourself reminders. Calling a program finished before all these points are checked off is lazy.
    -Partial Credit: Sun

    If I ask you to redescribe your problem, it's because when you describe issues in detail, you often get a *click* and you suddenly know the solutions.
    Ches Koblents
  4. #3
  5. <?PHP user_title("gimp"); ?>
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2005
    Location
    Internet
    Posts
    7,652
    Rep Power
    6084
    Now, one more thing. How do you turn a, for example, "it's basically" 2.5V output into a "it is" 2.5V output? I mean, most of your components will read 5V half the time as 2.5V but quite a few components will not. (Basically nothing digital that wants a continuous analog signal will be fooled by a duty cycle of a different voltage.)

    Well, consider what you want to smooth a signal. There's really only one component that does that - a capacitor. You basically want to make sure that when there's a HIGH signal the capacitor is getting filled up by any extra power, and when there's a LOW signal it gives you what is basically a regulated output at the desired voltage.

    Someone's going to have to explain it better than I can because I don't know enough, but I can tell you how to do it.

    Here's your basic diagram: (Vin is the PWM output, Vout is what you get, and the three lines at the bottom signify ground. The zigzag is the resistor and the two parallel lines are the capacitor. If you didn't know that, you need to google electronics symbols and learn it.)

    credit http://en.wikipedia.org/wiki/Low-pass_filter

    Now we need to decide what values we want for the resistor and capacitor.

    First, recall that t (Tau) = RC. This is your time constant.

    Next, we want a time constant that's about 100 times bigger than the period of our PWM output. If you wrote the PWM yourself, you'll be figuring the period out on your own. If you're using a built-in PWM, you can google to find the frequency and therefore the period.

    For example, consider the arduino.
    [I'll edit this later - the arduino is being kind of a **** with default values as around 500 on some and 1000 on others.]

    Comments on this post

    • jwdonahue disagrees : You're way out of your depth here buddy.
    Chat Server Project & Tutorial | WiFi-remote-control sailboat (building) | Joke Thread
    “Rational thinkers deplore the excesses of democracy; it abuses the individual and elevates the mob. The death of Socrates was its finest fruit.”
    Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken. Use TODO to leave yourself reminders. Calling a program finished before all these points are checked off is lazy.
    -Partial Credit: Sun

    If I ask you to redescribe your problem, it's because when you describe issues in detail, you often get a *click* and you suddenly know the solutions.
    Ches Koblents
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    887
    Originally Posted by gimp
    How do you turn a, for example, "it's basically" 2.5V output into a "it is" 2.5V output? I mean, most of your components will read 5V half the time as 2.5V but quite a few components will not. (Basically nothing digital that wants a continuous analog signal will be fooled by a duty cycle of a different voltage.)
    What?

    What exactly are you trying to do here? If your circuit had feedback to the PWM, this would be a very crude switching regulator. Vout is dependent on duty cycle and max current of Vin and the resistance and impedance of whatever the current sink is. A good diagram to characterize this kind of circuit should include a load resistance/impedance of some kind.

    Why don't you start with what PWM's are used for? Maybe pick one useful example, prototype and characterize it; and then do a write-up. Best one I can think of is an LED brightness control or perhaps a status indicator (based on rate and width of LED on/off).
    I no longer wish to be associated with this site.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    887
    Originally Posted by gimp
    Now, let's say that we keep sending this over and over. Let's say that we have 500 HIGH and 500 LOW signals per second. What happens?

    Well, since we have a duty cycle of 50%, most of your components will read that as 50% of the max voltage. If you were to have a duty cycle of 10%, that would be 10% of the max voltage.
    What kind of components? Most digital components will see either 0 or 5 volts (assuming 5V peak on the output pin) depending on timing. Yes the average voltage might be on the order of the percentage of duty cycle, but that actually depends on the current sink. Fed to a direct short, your output voltage will be zero. Given a high enough impedance input pin, it will probably average out as you expect, but the digital state of the pin itself is a different story. The pin will see alternating 5 and 0 volts and depending on your PWM frequency, that could represent a lot of state changes (interrupts for instance).

    So it's important that you define components here.
    I no longer wish to be associated with this site.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    887
    Originally Posted by gimp
    1) Send a pattern where HIGH and LOW signals are the same length, but send more HIGH than LOW signals or vice versa, or
    How do you do that? The only way to distinguish high periods is that they are bounded by low periods. So by definition there has to be exactly the same number of them (+/- 1 if you stop in the middle of a cycle). You can only change the duty cycle.
    Last edited by jwdonahue; October 27th, 2009 at 10:14 PM.
    I no longer wish to be associated with this site.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    887
    So, the whole point of PWM's is usually to control current using a digital output. Given a digital output connected to a fixed impedance or constant voltage drop, the only way to reduce current flow is to turn off the output pin or insert an inline resistance. An LED is an excellent example here. They tend to have an absolute drop of around 0.5 volts. They will begin to emit light when the current flow exceeds some threshold and they also tend to fry rapidly if you drive them with a TTL output. Now, you could put a current limiting resistor in series with the diode and then just use the pins output register as an on/off switch or you can resort to PWM to control the current flowing through the diode. You probably should at least have a small current limiting resistor in there, just in case, but with PWM you can control the brightness of the LED and you can also drive it with enough current to be visible, but way less current than would be required if you simply used a resistor and steady state voltage source.

    Motors are another good example. They generally don't care about voltage (within certain limits) and there speed or torque (depending on type) is dependent on current. You can vary the pulse width to control the speed of some motors under a given load. You can also use PWM and a simple circuit to drive some stepper motors.
    Last edited by jwdonahue; October 28th, 2009 at 07:22 PM.
    I no longer wish to be associated with this site.
  14. #8
  15. <?PHP user_title("gimp"); ?>
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2005
    Location
    Internet
    Posts
    7,652
    Rep Power
    6084
    ...

    Edit: Sorry. That was rude of me. However, please let me finish what I'm writing before jumping in and critiquing. I stopped halfway through.

    Comments on this post

    • jwdonahue agrees : LOL, guess I missed something ;)
    Last edited by gimp; October 28th, 2009 at 10:58 AM.
    Chat Server Project & Tutorial | WiFi-remote-control sailboat (building) | Joke Thread
    “Rational thinkers deplore the excesses of democracy; it abuses the individual and elevates the mob. The death of Socrates was its finest fruit.”
    Use XXX in a comment to flag something that is bogus but works. Use FIXME to flag something that is bogus and broken. Use TODO to leave yourself reminders. Calling a program finished before all these points are checked off is lazy.
    -Partial Credit: Sun

    If I ask you to redescribe your problem, it's because when you describe issues in detail, you often get a *click* and you suddenly know the solutions.
    Ches Koblents
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    May 2004
    Posts
    3,417
    Rep Power
    887
    LOL. It appears I missed something

    Originally Posted by gimp
    However, please let me finish what I'm writing before jumping in and critiquing. I stopped halfway through.
    Please bake your creations all the way through to the middle before taking them out of the oven. Gimp, I will be happy to assist you. If you have material you aren't sure of, just send it to me in a private message. I promise to respond with comments ASAP. I have been an electronics hobbyist since the 60's. To this day, I think "zero" whenever I see black.

    If not me, then find somebody you trust to review your work before posting it.

    Comments on this post

    • gimp agrees : Was writing, got frustrated by arduino's timers, had to go to class :) The ideas are there but not 100% laid out yet
    I no longer wish to be associated with this site.

IMN logo majestic logo threadwatch logo seochat tools logo