detect non pressed button.

Lets say a program is to detect rate of button presses. It should be pressed once every 10 seconds. If too slow, say, 12 seconds goes by an LED comes on. If pressed too early at 7 seconds, too early, a diffent LED would come on. That part of the program isn't too hard. BUT... my real question is how to detect (or code) in a way that the if someone stopped pressing the button completely, the the program would "see" that no state change has happened and it would turn on the "going too slow" LED. My trouble is that without the next button press there is no time to compare to. Is there a way to poll the button for a state change for a given time frame without user input? Do I use interupts? Any direction would help.

Here is some code that I have that does the timing but only if button is pressed. And it uses a motor rather than an LED. But the general question remains the same as my last post.

#include <AFMotor.h>

// Connect a stepper motor with 48 steps per revolution (7.5 degree)
// to motor port #1 (M1 and M2)
AF_Stepper motor(48, 1);

int stepCountForward = 0;         // number of steps the motor has taken
int stepCountBackward = 0;

const int inPin = 10;  //Sensor or button 
const int outPin= 13;  //led lights up to timed objects
const int relay= 5;

unsigned long elapsedtime=0;

int ledstate =HIGH;
int switchstate = HIGH;
int previous = HIGH;

unsigned long prevtime = 0;
unsigned long debounce = 150;
unsigned long dur_on = 0; //duration between on/off

void setup(){

  pinMode(inPin,INPUT);
  pinMode(outPin,OUTPUT);
  pinMode(relay,OUTPUT);

  Serial.begin(9600);
  motor.setSpeed(100);  // 10 rpm  
  digitalWrite(relay, LOW); 
}

void loop()
{
  switchstate=digitalRead(inPin);
  if ((millis()-prevtime)>debounce){
    if(switchstate!=previous && switchstate==LOW){
      if (ledstate==HIGH){
        digitalWrite(outPin,LOW);
        prevtime=millis();
        ledstate=LOW;
      }
      else if(ledstate==LOW){
        digitalWrite(outPin,HIGH);
        ledstate=HIGH;
        Serial.print("  time is ");
        elapsedtime=((millis()-prevtime));
        Serial.println(elapsedtime);
        prevtime=millis();

        if (elapsedtime > 10000){                    //solenoid off
          motor.step(400, FORWARD, INTERLEAVE);
          digitalWrite(relay, LOW);          //solenoid off
          delay(100000000);  //if solenoid is off delay code for ~1 day or 27 hours while on manual
          elapsedtime=((millis()-prevtime));
          Serial.print("The time is over 10 seconds, switch off solenoid");

        }

      }
      if (elapsedtime > 3500){                      // too slow
        motor.step(1, FORWARD, DOUBLE);
        digitalWrite(relay, HIGH);
        elapsedtime=((millis()-prevtime));
        Serial.print("so the motor has moved ");
        stepCountForward = ++stepCountForward;
        Serial.print(stepCountForward);
        Serial.println(" total times to loosen. ");
      }
      if (elapsedtime < 2500 && elapsedtime > 20){  // too fast
        motor.step(1, BACKWARD, DOUBLE);
        digitalWrite(relay, HIGH);
        elapsedtime=((millis()-prevtime));
        Serial.print("so the motor has moved ");
        stepCountBackward = ++stepCountBackward;
        Serial.print(stepCountBackward);
        Serial.println(" total times to tighten. ");
      }
    }
  }
}

My trouble is that without the next button press there is no time to compare to.

Not true. You know when the button was last pressed. Subtracting that from millis() will tell you number of milliseconds since then.

Not true. You know when the button was last pressed. Subtracting that from millis() will tell you number of milliseconds since then.

But how can I get my code to react without the next button press? Esp this part of my code.

 if (elapsedtime > 10000){                    //solenoid off
          motor.step(400, FORWARD, INTERLEAVE);
          digitalWrite(relay, LOW);          //solenoid off
          delay(100000000);  //if solenoid is off delay code for ~1 day or 27 hours while on manual
          elapsedtime=((millis()-prevtime));
          Serial.print("The time is over 10 seconds, switch off solenoid");

If the the button is not pressed, then the "elapsedtime" would never register as over 10000. I would like that part of the code to happen as soon as elapsedtime goes over 10000. With or without a pressed button.

I would like that part of the code to happen as soon as elapsedtime goes over 10000. With or without a pressed button.

Make the elapsed time check the primary one, not the button press.

Make the elapsed time check the primary one, not the button press.

I guess that is kind of what I want to do but not sure if I properly know how. If I compare elapsedtime to millis(), if that is what you suggest, won't that only work one cycle thru the code? Because millis doesn't reset. I want the code to run continuously checking for the pressed button.

I want the code to run continuously checking for the pressed button

That's the beauty of using millis() for timing. It enables you to check whether a certain time has passed yet and if not, go and do something else, like check for a button press.

save millis() to startTime variable
start of loop()
  if millis() - startTime >= 10000UL
    //the user has not pressed the button for 10 seconds
    //code here to do what you want about it
  end of if

  if button has been pressed
    elapsedTime = millis() - startTime
    startTime = millis()
    //check the elapsed time and act on whether
    //it is too short or too long since last time
  end of if
end of loop()

Thank you so much UKHeliBob. The last few days I took what you said and have been trying to get a better grasp on millis(). You pseudocode did just the trick!

My final test code for the functionality. Just in case it can help someone else. Two LEDs. Both blinks with every button press but if 10 seconds goes by with a press then led1 turns on. With every button press the 10 sec "timer" resets. Thanks.

const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin const int ledPin1 = 9;

unsigned long startTime = 0; unsigned long elapsedTime = 0;

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

void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); pinMode(ledPin1, 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); digitalWrite(ledPin1, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); digitalWrite(ledPin1, LOW); } if (millis() - startTime >= 10000) { digitalWrite(ledPin1, HIGH);

if (buttonState == HIGH) { elapsedTime = millis() - startTime; startTime = millis(); digitalWrite(ledPin1, HIGH); } else { digitalWrite(ledPin1, LOW); } } }

Opps. Last code didn't reset timer. Just timed every 10 sec and then turned led on. This code resets timer after each press.

const int buttonPin = 2; // the number of the pushbutton pin const int ledPin = 13; // the number of the LED pin const int ledPin1 = 9;

unsigned long startTime = 0; unsigned long elapsedTime = 0;

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

void setup() { // initialize the LED pin as an output: pinMode(ledPin, OUTPUT); pinMode(ledPin1, 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); digitalWrite(ledPin1, HIGH); } else { // turn LED off: digitalWrite(ledPin, LOW); digitalWrite(ledPin1, LOW); } if (millis() - startTime >= 10000) { digitalWrite(ledPin1, HIGH); } else { digitalWrite(ledPin1, LOW); }

if (buttonState == HIGH) { elapsedTime = millis() - startTime; startTime = millis(); digitalWrite(ledPin1, HIGH); } else { digitalWrite(ledPin1, LOW); } }