Getting 4 LEDs to do different sets of things via a button

Double post, but I originally posted this in the wrong section. Excuse me for that.

Greetings. Apologies for the rather noobish question, but this is my first attempt at cobbling together my own code.

Idea:

I want to light up 5 (or maybe 6) LEDs off of the PWM pins. Easy enough to do.

Now I would like to be able to get the LEDs to do different actions after a button is pressed. Thus the buttstatechange in the title.

Really I would like these options.

1) All LEDs on. (Easy) 2) All LEDs fading in and out together. (Easy) 3) Random fading. (Easyish I believe) 4) An LED Chaser (Easyish and totally childish)

Now I've done each of these things independently, but I'm completely at a loss as to how to get the sketch to switch between the different sets of code via a button press. From what I've been able to google the buttonstatechange seems like a good option, but I'm sure someone knows a much better option out there instead. (Or knows how to set up a buttonstatechange, or can show me a nice example code that changes between several different directions.)

Any ideas or thoughts oh great coders? I'd settle for just "On" and "All Fading Together."

I have no idea what buttonstatechange is but essentially all you need to do is increment a modulo N counter every time a button is pressed then perform different tasks based on the counter value. Something like this

loop () {

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   switch (count) {

      case 0:
           func0();
           break;
      case 1:
           func1();
           break;
      case 2:
           func2();
           break;
      case 3:
           func3();
           break;
      case 4:
           func4();
           break;
    }
}

This code will block while the funcs are running, if you want to interrupt them it's a bit harder.


Rob

So am I doing this right then…

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  9;

void setup() {
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}


loop () {

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   switch (count) {

      case 0:
           func0();
           digitalWrite(ledPin, low); 
           break;
      case 1:
           func1();
           digitalWrite(ledPin, HIGH); 
           break;
      case 2:
           func2();
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
           analogWrite(ledPin, fadeValue);          
           delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
           analogWrite(ledPin, fadeValue);           
           delay(30);                            
           } 
           break;
      case 3:
           func3();
           break;
      case 4:
           func4();
           break;
    }
}

Or am I rightfully messed up?

Sort of but the functions I had are just examples, if you use inline code like that then get rid of them, also buttonPressed() has to be written as well. Try this

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  9;
int butState = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);      
  pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
	if (butState == HIGH) 
		return false;
		
	if (digitalRead(buttonPin) == HIGH) {
		delay (20);		// wait 20mS then check again
		if (digitalRead(buttonPin) == HIGH) {
			butState = HIGH;
			return true;
		} else {
			return false;
		}
	} else {
		butState = LOW;
		return false;
	}
}

loop () {

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   switch (count) {

      case 0:
           digitalWrite(ledPin, low); 
           break;
      case 1:
           digitalWrite(ledPin, HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
			   analogWrite(ledPin, fadeValue);          
			   delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
			   analogWrite(ledPin, fadeValue);           
			   delay(30);                            
           } 
           break;
      case 3:
           break;
      case 4:
           break;
    }
}

Note that this assumes the button is connected to VCC and there is a pull down resistor on buttonPin.

EDIT: buttonPressed() is not right, I’ll see if I can fix it before I hit the sack.


Rob

Ahhhh… roger that roger that. Button is VCC powered with a resistor. Hmm… good good.

So could I do this then.

int pin2 = 2;
int pin3 = 3;
int pin4 = 4;
int pin5 = 5;
int pin6 = 6;
int pin7 = 7;
int timer = 100;

void setup() {
  pinMode(pin2, OUTPUT);
  pinMode(pin3, OUTPUT);
  pinMode(pin4, OUTPUT);
  pinMode(pin5, OUTPUT);
  pinMode(pin6, OUTPUT);
  pinMode(pin7, OUTPUT);   
  pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
	if (digitalRead(buttonPin) == HIGH) {
		delay (20);		// wait 20mS then check again
		return digitalRead(buttonPin) == HIGH ? true : false;
	} else {
		return (false);
	}
}

