How to Blink LEDs and Dim them at the same time using a Potentiometer - delay()

At this point, I'd just like an answer so I can memorize it. I've been stuck on this for 2 days now trying every variation. My code is to make Christmas lights. I have here a shortened version with just 3 of the lights and only 1 pattern for proof of concept:

//LED Patterns
int L1 = 23;
int L2 = 22;
int L3 = 21;


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

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);
  pinMode(potPin, INPUT);
  Serial.begin(9600);

}

void loop() 
{
 Serial.println(potPin);
 buttonState = digitalRead(buttonPin);
 int potPinValue = analogRead(potPin);

 if (buttonState == HIGH)
 
    {
      p++;
      delay(100);
    } 
 
  if(p==1)
  {
 digitalWrite(L1,1); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
  delay(de);  
  
 digitalWrite(L1,0); 
 digitalWrite(L2,1); 
 digitalWrite(L3,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,1); 
  delay(de); 

  }
             
}

As you can tell, 3 lights blink one after the other using delay(). p is a variable that increases everytime I push the button and it takes 100ms to switch to the next pattern. But I have not included the other patterns here so that we can focus on getting the potentiometer to work. I'd like to also dim/brighten them using a potentiometer whilst they are blinking. How can this be done?

Please don't tell me not to use delay() and to use state/millis() instead. I know this already, but for my own learning I want to see that delay() can be used and why it shouldn't be used afterwards. I know delay() blocks code and prevents consecutive code from being run during the time period. But I want to know whether it can be done on this code, so I can write a discussion on why it shouldn't be used and why millis/blink without delay is much better.

Many thanks for all your help and tutelage.

I know delay() blocks code and prevents consecutive code from being run during the time period.

There is your answer

Make your delays shorter, but use more of them.
Inbetween the delays, do more stuff.

At some point, you'll realise that the delays are so short, they may as well not be there at all.

AWOL:
Make your delays shorter, but use more of them.
I between the delays, do more stuff.

At some point, you'll realise that the delays are so short, they may as well not be there at all.

I'm putting "analogWrite(L1, potPinValue/4);" in the same block as the digitalWrite blink sequences, but it seems to just overwrite anyway.

Can you go into abit more depth? Preferably with an example please?

UKHeliBob:
There is your answer

So is there no way at all to have the Potentiometer dim the LEDs whilst they blink? The potentiometer is not exactly a "timed" event... yet it still just overwrites everything I do.

Could you enlighten me please?

FloatingWatcher:
So is there no way at all to have the Potentiometer dim the LEDs whilst they blink? The potentiometer is not exactly a "timed" event... yet it still just overwrites everything I do.

Could you enlighten me please?

What do you mean about it overwriting? You never use the value you read from it. You read a value, store it in a variable and then never use that variable for anything. You have to actually write some code for the pot to do anything. If you want what you describe then there should be an analogWrite in there somewhere.

FloatingWatcher:
So is there no way at all to have the Potentiometer dim the LEDs whilst they blink? The potentiometer is not exactly a "timed" event... yet it still just overwrites everything I do.

Could you enlighten me please?

Of course you can have a pot dim the LEDs whilst they blink. Using millis() for timing would allow you to read the pot frequenty to update the brightness of the LEDs

Delta_G:
What do you mean about it overwriting? You never use the value you read from it. You read a value, store it in a variable and then never use that variable for anything. You have to actually write some code for the pot to do anything. If you want what you describe then there should be an analogWrite in there somewhere.

I mention in a reply that I used analogWrite(LED, potentiometervalue); within the same code block as the blink pattern. All it did was overwrite the blinking of the LED I was dimming/brightening.

Start with the BlinkWithoutDelay example.

Read the pot each time through loop(). Change the program so that the value derived from analgRead() is written to the LED on each pass through loop() when the LED state indicates that it is turned on, otherwise write 0 to it. Use analogWrite() instead of digitalWrite() to control the LED and use a pin that is PWM enabled.

FloatingWatcher:
I mention in a reply that I used analogWrite(LED, potentiometervalue); within the same code block as the blink pattern. All it did was overwrite the blinking of the LED I was dimming/brightening.

Show that code.

FloatingWatcher:
I mention in a reply that I used analogWrite(LED, potentiometervalue); within the same code block as the blink pattern. All it did was overwrite the blinking of the LED I was dimming/brightening.

So you have some code that you want help with. But instead of posting that code you posted some other code that you didn’t need help with. How smart is that? Coding is a game for people that think.

Delta_G:
How smart is that? Coding is a game for people that think.

If everyone was good at coding, do you think there would be a help forum? For the record, I'm a Plasma Physicist (PhD) as well as I'm a simulations expert (Comsol and Opera3D). I'm crap at programming code though. Its nothing about my intelligence, I'm not a natural programmer nor do I consistently program.

//LED Patterns
int L1 = 23;
int L2 = 22;
int L3 = 21;


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

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(buttonPin, INPUT);
  pinMode(potPin, INPUT);
  Serial.begin(9600);

}

