Arduino debounce button with delay

I’m having a bit of trouble with my Arduino when I try and use long wires to a switch.

If I use a shorter wire I have no problems, but as soon as they are extended, things start playing up.

What I’m trying to do is, when I press a button I would like it to output to a pin, stay on for 2 seconds, then turn off regardless whether the button is still pressed or not.

The code I use at the moment that does work with short wires is:

// constants won't change. They're used here
// to set pin numbers:
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  10;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);
}

void loop() {
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 // check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (buttonState == HIGH) {
   // turn LED on:
   digitalWrite(ledPin, HIGH);
   delay(2000); // wait for a second
   digitalWrite(ledPin, LOW);
 }
}

I’ve been reading on forums that using debounce may solve this problem. However I’m new to Arduino and not sure how to implement this.

I used the Arduino button tutorial and used a 10k pull down resistor as stated. Is there any way I can allow, either with code or with a resistor / cap, to trigger via a switch that has a wire length of <2m?

Any help appreciated.

So you have a code that works at short distances but does not work with long ones. That means the is nothing wrong with your code but your hardware is at fault.
Unfortunately you have told us very little about this so there is little we can do to help but guess.
See our problem?

I the mean time read this:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

And try wiring your switches between input and ground.

Please read this:-
How to use this forum
Because your post is breaking the rules about posting code.

A hardware solution might be to connect a 1uF capacitor in parallel with your 10K pulldown resistor. Then connect a 1K resistor in series with your pushbutton to the input.

Grumpy Mike.

Thanks for the link. That's has solved the problem of the long wires.

I have one more problem. I need the output to turn off after 2 seconds regardless if the button is still pressed.

At the moment if I momentarily switch the code works. If I keep the switch closed the output stays constant. I need the out put to turn off even if the button is still pressed.

What am I missing?

Skella:
What am I missing?

Code tags,

as suggested by Mike. You could edit your first post and add them, using the </> button in the “Edit” window.

Sorry. I've added the code tags.

What is needed is a Timing sequence

unsigned long startTime = 0;
const long interval = 1000;  // 1 second = 1000 millis
bool timeFlag = false;

void setup()
{
}

void loop()
{
  if (something you want to Time)
  {
    timeFlag = true;         
    startTime = millis();    // Begin timing sequence
    // do stuff here when timing sequence starts
  }

  unsigned long currentTime = millis();
  if (timeFlag == true && currentTime - startTime >= interval) // End timing sequence
  {
    timeFlag = false;
    // do stuff here when time is up
  }
}

Skella:
Sorry. I've added the code tags.

Thanks for that. You've made an old man very happy. :smiley:

Thank you for the code example Hutkikz

So ive tried to use the exmple you gave me with the code i already had and what i intend to do. Have i done this right and will it work?

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  10;      // the number of the LED pin
unsigned long startTime = 0;
const long interval = 2000;  // 1 second = 1000 millis
bool timeFlag = false;
int buttonState = 0;   

void setup() {
 // initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);
 // initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);
}

void loop()
{
buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH);
  {
    timeFlag = true;        
    startTime = millis();    // Begin timing sequence
    digitalWrite(ledPin, HIGH);
  }

  unsigned long currentTime = millis();
  if (timeFlag == true && currentTime - startTime >= interval) // End timing sequence
  {
    timeFlag = false;
    digitalWrite(ledPin, LOW);
  }
}

Sorry for sounding like a complete newbie but we all have to start somewhere.

 if (buttonState == HIGH); //<<<<<Remove this semi-colon 
  {
    timeFlag = true;       
    startTime = millis();    // Begin timing sequence
    digitalWrite(ledPin, HIGH);
  }

except for the extra semi-colon it looks good.

