PIR sensor starts to trigger constantly after some time
-
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!
-
@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.
-
@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;
-
@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.
-
@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
-
@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!
-
@Yveaux Isn't the "sleep(3000)" already this blind time? But, sure an increase would be good start.
-
@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.inoIt is a bit complex, sorry. Also, ignore the temperature parts since that is a WIP and is untested.