PIR sensor starts to trigger constantly after some time


  • Hardware Contributor

    I recently updated my nodes to MySensors 2.0 and shortly after that my motion sensor started to behave strangely. It uses a mini PIR (linked in the mysensors store). It works for the first ~10-120 minutes and then starts to trigger constantly (without motion). I am using one of my minisensors boards (see here for pictures).

    The code I am using is based on the slim node pir from this forum, but converted to mysensors 2.

    /**
     * Based on the sketch of m26872 here https://forum.mysensors.org/topic/2715/slim-node-as-a-mini-2aa-battery-pir-motion-sensor
     * Documentation: http://forum.mysensors.org...
     *
     * Version 1 06.09.2016 basesketch
     * Version 2 12.11.2016 update to mysensors 2
     */
     
    // library settings
    #define MY_RADIO_NRF24
    #define MY_DEBUG    // Enables debug messages in the serial log
    //#define MY_DEBUG_VERBOSE_SIGNING //!< Enable signing related debug prints to serial monitor
    #define MY_BAUD_RATE  9600 // Sets the serial baud rate for console and serial gateway
    //#define MY_SIGNING_SOFT // Enables software signing
    //#define MY_SIGNING_REQUEST_SIGNATURES // Always request signing from gateway//
    //#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 // floating pin for randomness
    //#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x5B,0x96,0x29,0xDD,0x0F,0x80,0x80,0xC5,0x1B}}} // gateway address
    //#define MY_NODE_ID 7
    
    #include <SPI.h>
    #include <MyConfig.h>
    #include <MySensors.h>
    #include <Vcc.h>
    
    // program settings
    #define CHILD_ID 1
    #define CHILD_ID_BATTERY 2
    #define MOTION_INPUT_PIN 3
    #define BATTERY_REPORT_DAY 1   // Desired heartbeat(battery report) interval when inactive. 
    #define BATTERY_REPORT_BY_IRT_CYCLE 30 // Make a battery report after this many trips. Maximum report interval will also be equal to this number of days.
    #define ONE_DAY_SLEEP_TIME 86400000
    #define VCC_MIN 1.8
    #define VCC_MAX 3.3
    
    int dayCounter = BATTERY_REPORT_DAY;
    int irtCounter = 0;
    
    bool interruptReturn = false; // "false" will make the first loop disregard high output from HV-505 (from start-up) and make a battery report instead.
     
    Vcc vcc(1.0);
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    
    
    void before() {
      pinMode(MOTION_INPUT_PIN, INPUT);
      digitalWrite(MOTION_INPUT_PIN, LOW);    // Disable internal pull-ups
    }
    
    void presentation()  
    {  
      sendSketchInfo("Motion sensor", "12112016 v2.0");
      present(CHILD_ID, S_MOTION);
      present(CHILD_ID_BATTERY, S_MULTIMETER);
    
      sleep(20000); // Wait until HC-505 warmed-up and output returned low.
    }
    
    void loop() 
    {
      if (interruptReturn) {    // Woke up by rising pin
        send(msg.set("1"));  // Just send trip (set) commands to controller.
        wait(50);
        send(msg.set("0"));  // Send the off command right after
        irtCounter++;
        if (irtCounter >= BATTERY_REPORT_BY_IRT_CYCLE) {
            irtCounter=0;
            sendBatteryReport();
        }
      }
      else { // Woke up by timer  (or it's the first run)
        dayCounter++; 
        if (dayCounter >= BATTERY_REPORT_DAY) {
              dayCounter = 0;
              sendBatteryReport();
        }
      }
      
      sleep(3000);  // Make sure everything is stable before start to sleep with interrupts. (don't use "wait()" here). Tests shows false trip ~2s after battery report otherwise.
    
      // Sleep until interrupt comes in on motion sensor or sleep time passed.
      interruptReturn = sleep(MOTION_INPUT_PIN-2, RISING, ONE_DAY_SLEEP_TIME);
    } 
    
    void sendBatteryReport() {
      float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
      float v = vcc.Read_Volts();
      int batteryPcnt = static_cast<int>(p);
      sendBatteryLevel(batteryPcnt);
      send(voltage_msg.set(v,3));
    }
    

    Signing is disabled for now as I had some problems with that.

    I am not sure if this has anything to do with the update but it worked before. Any idea how to fix this? Perhaps some kind of pulldown/up resistor or another capacitor?
    Thanks for your help!


  • Mod

    @LastSamurai you could try with the development branch as I fixed some wake from interrupt issues there; it might solve your issues.
    However, I have a comparable experience with cheap pir sensors. Sometimes they trigger when the arduino wakes, probably due to power variation (any other ideas are welcome).
    I can imagine that due to changes in amount/order/speed of messages sent in 2.0 this might trigger this strange behavior of the pir sensor.


  • Hardware Contributor

    @Yveaux Thanks for the help, but it seems like the problem got only worse with the development branch. I guess its some kind of hardware problem then. Hopefully my pcb for the ikea motion sensor will arrive soon, then I will try them out.



  • Try with a fresh battery! Do you have any step-up converter for the PIR? I've also had the same problem recently, and I think (still need to test a bit more) that it was caused by the battery getting a bit discharged (after an OTA update).

    It usually triggers the PIR when the radio sends something. I think it is because the radio makes the voltage fluctuate when it sends.
    A simple workaround is to wait 3 seconds (the time my PIR takes to reset/settle after triggering) after sending data, and only then check if it has triggered. But I only wait if the previous state was zero (no motion), since I want it to fire instantaneously when motion is detected. So:

    • Get state;
    • Send state data;
    • If state was 1, sleep 3 secs;
    • Send new state if it changed from 0 to 1 (during 3 secs sleep);
    • Sleep with interrupt;

  • Hardware Contributor

    @abmantis Thanks for the answer. I think I got most of this. I modified some code from another pir post in this forum.
    Here is the code. Is that what you did too?

    // library settings
    #define MY_RADIO_NRF24
    #define MY_DEBUG    // Enables debug messages in the serial log
    //#define MY_DEBUG_VERBOSE_SIGNING //!< Enable signing related debug prints to serial monitor
    #define MY_BAUD_RATE  9600 // Sets the serial baud rate for console and serial gateway
    #define MY_SIGNING_SOFT // Enables software signing
    //#define MY_SIGNING_REQUEST_SIGNATURES // Always request signing from gateway
    #define MY_SIGNING_SOFT_RANDOMSEED_PIN 7 // floatingpin  for randomness
    #define MY_NODE_ID 12
    
    #include <SPI.h>
    #include <MyConfig.h>
    #include <MySensors.h>
    #include <Vcc.h>
    
    // program settings
    #define CHILD_ID 1
    #define CHILD_ID_BATTERY 2
    #define MOTION_INPUT_PIN 3
    #define BATTERY_REPORT_DAY 1   // Desired heartbeat(battery report) interval when inactive. 
    #define BATTERY_REPORT_BY_IRT_CYCLE 30 // Make a battery report after this many trips. Maximum report interval will also be equal to this number of days.
    #define ONE_DAY_SLEEP_TIME 86400000
    #define VCC_MIN 1.8
    #define VCC_MAX 3.3
    
    int dayCounter = BATTERY_REPORT_DAY;
    int irtCounter = 0;
    
    bool interruptReturn = false; // "false" will make the first loop disregard high output from HV-505 (from start-up) and make a battery report instead.
     
    Vcc vcc(1.0);
    MyMessage msg(CHILD_ID, V_TRIPPED);
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    
    
    void before() {
      pinMode(MOTION_INPUT_PIN, INPUT);
      digitalWrite(MOTION_INPUT_PIN, LOW);    // Disable internal pull-ups
    }
    
    void presentation()  
    {  
      sendSketchInfo("Motion sensor", "12112016 v2.0");
      present(CHILD_ID, S_MOTION);
      present(CHILD_ID_BATTERY, S_MULTIMETER);
    
      sleep(20000); // Wait until HC-505 warmed-up and output returned low.
    }
    
    void loop() 
    {
      if (interruptReturn) {    // Woke up by rising pin
        send(msg.set("1"));  // Just send trip (set) commands to controller.
        wait(50);
        send(msg.set("0"));  // Send the off command right after
        irtCounter++;
        if (irtCounter >= BATTERY_REPORT_BY_IRT_CYCLE) {
            irtCounter=0;
            sendBatteryReport();
        }
      }
      else { // Woke up by timer  (or it's the first run)
        dayCounter++; 
        if (dayCounter >= BATTERY_REPORT_DAY) {
              dayCounter = 0;
              sendBatteryReport();
        }
      }
      
      sleep(3000);  // Make sure everything is stable before start to sleep with interrupts. (don't use "wait()" here). Tests shows false trip ~2s after battery report otherwise.
    
      // Sleep until interrupt comes in on motion sensor or sleep time passed.
      interruptReturn = sleep(MOTION_INPUT_PIN-2, RISING, ONE_DAY_SLEEP_TIME);
    } 
    
    void sendBatteryReport() {
      wait(50);
      float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
      float v = vcc.Read_Volts();
      int batteryPcnt = static_cast<int>(p);
      sendBatteryLevel(batteryPcnt);
      send(voltage_msg.set(v,3));
    }
    


  • My code is a little different, since I only send 0 when the PIR reports 0, instead of sending it right after 1.

    If you want I may post the code later.


  • Hardware Contributor

    @abmantis Yes, I did that earlier too, but like this it was easier too use with my controller. Would be great if you could post your code too. Then I could test that too. Really want to get my pir up and working again 😉


  • Mod

    @LastSamurai a quick test would be to introduce a blind time after triggering by issuing a sleep for a fixed amount of time (e.g 30 secs) without wake from Interrupt.
    After this sleep you start another sleep which will wake when the sensor triggers.
    I added this to my pir sensors and it works great!


  • Hardware Contributor

    @Yveaux Isn't the "sleep(3000)" already this blind time? But, sure an increase would be good start.


  • Mod

    @m26872 yup, you're right 😏 I didn't look at the sketch.
    It should indeed wait longer than 3 seconds.



  • @LastSamurai Here is the code for my PIR and Light sensore node:
    https://github.com/abmantis/MySensors-Sketches/blob/master/MotionLightSensor/MotionLightSensor.ino

    It is a bit complex, sorry. Also, ignore the temperature parts since that is a WIP and is untested.


Log in to reply
 

516
Online

6.9k
Users

7.8k
Topics

82.7k
Posts

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