This page is part of my Model Remodel series of articles and a subset of my Arduino section.
DISCLAIMER: If you choose to attempt any of these modifications, you assume all risks thereof. I just wanted to share my experiences here. Neither Fanhome, nor myself, are responsible for any damages that may occur.
There are a few ways we can control the brightness of the LEDs with an Arduino: Resistors, Analog Pins, and PWM. I will do my best to explain all of them here, along with any drawbacks to each method.
Resistors
Using resistors inline with an LED is almost always required. This is because the Forward Voltage of an LED seldom matches the power supply voltage exactly, plus we need to limit the current passing through the LED. For example, if we consider the 5VDC output of an Arduino pin, our red LEDs need a 150Ω resistor to limit the current to their Operating Current of 20 mA. This same resistor also lowers the effective voltage of the LED circuit down to the 2.2V Forward Voltage that the red LED requires.
However, if we instead use a resistor with a higher resistance, the current will be lowered even further and the LED will become dimmer. In many cases, this is a very simple way to dim an LED to the specific brightness we desire.
There are a couple of downsides to using this method. First, as we increase the resistance, we will reach a point where the LED will not light at all. It takes trial and error with different resistor values to try and achieve the result we are looking for. Second, sending lower voltages to an LED can change the color of the light output by that LED. Many LEDs will slightly change color as the voltage is reduced below the Forward Voltage. So, as we dim an LED using the resistor method, the color of the light emitted may become something we do not want.
Analog Pins
A second way to dim LEDs is to use the ANALOG pins on our Arduino. While the DIGITAL pins are designed to input/output either zero (0) or five (5) volts, most Arduinos also have a few ANALOG pins that can input/output any value between 0V and 5V. By using the analogWrite command, we can tell the Arduino to output a certain voltage through an ANALOG pin. The analogWrite command has two required parameters: pin number and value. This value must be between 0 and 255, where 0 outputs zero volts and 255 outputs the full 5V.
Therefore, to turn on an LED (with the correct inline resistor of course) connected to an ANALOG pin, we could do something like this:
/* A sketch that will let us control the brightness of an LED using an ANALOG pin */ void setup() { pinMode(A0, OUTPUT); } void loop() { analogWrite(A0, 255); }
NOTE: The ANALOG pins can also be called by the actual pin number. Referring to pin 14 in your sketch is the same as referring to pin A0:
Sadly, this method of dimming LEDs is not very effective. It works, but only to a certain extent. What you will likely see is the appearance of the LED just turning on and off as you change the value sent via analogWrite. That is because there is a minimum voltage the LED needs before the diode inside it will light up. Any value below that and the LED won’t do anything. Once the value is high enough to turn on the LED, there is not much room to adjust it brighter from there. Therefore, much of the 0-255 range of the value parameter is useless. In reality, we should use probably just use these ANALOG pins for variable sensor/potentiometer inputs or as extra DIGITAL outputs.
Pulse Width Modulation (PWM)
What is PWM?
One of the great features built into an Arduino is something called PWM (Pulse Width Modulation). PWM is where the +5VDC voltage output of a DIGITAL pin can be switched on and off very quickly (up to nearly a thousand times a second). Because human eyes have something called ‘persistence of vision’, it takes some time for our eyes to perceive a change in light brightness. We can use this PWM feature to make an LED appear brighter or dimmer.
PWM creates this effect by creating a square wave output whereby a PWM-enabled pin is turned ON for some period of time, then turned OFF for some different period of time. By telling a PWM-enabled pin to be ON more often than OFF, the connected light will seem brighter to us. Inversely, if we have more OFF time, the same light will appear dimmer to us. The percentage of time that the pin is powered ON is called the duty cycle. The LED is turned ON more often with a longer duty cycle and turned ON less often with a shorter duty cycle.
It is worth noting that not all DIGITAL pins on an Arduino can support PWM. In the case of an Arduino Uno, there are six (6) DIGITAL pins that can output PWM signals – 3, 5, 6, 9, 10, and 11. These pins are marked on the board by a tilde (~):
If we look at the Arduino Nano there are no tilde markings on the board. But, it can do PWM on the same DIGITAL Pins 3, 5, 6, 9, 10, and 11:
Using PWM to Control LED Brightness
To use PWM on the DIGITAL pins of our Arduino that support it, we only need to use the analogWrite command with those pins. As I mentioned earlier, the analogWrite command has two required parameters: pin number and value. This value must be between 0 and 255, where 0 will effectively make the LED appear to be OFF (0% duty cycle) and 255 will make the LED appear to be at full brightness (100% duty cycle).
Therefore, to turn on an LED (with the correct inline resistor of course) connected to an PWM-enabled pin, we could do something like this. By changing the value parameter of this analogWrite command, we can change the brightness from 0 (OFF) to 255 (full bright):
/* A sketch that will let us control the brightness of an LED using PWM */ const byte PWMpin = 3; // PWM Enabled pin void setup() { pinMode(PWMpin, OUTPUT); } void loop() { analogWrite(PWMpin, 255); }
Just for fun, we can even use a for statement to slowly make this LED slowly dim from OFF to full brightness to OFF over and over again:
/* A sketch that will cycle the brightness of an LED using PWM */ int brightness = 0; // Integer to hold the brightness value const byte PWMpin = 3; // DIGITAL PWM-enabled pin void setup() { pinMode(PWMpin, OUTPUT); // Set Pin 3 as an analog output } void loop() { // Bring the brightness of the LED from 0 to 255 with a 30ms delay between steps for (brightness = 0; brightness <= 255; brightness += 5) { analogWrite(PWMpin, brightness); delay(30); // Wait for 30 millisecond(s) } // Bring the brightness of the LED from 255 to 0 with a 30ms delay between steps for (brightness = 255; brightness >= 0; brightness -= 5) { analogWrite(PWMpin, brightness); delay(30); // Wait for 30 millisecond(s) } }
Personally, I find PWM to be the best method of dimming LEDs. Because PWM does not change the actual voltage going to the LED, it does not effect the color of light from the LED. It also does not drop the average voltage down below what the LED needs to turn ON, so PWM can dim down to near zero before the LED appears to be OFF. The only drawback to using PWM is that as the duty cycle approaches 0%, you might be able to see a slight flicker in the LED.
To help reduce this flickering, most Arduinos have a few PWM pins that can switch faster than the others. For example, on the Uno and Nano, pins 5 and 6 operate at 980 cycles per second (frequency in Hertz or Hz). The other four pins 3, 9, 10, and 11 do PWM at 490 Hz. That is why I chose to connect my Bussard Collector LEDs and the Warp Nacelle Grille LED Strip to pins 5 and 6. The higher frequency of these pins looks better when changing the light levels as the engines startup and shutdown. As my Window lights will most be ON, yet dimmable, they are fine using the slower PWM on other pins. The faster the PWM frequency, the less noticeable this flicker will be at lower light levels.
Download my Sketch
I have shared this small LED brightness cycling main sketch via the Arduino Editor. Simply click the Open Code or Download buttons!
Next Arduino Page
HIGH CURRENT SWITCHING – Switching higher voltage/current devices on and off with Arduino