Cycling LEDs with a button

Ok, so this is a really simple question, and I know the solution is going to be obvious, but I keep finding myself baffled. Basically, all I need to do Is write a code that utilizes the push of a button to cycle through 9 LEDs. Pushing the button initially should turn on LED 1, pause for 3 seconds, then turn on LED 2 and turn off LED 1. This should continue all through all 9 LEDs. If the button is pushed again during this cycle, the currently lit LED should remain lit until the button is pushed again. Also, in order for this code to work in parallel with some code I have already finished, this new code must be written using a case switch statement. Any and all help is greatly appreciated. Thanks.

So you have code already that you're not going to post? Makes it pretty difficult to help...

Also, in order for this code to work in parallel with some code I have already finished, this new code must be written using a case switch statement.

"In parallel" implies that you need to compare the time a-la the [u]blink without delay[/u] example, and avoid using delay().

Switch/case might work, but from what you've told us that shouldn't be necessary... Every time you "make a decision" (Is the button pushed? Is the time up?) there are only two possible "answers," so a regular if-statement (or if-else) should do the trick. You normally use switch/case when there are many possible conditions (or "answers") and you need to choose one of them.

I apologize for my lack of clarity and forethought in my initial post. Hopefully this post will clear up any confusion and provide an idea of what this project is supposed to do. Here is my current code:

const int ledPin1 = 5;
const int ledPin2 = 6;
const int ledPin3 = 7;
const int ledPin4 = 8;
const int ledPin5 = 9;
const int ledPin6 = 10;

const int buttonPin = 3;
const int modePin = 2;

int led = 1;

int prevUp = HIGH;

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

void loop(){
  if( digitalRead(modePin == HIGH)){
  
  int currUp = digitalRead(buttonPin);
  if(currUp != prevUp)
  {
    if(currUp == LOW)
    led++;
    if (led >7) led = 1;
  }
  prevUp = currUp;
}
  
  else{
  int currUp = digitalRead(buttonPin);
  if(currUp != prevUp)
  {
    if(currUp == LOW)
    //Statement that will cycle through all cases with a 3 second delay
    if (led >7) led = 1;
  }
prevUp = currUp;
}

switch (led){
  case 1:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 2:
  analogWrite(ledPin1, 255);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 3:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 255);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 4:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 255);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 5:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 255);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 6:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 255);
  analogWrite(ledPin6, 0);
  break;
  
    case 7:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 255);
  break;
}
}

As you can see, I have a master toggle switch that determines which mode the LED's will cycle in (single or automatic). Mode 1 (single) is my working code. Every time i push the button, the case increases by one, as it should. The case switch statement is used because i want to be able to modify the brightness of all the "off" LED's. Mode 2 (automatic) should cycle through all the cases, then reset to a neutral state. If the button is pushed during this cycle, the LED should remain lit until the next button push. I've put a comment in the code where the function that will cycle the cases should go.

TL;DR The missing code needs to do the following: 1) Pushing the button once should cycle through all the cases from 1-7 with a 3 second delay on each case. 2) It should then reset to case 1 (no lights) and wait for a button push. 3) If the button is pushed while an LED is lit, that LED should freeze and stay lit. 4) Pushing the button again while an LED is frozen should reset to case 1 and wait for a button push.

I am working on a project that is supposed to light up 6 different panels on a wall mounted board individually. Currently i am using an inventors kit to prototype my code before i start buying parts or anything like that. However, i have run into some issues with an automatic cycling feature. I was hoping someone could give me some guidance and help me solve my problem. Any help is greatly appreciated.
Here is my current code:

const int ledPin1 = 5;
const int ledPin2 = 6;
const int ledPin3 = 7;
const int ledPin4 = 8;
const int ledPin5 = 9;
const int ledPin6 = 10;

const int buttonPin = 3;
const int modePin = 2;

int led = 1;

int prevUp = HIGH;

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

void loop(){
  if( digitalRead(modePin == HIGH)){
  
  int currUp = digitalRead(buttonPin);
  if(currUp != prevUp)
  {
    if(currUp == LOW)
    led++;
    if (led >7) led = 1;
  }
  prevUp = currUp;
}
  
  else{
  int currUp = digitalRead(buttonPin);
  if(currUp != prevUp)
  {
    if(currUp == LOW)
    //Statement that will cycle through all cases with a 3 second delay
    if (led >7) led = 1;
  }
prevUp = currUp;
}

switch (led){
  case 1:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 2:
  analogWrite(ledPin1, 255);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 3:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 255);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 4:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 255);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 5:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 255);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 0);
  break;
  
    case 6:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 255);
  analogWrite(ledPin6, 0);
  break;
  
    case 7:
  analogWrite(ledPin1, 0);
  analogWrite(ledPin2, 0);
  analogWrite(ledPin3, 0);
  analogWrite(ledPin4, 0);
  analogWrite(ledPin5, 0);
  analogWrite(ledPin6, 255);
  break;
}
}

