This recipe reuses the code to blink an LED and the schematics from the preceding recipe. We moved this code from the main function to a new function, Blink.
The Blink function accepts two parameters—duration and percent_on:
void Blink(std::chrono::microseconds duration, int percent_on)
duration determines the total width of the pulse in microseconds. percent_on defines a ratio of the time when the signal is HIGH to the total duration of the pulse.
The implementation is straightforward. When Blink is invoked, it turns the pin to HIGH and waits for the amount of time proportional to percent_on:
digitalWrite (kLedPin, HIGH);
std::this_thread::sleep_for(
duration * percent_on / 100);
After that, it turns the pin to LOW and waits for the remaining time:
digitalWrite (kLedPin, LOW);
std::this_thread::sleep_for(
duration * (100 - percent_on) / 100);
Blink is the main building block for implementing PWM. We can control the brightness by changing percent_on from 0 to 100, and if we pick duration short enough, we will not see any flickering.
A duration that is equal to or shorter than the refresh rate of a TV or monitor is good enough. For 60 Hz, the duration is 16.6 milliseconds. We use 10 milliseconds for simplicity.
Next, we wrap everything up in another endless loop, but now it has another parameter, count:
int count = 0;
It is updated with each iteration and bounces between 0 and 100. The delta variable defines the direction of change—either a decrease or increase—as well as the amount of change, which is always 1 in our case:
int delta = 1;
When the count reaches 101 or 0, the direction changes:
if (count == 101) {
delta = -1;
} else if (count == 0) {
delta = 1;
}
On each iteration, we invoke Blink, passing 10ms as a pulse and count as a ratio that defines the amount of time when LED is on, hence its brightness (as shown in the following image):
Blink(10ms, count);
Due to the high frequency of updates, we cannot tell when the LED turns from on to off.
When we wire everything up and run the program, we can see that the LED gets brighter or dimmer smoothly.