Pulse Width Modulation, or PWM, is a technique used to create an analog signal from a digital source. On an Arduino board, this functionality is implemented in hardware, allowing the microcontroller to simulate a voltage that sits between the standard HIGH (5V or 3.3V) and LOW (0V) states. Instead of actually outputting a variable voltage, the Arduino rapidly switches the pin on and off; by adjusting the ratio of "on" time to "off" time, known as the duty cycle, the average voltage delivered to the load is effectively controlled.
Understanding the Duty Cycle
The core principle of PWM control revolves entirely around the duty cycle, which is expressed as a percentage. A 0% duty cycle means the signal is always off, resulting in an effective voltage of 0 volts. Conversely, a 100% duty cycle means the signal is always on, delivering the full supply voltage. Intermediate values, such as 50%, indicate that the signal is on for half the period and off for the other half, yielding an average voltage roughly half of the supply. This modulation happens at a frequency high enough that the human eye or the connected component cannot perceive the switching, perceiving only a stable power level.
Hardware PWM Pins on Arduino
Not all digital pins on an Arduino are created equal regarding PWM capability. Specific pins are designated as hardware PWM pins, meaning they are managed by dedicated timer registers within the microcontroller. This hardware-based approach ensures a steady and accurate signal without consuming CPU cycles, making it ideal for time-sensitive applications. On popular boards like the Arduino Uno, pins 3, 5, 6, 9, 10, and 11 are hardware PWM pins. Users must consult the specific pinout diagram for their board to identify which pins support this functionality.
Writing the Code: The analogWrite Function
Controlling the PWM signal via software is straightforward thanks to the analogWrite() function, which is distinct from reading analog sensor data. This function requires two arguments: the pin number and a value representing the desired duty cycle. The pin number specifies which hardware PWM pin to use, while the value, ranging from 0 to 255, sets the intensity. A value of 0 corresponds to a 0% duty cycle (off), and 255 corresponds to a 100% duty cycle (fully on). The syntax looks like this: analogWrite(pin, value); .
Practical Applications and Use Cases
Implementing PWM control opens a wide array of practical projects. The most common application is LED brightness control, where the intensity of the light adjusts smoothly rather than flickering on and off. Furthermore, PWM is essential for controlling the speed of DC motors via motor driver circuits, allowing for precise robotic movement. Servo motors, widely used in robotics and automation, rely on specific PWM signal protocols to determine their angular position, demonstrating the technique's versatility beyond simple lighting.
Considerations and Limitations
While PWM is efficient, it is not suitable for every scenario. Because the signal is a square wave, it generates significant electrical noise, which can interfere with sensitive audio or radio frequency circuits. Additionally, the voltage is not a true analog output; it is a digital signal that can only supply the full voltage or nothing. Consequently, circuits requiring a precise, stable voltage—such as operational amplifier feedback loops—require a dedicated Digital-to-Analog Converter (DAC) rather than relying on basic PWM functionality.