Understanding pulse width modulation

From Knowledge Kitchen
Jump to navigation Jump to search

Pulse Width Modulation (PWM) is a way of using rapid digital on/off pulses of voltage and current to control external devices and components. PWM generally serves one of two purposes:

  • to simulate an analog signal
  • to transfer information between digital systems

Using PWM to simulate an analog signal

Digital devices, such as Arduino, PIC and most contemporary microcontrollers, use Pulse Width Modulation to simulate analog output by sending pulses of high voltage alternating with low voltage, such that over time, the average voltage output by the system can be a range of values between HIGH and LOW.

Let's first agree that if a microcontroller pin outputs a high signal over a period of time, there is not much to say the signal is high, the average signal over that time is also high, and this is nothing more than regular digital HIGH output.

PWM duty cycle at 100%

PWM duty cycle at 100%

What links here

And outputting 0V over a period of time is also nothing special to talk about it produces an average voltage of 0V over that time, which is also a regular digital low signal.

PWM duty cycle at 0%

PWM duty cycle at 0%

But, if the microcontroller outputs a HIGH signal only 75% of a given time, if you look at the average voltage over that period of time (t), it is only 75% of the pure high voltage Now were producing something besides digital highs and lows.

PWM duty cycle at 75%

PWM duty cycle at 75%

And outputting HIGH pulses only 50% of the time creates an average voltage of 50% of the high voltage.

PWM Duty cycle at 50%

PWM duty cycle at 50%

Same with 25% HIGH it produces an average voltage of 25% of each pulse's voltage.

PWM duty cycle at 25%

PWM duty cycle at 25%

So, you see that varying the width of pulses within a given time varies the average voltage over that time, which can be an okay approximation of an analog signal.

Microcontrollers, such as that in the Arduino, have about 500 of these pulses per second. This fast pulsing pseudo-analog signaling is often good enough to control motors at speeds in-between full on or off, and to light up LEDs and other lights at levels besides totally on or off.

For any given time period, the amount of time that the pin is HIGH is called the duty cycle.

Using PWM to transmit information

Besides creating pseudo-analog signals, PWM, similar to Frequency Modulation (FM) and Amplitude Modulation (AM), is a way of using variations in a cyclical signal to carry information.

For example, microcontrollers can use PWM signals to tell a servo motor how much to rotate by varying how long the HIGH pulses last for. Unlike when using PWM to simulate an analog signal, it is not the percentage of HIGH time (i.e. the duty cycle) that is important to the servo, nor many times the pulse is repeated per second. The important information that the servo depends upon is simply how long the HIGH pulses last for. The circuit embedded within the servo is designed to detect how long the HIGH pulses last for, and rotate the motor accordingly.

Servo motor control via PWM

from Wikipedia's Servo Control page

Most servos will interpret pulses that last about 1.5 milliseconds to indicate that the servo should rotate to its neutral (i.e. middle) position. Pulses longer than 1.5ms indicate to rotate to a more clockwise position, and pulses shorter than 1.5ms indicate to the servo that it should rotate to a more counter-clockwise position. These pulses are usually repeated every 20ms or so, but the frequency of pulsing is not a critical component of this way of using PWM.

Using pulses to play sounds from speakers

Although not quite pulse-width modulation, piezo speakers can be powered by sending square waves (i.e. pulses) to them. In the case of using speakers and making sounds, the pulses must have about a 50% duty cycle in order to properly power the speaker.

Varying the pitch of the sound is simply a matter of varying the frequency at which the pulses are produced. This is how the Arduino's tone() function works it sends out 50% duty cycle pulses at the frequency specified in the code.

What links here