As you can see, I have a master toggle switch that determines which mode the LED’s will cycle in (single or automatic). Mode 1 (single) is my working code. Every time i push the button, the case increases by one, as it should.
The case switch statement is used because i want to be able to modify the brightness of all the “off” LED’s.
Mode 2 (automatic) should cycle through all the cases, then reset to a neutral state. If the button is pushed during this cycle, the LED should remain lit until the next button push.
I’ve put a comment in the code where the function that will cycle the cases should go.

TL;DR
The missing code needs to do the following:

  1. Pushing the button once should cycle through all the cases from 1-7 with a 3 second delay on each case.
  2. It should then reset to case 1 (no lights) and wait for a button push.
  3. If the button is pushed while an LED is lit, that LED should freeze and stay lit.
  4. Pushing the button again while an LED is frozen should reset to case 1 and wait for a button push.

Let’s get rid of those dozens of analogWrites:

const byte pinCount = 6;
const byte ledPins [pinCount] = { 5, 6, 7, 8, 9, 10 };

const int buttonPin = 3;
const int modePin = 2;

int led = 1;

int prevUp = HIGH;

void setup()
  {
  pinMode (buttonPin, INPUT);
  pinMode (modePin, INPUT); 
  }  // end of setup

void turnOnLED (const byte which, const byte brightness)
  {
  for (byte i = 0; i < pinCount; i++)
    analogWrite (ledPins [i], 0);
  
  if (which > 1)
    analogWrite (ledPins [which - 2], brightness);  // make "which" zero-relative
  }  // end of turnOnLED
  
void loop()
  {
  if( digitalRead(modePin == HIGH)){

    int currUp = digitalRead(buttonPin);
    if(currUp != prevUp)
    {
      if(currUp == LOW)
        led++;
      if (led >7) led = 1;
    }
    prevUp = currUp;
  }

  else{
    int currUp = digitalRead(buttonPin);
    if(currUp != prevUp)
    {
      if(currUp == LOW)
        //Statement that will cycle through all cases with a 3 second delay
        if (led > 7) led = 1;
    }
    prevUp = currUp;
  }

  turnOnLED (led, 255);
  
}  // end of loop

Now that turning on the right LED, to the right brightness, is a single line, I’ll let you play with automating it.

I should point out that on the Uno not all the pins you mention can do PWM. You might want to choose 3, 5, 6, 9, 10, 11.

Currently i am using an inventors kit to prototype my code before i start buying parts or anything like that.

Excellent!

I haven't completely studied & analyzed your code, and I'm not going to try and write your code for you.

...So just some thoughts.

After setting-up the initial condition (all LEDs off?), there is no need to write to all of the LEDs in each "case". You only need to turn-on one LED, and/or turn-off one LED each time, and you only need to "write" when something changes, such as a time-up state, or when a button is pushed.

The missing code needs to do the following: 1) Pushing the button once should cycle through all the cases from 1-7 with a 3 second delay on each case. 2) It should then reset to case 1 (no lights) and wait for a button push. 3) If the button is pushed while an LED is lit, that LED should freeze and stay lit. 4) Pushing the button again while an LED is frozen should reset to case 1 and wait for a button push.

I'd recommed simply attacking these one at at time. I'd start with the timing "delays" and then add the other features one at a time (in whatever order makes sense to you).


I don't want to tell you how to write your program, especially if it's working so-far. But, I don't think I'd use switch/case statements... I'd put several loops inside your main loop -

Turn the 1st LED Sit in a loop 'till time's up (or unitl button pushed?)

When time is up,

Turn off 1st LED Turn on 2nd LED Sit in a loop 'till time's up

Etc...

What was wrong with the last thread?

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Threads merged.

  • Moderator

Sorry for the cross posting. I was unsure of the best way to go about explaining my project in more detail. And thanks for all the help everyone. As soon as i get a chance to implement my new code and play with it a bit, I'll let you know the results. Until then, if anyone has anything else they'd like to add, i am still very much open to suggestion.

  if( digitalRead(modePin == HIGH)){

If modePin is 1, read from pin 1. Otherwise, read from pin 0. How useful is that?

Parentheses go in logical places, not wherever you feel like putting them.