But it records the duration the pin is high before going low or vice versa depending on how it's coded.
Whereas, I would like to measure the time between: the first event of the pin going low and the second event of the pin going low. Forgetting the high period in-between.
Such a scenario has a minimum recovery time as you
idle at a high
begin timing on a low
continue timing while pin is high
stop timing when pin is low
Stray capacitance and inductance may play a role if the low-to-low period is small. As the input pin is high-Z, you will need pull-up or pull-down resistance depending on the nature of the single-pin signal (internal, weak pull up/down may not be satisfactory.)
Thus, I have marked the 1st transition if I understand what you are wishing to accomplish:
Ec2021, so I could run your code without the de-bounce function?
state = actstate();
if (lastState != state) {
if (state) {
actHigh = millis();
if (lastHigh > 0) {
timeDifference = actHigh - lastHigh;
Serial.println(timeDifference);
}
lastHigh = actHigh;
}
lastState = state;
}
Mrburnette, yep, start counting at the first low, idle at high, stop counting at the next low. Idle at high, start counting at next low etc. The input pin is already defined as as INPUT_PULLUP.
Im trying to calculate RPM by detecting the time between pulses (low when active, high when not) of a magnetic proximity sensor.
At minimum rotation speed the pin is LOW for probably 2 seconds, HIGH for 20 seconds. Max rotation pin LOW for estimated 300ms, HIGH for 2.5 seconds.
I want to keep the code as simple as possible and without the use of interrupts, as I don’t think the speeds involved above warrant it.
//********************************************^************************************************
#define PUSHED LOW
#define RELEASED HIGH
#define CLOSED LOW
#define OPEN HIGH
#define ENABLED true
#define DISABLED false
#define LEDon HIGH
#define LEDoff LOW
//********************************************^************************************************
const byte buttonPin = 2;
const byte ledPin = 12;
const byte heartbeatLED = 13;
byte lastButtonPinState = RELEASED;
//timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;
unsigned long switchLowMillis;
// s e t u p ( )
//********************************************^************************************************
void setup()
{
Serial.begin(115200);
pinMode(buttonPin, INPUT_PULLUP);
pinMode(heartbeatLED, OUTPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LEDoff);
} //END of setup()
// l o o p ( )
//********************************************^************************************************
void loop()
{
//********************************* h e a r t b e a t T I M E R
//is it time to toggle the heartbeatLED ?
if (millis() - heartbeatMillis >= 500ul)
{
//restart this TIMER
heartbeatMillis = millis();
//toggle the heartbeatLED
digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
}
//********************************* c h e c k s w i t c h T I M E R
//is it time to check the switches ?
if (millis() - switchMillis >= 50ul)
{
//restart this TIMER
switchMillis = millis();
checkSwitches();
}
} //END of loop()
// c h e c k S w i t c h e s ( )
//********************************************^************************************************
//this function runs every 50ms; this effectively debounces your inputs
void checkSwitches()
{
byte currentState;
//************************************************ b u t t o n P i n
currentState = digitalRead(buttonPin);
//has this switch changed state ?
if (lastButtonPinState != currentState)
{
//update to the new switch state
lastButtonPinState = currentState;
//*************************
//has this switch been pushed ?
if (currentState == PUSHED)
{
//**********
//1st push of this switch
//is the output currently OFF ?
if (digitalRead(ledPin) == LEDoff)
{
//save the time the switch was first pushed
switchLowMillis = millis();
Serial.println("1st Push Detected");
digitalWrite(ledPin, LEDon);
}
//**********
//2nd push of this switch
else
{
digitalWrite(ledPin, LEDoff);
Serial.print(millis() - switchLowMillis);
Serial.println(" ms \n");
}
}
} //END of this switch
//*********************************
// Future switches go here
//*********************************
} //END of checkSwitches()
That should work depending on what your actState() function returns.
The debouncing is required if the physical switch is not providing "clean" state changes but e.g. spikes before the state settles. Bouncing leads to multiple unwanted changes in short time.
The function in loop() checks for a change of the state. If a change to HIGH was detected
the difference between the last LOW to HIGH (lastHigh) change is calculated and printed
the recent time of the change is then stored in the global variable
the function waits for the next LOW to HIGH change.
The "if (lastHigh > 0)" avoids printing the first time a change to HIGH is detected (as 0 is not a valid detected time).