loop () {

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   switch (count) {

      case 0:
           digitalWrite(ledPin3, low); 
           break;
      case 1:
           digitalWrite(ledPin3, HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
			   analogWrite(pin3, fadeValue);          
			   delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
			   analogWrite(pin3, fadeValue);           
			   delay(30);                            
           } 
           break;
      case 3:
digitalWrite(pin2, HIGH);
   delay(timer);
   digitalWrite(pin2, LOW);
   delay(timer);

   digitalWrite(pin3, HIGH);
   delay(timer);
   digitalWrite(pin3, LOW);
   delay(timer);

   digitalWrite(pin4, HIGH);
   delay(timer);
   digitalWrite(pin4, LOW);
   delay(timer);

   digitalWrite(pin5, HIGH);
   delay(timer);
   digitalWrite(pin5, LOW);
   delay(timer);

   digitalWrite(pin6, HIGH);
   delay(timer);
   digitalWrite(pin6, LOW);
   delay(timer);

   digitalWrite(pin7, HIGH);
   delay(timer);
   digitalWrite(pin7, LOW);
   delay(timer);

   digitalWrite(pin6, HIGH);
   delay(timer);
   digitalWrite(pin6, LOW);
   delay(timer);

   digitalWrite(pin5, HIGH);
   delay(timer);
   digitalWrite(pin5, LOW);
   delay(timer);

   digitalWrite(pin4, HIGH);
   delay(timer);
   digitalWrite(pin4, LOW);
   delay(timer);

   digitalWrite(pin3, HIGH);
   delay(timer);
   digitalWrite(pin3, LOW);
   delay(timer);
}
           break;
      case 4:
           break;
    }
}

Yep you could but case 3 looks like crap :slight_smile:

Here’s a simplified version

const int timer = 100;
const int buttonPin = 2; 
int count;

int pins [] = {2,3,4,5,6,7};
const int Npins = sizeof(pins) / sizeof(pins[0]);

void setup(void) {
	for (int i = 0; i < Npins; i++)
		pinMode(pins[i], OUTPUT);
		
	pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
      return (false);
}

void loop (void) {

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   count = 2; // change this to test the various options until buttonPressed() works
   
   switch (count) {

      case 0:
           digitalWrite(pins[2], LOW); 
           break;
      case 1:
           digitalWrite(pins[2], HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
            analogWrite(pins[3], fadeValue);          
            delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
            analogWrite(pins[3], fadeValue);           
            delay(30);                            
           } 
           break;
      case 3:
			for (int i = 0; i < Npins; i++) {
				digitalWrite(pins[i], HIGH);
				delay(timer);
				digitalWrite(pins[i], LOW);
				delay(timer);
			}
           break;
      case 4:
           break;
    }
}

Change the hardcoded count value to test the options.

There’s also a Debounce library that handles button pressing, maybe look into that.


Rob

Here’s an updated buttonPressed() function

boolean buttonPressed () {
	if (butState == LOW) {
		if (digitalRead(buttonPin) == HIGH) {
			delay (20);		// wait 20mS then check again
			if (digitalRead(buttonPin) == HIGH) {
				butState = HIGH;
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else { // button is already detected as being pressed
		if (digitalRead(buttonPin) == LOW) {
			delay (20);		// wait 20mS then change the button state
			butState = LOW;
		}
		return false; 
	}
}

Bit if a dog’s breakfast but all my tired brain can do right now.


Rob

Ha ha ha ha. Case 3 was stolen off the example codes on the Arduino site. It seemed messy, but what do I know.

Ok, so, would these modifications work? I changed the pins so that each of the 6 LEDs I would be using would be connected to a PWM pin. As for Case 4, did I set up the random fade correctly?

const int timer = 100;
const int buttonPin = 2; 
int count;

int pins [] = {3,5,6,9,10,11};
const int Npins = sizeof(pins) / sizeof(pins[0]);

void setup(void) {
	for (int i = 0; i < Npins; i++)
		pinMode(pins[i], OUTPUT);
		
	pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
      return (false);
}

void loop (void) {
  
  int x = 0;
  x = random(30, 300);
  
  int y = 0;
  y = random(30, 300);

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   count = 2; // change this to test the various options until buttonPressed() works
   
   switch (count) {

      case 0:
           digitalWrite(pins[3,5,6,9,10,11], LOW); 
           break;
      case 1:
           digitalWrite(pins[3,5,6,9,10,11], HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);          
            delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);           
            delay(30);                            
           } 
           break;
      case 3:
			for (int i = 0; i < Npins; i++) {
				digitalWrite(pins[i], HIGH);
				delay(timer);
				digitalWrite(pins[i], LOW);
				delay(timer);
			}
           break;
      case 4:
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(pins[3,5,6,9,10,11], fadeValue);          
    delay(x);                            
  } 

  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    analogWrite(pins[3,5,6,9,10,11], fadeValue);         
    delay(y);                            
  } 
           break;
    }
}

Hmm… where exactly do I put in the updated ButtonPress() code? In the setup or the loop?

const int timer = 100;
const int buttonPin = 2; 
int count;

int pins [] = {3,5,6,9,10,11};
const int Npins = sizeof(pins) / sizeof(pins[0]);

