turning 3 LEDs on with one push button

hi there
i'm trying to use one push button to turn 3 LEDs on, so if i push the button for 20ms it turns on LED1 if i hold for 4000ms LED2 will come on and if i hold for 8000ms LED3 will come on.
how can i accomplish this?

any help will be appreciated
thanks Joe

You've made over 300 posts, you should know by now what we expect to see when you ask this kind of question.
What code do you have?
What have you tried?
What are the errors are you getting?

Lets start with the first one.

Are you "The Flash" ? :o
20ms

It sounds to me as though there are a number of states that the system can be in. If so, it would seem that a state machine would be a suitable way to implement this with timing done using millis() as in the BlinkWithoutDelay example.

In state 0, if the button is held down move to state 1
In state 1 wait 20 ms then turn on LED1 and move to state 2
In state 2 wait 4000 ms then turn on LED2 and move to state 3
In state 3 wait 8000 ms then turn on LED3 and move to state 4
In state 4, when the button is released set state to 0 and turn off all LEDs

At any time in any state if the button is released turn off all LEDs and move to state 0

switch/case based on the value of state is a good way of doing all of this.

Have you seen the SwitchManager.h offering at the bottom of Nicks page:

Here is the zip URL

http://gammon.com.au/Arduino/SwitchManager.zip

well thanks all for your replies

here is what i have at mo but just seems to be a right balls up lol

#define buttonPin 2 //digital input  pin for button
#define ledPin1 11 // digital output pin for LED 1 indicator
#define ledPin2 12 // digital output pin for LED 2 indicator
#define ledPin3 13 // digital output pin for LED 3 indicator

#define debounce 20

// Button variables
int buttonVal = 0; 
int buttonLast = 0; 
long btnDnTime;
long btnUpTime; 


// LED variables
boolean ledVal1 = false; // state of LED 1
boolean ledVal2 = false; // state of LED 2
boolean ledVal3 = false; // state of LED 3


//=================================================


void setup() 
{

 // Set button input pin
 pinMode(buttonPin, INPUT);
 digitalWrite(buttonPin, HIGH );

 // Set LED output pins
 pinMode(ledPin1, OUTPUT);
 digitalWrite(ledPin1, ledVal1);
 pinMode(ledPin2, OUTPUT);
 digitalWrite(ledPin2, ledVal2);
  pinMode(ledPin3, OUTPUT);
 digitalWrite(ledPin3, ledVal3);

 }


//=================================================


void loop()
{

 // Read the state of the button
 buttonVal = digitalRead(buttonPin);

 // Test for button pressed and store the HIGH time
 if (buttonVal == HIGH && buttonLast == LOW && (millis() - btnUpTime) > long(debounce))
 {
 btnDnTime = millis();
 }

 // Test for button held HIGH for longer than the hold time
 if (buttonVal == HIGH && (millis() - btnDnTime) > 20)
 {
 event1();

 btnDnTime = millis();
 }
 
 // Test for button held HIGH for longer than the hold time
 if (buttonVal == HIGH && (millis() - btnDnTime) > 2000)
 {
 event2();

 btnDnTime = millis();
 }
 
  // Test for button held HIGH for longer than the hold time
 if (buttonVal == HIGH && (millis() - btnDnTime) > 4000)
 {
 event3();

 btnDnTime = millis();
 }

 buttonLast = buttonVal;

}







void event1()
{
 ledVal1 = !ledVal1;
 digitalWrite(ledPin1, ledVal1);
 delay(2000);
 digitalWrite(ledPin1, LOW);
}

void event2()
{
 ledVal2 = !ledVal2;
 digitalWrite(ledPin2, ledVal2);
  delay(2000);
 digitalWrite(ledPin2, LOW);
}

void event3()
{
 ledVal3 = !ledVal3;
 digitalWrite(ledPin3, ledVal3);
  delay(2000);
 digitalWrite(ledPin3, LOW);
}

i do like the sound of this state machine any example on this?

You can give my library a try. Its basically everything that has been said in this post.
ImprovedButton

i do like the sound of this state machine any example on this?

http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

And:

//State machine skeleton

const unsigned long AppleWaitTime  = 50UL;   //time to wait, 50ms 
const unsigned long OrangeWaitTime = 100UL;  //time to wait, 100ms
const unsigned long PearWaitTime   = 500UL;  //time to wait, 1/2Sec
const unsigned long KiwiWaitTime   = 1000UL; //time to wait, 1Sec
//add more as needed

unsigned long AppleMillis;                   //used to calculate when 
unsigned long OrangeMillis;                  //the associated machine state
unsigned long PearMillis;                    //code will be run next
unsigned long KiwiMillis;                    //
//add more as needed

//other variables
const byte ledPin = 13;
const byte buttonPin =2;

unsigned long currentMillis;              //stores the return value from millis() 

//define the available machine states that we can have for this sketch
enum States{
  stateStart, stateApple, stateOrange, statePear, stateKiwi};
//add more states as needed

States mState = stateStart;              //we start out in this machine state 


