Blinking and Dimming Several LEDs at the Same Time

I have this code:

//LED Patterns
int L1 = 23;
int L2 = 22;
int L3 = 21;
int L4 = 20;
int L5 = 19;
int L6 = 18;
int L7 = 17;  
int L8 = 16;  
int L9 = 15;  
int L10 = 14;  


int buttonPin = 39;  //the number of the pushbutton pin

int de=50;  // delay time

int p=0;    // variable for pattem

int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  

  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT);
  pinMode(L4, OUTPUT);
  pinMode(L5, OUTPUT);
  pinMode(L6, OUTPUT);
  pinMode(L7, OUTPUT);
  pinMode(L8, OUTPUT);
  pinMode(L9, OUTPUT);
  pinMode(L10, OUTPUT);
  
  pinMode(buttonPin, INPUT);

}

void loop() 
{
 buttonState = digitalRead(buttonPin);

 if (buttonState == HIGH)
 
    {
      p++;
      delay(100);
    } 
 
  if(p==1)
  {
 digitalWrite(L1,1); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de);  
  
 digitalWrite(L1,0); 
 digitalWrite(L2,1); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,1); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,1); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,1); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,1); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,1); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 

 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,1); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de); 

 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,1); 
 digitalWrite(L10,0); 
  delay(de); 

 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,1); 
  delay(de); 
  }
             
}

It is part of a longer code I put together to emulate Christmas Tree lights. I show you only this part for proof of concept.

I'm struggling to incorporate a Potentiometer input into the code which can dim/brighten the lights without interuppting the blinking patterns. I've tried several variations but they either end up blocking or changing the lights to be constant.

One attempt was this:

//LED Patterns
int L1 = 23;
int L2 = 22;
int L3 = 21;
int L4 = 20;
int L5 = 19;
int L6 = 18;
int L7 = 17;  
int L8 = 16;  
int L9 = 15;  
int L10 = 14;  


int buttonPin = 39;  //the number of the pushbutton pin
[b]int potPin = 38;[/b]

int de=50;  // delay time

int p=0;    // variable for pattem

int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  

  pinMode(L1, OUTPUT);
  pinMode(L2, OUTPUT);
  pinMode(L3, OUTPUT);
  pinMode(L4, OUTPUT);
  pinMode(L5, OUTPUT);
  pinMode(L6, OUTPUT);
  pinMode(L7, OUTPUT);
  pinMode(L8, OUTPUT);
  pinMode(L9, OUTPUT);
  pinMode(L10, OUTPUT);
  
  pinMode(buttonPin, INPUT);
  [b]pinMode(potPin, INPUT);[/b]

}