void setup(void) {
	for (int i = 0; i < Npins; i++)
		pinMode(pins[i], OUTPUT);
		
	pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
      return (false);
}

void loop (void) {
  
  
  int x = 0;
  x = random(30, 300);
  
  int y = 0;
  y = random(30, 300);

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   count = 2; // change this to test the various options until buttonPressed() works
   
   switch (count) {

      case 0:
           digitalWrite(pins[3,5,6,9,10,11], LOW); 
           break;
      case 1:
           digitalWrite(pins[3,5,6,9,10,11], HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);          
            delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);           
            delay(30);                            
           } 
           break;
      case 3:
			for (int i = 0; i < Npins; i++) {
				digitalWrite(pins[i], HIGH);
				delay(timer);
				digitalWrite(pins[i], LOW);
				delay(timer);
			}
           break;
      case 4:
      for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
    analogWrite(pins[3,5,6,9,10,11], fadeValue);          
    delay(x);                            
  } 

  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
    analogWrite(pins[3,5,6,9,10,11], fadeValue);         
    delay(y);                            
  } 
           break;
    }
}

Here’s an updated buttonPressed() function

where exactly do I put in the updated ButtonPress() code? In the setup or the loop?

Just a guess but I’d say it replaces the existing buttonPressed() function. Anyway it’s not being used at present, you need to get all the cases working first.

digitalWrite(pins[3,5,6,9,10,11], LOW);

Wrong with a capital W. Use a loop like I did in case 4


Rob

Each individual case is working fine on it’s own. I get “butstate was not declared in this scope” when compiling.

const int timer = 100;
const int buttonPin = 2; 
int count;

int pins [] = {3,5,6,9,10,11};
const int Npins = sizeof(pins) / sizeof(pins[0]);

int brightness = 0;  
int fadeAmount = 5;

