# Re: fading 4 leds in a row with digital output

One way to do this is to vary the time that the LED is on, but do it so fast the eye can’t see the LED in the off state.

For example, if you were to want the LED at 90% brightness and assuming a repeating time of 10ms, you would switch the LED on for 9ms then off for 10ms then repeat over and over.

This is called pulse width modulation (PWM).

The arduino has some facilities for PWM which may help, but it isn’t too hard to code this yourself for 4 LEDs.

Mike

Well, up for the challenge I decided to have my own go at PWM!

Here’s the result (and it only took 5 minutes! - I’m impressed since I’ve only been playing with Arduino for a day now)

``````int LEDPIN = 2;
int currenton = 10;
int currentoff = 0;
int goingdown = 1;

void setup()                    // run once, when the sketch starts
{
pinMode(LEDPIN, OUTPUT);    // sets the digital pin as output for LED
}

void loop()                     // run over and over again
{
digitalWrite(LEDPIN, HIGH);    // turn LED off
delay(currenton);
digitalWrite(LEDPIN, LOW);    // turn LED off
delay(currentoff);

// reset
if (goingdown == 1) {
currenton = currenton - 1;
currentoff = currentoff + 1;
if (currenton == 0) {
goingdown = 0;
}
} else {
currenton = currenton + 1;
currentoff = currentoff - 1;
if (currentoff == 0) {
goingdown = 1;
}
}
}
}
``````

My LED flickers a bit though. I am thinking this is because my software PWM works slower than hardware PWM?
delaymicroseconds instead of delay(); caused unexpected results (Just flashing or something)

Todbot has some tutorials for this- just google todbot + LED

Well, up for the challenge I decided to have my own go at PWM!

Here’s the result (and it only took 5 minutes! - I’m impressed since I’ve only been playing with Arduino for a day now)

{ Code snipped }

My LED flickers a bit though. I am thinking this is because my software PWM works slower than hardware PWM?

That’s good work, Nabisco. There is a little flicker, which is probably to do with the period.

Delay() wastes so much processor time - how about trying to do it without using Delay()?

Regards,

Mike

BigMike,

How do I keep a ration of ON to OFF without some kind of a delay?

Hi Nabisco,

You could use the technique shown in here:

you might also look at using a timer interrupt.

Mike

Wow, I didn’t even know this was possible! I’m learning so many things every day from this forum.

Thanks!

Yeah - there are some good people here.

This is what I came up with - software PWM led dimmer without Delay():

``````#define ON HIGH
#define OFF LOW
#define ledPin 13
#define pwmPeriod 20

int value = LOW;                // previous value of the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long ulMillis = 0;
unsigned long interval = 1;           // interval at which to blink (milliseconds)
int ledVal = 0;
int pwmCount = 0;
int ic = 0;

void setup()
{
pinMode(ledPin, OUTPUT);      // sets the digital pin as output
}

void loop()
{
ulMillis = millis();
if (ulMillis - previousMillis >= interval) {
previousMillis = ulMillis;

pwmCount++;
if (pwmCount > pwmPeriod) {
pwmCount = 0;
}
if (pwmCount > ledVal) {
value = OFF;
} else {
value = ON;
}

digitalWrite(ledPin, value);

ic++;
if (ic>333) {
ic=0;
ledVal = random(pwmPeriod)-1;
}
}
}
``````

It works on a 20ms period and can display 20 different brightness levels.

Every 333ms it changes the led brightness to a random value.

As the Delay() function is not used there are no wasted clock cycles and other things can be done. For example, it would easily handle more leds and could handle a keypad (with debounce) whiich could control brightness of the leds.

Mike