Motion Sensor debounce
-
Hello,
I am not sure how this can be done.
Basically, I have a Panasonic PIR on Moteino with RFM69W working just fine. The problem is that it is spamming GW with messages.
I need to introduce a delay - if PIR triggered, no more messages to GW for 30 secs or so. My issue is that the node is sleeping:sleep(digitalPinToInterrupt(MOTION_INPUT_PIN), CHANGE, SLEEP_TIME)
and millis() are not working during sleeping.
My question is this: How do I introduce a delay, say 30 sec, in order not to spam my GW/Controller with "Security Lighting" (this is how it is recognised in Domoticz). Such delay must work with the sleep function above.
Appreciate if you could share your ideas
Regards
Alex
-
@alexsh1 how about adding
sleep(30*1000)
just before
sleep(digitalPinToInterrupt(MOTION_INPUT_PIN), CHANGE, SLEEP_TIME)
perhaps with an if statement that only invokes sleep(30*1000) if the sensor was triggered.
An alternative could be to add an if-statement that only sends a message if the value was changed from last time.
Edit: added *1000 to convert the seconds to milliseconds
-
@mfalkvidd, you mean
define DEBOUNCE 30000 // ............ sleep(DEBOUNCE);
This just delays it ANYWAY regardless whether the PIR was triggered or not.
When it comes to "if", during one trigger, my PIR is changing the status from 0 to 1 and back to 0. Unfortunately, I cannot count millis() when sleeping. How can use count 30 secs from the last even when the PIR was triggered please? Very much appreciate your suggestion.
-
@alexsh1 hard to say without knowing what else your node does. If it does nothing, the sleep 30000 will be enough. You could connect a RTC, but that might also affect what else the node does.
-
@mfalkvidd The node is a PIR + reporting baro+temp+hum (BME280) every 5 minutes as well as battery voltage.
-
@alexsh1 save the return value from your existing sleep into a variable. Add an if statement that does sleep(30000) only if your node was waken up by interrupt.
Documentation for the return value is available at https://www.mysensors.org/download/sensor_api_20#sleeping
-
@mfalkvidd That's got be the last nail in the coffin - thanks for your help!
-
I think the final product would be looking like this:
#define DUPLICATE_INTERVAL 30000 ..................... if (sleep(digitalPinToInterrupt(MOTION_INPUT_PIN), CHANGE, SLEEP_TIME)) { motionDetected = true; motionTrips++; sleep(DUPLICATE_INTERVAL); }
Testing now
-
@alexsh1 I think you need to test för >= 0. The If statement will return true for anything non-zero so the current test will fail. Except that, the code looks great.
-
This worked well for me, for a vibration sensor:
if (sleep(digitalPinToInterrupt(MOTION_INPUT_PIN), CHANGE, SLEEP_TIME) != -1) {
// Interrupt occurred, do whatever is needed and then
// clear any "floating" interrupts before going on.
while (sleep(digitalPinToInterrupt(MOTION_INPUT_PIN),CHANGE,1000) != -1 ) {
Serial.println("Clearing interrupts");
}
}