void setup(void) {
	for (int i = 0; i < Npins; i++)
		pinMode(pins[i], OUTPUT);
		
	pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
	if (butState == LOW) {
		if (digitalRead(buttonPin) == HIGH) {
			delay (20);		// wait 20mS then check again
			if (digitalRead(buttonPin) == HIGH) {
				butState = HIGH;
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else { // button is already detected as being pressed
		if (digitalRead(buttonPin) == LOW) {
			delay (20);		// wait 20mS then change the button state
			butState = LOW;
		}
		return false; 
	}
}

void loop (void) {
  
  
  int x = 0;
  x = random(30, 300);
  
  int y = 0;
  y = random(30, 300);

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   count = 2; // change this to test the various options until buttonPressed() works
   
   switch (count) {

      case 0:
           digitalWrite(pins[3,5,6,9,10,11], LOW); 
           break;
      case 1:
           digitalWrite(pins[3,5,6,9,10,11], HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);          
            delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);           
            delay(30);                            
           } 
           break;
      case 3:
			for (int i = 0; i < Npins; i++) {
				digitalWrite(pins[i], HIGH);
				delay(timer);
				digitalWrite(pins[i], LOW);
				delay(timer);
			}
           break;
      case 4:
     {	 analogWrite(3, brightness);    
    brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);    
	 analogWrite(5, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(6, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(9, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(10, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(11, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);     
   }
           break;
    }
}

Oops, add

boolean butState = LOW;

At the top of the program.

Also refer back to reply #9, I see that code (the yellow bit) compiles but I have no idea what it will do. Are you saying it works?


Rob

Ahhh, cool beans. I'll give that a try tomorrow. I'm up way too late this evening.

Oh, any reason why when case 2 has three of it's LEDs flickering?

LEDs on pins 3, 5, 6 are fine BUT LEDs on 9,10,11 are flickering. Power issues?

Oh, here is what I’m using. All the cases work, though there is that weird flickering issue with case #1 for some reason.

const int timer = 100;
const int buttonPin = 2; 
int count;
boolean butState = LOW;

int pins [] = {3,5,6,9,10,11};
const int Npins = sizeof(pins) / sizeof(pins[0]);

int brightness = 0;  
int fadeAmount = 5;

void setup(void) {
	for (int i = 0; i < Npins; i++)
		pinMode(pins[i], OUTPUT);
		
	pinMode(buttonPin, INPUT);     
}

boolean buttonPressed () {
	if (butState == LOW) {
		if (digitalRead(buttonPin) == HIGH) {
			delay (20);		// wait 20mS then check again
			if (digitalRead(buttonPin) == HIGH) {
				butState = HIGH;
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	} else { // button is already detected as being pressed
		if (digitalRead(buttonPin) == LOW) {
			delay (20);		// wait 20mS then change the button state
			butState = LOW;
		}
		return false; 
	}
}


void loop (void) {
  
  
  int x = 0;
  x = random(30, 300);
  
  int y = 0;
  y = random(30, 300);

   if (buttonPressed ()) {
       count++;
       if (count > 4) count = 0;
   }

   count = 1; // change this to test the various options until buttonPressed() works
   
   switch (count) {

      case 0:
           digitalWrite(pins[3,5,6,9,10,11], LOW); 
           break;
      case 1:
           digitalWrite(pins[3,5,6,9,10,11], HIGH); 
           break;
      case 2:
           for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);          
            delay(30);                            
           } 
           for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) { 
            analogWrite(pins[3,5,6,9,10,11], fadeValue);           
            delay(30);                            
           } 
           break;
      case 3:
			for (int i = 0; i < Npins; i++) {
				digitalWrite(pins[i], HIGH);
				delay(timer);
				digitalWrite(pins[i], LOW);
				delay(timer);
			}
           break;
      case 4:
     {	 analogWrite(3, brightness);    
    brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);    
	 analogWrite(5, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(6, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(9, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(10, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);   

	 analogWrite(11, brightness);    
  brightness = brightness + fadeAmount;
  if (brightness == 0 || brightness == 255) {
    fadeAmount = -fadeAmount ; 
  }     
  delay(30);     
   }
           break;
    }
}

any reason why when case 2 has three of it's LEDs flickering?

I still don't get this

pins[3,5,6,9,10,11]

Is this a C++ shorthand I've not seen before?

BTW I will be out of touch for a few days or even a week or so.


Rob

Sorry, that was a late night mistake. I mean case #1.

As for the code... it seems to work well. I forget the reason why I did it. Should I not be doing that? (ok, someone told me I should not be doing that. I'll change that tomorrow when I have the time.)

Should I not be doing that?

I don't know, I've just never seen that syntax before. Maybe it explains the "weird flickering".


Rob

Now I’m guessing that my problems with random flickering LEDs is from my poor poor coding. Sadness. (Someone else told me not to do that. Bad me and my coding.)

Anyway to change your “chaser” code to make it go back and forth, as opposed to just one direction?

Right now it’s moving 1-2-3-4-5-6-1-2-3-4-5-6 but it would be nice to have it go 1-2-3-4-5-6-5-4-3-2-1. Not a big deal, but eh.

Now I’m guessing that my problems with random flickering LEDs is from my poor poor coding.

Use a loop like I did in setup

case 0:
	for (int i = 0; i < Npins; i++)
		digitalWrite(pins[i], LOW);

Anyway to change your “chaser” code to make it go back and forth, as opposed to just one direction?

The quick and dirty way to do it is simply duplicate the code and make some changes so the second loop counts down

for (int i = 0; i < Npins; i++) {
	digitalWrite(pins[i], HIGH);
	delay(timer);
	digitalWrite(pins[i], LOW);
	delay(timer);
}

for (int i = Npins-1; i >= 0; i--) {
	digitalWrite(pins[i], HIGH);
	delay(timer);
	digitalWrite(pins[i], LOW);
	delay(timer);
}

Rob

JoshuaZimmerman:
Anyway to change your “chaser” code to make it go back and forth, as opposed to just one direction?

Right now it’s moving 1-2-3-4-5-6-1-2-3-4-5-6 but it would be nice to have it go 1-2-3-4-5-6-5-4-3-2-1. Not a big deal, but eh.

case 3: {
	// Chase Animation

	// Chase up
	for (int i = 0; i < Npins; i++) {
		digitalWrite(pins[i], HIGH);
		delay(timer);
		digitalWrite(pins[i], LOW);
		delay(timer);
	}

	// Chase down
	for (int i = Npins - 1; i >= 0; i--) {
		digitalWrite(pins[i], HIGH);
		delay(timer);
		digitalWrite(pins[i], LOW);
		delay(timer);
	}
}

There are (as with all coding tasks) multiple ways to do this, but here’s a simple way. The for loop you have for case 3 is accomplishing the chase this way:

  • It starts at 0 (int i = 0)
  • It will keep going as long as i is less than the number of pins, in other words until it reaches the last pin (i < Npins)
  • After each time it runs, it goes to the next pin (i++)

So to have it chase the other direction, just add a for loop that does the reverse of what your first one did.

  • It starts at the END of your array of pins (int i = Npins)
  • It keeps going until it reaches the beginning, ie 0 (i >= 0)
  • After each time it runs, it goes to the previous pin (i–)

Another good habit to start forming is frequent commenting. Leaving comments that let others (and future you) know what everything does will save you tons of time down the road.