void loop() 
{
 Serial.println(potPin);
 buttonState = digitalRead(buttonPin);
 int potPinValue = analogRead(potPin);

 if (buttonState == HIGH)
 
    {
      p++;
      delay(100);
    } 
 
  if(p==1)
  {
 analogWrite(L1, potentiometervalue/4);
 digitalWrite(L1,1); 
 digitalWrite(L2,0); 
 digitalWrite(L3,0); 
  delay(de);  
  
 digitalWrite(L1,0); 
 digitalWrite(L2,1); 
 digitalWrite(L3,0); 
  delay(de); 
  
 digitalWrite(L1,0); 
 digitalWrite(L2,0); 
 digitalWrite(L3,1); 
  delay(de); 

  }
             
}

^ This is what I was referring to. I put an analogWrite in the same code block as the blink patterns, but it overwrites the blinking of the LED that I want to dim. Turning the potentiometer does dim/brighten it, but it no longer blinks. The pins are all on PWM.

Let's look at some of your code

int L1 = 23;

From the pin number I assume that you are using a Mega
Pin 23 on a Mega is not a PWM pin so can only output a digital (HIGH or LOW) signal

 analogWrite(L1, potentiometervalue/4);
 digitalWrite(L1,1);

Here you use the analogWrite() function to write a value to a non PWM pin so that is not going to work as expected. Then you write 1 (ie HIGH ) to the same pin using digitalWrite() Is that likely to work ? The pin, even if it were a PWM pin, cannot do 2 things at the same time.

I appreciate that you are not a programmer but surely getting your PhD required logical thinking and it is illogical to expect the pin to do 2 different things at the same time even if it were capable of doing either of them.

Suppose that I told you to turn the dimmer on a lamp to half brightness then a couple of microseconds later to turn the lamp off. Would you be surprised if it were not on at half brightness ?

You will get plenty of help here but you must be prepared to listen to advice. You appear to know that the best way to do what you want involves using millis() for timing but you don't seem to like that answer.

FloatingWatcher:
If everyone was good at coding, do you think there would be a help forum? For the record, I'm a Plasma Physicist (PhD) as well as I'm a simulations expert (Comsol and Opera3D). I'm crap at programming code though. Its nothing about my intelligence, I'm not a natural programmer nor do I program.

It’s not about your programming skill. You don’t need to be a programmer to understand that if you want help with a piece of code then you need to show the piece you need help with. Any idiot could understand that.

When you have a problem with your car do you take your friends car to the mechanic? No, you bring the car that has the problem. That’s not something you need to be good at programming to understand. That just takes basic intelligence.

UKHeliBob:
Let's look at some of your code

int L1 = 23;

From the pin number I assume that you are using a Mega
Pin 23 on a Mega is not a PWM pin so can only output a digital (HIGH or LOW) signal

 analogWrite(L1, potentiometervalue/4);

digitalWrite(L1,1);



Here you use the analogWrite() function to write a value to a non PWM pin so that is not going to work as expected. Then you write 1 (ie HIGH ) to the same pin using digitalWrite() Is that likely to work ? The pin, even if it were a PWM pin, cannot do 2 things at the same time.

I appreciate that you are not a programmer but surely getting your PhD required logical thinking and it is illogical to expect the pin to do 2 different things at the same time even if it were capable of doing either of them.

Suppose that I told you to turn the dimmer on a lamp to half brightness then a couple of microseconds later to turn the lamp off. Would you be surprised if it were not on at half brightness ?

You will get plenty of help here but you must be prepared to listen to advice. You appear to know that the best way to do what you want involves using millis() for timing but you don't seem to like that answer.

"I appreciate that you are not a programmer but surely getting your PhD required logical thinking and it is illogical to expect the pin to do 2 different things at the same time even if it were capable of doing either of them."