//======================================================================
void setup()
{
  //Serial.begin(9600);

  currentMillis = millis();
  AppleMillis  = currentMillis;          //initailize all times 
  OrangeMillis = currentMillis;          //
  PearMillis   = currentMillis;          //
  KiwiMillis   = currentMillis;          //

  pinMode(ledPin,OUTPUT);                //
  pinMode(buttonPin,INPUT_PULLUP);

  mState = stateStart;                   //we start out in this machine state 

} //        >>>>>>>>>>>>>> END OF setup() <<<<<<<<<<<<<<<<<

//======================================================================
void loop()
{
  // keep this line here
  currentMillis = millis();  


  //*********** Other loop stuff goes here ************ 



  //************** State Machine section ************** 
  switch (mState)
  {
    //***************************
  case stateStart:
    //code for this state goes here

    //example below, how to change the machine state
    mState = stateApple;          //now switching to this state
    AppleMillis = currentMillis;  //initialize the state delay if there is one

    break;

    //***************************
  case stateApple:
    //is it time to run this section of code?
    if (currentMillis - AppleMillis >= AppleWaitTime) 
    {
      AppleMillis = currentMillis;  //get ready for the next iteration

      //example, toggle a LED
      digitalWrite(ledPin, !digitalRead(ledPin));
    }

    //other state code here
    if (digitalRead(buttonPin) == LOW)
    {
      mState = stateOrange;          //now switching to this state
      OrangeMillis = currentMillis;  //initialize the state delay if there is one
    }  

    break;

    //***************************
  case stateOrange:
    //is it time to run this section of code?
    if (currentMillis - OrangeMillis >= OrangeWaitTime) 
    {
      OrangeMillis = currentMillis;  //get ready for the next iteration

      //other state code here
      digitalWrite(ledPin, !digitalRead(ledPin));
    }

    //other state code here
    if (digitalRead(buttonPin) == HIGH)
    {
      mState = stateApple;          //now switching to this state
      AppleMillis = currentMillis;  //initialize the state delay if there is one
    }  


    break;

    //***************************
  case statePear:
    //is it time to run this section of code?
    if (currentMillis - PearMillis >= PearWaitTime) 
    {
      PearMillis = currentMillis;  //get ready for the next iteration

      //other state code here
      digitalWrite(ledPin, !digitalRead(ledPin));
    }

    //other state code here

    break;

    //***************************
  case stateKiwi:
    //is it time to run this section of code?
    if (currentMillis - KiwiMillis >= KiwiWaitTime) 
    {
      KiwiMillis = currentMillis;  //get ready for the next iteration

      //other state code here
      digitalWrite(ledPin, !digitalRead(ledPin));
    }

    //other state code here

    break;

    //***************************
  default: 
    // default code goes here
    break;

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

  } // end of switch/case


} //        >>>>>>>>>>>>>> END OF loop() <<<<<<<<<<<<<<<<<



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




//======================================================================
//                             END OF CODE
//======================================================================

thanks for those links just going throw them now, but just tried that example and it just flashes every 1s and when you put it high them flash every 50ms them thats it :confused:

You can give my library a try. Its basically everything that has been said in this post.
ImprovedButton

thanks for your link i have download your library and tried the example but i get all this faults:

Test_Button.ino: In function 'void setup()':
Test_Button:40: error: 'class Button' has no member named 'SetStateAndTime'
Test_Button:42: error: 'class Button' has no member named 'onPressed'
Test_Button:43: error: 'class Button' has no member named 'onHold'
Test_Button:44: error: 'class Button' has no member named 'onReleased'
Test_Button.ino: In function 'void loop()':
Test_Button:49: error: 'class Button' has no member named 'checkButton'
Test_Button:55: error: 'PRESSED' was not declared in this scope
Test_Button:58: error: 'HELD' was not declared in this scope
Test_Button:61: error: 'RELEASED' was not declared in this scope
Test_Button:66: error: 'class Button' has no member named 'GetHeldTime'
Test_Button:66: error: 'SECONDS' was not declared in this scope

any ideas?

thanks Joe

Do you by any chance have the other button library too? Because both use class Button.

Try this example file and see if you get the same errors.

#include<Button.h>

#define buttonPin 2
#define ledPin 13

unsigned long blinkTime = millis();
Button B(HIGH); // LOW = milliseconds, HIGH = microseconds, default is LOW
//========================================================================================
//
//========================================================================================
void LED_ON()
{
  digitalWrite(ledPin, HIGH);
}

void LED_OFF()
{
  digitalWrite(ledPin, LOW);
}

