Pushbutton

Hi! I am having some problems. I have multiple LEDs and one pushbutton. I want to push the button and 1 led turns on and off, i then push the button again and the next led turns on and off, push the button and the next turns on and off... Besides this i also want to be able to push the button for 3 seconds and instead of going to the next led, the same led turns on and off. I have tried several programs but they dont work. I could use your help

It's a forum for help, not whole programs. A bit of effort from you side is required. So what have you tried so far? What went wrong with that? etc

Joan_Saints: Hi! I am having some problems. I have multiple LEDs and one pushbutton. I want to push the button and 1 led turns on and off, i then push the button again and the next led turns on and off, push the button and the next turns on and off... Besides this i also want to be able to push the button for 3 seconds and instead of going to the next led, the same led turns on and off. I have tried several programs but they dont work. I could use your help

Sounds like a school assignment.

If it isn't, I would use two pushbuttons to make it easy on myself. One that cycles through the LEDs and one that does the 3 seconds on/off.

Post your code as you have it. We help people fix code, but we don't write it for them.

If it's a school assignment, that's OK. We will help you with that too, but you have to do the work. We will nudge you in the right direction and make sure you are learning what the assignment wants you to learn (which is what the teacher wants too).

Until now I have this (and I’m using a led driver whose output is the inverse of the input):
int ledPins={0,1,2,3,4,5,6,7,8,9,10,11,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; //44 LEDs
int buttonPin=12;
float pressLength_milliSeconds = 0;
int nextled_milliSeconds = 100;
int sameled_milliSeconds = 2000;

void setup() {
int index;
digitalWrite(ledPins[index],HIGH);//turns off the leds initially
pinMode(buttonPin,INPUT);

for(index=0;index<=43;index++)
{
pinMode(ledPins[index],OUTPUT);
}
}

void loop()

{ int index;
int buttonState;
buttonState=digitalRead(buttonPin);
while (digitalRead(buttonPin) == LOW ){
delay(100);
pressLength_milliSeconds = pressLength_milliSeconds + 100; }

if (pressLength_milliSeconds >= sameled_milliSeconds){
digitalWrite(ledPins[index], LOW);

}

else if(pressLength_milliSeconds >= nextled_milliSeconds){

for(index=0;index<=43;index++){
digitalWrite(ledPins[index],LOW);//turns the led on
delay(3000);
digitalWrite(ledPins[index],HIGH);//turns the led off
delay(1000);
}

}
pressLength_milliSeconds = 0;
}

May I refer to my signature?

int ledPins[]={0,1,2,3,4,5,6,7,8,9,10,11,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; //44 LEDs
int buttonPin=12;
float pressLength_milliSeconds = 0;
int nextled_milliSeconds = 100;
int sameled_milliSeconds = 2000;

void setup() {
  int index;
  digitalWrite(ledPins[index],HIGH);//turns off the leds initially
  pinMode(buttonPin,INPUT);
 
  for(index=0;index<=43;index++)
  {
    pinMode(ledPins[index],OUTPUT);
  }
}
 
void loop()

 { int index;
  int buttonState;
   buttonState=digitalRead(buttonPin);
   while (digitalRead(buttonPin) == LOW ){
      delay(100); 
      pressLength_milliSeconds = pressLength_milliSeconds + 100; }

   if (pressLength_milliSeconds >= sameled_milliSeconds){
       digitalWrite(ledPins[index], LOW);     
 
  }
 
  else if(pressLength_milliSeconds >= nextled_milliSeconds){
 
    for(index=0;index<=43;index++){
    digitalWrite(ledPins[index],LOW);//turns the led on
    delay(3000);
    digitalWrite(ledPins[index],HIGH);//turns the led off
    delay(1000);
   } 
 
  }
  pressLength_milliSeconds = 0;
}

At least you’re using an array! Great job. Now make them a const byte and that part is fine (save memory :wink:

But

digitalWrite(ledPins[index],HIGH);//turns off the leds initially

Does not work. And is there a special reason you have the leds connected between Vcc and the pin? Try

for(byte i = 0; i < (sizeof(ledPins)/sizeof(ledPins[0]))l i++){
  pinMode(ledPins[i], OUTPUT);
  digitalWrite(ledPins[i], HIGH);
}

You can skip the /sizeof(ledPins[0] if you made ledPins a byte.

Next step is to ban delay() :wink: User input and delay’s don’t mix that well. Have a look at blink without delay :slight_smile:

And to make life easy, just use a library like Bounce2 to take care of the button.

float pressLength_milliSeconds = 0;

pressLength_milliSeconds should be an unsigned long, not a float.

pick one “{}” style and use it consistently to make your code more readable.

Here’s your code cleaned up (notice you can declare the variable type the first time you use it. It doesn’t need to be a separate declaration):

const byte ledPins[]={0,1,2,3,4,5,6,7,8,9,10,11,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53}; //44 LEDs
const byte buttonPin=12;
unsigned long pressLength_milliSeconds = 0;
unsigned int nextled_milliSeconds = 100;
unsigned int sameled_milliSeconds = 2000;

void setup() 
{
    pinMode(buttonPin,INPUT);

    for(int index=0;index<=43;index++)
    {
        pinMode(ledPins[index],OUTPUT);
        digitalWrite(ledPins[index],HIGH);//turns off the leds initially
    }
}

void loop()
{ 
    int buttonState=digitalRead(buttonPin);
    while (digitalRead(buttonPin) == LOW)
    {
        delay(100);
        pressLength_milliSeconds = pressLength_milliSeconds + 100; 
    }

    if (pressLength_milliSeconds >= sameled_milliSeconds)
    {
        digitalWrite(ledPins[index], LOW);    
    }
    else if (pressLength_milliSeconds >= nextled_milliSeconds)
    {
        for (int index=0;index<=43;index++)
        {
            digitalWrite(ledPins[index],LOW);//turns the led on
            delay(3000);
            digitalWrite(ledPins[index],HIGH);//turns the led off
            delay(1000);
        }
    }
    pressLength_milliSeconds = 0;
}

Remove delay() at least in the button timing loop, and use millis() instead.

You don’t want to do this:

        for (int index=0;index<=43;index++)
        {
            digitalWrite(ledPins[index],LOW);//turns the led on
            delay(3000);
            digitalWrite(ledPins[index],HIGH);//turns the led off
            delay(1000);
        }

In your case, when the button is pressed you want to turn the next led on then off, then wait for another button press.

The loop gets called continuously, and is where you check for a button press.

So, you need to store the last led number that was turned on/off, and increment it every time a button is pressed, then turn that led on/off.

Replace the for loop with something like (I’ll leave it up to you to replace the delays with millis() calls if you want to do that):

        digitalWrite(ledPins[index],LOW);//turns the led on
        delay(3000);
        digitalWrite(ledPins[index],HIGH);//turns the led off
        delay(1000);
        index = (index + 1) % 44; // use modulo operator to reset the index to 0 after it gets to 43.

you will need to create a new global variable (before the loop()) to store the current LED index number:

unsigned byte index = 0;

and create a constant at the top of the program to use instead of 43/44 so you don’t have 43/44 as a hard-coded number throughout your program.

Thanks for the help. I will try this tomorrow and see if it works

@Join_Saints: Please edit your post, select the code, and put it between [code][/code] tags.

You can do that by hitting the “Code” icon above the posting area. It is the first icon, with the symbol: </>

How to use this forum


void setup() {
  int index;
  digitalWrite(ledPins[index],HIGH);//turns off the leds initially

That does not do that. The value of index is undefined at this point, so the third line there makes one (random) pin go HIGH (possibly no pins at all if index is out of the range 0 to 43).