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


  • Mod

    @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.


  • Mod

    @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.


  • Mod

    @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


  • Mod

    @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.



  • @mfalkvidd

    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");
    }
    }


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.