I just remembered that you also wanted to debounce the button.
That code is only for timing.
this example adds a simple debounce also.
Note that I used INPUT_PULLUP so the button is connected to the pin and ground and the logic is reversed(LOW(0) when pressed and HIGH(1) when NOT pressed

// Connect Button between pin and ground
const byte button = 5; // choose your pin

// timing variables
unsigned long startTime = 0;
const long interval = 1000;  // 1 second = 1000 millis
bool timeFlag = false;


void setup()
{
  // Set Button to Input and Enable Built in Pull up Resistor
  pinMode (button, INPUT_PULLUP);
}

void loop() 
{
  bool buttonPressed = checkButton();

  if (buttonPressed)
  {
    timeFlag = true;
    startTime = millis(); // Begin timing sequence
    // do stuff here when timing sequence starts
  }
  
  unsigned long currentTime = millis();
  if (timeFlag == true && currentTime - startTime >= interval) // End timing sequence
  {
    timeFlag = false;
    // do stuff here when time is up
  }
}


bool checkButton()   // Function to read button and Debounce it
{
  static unsigned int buttonCount = 0;
  bool buttonState;

  bool buttonRead = digitalRead(button);
  if (buttonRead == 0) // the button was pressed
  {
    buttonCount++;  // increment the counter
  }
  else   // if the button bounced
  {
    buttonCount = 0;  // reset the counter
  }
         // if we get x number of consecutive positive reads
  if (buttonCount == 10) // This is what adjusts sensitivity
  {
    buttonState = true; // we accept this as a good button press
  }
  else
  {
    buttonState = false;  // we do not accept this as a good button press
  }
  return buttonState;
}

Thank you. I will go and give that a try now.

I made a mistake in the debounce code which is now corrected.
Hope it didn't mess you up.

Thank you for the support.

So this is working, but only the same as before.

This is my code :

// Connect Button between pin and ground
const byte button = 2; // choose your pin
const int ledPin =  13;      // the number of the LED pin

// timing variables
unsigned long startTime = 0;
const long interval = 2000;  // 1 second = 1000 millis
bool timeFlag = false;


void setup()
{
  // Set Button to Input and Enable Built in Pull up Resistor
  pinMode (button, INPUT_PULLUP);
// initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);
}

void loop()
{
  bool buttonPressed = checkButton();

  if (buttonPressed)
  {
    timeFlag = true;
    startTime = millis(); // Begin timing sequence
    digitalWrite(ledPin, HIGH);
  }
 
  unsigned long currentTime = millis();
  if (timeFlag == true && currentTime - startTime >= interval) // End timing sequence
  {
    timeFlag = false;
    digitalWrite(ledPin, LOW);
  }
}


bool checkButton()   // Function to read button and Debounce it
{
  static unsigned int buttonCount = 0;
  bool buttonState;

  bool buttonRead = digitalRead(button);
  if (buttonRead == 0) // the button was pressed
  {
    buttonCount++;  // increment the counter
  }
  else   // if the button bounced
  {
    buttonCount = 0;  // reset the counter
  }
         // if we get x number of consecutive positive reads
  if (buttonCount == 10) // This is what adjusts sensitivity
  {
    buttonState = true; // we accept this as a good button press
  }
  else
  {
    buttonState = false;  // we do not accept this as a good button press
  }
  return buttonState;
}

If the button remains pressed the led just stays lit and does not go off after 2 seconds. If i i just press the button it works, its only when i keep my finger on it that it stays lit.

This is for a semi automated bottle capping machine. I place a bottle against a stop which in turn engages a switch, that switch then outputs from pin 13 to a pneumatic solenoid that activates a pneumatic actuator that extends down to cap the bottle. It takes 2 seconds to tighten the cap after that point pin 13 needs to switch off to deactivate the solenoid and return the actuator to its original position so i can remove the bottle, only when i remove the bottle will the switch be 'un pressed' and ready for the next bottle to start the sequence again.

As it stands if i place a bottle in because the switch is contstantly pressed the actuator remains to be extended and never returns after 2 seconds so i am unable to remove the bottle.

The output from pin 13 drives a mosfet to switch the power to the solenoid.

Try this.
it should keep the sequence from restarting until after the sequence is complete.

if (buttonPressed && timeFlag == false)
  {
    timeFlag = true;
    startTime = millis(); // Begin timing sequence
    digitalWrite(ledPin, HIGH);
  }

edit:
If the button is still pressed after the timing expires it will restart immediately.
In that case you will need to detect when the button is released(modify the checkbutton function) and add code to deal with that.
unfortunately I need to go to work and so will not be able to help further till after

Hutkikz you have been a life saver :slight_smile:

i Added a 5 second timer and now i have seconds to remove the bottle

this is the code for anyone else who might have this problem

// Connect Button between pin and ground
const byte button = 2; // choose your pin
const int ledPin =  13;      // the number of the LED pin

// timing variables
unsigned long startTime = 0;
const long interval = 2000;  // 1 second = 1000 millis
const long interval2 = 5000;
bool timeFlag = false;


void setup()
{
  // Set Button to Input and Enable Built in Pull up Resistor
  pinMode (button, INPUT_PULLUP);
// initialize the LED pin as an output:
 pinMode(ledPin, OUTPUT);
}

void loop()
{
  bool buttonPressed = checkButton();
unsigned long currentTime2 = millis();
  if (buttonPressed && timeFlag == false && currentTime2 - startTime >= interval2)
  {
    timeFlag = true;
    startTime = millis(); // Begin timing sequence
    digitalWrite(ledPin, HIGH);
  }
 
  unsigned long currentTime = millis();
  if (timeFlag == true && currentTime - startTime >= interval) // End timing sequence
  {
    timeFlag = false;
    digitalWrite(ledPin, LOW);
  }
}


bool checkButton()   // Function to read button and Debounce it
{
  static unsigned int buttonCount = 0;
  bool buttonState;

  bool buttonRead = digitalRead(button);
  if (buttonRead == 0) // the button was pressed
  {
    buttonCount++;  // increment the counter
  }
  else   // if the button bounced
  {
    buttonCount = 0;  // reset the counter
  }
         // if we get x number of consecutive positive reads
  if (buttonCount == 10) // This is what adjusts sensitivity
  {
    buttonState = true; // we accept this as a good button press
  }
  else
  {
    buttonState = false;  // we do not accept this as a good button press
  }
  return buttonState;
}

however i am having one small problem. when i power the arduino up using the usb cable things work perfect. when i remove the usb and power the board with a 12v supply when i press the button it works as intended but when the button hes been released the code continues to loop. it comes on for 2 seconds, goes off for 5 then back on for 2 and so on.

what can cause this by runnin the board on the 12v power supply?

really quick as I leave.

2nd startTime and timeFlag also