Delayed check on digital input change - not working

Hello :smiley:

I’m having trouble understanding how to program a delayed “double check” on a digital input. I want to sense a digital input change and then check it again 5s later to make sure it is a permanent change.

I have pasted the relevant code from my script below. The loop routine checks to see if a digital pin, DryerPin, has changed state. If it has, a timer is started (DryerCheckDelay, currently set to 5000ms).

After that time expires the code should check that the DryerPin is STILL in the new state - if so, it calls a routine SendData(StrToSend). The SendData routine works well. If DryerPin is not in the new state DryerInChange is reset to 0 and we start again.

The code in my loop routine doesn’t work properly. It detects the change of state but doesn’t wait the 5000ms; instead it reports the change immediately.

I am probably misunderstanding something. I would be grateful if someone could point out what. :slight_smile:

#include <SPI.h>
#include <Ethernet.h>


// Set up pins
int DryerPin = 30; // Digital in for dryer on/off digital sensor


// Set up dryer sensor
int DryerState = 0; // dryer off initially
int OldDryerState = 0; // Previous dryer state

int DryerCheckDelay = 5000; // millis to wait between checks to see if dryer is still at new state
unsigned long ChangeMillis = 0;
unsigned long CurrentMillis = 0;
int DryerInChange = 0; // Is the dryer in a changed state?

char StrToSend[20];

void setup()  {

	pinMode(DryerPin, INPUT);           // set pin to input
	digitalWrite(DryerPin, HIGH);       // turn on pullup resistors

}


void loop()
{

	DryerState = digitalRead(DryerPin);
        CurrentMillis = millis();
	// Serial.println(DryerState);
	if (DryerState != OldDryerState && DryerInChange == 0) { // Start timer before 2nd check
		ChangeMillis = CurrentMillis;
                DryerInChange = 1;
	}
        
        if(DryerInChange == 1 && CurrentMillis - ChangeMillis > DryerCheckDelay) {
          // If dryer state changing and we have waited long enough
          if (DryerState != OldDryerState) { // Still changed state - send the change of state now
                DryerInChange = 0;
                sprintf(StrToSend, "d=%d", DryerState);
		SendData(StrToSend);
		OldDryerState = DryerState;
          }
          else
          {
            DryerInChange = 0; // Not permanent change, so stand down
          }
	}
}



void SendData (char *ToSend) {
	
	
	// This bit works fine  :-)
	

	// Idea from http://arduino.cc/en/Tutorial/WebClient
	if (client.connect()) {
		Serial.println("Connected");
		// Make a HTTP request:
		client.print("GET /~maidhous/dev/input/in.php?");
		client.print(ToSend);
		Serial.println(ToSend);
		client.print("&p=");
		client.print(DataWritePassword); // Password
		client.println(" HTTP/1.0");
		client.println();
	}
	
	// if there are incoming bytes available 
	// from the server, read them and print them:
	if (client.available()) {
		//Serial.println("Server responded");
		//char c = client.read();
		//Serial.print(c);
	}
	
	// if the server's disconnected, stop the client:
	//if (!client.connected()) {
	//Serial.println();
	//Serial.println("Disconnecting.");
	delay(30);
	client.stop();
}

if(DryerInChange == 1 && CurrentMillis - ChangeMillis > DryerCheckDelay) {

Do you KNOW the precedence of each of the operators (==, &&, -, and >)? If not, use parentheses so that the compiler and you have the same understanding.

Ah! Perfect. I added some brackets (quite possibly more than required) and now it’s working exactly as I expected:

if(DryerInChange == 1 && ((CurrentMillis - ChangeMillis) > DryerCheckDelay)) {

Thank you PaulS! :stuck_out_tongue: