If button pressed more than 5 times in 5 seconds the LED will turn on

I have a problem with coding....

How to code the arduino IF BUTTON PRESSEND MORE THAN 5 TIMES IN 5 SECONDS THE LED WILL TURN ON

Please anyone help me on this

Show us what you've got so far :D

What have you tried so far?

The State Change Detection example in the IDE @ File > Examples > 2 Digital will show you how to count presses. Store the value of millis() into a variable when you get the first press, then see what the new millis() is (and hence the time gap) when the 5th press happens.

edit: or if the gap is 5 seconds, see what the count is by then.

Is this for school?

Show us your current compete sketch. Use CTRL T to format the sketch. Please use code tags. Use the </> icon in the posting menu. [code] Paste sketch here. [/code]

How are you proposing to wire things?
.

If the button count is zero when the button is pressed save the value of millis() and increment the button count. As eacj successive button press happens increment the button count until it reaches 5. In the meantime if the difference between millis() and the saved value exceeds 5000 set the count back to zero.

…R

To be really correct, you will need to record the time (millis) of all of the last five button presses, not just the first one. If the interval between the last and the fifth from last press in less than 5000, turn LED on

+1 with Olf

Could be a good idea to implement with a 5 slot circular buffer to show creativity

Alternatively fill up an array of 6 elements and starts shifting data out FIFO and perform the 5 sec test between index 0 and index 4

(Or if more than 5 times means at least 6 then add 1 position to the buffer)

olf2012:
To be really correct, you will need to record the time (millis) of all of the last five button presses, not just the first one. If the interval between the last and the fifth from last press in less than 5000, turn LED on

I don’t believe that matches the specification in the Title.

…R

Robin2: I don't believe that matches the specification in the Title.

...R

You may be right if I think about it :) This dispute has to be resolved by the OP

Whatever, there's enough suggestions there to get the OP going, regardless of the details of the implementation.

State change detection and recording the time with millis() are certainly things s/he needs to come to terms with.

I still can't get it. Can someone give me the specific hint, I've tried to turn on the LED with one time hit button. But now I want to turn on the led when the button hit more than 5 times in 5 seconds. I still can't figure it out.

show what you tried

Hi,

I had a similar problem. Here is my modified state change example. Might help you out

const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int TailUpCounter = 0;
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

long buf[5];
int bufCount = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize serial communication:
  Serial.begin(9600);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button
      // wend from off to on:
      Serial.println("Tail up");
      buf[bufCount++] = millis();
      if(bufCount >= 5){
        bufCount = 0;
      }

      for (int count = 0; count < 5; count++) {
        if(buf[count] < (millis() - 60000)){
          buf[count] = 0;
        }
        Serial.println(buf[count]);
      }
      TailUpCounter = 0;
      for (int count = 0; count < 5; count++) {
        if(buf[count] > 0){
          TailUpCounter++;
          Serial.println(TailUpCounter);
        }
      }
      if(TailUpCounter == 5){
        Serial.println("Cow Calving");
      }
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state,
  //for next time through the loop
  lastButtonState = buttonState;
  delay(1000);
}

See if this does what you want, not perfect but works:

const byte btnPin = 4,
           ledPin = 13,
           dbTime = 25; // debounce time
unsigned long timeStart, // debounce timer
              cntStart; //button press timer
const int timeOut = 5000; // 5 seconds 
bool btn,
     oldBtn = false, // previous button state
     btnState = true,
     timing = false;
byte cnt = 0; // button press counter

void setup()
{
  Serial.begin(9600);
  pinMode(btnPin,INPUT_PULLUP);
  pinMode(ledPin,OUTPUT);
}
void loop()
{
  // first, debounce the button +++++++++++++++
  if(digitalRead(btnPin) != btnState)
  {
    timeStart = millis();
    btnState ^= 1;
  } 
  if(millis() - timeStart > dbTime)
    btn = !btnState;
  // end debounce +++++++++++++++++++++++++++++  
  if(btn != oldBtn && btn == true) // if state changed and button is pressed
  {
    if(!timing) // if first press, start timer
    {
      cntStart = millis();
      timing = true;
    }
  if(++cnt > 5)
    digitalWrite(ledPin,HIGH); // press reset button to clear
  Serial.println(cnt);  
  }
  oldBtn = btn;
  if(millis() - cntStart > timeOut)
  {
    cnt = 0;
    timing = false;
    cntStart = millis(); // reset counter and timer
  }
}

This did come up in Seedler’s other thread that I’m too lazy to find again. It’s got to be a school problem, too much of a coincidence that two people have the same weird request inside of 24 hours. I suggested the circular buffer. The key realization is that if you simply store only the last 5 time stamps in the buffer as they come in, all the information you need to detect the 5 presses is sitting right there. But you have to think “upside down” a little. Any time 5 presses have occurred within the last specified time window, none of them will be older than the window. So all you have to do is look for any old time stamps. If there are none, then you raise an alert.

A sub issue is whether you want to keep detecting excesses, or start over again. I made that optional by using a flag.

Thanks to Bulldog Lowell for providing the framework.

#include <TimeLib.h>

#define READINGS 5
#define TIMEFRAME 60L

class CircularBuffer {
  public:
    CircularBuffer(int size);
    void addElement(uint32_t newElement);
    void init();
    boolean eventsExceeded();

  private:
    uint32_t* array;
    int index = 0;
    int num_elements = READINGS;
};

CircularBuffer::CircularBuffer(int arraySize)
{
  array = new uint32_t[arraySize];
}

void CircularBuffer::init()
{
  for (int i = 0; i < num_elements; i++)
  {
    array[i] = now() - TIMEFRAME - 10L;
  }
  Serial.println("Starting a new TIMEFRAME...");
}

void CircularBuffer::addElement(uint32_t newElement)
{
  array[index] = newElement;
  index++;
  if (index >= num_elements)
  {
    index = 0;
  }
}

boolean CircularBuffer::eventsExceeded()
{
  uint32_t presentTime = now();
  boolean oldFound = false;
  for (int i = 0; i < num_elements; i++)
  {
    if (presentTime - array[i] > TIMEFRAME)
    {
      oldFound = true;
    }
  }
  return not oldFound;
}

CircularBuffer myBuffer(READINGS);
byte buttonPin = 4;
boolean resetTimeframe = true;

void setup()
{
  Serial.begin(9600);
  pinMode(buttonPin, INPUT_PULLUP);
  myBuffer.init();
}

void loop()
{
  if (buttonPressed())
  {
    myBuffer.addElement(now());
    Serial.println(now());
    if (myBuffer.eventsExceeded())
    {
      Serial.println("5 or more events in the last TIMEFRAME seconds!");
      if (resetTimeframe)
      {
        myBuffer.init();
      }
    }
  }
}

bool buttonPressed(void)
{
  static byte lastPressed = 1;
  byte currentPress = digitalRead(buttonPin);
  if (currentPress != lastPressed)
  {
    if (currentPress == 0)
    {
      lastPressed = currentPress;
      return true;
    }
  }
  lastPressed = currentPress;
  delay(50);
  return false;
}