Please don't do this. I came here to learn and to upskill. Not to have my intelligence questioned. I'm using a Teensy 3.5. Pin 23 is PWM. (https://images.app.goo.gl/79FXxfvJM8qXARD98). And I was questioning not whether it can do 2 things at the same time, but if it can do it one after the other. Why can't I spend a few milliseconds modulating the power to the pin, then have it blink as normal a few milliseconds later? So my mind is telling me that the problem is that its in the loop and it KEEPS modulating, thereby overwriting the blink part on that LED. Is there a way to not have this happen? I can do it with millis() yes, is it possible to do it with delay() however horrible the code may be? That is a learning experience for me and I'd like to have it. I'm a hobbyist, this isn't school work so I have time to learn every nook and cranny.

"Suppose that I told you to turn the dimmer on a lamp to half brightness then a couple of microseconds later to turn the lamp off. Would you be surprised if it were not on at half brightness ?"

Can the LED not blink at a lower PWM value that I set with the Potentiometer though? I can already fade an LED using a pot, so surely I can use a pot to set a PWM value to a lower value as it blinks? I appreciate that the code I wrote just turns it off, but its supposed to come back on again in a few ms at a lower power.

"You appear to know that the best way to do what you want involves using millis() for timing but you don't seem to like that answer."

Like I mentioned, I wrote a code that blinked lights using millis() and I used use a pot to dim them or turn off the lights 1 by 1 whilst others were still blinking. So yes I know I can use millis(). But I'm doing a youtube series where I start electricity, electronics and coding from scratch. I'm 4 videos in and I haven't talked about millis(). The last video was using delays(), a potentiometer and fading an LED. I wanted to capitalize on that by building Christmas Lights and showing people how use a pushbutton to change the patterns on the Christmas Lights. I've done this. But I thought it would be interesting to show how you can dim the lights too whilst blinking.

If I introduce Millis() in the video, I've jumped without explaining why its better to use millis(). The christmas light presents an example where delay() can be used, but due to its clunkiness and difficulty, why we will use millis() from here on out. I had that lesson in mind both to cement the learning to myself, and to teach others.

That is why I'm intent on seeing if delay() can be used in this situation.

analogWrite(L1, potentiometervalue/4);
 digitalWrite(L1,1);

You tell it to write the analog value and then less than a microsecond later you tell it to turn the pin on full. You didn’t leave it at the analog level long enough to see it. If you don’t want to write the pin high, then maybe you should take out that digitalWrite line that writes it high.

If you don’t understand that then please stop trying to instruct others. We have enough trouble with people who only half know this stuff filling people with bad information that e then have to clear up.

Would you have a lay person teaching physics? Or would you have someone trained in physics? You need to have at least a basic understanding of something if you want to be able to teach it.

Also, if you’re teaching then please press control-T and format that code. It’s atrocious. Please don’t teach people to write code all over the place like that. If you’re going to teach it then you need to learn it yourself first.

Delta_G:

analogWrite(L1, potentiometervalue/4);

digitalWrite(L1,1);




You tell it to write the analog value and then less than a microsecond later you tell it to turn the pin on full. You didn’t leave it at the analog level long enough to see it. If you don’t want to write the pin high, then maybe you should take out that digitalWrite line that writes it high.

I actually took out the digitalWrite in another test example, it still seemed not to blink. I'll try again...

...Through the magic of time.... :

void loop() 
{
 Serial.println(potPin);
 buttonState = digitalRead(buttonPin);
 int potPinValue = analogRead(potPin);
 
 
 if (buttonState == HIGH)
 
    {
      p++;
      delay(100);
      
    } 
    
  if(p==1)
  {
 analogWrite(L1,potPinValue/4); 
 analogWrite(L2,0); 
 analogWrite(L3,0); 
 delay(50);  
  
 analogWrite(L1,0); 
 analogWrite(L2,potPinValue/4); 
 analogWrite(L3,0); 
 delay(50); 
  
 analogWrite(L1,0); 
 analogWrite(L2,0); 
 analogWrite(L3,potPinValue/4); 
 delay(50); 

 }

All 3 LEDs blink and recieve their powerlevels from the Potentiometer such that they dim and blink all at the SAME TIME. There is no delay at all. This is what I attempted to do before but due to work (I've been doing simulation alot recently) and a combination of other things, I was too frustrated to think straight.

Coming here and just being schooled helped me iron things out. So thank you, I've learnt something. In my next lesson I can now introduce millis(). For now, I will clean up and tidy the code to make it more succint, such as using an array for all 10 LEDs and such.

Kind regards and once again, thanks!

congratulation - you just wasted time of others with your cross post

I really hope one of the admins bans you for a couple of weeks.

noiasca:
congratulation - you just wasted time of others with your cross post

How to Blink LEDs and Dim them at the same time using a Potentiometer - delay() - Programming Questions - Arduino Forum
Blinking and Dimming Several LEDs at the Same Time - LEDs and Multiplexing - Arduino Forum

I really hope one of the admins bans you for a couple of weeks.

You're the second person to write me this sort of passive aggressive post. In the other thread, people started talking about millis() when I specifically stated that I didn't want to use millis(). What I got from that other thread however, were tips to make my code more succint. I made another thread here because I figured it was more a programming issue since I was using delay() and whether someone with programming experience could shed a greater light. I have learnt from BOTH threads.

The hell is wrong with you all? I'm not holding you to ransom nor am I trashing any advice you gave. As it happens, both combined threads helped to understand some important differences between analogWrite and digitalWrite. It also helped me cement (through theory) how the loops work, how time works and how each line of code is played out. It also helped me to understand how to write better code.

I'm a Physics and Maths tutor in my spare time and I teach up to 1st year university level, I have NEVER reprimanded someone for not knowing something even they show me they want to learn - however many questions they ask. Its highly infuriating to see it here.

FloatingWatcher:
You're the second person to write me

If I'm the second one, just think about what YOU might have done wrong.

Have you ever read the "Read this before posting a programming question"?

Don't double-post (cross-post). Your question will be noticed. If you post it in multiple places you will just annoy people who might otherwise have answered.

ok, I will give you a link to read Read this before posting a programming question ... - Programming Questions - Arduino Forum

Compare the timestamps of the posts in the two threads. Very similar answers from different people to the same question. I wasted my spare time for nothing.

Can you now understand why cross posts are an absolute no go?


Warning: this is a cross post: Blinking and Dimming Several LEDs at the Same Time - LEDs and Multiplexing - Arduino Forum