Simple project with 3 button and 3 LED

Hello !

I have a simple idea in mind but would like to receive some help to know if it's possible with Arduino.

I have 3 buttons / 3 leds linked to the Arduino board.

My target is : the led of the last button pressed is on. simple as that !

Thanks a lot.

It's possible.

thanks !

Sooooo.... are you asking how to do it? What are your thoughts?

Pretty simple project actually. Just need 3 buttons, 3 LEDs, 3 current limit resistors. Just 1 resistor even if only 1 LED will ever be on.

Hello thanks for the interest ! So I think I can manage to code it, but I would like to know if it's possible.

The main problem I forgot to tell is that they are momentary buttons.

What do you think ? Thanks.

Maybe I could inspire from this Switch example ?

/* switch
 * 
 * Each time the input pin goes from LOW to HIGH (e.g. because of a push-button
 * press), the output pin is toggled from LOW to HIGH or HIGH to LOW.  There's
 * a minimum delay between toggles to debounce the circuit (i.e. to ignore
 * noise).  
 *
 * David A. Mellis
 * 21 November 2006
 */

int inPin = 2;         // the number of the input pin
int outPin = 13;       // the number of the output pin

int state = HIGH;      // the current state of the output pin
int reading;           // the current reading from the input pin
int previous = LOW;    // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time = 0;         // the last time the output pin was toggled
long debounce = 200;   // the debounce time, increase if the output flickers

void setup()
{
  pinMode(inPin, INPUT);
  pinMode(outPin, OUTPUT);
}

void loop()
{
  reading = digitalRead(inPin);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (state == HIGH)
      state = LOW;
    else
      state = HIGH;

    time = millis();    
  }

  digitalWrite(outPin, state);

  previous = reading;
}

The debounce time of 200 mS will surely work as long as the frequency of button pressings is low. In my opinion "normal" manual push button debounce time could be in the range of some 10 - 25 mS.

Yes, that's the complicated part.

You can "test and see". From my old microcoputer lessons I think we aimed at 10 mS but i depends on the switch of course.

thanks ! So I just need to have 1 conditions for each button, and then it should work !

I just found this, I'll try, it seems perfect :

/*
  SwitchChangeDetectionSimple.ino
  LarryD
  Version YY/MM/DD
  1.00    16/09/28   Running code
  1.01    16/09/30   Added heartbeat LED

  Demonstrates switch state change detection, no library.

*/

//**********************************************************************
//+5V----InternalPullupResitor----InputPin----[SwitchPin1/SwitchPin2]----GND
#define Pressed  LOW
#define Released HIGH

//+5V----[LEDanode/LEDcathode]----[220ohmResistor]----OutputPin
#define LEDon    LOW
#define LEDoff   HIGH
//***************************

/*
  //**********************************************************************
  //+5V----[SwitchPin1/SwitchPin2]----InputPin----[10K resistor]----GND
  #define Pressed  HIGH
  #define Released LOW

  //OutputPin----[LEDanode/LEDcathode]----[220ohmResistor]----GND
  #define LEDon    HIGH
  #define LEDoff   LOW
  //***************************
*/

const byte  switchOne    = 8;
const byte  switchTwo    = 9;
const byte  LED_One      = 11;
const byte  LED_Two      = 12;
const byte  heartBeatLED = 13;

byte switchOneState;
byte lastswitchOneState;
byte lastswitchTwoState;

unsigned long heartBeatMillis;
unsigned long switchMillis;

//                          s e t u p ( )
//**********************************************************************
void setup()
{
  pinMode(switchOne, INPUT_PULLUP);
  pinMode(switchTwo, INPUT_PULLUP);

  pinMode(heartBeatLED, OUTPUT);

  pinMode(LED_One, OUTPUT);
  digitalWrite(LED_One, LEDoff);

  pinMode(LED_Two, OUTPUT);
  digitalWrite(LED_Two, LEDoff);

} //END of                  s e t u p ( )