void BLINK()
{
  if (millis() - blinkTime >= 100)
  {
    blinkTime += 100;
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}
//========================================================================================

void setup()
{
  Serial.begin(115200);

  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // Set what the button will be when pressed (default is HIGH)
  // and set the hold time (default is 500)
  B.SetStateAndTime(LOW, 1000);

  B.onPressed(LED_ON);
  B.onHold(BLINK);
  B.onReleased(LED_OFF);
}

void loop()
{
  byte myButton = B.checkButton(buttonPin);
  
  if (myButton) // if myButton is anything but 0, it is true
  {
    switch (myButton)
    {
      case PRESSED:
        Serial.print("Button was Pressed ");
        break;
      case HELD:
        Serial.print("Buttons is Held:");
        break;
      case RELEASED:
        Serial.print("Button was Released ");
        break;
      default: break;
    }
    Serial.println(B.GetHeldTime(SECONDS));
  }
}

//void loop()
//{
//  byte myButton = B.checkButton(digitalRead(buttonPin));
//
//  if (myButton) // if myButton is anything but 0, it is true
//  {
//    unsigned long timer = B.GetHeldTime(SECONDS);
//    switch (timer)
//    {
//      case 0: Serial.println("Quick press"); break;
//      case 6 ... 10: Serial.println("Longer than 5 seconds"); break;
//      default: Serial.print(timer); Serial.println(" Seconds"); break;
//    }
//  }
//}

Do you by any chance have the other button library too?

if it does not come with the arduino then no

that gets the same errors

so what button librery should i be downloading?

thanks Joe

No all you need is mine but let me ask you this, where did you put the library when you downloaded it?

You did download it, and not just copy the example sketch, right?

I just reuploaded the library to Github, here is the direct link. Improved-Button-library

download from that link copy and then paste into my libary file ( i have dun this be for)
i am on a mac if that makes any difference?

i am on a mac if that makes any difference?

It shouldn't make any difference, I don't think. I don't own a MAC to be sure.

that is a shame then :confused:

If I can get on the arduino playground, I'll give you the abstract sketch.

Put this at the top of your sketch.

#define WAITING 0
#define PRESSED 1
#define HELD 2
#define RELEASED 3

#define SECONDS 1000000
#define MILLISECONDS 1000
#define MICROSECONDS 1

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
//just in case someone is still using old versions
#include "WProgram.h"
#endif

class Button
{
  private:
    bool            State, lastState;
    unsigned long   onTime, holdTime, heldTime, DBTime, DBInterval;
    byte            _P;
    byte            ButtonState;
    void            (*F_on)();
    void            (*F_hold)();
    void            (*F_off)();

  public:
    Button(byte Precision = LOW) : _P(Precision) { } // precision default = LOW or Milliseconds

    void SetStateAndTime(byte S = HIGH, unsigned long T = 500)
    {
      State = S; // Set the preferred state of the button. (Is the button HIGH or LOW when pressed?)
      lastState = !State; //lastState should be inverted from State
      holdTime = _P ? (T * 1000) : T; // Set the hold time in seconds
    }

    void SetDebounceTime(unsigned long T = 50)
    {
      DBInterval = _P ? (T * 1000) : T;
    }

    void onPressed(void (*ON)() )
    {
      F_on = ON;
    }

    void onHold(void (*HOLD)() )
    {
      F_hold = HOLD;
    }

    void onReleased(void (*OFF)() )
    {
      F_off = OFF;
    }

    byte checkButton(byte _buttonPin )
    {
      static byte _button;
      // Button has not been pressed yet
      ButtonState = WAITING;
      _button = digitalRead(_buttonPin);

      // First check to see if the button is pressed ie. State -> (LOW or HIGH)
      // and if it is different from it's lastState
      if (_button == State && lastState == !State)
      {
        DBTime = _P ? micros() : millis();
        // record time
        onTime = _P ? micros() : millis();

        // Execute ON function
        if (*F_on) // if something was assigned to that function, do it
          F_on();

        // This prevents the code from entering this IF statement,
        // until lastState is set to the perferred State again.
        lastState = State;

        // Button was pressed
        ButtonState = PRESSED;
      }
      if ((_P ? micros() : millis()) - DBTime  >= DBInterval)
      {
        // button is still held down
        if (_button == State && lastState == State)
        {
          // check to see if button is held down for X seconds
          if ( (heldTime = ((_P ? micros() : millis()) - onTime)) >= holdTime) // 1 second is 1,000 milliseconds or 1,000,000 microseconds
          {
            if (*F_hold) // if something was assigned to that function, do it
              F_hold(); // if button is held down for X seconds, execute the HOLD function

            ButtonState = HELD;
          }
        }

        if (_button == !State && lastState == State)//Button was released
        {
          if (*F_off) // if something was assigned to that function, do it
            F_off(); // otherwise execute the OFF function

          ButtonState = RELEASED;
          lastState = !State; // Update lastState
        }
      }
      return ButtonState;
    }

    // This returns the elapsed held time
    float GetHeldTime(float divisor = SECONDS)
    {
      if (divisor > 0)
        return heldTime / divisor;
    }
};// End Of Class

copy and paste at top of me sketch and come up with this ::slight_smile:

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Mac OS X), Board: "Arduino Uno"
In file included from Test_Button.ino:119:
/Users/Joe/Documents/Arduino/libraries/Button_master/Button.h:28: error: redefinition of 'class Button'
Test_Button:18: error: previous definition of 'class Button'

You need to take out #include<Button.h> from your code.

if you still get issues post your sketch, i'll fix it.

it compiling :grinning: thanks, now to have a good look at it ( so i mite be back lol)