Controlling multiple leds with 1 switch


Am new to the Arduino world and am using it with my hobby of model making, I am looking for a way to use 1 push button to turn on 1 led, then when pressed again it turns off that led but turns on another, and on a 3rd push it will turn on both leds, and finally the 4th time it turns them all off and repeat. Have been searching for 3 days but can’t seem to find a topic that covers this part.

Any help and guidance is appreciated.

Using an Uno R3 and final project with a Nano.

It is quite simple. Wire up a button between ground and an input pin. Initialize these in the setup function and then just count the button pushes. Note that you keep a note of the button state last time you looked and only increment the number when last time it was not pressed and this time it was. This is the bulk of the code, it won't compile until you add the setup function.

void loop(){
  static int numberOfPushes = 0, lastReading, maxPushes = 5;
  int reading = digitalRead(button);
  if(lastReading == HIGH && reading == LOW){
    numberOfPushes ++;
    if(numberOfPushes > maxPushes) numberOfPushes = 0; // wrap round if too big
    delay(40); // debounce delay

// now do what you want based on the value of numberOfPushes maybe use a switch structure here

  lastReading = reading; // save for next time

I did a write up a few years ago.

Here’s a link.

Selector Switch

It should be pretty simple to cobble up any variations you want.

OK then, try this:

// Binary cycling multiple LEDs

const int led1Pin =  13;    // LED pin number
const int led2Pin =  11;
const int button1 =  4;
char led1State = LOW;        // initialise the LED
char led2State = LOW;
char allState = 0;
char bstate1 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) {
    *marker += interval;    // move on ready for next interval
    return true;
  else return false;

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
    case 0: // Button up so far,
      if (button == HIGH) return false; // Nothing happening!
      else {
        *butnstate = 2;                 // record that is now pressed
        *marker = millis();             // note when was pressed
        return false;                   // and move on

    case 1: // Button down so far,
      if (button == LOW) return false; // Nothing happening!
      else {
        *butnstate = 3;                 // record that is now released
        *marker = millis();             // note when was released
        return false;                   // and move on

    case 2: // Button was up, now down.
      if (button == HIGH) {
        *butnstate = 0;                 // no, not debounced; revert the state
        return false;                   // False alarm!
      else {
        if (millis() - *marker >= interval) {
          *butnstate = 1;               // jackpot!  update the state
          return true;                  // because we have the desired event!
          return false;                 // not done yet; just move on

    case 3: // Button was down, now up.
      if (button == LOW) {
        *butnstate = 1;                 // no, not debounced; revert the state
        return false;                   // False alarm!
      else {
        if (millis() - *marker >= interval) {
          *butnstate = 0;               // Debounced; update the state
          return false;                 // but it is not the event we want
          return false;                 // not done yet; just move on
    default:                            // Error; recover anyway
        *butnstate = 0;
        return false;                   // Definitely false!

void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(button1, INPUT);
  digitalWrite(button1, HIGH);          // internal pullup all versions

void loop() {
  // Cycle LEDs if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    allState++; allState &= 3;          // Increment state, constrain to 0 to 3
    if (allState & 1) led1State = HIGH; // LED 1 on if odd state
    else led1State = LOW;
    if (allState & 2) led2State = HIGH; // LED 2 on if 2 or 3
    else led2State = LOW;
  digitalWrite(led1Pin, led1State);
  digitalWrite(led2Pin, led2State);

Note the ironclad debounce routine, can be easily extended to any number of buttons.

thanks all you have given me plenty to work with and am trying to learn as i go and appreciate the help.