Controlling LED brightness is a fundamental concept in electronics and embedded systems, playing a key role in dimmable lighting, display backlighting, and even motor speed control. Rather than just switching an LED on or off, we use Pulse Width Modulation (PWM) to achieve smooth and precise brightness adjustment.
PWM works by rapidly toggling the LED between ON and OFF states at a high frequency. The brightness is controlled by varying the duty cycle, which represents the percentage of time the signal stays HIGH in each cycle.
When toggled at a sufficiently high frequency, the human eye cannot perceive the rapid switching between ON and OFF states. Instead, due to persistence of vision, the LED's brightness appears as a continuous average, creating the illusion of dimming.
By the end of this tutorial, you’ll learn:
✅ What PWM is and how it controls brightness.
✅ How to use the analogWrite() function on the Mercury Board.
- Setting up the environment - if you haven't added the Mercury Board on your Arduino®, this is a good time to do so. Refer to this tutorial for setup: https://www.hackster.io/ral/getting-started-with-mercury-arduino-setup-705f4d
- Plug the USB Cable to Mercury Board and connect it you your laptop.
- Refer to the code below
- To initiate upload process, press and hold FLASH button when "Connecting..." is visible on Arduino Terminal.
Crash Course: Understanding GPIO Control in the Arduino® Environment
For those new to the Arduino® coding environment, let's break down the basics of controlling an LED Brightness using digital GPIO (General-Purpose Input/Output) pins and analogWrite() function. For more details on analogWrite() refer to this link: https://www.arduino.cc/reference/tr/language/functions/analog-io/analogwrite/
The analogWrite() function in Arduino is used to generate a Pulse Width Modulation (PWM) signal on supported digital pins. Unlike digitalWrite(), which simply sets a pin to HIGH or LOW, analogWrite() allows for intermediate output levels by varying the duty cycle of a square wave.
analogWrite(D7, brightness);
Here, "brightness" represents the user input for the desired LED brightness.
On the Mercury Development Board, the HIGH level is 3.3V, and the LOW level is 0V. The analogWrite() function enables the output to achieve a perceivable voltage between the two extremes.
The analogWrite() function takes two inputs: pin and duty cycle. On the Mercury Board, the built-in LED is connected to pin D7 (GPIO 2). By setting the duty cycle to a value between 0 and 255 [0 = 0% duty cycle, 255 = 100% duty cycle], we can adjust the LED brightness smoothly.
Thus, to set the LED to 50% brightness, the code would be:
analogWrite(D7, 128);
To make this more interactive, we can introduce Serial.parseInt(); to allow user input for controlling the LED brightness. This will enable users to enter a brightness level between [0,255], which the Mercury Board will read and use to adjust the LED's brightness accordingly.
int brightness = Serial.parseInt();
*** DISCLAMER ***Everything mentioned above is generally true; however, on the Mercury Board, which uses the ESP-12F module, the default built-in LED on the ESP-12F module, is wired in an inverted configuration. This means that when GPIO 2 (D7) is set HIGH, the LED turns OFF, and when GPIO 2 is set LOW, the LED turns ON.
As a result, the behavior of PWM is also inverted. When the PWM value is set to 0, the LED glows at full brightness, and when the PWM value is set to 255, the LED turns completely OFF. Otherwise, the conceptual understanding remains the same.
To account for this inverted LED behavior, we need to make a small adjustment in the code as follows:
analogWrite(D7, 255 - brightness);
Here, "brightness" represents the user input for the desired LED brightness.
Quick Video Tutorial
Comments
Please log in or sign up to comment.