void loop() 
{
 buttonState = digitalRead(buttonPin);
 [b]potPinValue = analogRead(potPin);[/b]

 if (buttonState == HIGH)
 
    {
      p++;
      delay(100);
    } 
 
  if(p==1)
  {
 digitalWrite(L1,1);
 [b]analogWrite(L1, potPinValue/4); [/b] <-- do this every time a light is ON.
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
 digitalWrite(L4,0); 
 digitalWrite(L5,0); 
 digitalWrite(L6,0); 
 digitalWrite(L7,0); 
 digitalWrite(L8,0); 
 digitalWrite(L9,0); 
 digitalWrite(L10,0); 
  delay(de);  

....
             
}

But of course it just blocks.

Is there anyway to add a potentiometer on another pin and dim the LEDs. The request is also that the delay stays (can this be done using delays?). I will move onto states in my next hobby project. I already know that delays are bad, but I like to start from the ground up and work at more and more eloquent tasks.

TL;DR
I'm trying to blink LEDs (using a set delay pattern) and dim them using a potentiometer at the same time. How can I go about doing this?

Many thanks!

Never ever use delay() in your sketches.

Well, you can if you know what the drawbacks will be.

delay() stops regular code execution for the delay interval.
You can replace delay() with a technique called Blink Without Delay, BWD.
When using BWD, your sketch can run other code during the delay time.
Read Robin2’s discussion, Demonstration code for several things at the same time:
https://forum.arduino.cc/index.php?topic=223286.0

Why not put the LEDs on the PWM pins, and then
analogWrite(pin, value);
the brightness level you want?
Hold each level for as long as needed for the transition.

CrossRoads:
Why not put the LEDs on the PWM pins, and then
analogWrite(pin, value);
the brightness level you want?
Hold each level for as long as needed for the transition.

Some of them are and some of them are not. I'll need to change the wires around as I'm using a Teensy 3.5.

I did attempt AnalogWrite with one of the pins (Pin 23 is a PWM pin) but it just overwrote the part of the code that made it blink:

digitalWrite(L1,1); <-- This switches on the LED for about 50ms before switching on the next LED
analogWrite(L1, potPinValue/4); <-- This controls the brightness

Surely this can't be what you meant?

What do you mean by "Hold each level as long as needed for the transition"?

larryd:
Never ever use delay() in your sketches.

Well, you can if you know what the drawbacks will be.

delay() stops regular code execution for the delay interval.
You can replace delay() with a technique called Blink Without Delay, BWD.
When using BWD, your sketch can run other code during the delay time.
Read Robin2’s discussion, Demonstration code for several things at the same time:
Demonstration code for several things at the same time - Project Guidance - Arduino Forum

Hi, thanks for your reply. I made a code about a month ago that blinks LEDs using Millis and I used a Potentiometer to slowly turn off the LEDs one by one. I think I can recycle that code and have the Potentiometer control brightness instead.

But honestly I'd prefer to use delay() for now as I'm really trying to work my way from the ground up again and I've already committed to using delay(). My next project was going to actually be leaving delay() behind for good, I just don't want to do it on this particular Christmas Light project.

I did download the code in the link and I'm looking through it, I can see how states enable you to do many things at once. So thanks.

It would help you tremendously if you learned to use arrays, it would cut out all the tedious repeating of stuff. For example first define your pin numbers as an array, then you can use a for loop to go through them:-

int led [] = {23,22,21,20,19,18,17,16,15,14};

Then in the setup function you can do:-

for(int i; i<10;i++){
   pinMode(led[i], OUTPUT);
}

Now write a function to turn all the LEDs off:-

void allOff(){
  for(int i; i<10;i++){
   digitalWrite(led[i], 0);
}
}

Now to replace all that tedious stuff in the if statements:-

  if(p==1)
  {
 digitalWrite(L1,1);
 digitalWrite(L2,0);
 digitalWrite(L3,0);
 digitalWrite(L4,0);
 digitalWrite(L5,0);
 digitalWrite(L6,0);
 digitalWrite(L7,0);
 digitalWrite(L8,0);
 digitalWrite(L9,0);
 digitalWrite(L10,0);
  delay(de);

becomes simply:-

  if(p==1)
  {
      allOff()
     digitalWrite(led[0],1);
     delay(de);
}

Hi Mike,

Thank you for your educational reply. Could you explain this part of the code:

  if(p==1)
  {
      allOff()
     digitalWrite(led[0],1);
     delay(de);
}

I'm a novice/intermediate Python programmer. I can't see how this bit of code cycles through all the lights to make them blink one by one. Unless allOff() is a function that calls this entire block of code:

void allOff(){
  for(int i; i<10;i++){
   digitalWrite(led[i], 0);
}
}

? But that part of the code looks like its switching all the lights off. How does digitalWrite(led[0],1); now know how to switch them back on one after the other? There is no 'i' in it.

I can't see how this bit of code cycles through all the lights to make them blink one by one.

It doesn’t, It is simply replacing all the lines of code you had in that part of the code.

But that part of the code looks like its switching all the lights off

Yes that is what it does.
I was showing how you don’t have to keep on repeating all those lines that look almost the same.

How does digitalWrite(led[0],1); now know how to switch them back on one after the other? There is no 'i' in it.

That line switches on led zero, the first led in the list.

My code did not attempt to change what your code does. It shows you the changes you need to make to your code in order to make it bearable to read.

I'm struggling to incorporate a Potentiometer input into the code which can dim/brighten the lights without interuppting the blinking patterns. I've tried several variations but they either end up blocking or changing the lights to be constant.

split it in simple tasks

  • read a potentionemter
  • set a PWM Value to the given ADC Read out
  • Blink a LED (or many LEDs) between dark(off) and the calculated PWM value

is that correct?
If not describe your feature in your own words in as short sentences as you can.

noiasca:
split it in simple tasks

  • read a potentionemter
  • set a PWM Value to the given ADC Read out
  • Blink a LED (or many LEDs) between dark(off) and the calculated PWM value

is that correct?
If not describe your feature in your own words in as short sentences as you can.

That makes alot of sense actually.. Because I was blinking the LEDs using 0 & 1. But they are connected to PWM pins so I can set those pins to a voltage I want based on the reading from the potentiometer.

HMM.

Are there tutorials on how to set a PWM value? Actually I think I know how to do this already, I already know how to dim an LED using a Potentiometer. Its probably this part I have trouble with:

"Blink a LED (or many LEDs) between dark(off) and the calculated PWM value"

Because setting the PWM value means they won't blink. I'm sure its because of the delays() but there has got to be a way to bruteforce it to work (however unelegant it might be) without resorting to millis().

Many thanks for your enlightenment.

if these 3 steps are true, just combine what's given

the hints grumpy gave already.

and then you might come up with something like

const int adcPin = A1;
//const int led [] = {23, 22, 21, 20, 19, 18, 17, 16, 15, 14};
const int led [] = {3, 5, 6, 9, 10, 11, 3, 5, 6, 9};  // on UNO only  3, 5, 6, 9, 10 und 11.
const byte numberOfLeds = 10;
byte ledState = LOW;             // ledState used to set the LED
unsigned long previousMillis = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)
const int adcResolution = 1024;
const int pwmResolution = 256;

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Blink Without Delay PWM LEDs"));
  for (byte i; i < numberOfLeds; i++) {
    pinMode(led[i], OUTPUT);
  }
  pinMode(adcPin, INPUT);
}

void loop()
{
  //read a potentionemter
  int adc = analogRead(adcPin);
  //Blink a LED (or many LEDs) between dark and the calculated PWM value
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    // if the LED is off turn it on and vice-versa:
    int pwmToSet = 0;
    if (ledState == LOW) {
      ledState = HIGH;
      //set a PWM Value to the given ADC Read out
      pwmToSet = map(adc, 0, adcResolution - 1, 0, pwmResolution - 1);
      Serial.print(F("adc=")); Serial.print(adc);
      Serial.print(F("   pwmToSet=")); Serial.println(pwmToSet);
    } else {
      ledState = LOW;
      Serial.println(F("all LEDs off"));
    }
    // set the LED with the ledState of the variable:

    for (byte i = 0; i < numberOfLeds; i++) {
      //digitalWrite(led[i], ledState);  // no we don't want to write on, off any more
      analogWrite(led[i], pwmToSet);
    }
  }
}

This code is non optimized in any way, to keep it as consistent with the existing examples as possible.

If you don't understand a line - asking is still allowed after you have checked the examples and Google.

You will even find the 3 lines of "feature requests" as comments in the code. This is to show you how to elaborate a "program". Define what's wanted, bring it in an order and finally code it. If you are not good in coding - try to reuse as many examples as possible. The IDE comes with tons of examples for you.

Very similar topic here