//                           l o o p ( )
//**********************************************************************
void loop()
{
  //check for blocking code
  heartBeat();

  //***************************

  //do some loop() stuff

  //***************************
  //every 50ms check the switches
  if (millis() - switchMillis >= 50ul)
  {
    //reset timing
    switchMillis = millis();

    //***************
    //check switchOne
    if (checkSwitch(switchOne, lastswitchOneState) == true)
    {
      //toggle LED
      digitalWrite(LED_One, !digitalRead(LED_One));
    }
    //***************
    //check switchTwo
    if (checkSwitch(switchTwo, lastswitchTwoState) == true)
    {
      //toggle LED
      digitalWrite(LED_Two, !digitalRead(LED_Two));
    }
    //***************

  }//END of     if (millis() - switchMillis >= 50ul)
  //***************************

} //END of                   l o o p ( )


//======================================================================
//                        F U N C T I O N S
//======================================================================


//                      h e a r t B e a t ( )
//**********************************************************************
//optional, check for blocking code
//toggle heartBeatLED every 500ms
void heartBeat()
{
  if (millis() - heartBeatMillis < 500ul)
  {
    //nothing to do yet
    return;
  }

  //reset timing
  heartBeatMillis = millis();

  //toggle LED
  digitalWrite(heartBeatLED, !digitalRead(heartBeatLED));

}//END of               h e a r t B e a t ( )



//                    c h e c k S w i t c h ( )
//**********************************************************************
//check if a switch has changed state
bool checkSwitch(byte switchPin, byte &lastState)
{
  byte thisSwitchState = digitalRead(switchPin);

  //***************************
  //was there a change in state?
  if (thisSwitchState != lastState)
  {
    //update the switch state
    lastState = thisSwitchState;

    //***************************
    if (thisSwitchState == Pressed)
    {
      //this switch was pressed
      return true;
    }

    else
    {
      //this switch was released
      //nothing to do here
    }

  }//END of    if (thisSwitchState != lastState)
  //***************************

  return false;

}//END of             c h e c k S w i t c h ( )



//======================================================================
//                       E N D  O F  C O D E
//======================================================================

It may be simple, and it may not be.

The complication arises when - and only if - more than one button may be pressed at the same time. If that will not happen, then no de-bouncing is needed.

If it is, then

// Radio Buttons!
const int led1Pin =  3;    // LED pin number
const int button1 =  2;
const int led2Pin =  5;
const int button2 =  4;
const int led3Pin =  6;
const int button3 =  7;
const int led4Pin =  9;
const int button4 =  8;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
char bstate4 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
unsigned long bcount4 = 0;


// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
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.
// Routines by Paul__B of Arduino Forum
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!
        }
        else
          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
        }
        else
          return false;                 // not done yet; just move on
      }
    default:                            // Error; recover anyway
      {
        *butnstate = 0;
        return false;                   // Definitely false!
      }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(led2Pin, OUTPUT);
  pinMode(button2, INPUT);
  pinMode(led3Pin, OUTPUT);
  pinMode(button3, INPUT);
  pinMode(led4Pin, OUTPUT);
  pinMode(button4, INPUT);
  digitalWrite (led1Pin, LOW);
  digitalWrite (led2Pin, LOW);
  digitalWrite (led3Pin, LOW);
  digitalWrite (led4Pin, LOW);
}

void loop() {
  // Select LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    digitalWrite (led1Pin, HIGH);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
  }
  // Select LED if button debounced
  if (butndown(digitalRead(button2), &bcount2, &bstate2, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, HIGH);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, LOW);
  }
  // Select LED if button debounced
  if (butndown(digitalRead(button3), &bcount3, &bstate3, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, HIGH);
    digitalWrite (led4Pin, LOW);
  }
  // Select LED if button debounced
  if (butndown(digitalRead(button4), &bcount4, &bstate4, 10UL )) {
    digitalWrite (led1Pin, LOW);
    digitalWrite (led2Pin, LOW);
    digitalWrite (led3Pin, LOW);
    digitalWrite (led4Pin, HIGH);
  }
}

Hello Paul ! Thank you so much, I'll test it today !

Paul__B ! Thanks it's working perfectly !!

Of course! :roll_eyes:

I coded that some years back. While it looks a little complex, you will see that it is designed so you can easily add (or subtract) buttons and LEDs as many as you want. If you were using many, you should arrange the details in arrays to make it neater; I don't offhand recall whether I did that in some other version.

All the buttons are separately de-bounced so do not interact in any way, I refer to it as "ironclad" code, the de-bouncing is extremely strict but guaranteed to respond within the specified interval of the input becoming stable.

The foundational "timeout" function is modular so can be used to perform any other timing job such as flashing LEDs at different rates. :grinning: