Arduino

10-min tutorial: What happens when PWM registers overflow?

May 8, 2018

By  Peter

We publish fresh content each week. Read how-to's on Arduino, ESP32, KiCad, Node-RED, drones and more. Listen to interviews. Learn about new tech with our comprehensive reviews. Get discount offers for our courses and books. Interact with our community.

One email per week, no spam, unsubscribe at any time.

As you may know, in the Atmega328 that powers the Arduino Uno, several of the pins are capable of Pulse Width Modulation (PWM). These are pins 3, 5, 6, 9, 10, and 11. With PWM, we can approximate analog output programmatically and do things like fade an LED on and off or control the speed of a motor.

In the Atmega328, the register that is used by the PWM function has a resolution of 8 bits. This gives us a total of 255 possible “analog” output levels. If we attach an LED to a PWM-capable pin, we can drive it to 255 different brightness levels. And if we attach a motor, we can drive it to 255 different speed levels.

We can set a PWM value by using the analogWrite(pin, value) instruction.

So, analogWrite(3, 125) would set pin 3 to value 125. The maximum value is 255 since the PWM register is 8 bits wide (2 in the power of 8 is 255).

What happens if we set analogWrite to a value bigger than 255? Say, 256?

If the PWM value is 255, the binary version is 11111111 is stored in the PWM register. A connected LED would light up in maximum brightness.

Let’s add 1 to the register, and make the PWM value 256. The binary version of 256 is 0000000100000000 since now we need two bytes to represent this value. But, the Arduino (Atmega) can only fit the first byte in its PWM register, the one in bold. The second byte will overflow and “disappear”.

So, what you have stored in the PWM register is 00000000. This is decimal “0”, which means that your LED is practically turned off.

In other words, analogWrite(3, 0) and analogWrite(3, 256) would have the exact same effect on an LED or a motor.

Add another “1” to the register, and the PWM value now is 257. The binary version of 257 is 0000000100000001. The byte in bold is stored in the PWM register, and the rest disappears. In the register now the decimal value “1” is stored.

The lesson to take home is that although you can set the PWM value in analogWrite to any decimal you like, only the first byte of this number will fit in the PWM register. The rest will overflow and disappear.

Tags

10, Min, Overflow, PWM, Registers, Tip, Tutorial