01 - What is PWM?

PWM stands for Pulse Width Modulation. This means that we can generate a pulse whose width (ie duration) can be altered.


The digital world


Since microcontrollers live in a digital world then their output pins can be either low (0v) or high (5v). However: the rest of the world tends not to speak such an open-or-shut case ie the rest of the world tends to be analogue. Rather than just being on or off: motors tend to need speed control, lighting may need to be dimmed, servos need to move to a particular position, buzzers need a sound frequency etc.


AVR microcontrollers have Analogue To Digitals Convertors (ADC) to convert a voltage from the analogue world to a number but do not have Digital to Analogue Convertors (DAC) to convert digital numbers back into variable voltages.


PWM is the closest solution.


By turning an output pin repeatedly high and low very quickly then the result is an average of the amount of time the output is high. If it is always low the result is 0v, always high then the result is 5v, if half-and-half then the result is 2.5v.


Why does this work? Well most real world devices have some kind of latency (ie they don't do what you ask immediately). This could be caused by a mixture of momentum, inductance, capacitance, friction (amongst others).


For example: if you connect a motor to a battery then it will, eventually, rotate at full speed. Disconnect the battery and the motor will take a little while to slow down until it stops. Equally if the motor is only connected to the battery for a very short time before being disconnected then it wont have enough time to get up to full speed. So if we repeatedly connected and disconnected the battery then the motor would start turning, then slow down, start turning, slow down etc. Obviously if we only did this a few times a second then it would be kind of jerky - but if we did it fast enough then we could control the speed of the motor dependent on the percentage of time the battery was connected versus not connected.


Similarly - if we wanted to dim lights or LEDs then they take a little while to get up to 'full glow' and, once disconnected from the power, the glow fades away. So we could create a dimmer by varying the amount of time on or off.


Servos are another example. They tend to expect a pulse every 20ms - depending on the width of the pusle they move to a given location.


How do we create a PWM signal

Before we discuss the intricacies of how we program a microcontroller then let's consider some basics to get a general idea of what we want to achieve.


Microcontrollers are very good with whole (integer) numbers. So assuming we have two numbers: one called BOTTOM and a higher number called TOP. By making the microcontroller start at BOTTOM, and then count upwards until it reaches TOP, and then repeat the process - if we were to then plot the resulting numbers on a graph then we end up with what is called a Sawtooth waveform that looks like this.



Of course you can never output this signal from your controller as it can only cope with on or off and not all these numbers - it just shows how the number starts at BOTTOM, counts up to TOP, and then starts all over again.

So the next step is to add a 'comparator' which is used to decide whether our output pin should be high or low. This comparator is yet another number which is somewhere in the range between BOTTOM and TOP. If the current Sawtooth number is less than the comparator value then the output will be low, otherwise the output will be high.

If the value of the comparator was equal to BOTTOM then the Sawtooth value could never be lower than bottom so our output pin would always be high. Equally if the comparator value was equal to TOP then the output pin would always be low. However: if the comparator value was the mid-value between BOTTOM and TOP then the output pin would spend 50% of its time being low and the other 50% being high. By varying the comparator value we can change the 'high' time anywhere between 0% and 100% of the time.

Looking back at the previous diagram we can see that the sawtooth waveform is 6 units high and repeats every 3 units across. So if we were to set our comparator to be 2 units above the BOTTOM value then what would happen?
The sawtooth waveform would spend 1/3 of the time below this value and the remaining 2/3 of the time above value. So our digital output pin would be a square wave that is low for 1/3 of the time and high for 2/3 of the time.



In the above example the sawtooth waveform repeated every 3 units. Assuming that each unit was 1ms then our waveform repeats every 3ms.

Given that Frequency = 1 / Time

then the signal frequency is 1/0.003, or 333.33 Hz. Note that with PWM this frequency remains constant - we just use the comparator value to adjust the duty cycle.


Duty Cycle

The percentage of time that our output pin is high is called the duty time. In the example above it is high for 2/3 of the time ie a 66.66% duty cycle.