Slim Node as a Mini 2AA Battery PIR Motion Sensor


  • Hardware Contributor

    After reading about @AWI 's C123A battery based slim PIR sensor, I've finally have had time to play with the mini PIR motion sensor a little myself. Luckily I found a little for me easier, working design which I believe will satisfy my own needs sufficiently. It's basically just the mini-PIR HC-SR505 with its diode and voltage regulator removed, attached to the Slim Node and with simple but suitable sketch.

    Conclusion from my playing with the HC-SR505 was

    • power consumption was identical to mesurements by AWI, 46uA (no movement) and 62uA (movement) . Removing the 7133-regulator did not affect anything significantly due to its very low quiescent current (see datasheet, perhaps useful in some other project?)
    • it's flexible regarding output (load) impedance and load will not affect sensitivity, no need for pull-up/down, filter, etc
    • the supply voltage range with diode and 7133-regulator removed was great. Flawless results with only one AA (1.6V), and I saw no point to go lower.
    • it's very supply noise sensitive and will false trigger on almost anything. Any kind of switching boost (voltage step-up) regulator made it trip continuously. (Found some differences between small and big 3.3V-step-ups btw). Any activity on a nRF connected to same supply would also generate a false trip.
    • the ~3m max range or sensitivity doesn't seem to be affected by voltage level or noise.

    I'm not going to try some hw-filter to get rid of the nRF false trip issue. I think we're all aware of the very hard task to to this when it comes to the nRF itself. For my need it's good enough to just dealing with it in the sketch.

    Two sensor nodes, one shorter enclosure with the PIR peeking out and the other one with a traditional oriented fit. I resoldered one of the three PIR legs so they're all on the same board side to facilitate the angled position.
    20160102_001318.jpg

    The sketch
    The sketch (and this sensor) is not intended to reside in a busy place or work as presence sensor. It's better as a guard, alarm or notification in a low frequency/activity environment. One obvious reason is that the range is not very impressive (max 3m). Then, with this sketch, the controller will just be informed when motion starts. After that, there's no way for it to distinguish absent motion from continuous motion. My reasons for this are (1) it's ok for my application (2) simple (3) save battery and (4) to overcome the false trip problem.

    /**
     * EgSlimReed2
     * Sketch for Slim Node and HC-SR505 based motion sensor. 
     * Inspired by:
     * - MySensors motion sensor example: http://www.mysensors.org/build/motion
     * - AWI's CR123A based Slim Node motion sensor: http://forum.mysensors.org/topic/2478/slim-cr123a-2aa-battery-node
     *
     * Created by m26872
     * Documentation: http://forum.mysensors.org...
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Test to if node can operate in some way dealing with the Pir extreme sensitivity to noise on Vcc.
     * Version 2.0 - First "production node". "Inactivity day counter" introduced.
     * 
     * DESCRIPTION
     * This sketch will only send trips as "1" to the controller. It's up to the controller to deal with the info. 
     * The motion node will not notify controller when resets back to low state and is ready for a new trip. In reality 
     * this is ~10s. And EVEN IF motion is detected continuously, there will be no new trip until motion has stopped for ~10s.  
     * The HC-SR505 is very noise sensitive and will trigger spuriously for almost any activity 
     * on Vcc (test thoroughly). To run the HC-505 at low voltages (tested flawlessly down to 1.6V), 
     * the 7133-reg and diode are removed (and possibly increase the sensitivity even further). 
     * Solution is to deal with it by interrupt type, check which source, block by sleep time etc.
     * 
     * HC-505 output connects to MOTION_INPUT_PIN (here D3) without any supporting component. Input pull-up disabled.
     * Every 24 hrs without trip, increments a counter and after "BATTERY_REPORT_DAY" counts a battery report will be sent as a heartbeat signal.
     * Else a battery report will be sent after every "BATTERY_REPORT_BY_IRT_CYCLE" motion trips.
     *
     */
     
    #include <MySensor.h>
    #include <SPI.h>
    #include <Vcc.h>
    
    //#define DEBUG
    
    #define NODE_ID 14  // Use static Node_ID  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  //14 var senaste "slim-PIR"-id 
    #define SKETCH_NAME "EgSlimPIR2"
    #define SKETCH_VERSION "2.0 2016-01-01"
    #define CHILD_ID 5
    #define MOTION_INPUT_PIN 3
    #define BATTERY_REPORT_DAY 2   // Desired heartbeat(battery report) interval when inactive. 
    #define BATTERY_REPORT_BY_IRT_CYCLE 10  // 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.9
    #define VCC_MAX 3.3
    
    #ifdef DEBUG
    #define DEBUG_SERIAL(x) Serial.begin(x)
    #define DEBUG_PRINT(x) Serial.print(x)
    #define DEBUG_PRINTLN(x) Serial.println(x)
    #else
    #define DEBUG_SERIAL(x)
    #define DEBUG_PRINT(x) 
    #define DEBUG_PRINTLN(x) 
    #endif
    
    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;
    MySensor gw;
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()  
    {  
      DEBUG_SERIAL(9600);
      DEBUG_PRINTLN(("Serial started"));
      delay(100); // to settle power for radio
      gw.begin(NULL,NODE_ID);
      pinMode(MOTION_INPUT_PIN, INPUT);
      digitalWrite(MOTION_INPUT_PIN, LOW);    // Disable internal pull-ups
      gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
      gw.present(CHILD_ID, S_MOTION);
      DEBUG_PRINTLN("Warming and blocking PIR trip for 20s.");
      gw.sleep(20000); // Wait until HC-505 warmed-up and output returned low.
    }
    
    void loop() 
    {
      if (interruptReturn) {	// Woke up by rising pin
    	gw.send(msg.set("1"));  // Just send trip (set) commands to controller. (Let controller reset and decide what to do with it.)
    	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();
    	}
      }
      
      gw.sleep(3000);  // Make sure everything is stable before start to sleep with interrupts. (don't use "gw.wait()" here). Tests shows false trip ~2s after battery report otherwise.
    
      // Sleep until interrupt comes in on motion sensor or sleep time passed.
      interruptReturn = gw.sleep(MOTION_INPUT_PIN-2,RISING, ONE_DAY_SLEEP_TIME);
      // DEBUG_PRINT("interruptReturn: ");DEBUG_PRINTLN(interruptReturn);
    
    } 
    
    void sendBatteryReport() {
    		  float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
    		  int batteryPcnt = static_cast<int>(p);
    		  gw.sendBatteryLevel(batteryPcnt);
    }
    

    Future development
    In future sketch versions an idea is to let the sensor ask my controller when to arm or to disarm. Maybe hourly or with a controller set next sleep time duration. This will be combined with a digital-out pin controlled supply of the HC-SR505 to save the 47uA. Necessary warm-up and false trip blocking and will hopefully be mastered without side effects.

    Power economy
    Idling current 52uA of this PIR motion sensor node is ok, but I'm worried about sending to frequent messages. Especially since I also want some kind of heartbeat for the longer motionless durations. Just to give me perspective I set up the two PIRs to cover the busiest areas in my home for 4 days, busier than usual due to holidays and guests. This produced 1765 messages (9% being battery reports) which is 220 messages/day/sensor. (For a normal weekday the figure was <100.)
    Compare this with my reference Node 105 with ~100uA sleep mode current, 130 messages/day and for which my (today) guess is that it will survive on it's batteries for about 24 months (I know it theoretically doubtful, but the 100uA is probably lower).
    My conclusion is that it's ok to use this PIR motion sensor as it is. The test setup was rather conservative and with a little more thought about how and where to place them, it could be improved.
    I buy 40 AA batteries for the price of one rechargeable CR123A. But sure, the size becomes more attractive with a CR123A.

    Some more photos
    20160101_235910.jpg
    20160101_235844.jpg
    20160101_235800.jpg
    20160102_003416.jpg
    20160102_003452.jpg


  • Mod

    Awesome, great work @m26872 ! Love the pictures.



  • yep i love it, when i can get some inspirations from him. It's one of my greatest problems, howto hide all the stuff i assemble. Here is howto to do it 😄
    Thanks!



  • That looks good! As a newbie, I'm currently building an ethernet/MQTT gateway, and my intention is to build some battery powered nodes to connect to the gateway. What I had planned on researching is building a combination temp/humidity/sensor node for some of the bedrooms, so I can check what the temperatures are and whether there is someone present, to then switch the radiators on/off.

    So my question is this - can you add a DHT11/DHT22 to this with minimal effort?

    Thanks!


  • Hardware Contributor

    @rsachoc Use AWI's design if you need to use the DHT or else use a 1-3V compatible sensor like Si7021 or HTU21. The rechargeable (or at least easy replaceable) battery would also be better if you want to have a more active sensor.



  • Hello,
    I've successfuly uploaded these sketch to my Atmega328p. It works fine. Two things I want add:

    • I have changed the speed in the file MyConfig_h -> #define BAUD_RATE 9600 (otherwise I got nothing at the serial output)
    • The sensor sends an 1 on "motion". How can I send an 0 on "no Motion" after 20sec? (low on data pin?)

    Thank you


  • Hardware Contributor

    @Tom71 said:

    How can I send an 0 on "no Motion" after 20sec? (low on data pin?)

    I suppose you'll need to manipulate sleep time so it wakes up to send "0" after 20s and then go to long sleep after that. Each activity comes with the need of blocking against false trig from the sensor. This would mean that you can't detect motion while sending "0" i.e. 20-30s after the first trip. No big deal, just to mention.



  • Hello !

    @Tom71 Had you had the bigger PIR sensor, you could have adapted the delay manually, but it seems this smaller device doesn't offer that possibility. But I think you could wake up the node on a "CHANGE" interrupt instead of only "RISING" as in the example. For this PIR, it would happen approx 8s after last movement detection. Maybe you could add a 12s sleep phase before sending the zero ?

    @m26872 I've read somewhere that a short distance between the nrf24l01 and the motion sensor could lead to perturbations, and I wonder if you've tested a bigger separation between them and also got those false trips ? They are very close to each other on your example, which makes me wonder.

    Mikael



  • @m26872 You wrote about the idea of letting the sensor ask my controller when to arm or to disarm : have you figured out what way the node could get that information from the controller ?


  • Hardware Contributor

    @Mikael-Kermorgant said:

    Maybe you could add a 12s sleep phase before sending the zero ?

    Yes, but keep in mind that sending of "0" will also trig a new false motion signal, so sleep for another >8s before sleep with interrupt.

    if you've tested a bigger separation between them and also got those false trips ?

    Yes, when I breadboarded this setup, I had them approx. 10cm apart with exactly the same behaviour. I also did test with supply from different boosters (and only LED-resistor as load on motion output). Similar separation and no nRF, all together lead to my conclusion.



  • @m26872 Thanks for the input.

    @Tom71 Have you looked at your controller software if you could manage the "no Motion state" after 20sec ? I'm using domoticz and I could set an "Off delay", avoiding the emission of a zero from the sensor.



  • @Mikael-Kermorgant I'm using fhem. It is possible, that I can set an offline state after 20sec with fhem. I will try this.



  • Hi guys,

    I am wondering, if it wouldn´t be a good idea to use the PinChangeInt Library to wake the arduino from sleep by pin change interrupts. Wouldn´t this be the most power efficient variant? Or did I understand sth. wrong with the pin change interrupts? Thanks for your help in advance!!


  • Hardware Contributor

    I have build a small sensor platform and I am currently running it off of a CR2032 coin cell (small and cheap). I used the same motion sensor as in this thread to build a motion detector. Everything seems to work fine until the voltage drops below ~2.8V, then it starts to trigger constantly. I guess the problem is the low voltage.
    Has anyone found a working setup with a low(er) voltage? Or successfully used a boost converter with a pir (creates false positives as well for me, although I will try that later too).

    Otherwise I would have to use 2xaa (too big) or CR123A (still kinda big and not very cheap) too ;(


  • Hardware Contributor

    @LastSamurai Since I tested it ok down to 1.6V with one AA, I have a feeling that the issue could be voltage stability rather than level. Maybe you could try two CR2032 in parallel ?


  • Hardware Contributor

    @m26872 Great idea, that might help. I am currently trying out another battery, and if that doesn't work I will try 2 in parallel.



  • @m26872, am I understanding correctly that you did not need to step the voltage up to 5v in order to use this PIR sensor? If that's correct, do you know if the HC-SR505 works the same way? I will probably buy some of these smaller ones, but I have HC-SR505s on hand right now and would want to try it soon.


  • Hardware Contributor

    @JonnyDev13 This IS the HC-SR505 (5V Mini PIR). With the voltage regulator and diode removed.

    Did you mean that you have the larger HC-SR501 ? In that case I don't know. I only remember that you'll need to remove the v-reg and diode in the same way to make it run on 3.3V. And I think @bjornhallberg reported successful results from longterm use of a batterypowered outdoor one.



  • @m26872, yes you are correct. I have the larger ones. I must have copied and pasted the wrong part number. Thanks for the quick response. That's helpful information!



  • Hello everybody,

    I´m struggeling with getting this sensor
    to work.
    The node registers with the GW, but doesnt submit the tripped reading.
    Not even a permanent on or something. Just nothing. So i dont know how to troubleshoot here.
    The PIR HC-SR505 is functional. I tested it with a testscript on a UNO.
    And the 2AA Slimnode is functional as well. When using the node as a binary switch it works perfectly fine,
    Just the combination 2AA Slimnode and HC-SR505 doesnt work.

    Anybody has an idea ?

    Thanks in advance Komaandy


  • Hero Member

    @Komaandy how are you powering the circuit?
    The pir sensor is very sensitive to power fluctuations and not suited for below 3v. Also for 3v you need to "modify" the sensors power circuit. You should be able to find a lot of information when searching for the sensor.



  • @ awi, so i desolderd and bridged the two mentioned components, and with the standard " Motion Detector " sketch it transmits tripped readings now 🙂
    I power the circuit via a UNO ( 3,3Volt) or via 2 AA batterys ( 3,1 Volts -> meassured via multimeter)

    but when using the given sketch in this thread only battery readings are transmitted...

    KR

    Komaandy



  • Hello, when running the "Motion Detector sketch from the mysensors-examples" on these nodes with the 1Mhz bootloader with 2aa batteries some nodes freeze after appr. 24h .
    Some continue working, i cant find the problem.
    Does anybody have a idea what could cause those freezes ?
    Thanks in advance


  • Hardware Contributor

    @Komaandy Have you tried to add a sleep(3000); before the last sleep(...)?



  • @m26872 Thanks for your answer and thanks for this superb node 🙂 🙂
    No, i didnt put the additional sleep in , where should I put this ? Im a little confused...

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    // #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    void loop()
    {
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }```

  • Hardware Contributor

    @Komaandy said in Slim Node as a Mini 2AA Battery PIR Motion Sensor:

    I meant like this (look in code below), but it's just a wild guess.

    /**
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Henrik Ekblad
     *
     * DESCRIPTION
     * Motion Sensor example using HC-SR501
     * http://www.mysensors.org/build/motion
     *
     */
    
    // Enable debug prints
    // #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    
    #include <MySensors.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    void loop()
    {
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        sleep(3000);  // Sleep 3s to make sure everything is stable before we start to sleep with interrupts.
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }```


  • @m26872 said in Slim Node as a Mini 2AA Battery PIR Motion Sensor:

    Removing the 7133-regulator did not affect anything significantly due to its very low quiescent current (see datasheet, perhaps useful in some other project?)

    ok, does that mean one does not have to remove the voltage regulator and the diode? @AWI is saying one must modify the PIR and now I am irritated...



  • @siod
    I removed both to make the smaller ( HC-SR505 ) work with ~3Volt and bridged these contacts as shown in the picture
    0_1496861069519_11^^.PNG
    They work perfectly fine for me and are not too sensitive.
    Actually they dont even react on my cats, which is nice, because the "bigger" HC-SR501 always did... 🙂



  • And with the "bigger" HC-SR501 all one need to do is obviously to connect the VCC to the pad or pin.
    For me at least it is working pretty fine as well. No false positives or anything else negative.
    Of course you have to remove the jumper first.

    0_1496861876718_pir_motion_sensor_arduino.jpg


  • Hardware Contributor

    @siod said in Slim Node as a Mini 2AA Battery PIR Motion Sensor:

    @m26872 said in Slim Node as a Mini 2AA Battery PIR Motion Sensor:

    Removing the 7133-regulator did not affect anything significantly due to its very low quiescent current (see datasheet, perhaps useful in some other project?)

    ok, does that mean one does not have to remove the voltage regulator and the diode? @AWI is saying one must modify the PIR and now I am irritated...

    That was only regarding the power consumption. I don't remember the voltage drops but I guess you'll get to it work with 2AA but for a shorter time. Why wont you remove them?



  • ok guys, I tried the mini PIR and the big one, on the mini PIR I removed the regulator and diode just as explained and I uploaded this sketch

    /**
     * EgSlimReed2
     * Sketch for Slim Node and HC-SR505 based motion sensor. 
     * Inspired by:
     * - MySensors motion sensor example: http://www.mysensors.org/build/motion
     * - AWI's CR123A based Slim Node motion sensor: http://forum.mysensors.org/topic/2478/slim-cr123a-2aa-battery-node
     *
     * Created by m26872
     * Documentation: http://forum.mysensors.org...
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Test to if node can operate in some way dealing with the Pir extreme sensitivity to noise on Vcc.
     * Version 2.0 - First "production node". "Inactivity day counter" introduced.
     * 
     * DESCRIPTION
     * This sketch will only send trips as "1" to the controller. It's up to the controller to deal with the info. 
     * The motion node will not notify controller when resets back to low state and is ready for a new trip. In reality 
     * this is ~10s. And EVEN IF motion is detected continuously, there will be no new trip until motion has stopped for ~10s.  
     * The HC-SR505 is very noise sensitive and will trigger spuriously for almost any activity 
     * on Vcc (test thoroughly). To run the HC-505 at low voltages (tested flawlessly down to 1.6V), 
     * the 7133-reg and diode are removed (and possibly increase the sensitivity even further). 
     * Solution is to deal with it by interrupt type, check which source, block by sleep time etc.
     * 
     * HC-505 output connects to MOTION_INPUT_PIN (here D3) without any supporting component. Input pull-up disabled.
     * Every 24 hrs without trip, increments a counter and after "BATTERY_REPORT_DAY" counts a battery report will be sent as a heartbeat signal.
     * Else a battery report will be sent after every "BATTERY_REPORT_BY_IRT_CYCLE" motion trips.
     *
     */
    
     //Sensor 21, erster PIR Sensor
    
    #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen
    // Define Node ID
    #define MY_NODE_ID 21
    #define MY_PARENT_NODE_ID 0 //Repeater Node 1!
    #define MY_PARENT_NODE_IS_STATIC
    
    //Batterysensor
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    #define CHILD_ID_BATT 7
     
    #include <MySensors.h>
    #include <SPI.h>
    #include <Vcc.h>
    
    
    unsigned long SLEEP_TIME = 86400000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of the sensor child
    
    //Battery
    MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE);
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    
        //Batterysensor
         // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor Keller_1", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
        
        //Battery
        present(CHILD_ID_BATT,V_VOLTAGE);
    }
    
    void loop()
    {
        //Batterysensor
      // get the battery Voltage
       int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       #endif
       
       // 1M, 470K divider across battery and using internal ADC ref of 1.1V
       // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
       // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
       // 3.44/1023 = Volts per bit = 0.003363075
       //float batteryV  = sensorValue * 0.003363075;
       int batteryPcnt = sensorValue / 10;
         
         sendBatteryLevel(batteryPcnt);
         wait(500);
         send(msgbatt.set(batteryPcnt));
         wait(500);
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        sleep(3000);  // Sleep 3s to make sure everything is stable before we start to sleep with interrupts.
    
        // Sleep until interrupt comes in on motion sensor. Send update every 24 hours.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    

    But with any PIR I get continuos trip messages every 3 seconds. Any idea?



  • I am having the exact same issues with the Mysensor2.0 version ... (!)

    When using Arduino IDE 1.65 and Mysensor 1.54 librarys and the sketch that is pinned in the header it works .


  • Hardware Contributor



  • Nope, 2.2 is giving me the same fail trip messages.
    When using IDE 1.6.5 with 1.5.4 I don´t even get it compiled, Arduino is automatically using 2.2.0 library from 1.8.2 version which is, of course, still installed on my system and I don´t want to uninstall it...

    edit: Ok, the way @komaandy proposed is working, though I like the other sketch more...

    edit2: Well, seems like it has sth. to do with the battery sensing: when removing this part from void loop() it works as it is supposed to (see what I commented out between /* and */):

    void loop() 
    {
        //Batterysensor
      // get the battery Voltage
       /*int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       #endif
       
       int batteryPcnt = sensorValue / 10;
         
         gw.sendBatteryLevel(batteryPcnt);
         gw.wait(500);
         gw.send(msgbatt.set(batteryPcnt));
         gw.wait(500);
      */
      if (interruptReturn) {  // Woke up by rising pin
      gw.send(msg.set("1"));  // Just send trip (set) commands to controller. (Let controller reset and decide what to do with it.)
      irtCounter++;
    
      }
      
      gw.sleep(3000);  // Make sure everything is stable before start to sleep with interrupts. (don't use "gw.wait()" here). Tests shows false trip ~2s after battery report otherwise.
    
      // Sleep until interrupt comes in on motion sensor or sleep time passed.
      interruptReturn = gw.sleep(MOTION_INPUT_PIN-2,CHANGE, ONE_DAY_SLEEP_TIME);
      // DEBUG_PRINT("interruptReturn: ");DEBUG_PRINTLN(interruptReturn);
    
    } 
    

    edit3: I obviously mixed up things, now it seems like it´s working... I will report back after some time of testing, but this should be my working code:

    /**
     * EgSlimReed2
     * Sketch for Slim Node and HC-SR505 based motion sensor. 
     * Inspired by:
     * - MySensors motion sensor example: http://www.mysensors.org/build/motion
     * - AWI's CR123A based Slim Node motion sensor: http://forum.mysensors.org/topic/2478/slim-cr123a-2aa-battery-node
     *
     * Created by m26872
     * Documentation: http://forum.mysensors.org...
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Test to if node can operate in some way dealing with the Pir extreme sensitivity to noise on Vcc.
     * Version 2.0 - First "production node". "Inactivity day counter" introduced.
     * 
     * DESCRIPTION
     * This sketch will only send trips as "1" to the controller. It's up to the controller to deal with the info. 
     * The motion node will not notify controller when resets back to low state and is ready for a new trip. In reality 
     * this is ~10s. And EVEN IF motion is detected continuously, there will be no new trip until motion has stopped for ~10s.  
     * The HC-SR505 is very noise sensitive and will trigger spuriously for almost any activity 
     * on Vcc (test thoroughly). To run the HC-505 at low voltages (tested flawlessly down to 1.6V), 
     * the 7133-reg and diode are removed (and possibly increase the sensitivity even further). 
     * Solution is to deal with it by interrupt type, check which source, block by sleep time etc.
     * 
     * HC-505 output connects to MOTION_INPUT_PIN (here D3) without any supporting component. Input pull-up disabled.
     * Every 24 hrs without trip, increments a counter and after "BATTERY_REPORT_DAY" counts a battery report will be sent as a heartbeat signal.
     * Else a battery report will be sent after every "BATTERY_REPORT_BY_IRT_CYCLE" motion trips.
     *
     */
    
     #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen
    // Define Node ID
    #define MY_NODE_ID 21
    #define MY_PARENT_NODE_ID 0 //Repeater Node 1=50 / Gateway=0!
    #define MY_PARENT_NODE_IS_STATIC
    
    //Batterysensor
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    #define CHILD_ID_BATT 7
     
    #include <MySensor.h>
    #include <SPI.h>
    #include <Vcc.h>
    
    //#define DEBUG
    
    #define SKETCH_NAME "Motion PIR Keller_1"
    #define SKETCH_VERSION "2.0"
    #define CHILD_ID 1
    #define MOTION_INPUT_PIN 3
    #define BATTERY_REPORT_DAY 2   // Desired heartbeat(battery report) interval when inactive. 
    #define BATTERY_REPORT_BY_IRT_CYCLE 10  // 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.9
    #define VCC_MAX 3.3
    
    
    #ifdef DEBUG
    #define DEBUG_SERIAL(x) Serial.begin(x)
    #define DEBUG_PRINT(x) Serial.print(x)
    #define DEBUG_PRINTLN(x) Serial.println(x)
    #else
    #define DEBUG_SERIAL(x)
    #define DEBUG_PRINT(x) 
    #define DEBUG_PRINTLN(x) 
    #endif
    
    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;
    MySensor gw;
    MyMessage msg(CHILD_ID, V_TRIPPED);
    //Battery
    MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE);
    
    void setup()  
    {  
          //Batterysensor
         // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
    
      DEBUG_SERIAL(9600);
      DEBUG_PRINTLN(("Serial started"));
      delay(100); // to settle power for radio
      gw.begin(NULL,MY_NODE_ID);
      pinMode(MOTION_INPUT_PIN, INPUT);
      digitalWrite(MOTION_INPUT_PIN, LOW);    // Disable internal pull-ups
      gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
      gw.present(CHILD_ID, S_MOTION);
      DEBUG_PRINTLN("Warming and blocking PIR trip for 20s.");
      gw.sleep(20000); // Wait until HC-505 warmed-up and output returned low.
    }
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        gw.sendSketchInfo("Motion Sensor Keller_1", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID, S_MOTION);
        
        //Battery
        gw.present(CHILD_ID_BATT,V_VOLTAGE);
    }
    
    void loop() 
    {
        //Batterysensor
      // get the battery Voltage
       /*int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       #endif
       
       int batteryPcnt = sensorValue / 10;
         
         gw.sendBatteryLevel(batteryPcnt);
         gw.wait(500);
         gw.send(msgbatt.set(batteryPcnt));
         gw.wait(500);
      */
      if (interruptReturn) {  // Woke up by rising pin
      gw.send(msg.set("1"));  // Just send trip (set) commands to controller. (Let controller reset and decide what to do with it.)
        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();
      }
      }
    
      
      
      gw.sleep(3000);  // Make sure everything is stable before start to sleep with interrupts. (don't use "gw.wait()" here). Tests shows false trip ~2s after battery report otherwise.
    
      // Sleep until interrupt comes in on motion sensor or sleep time passed.
      interruptReturn = gw.sleep(MOTION_INPUT_PIN-2,CHANGE, ONE_DAY_SLEEP_TIME);
      // DEBUG_PRINT("interruptReturn: ");DEBUG_PRINTLN(interruptReturn);
    
    } 
    
    void sendBatteryReport() {
          float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
          int batteryPcnt = static_cast<int>(p);
          gw.sendBatteryLevel(batteryPcnt);
    }
    

    edit4: ok, with my edited code this sketch is also working fine now with IDE 1.8.2 and lib 2.2.0 beta. So now everythings works fine!

    /**
     * EgSlimReed2
     * Sketch for Slim Node and HC-SR505 based motion sensor. 
     * Inspired by:
     * - MySensors motion sensor example: http://www.mysensors.org/build/motion
     * - AWI's CR123A based Slim Node motion sensor: http://forum.mysensors.org/topic/2478/slim-cr123a-2aa-battery-node
     *
     * Created by m26872
     * Documentation: http://forum.mysensors.org...
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 1.0 - Test to if node can operate in some way dealing with the Pir extreme sensitivity to noise on Vcc.
     * Version 2.0 - First "production node". "Inactivity day counter" introduced.
     * 
     * DESCRIPTION
     * This sketch will only send trips as "1" to the controller. It's up to the controller to deal with the info. 
     * The motion node will not notify controller when resets back to low state and is ready for a new trip. In reality 
     * this is ~10s. And EVEN IF motion is detected continuously, there will be no new trip until motion has stopped for ~10s.  
     * The HC-SR505 is very noise sensitive and will trigger spuriously for almost any activity 
     * on Vcc (test thoroughly). To run the HC-505 at low voltages (tested flawlessly down to 1.6V), 
     * the 7133-reg and diode are removed (and possibly increase the sensitivity even further). 
     * Solution is to deal with it by interrupt type, check which source, block by sleep time etc.
     * 
     * HC-505 output connects to MOTION_INPUT_PIN (here D3) without any supporting component. Input pull-up disabled.
     * Every 24 hrs without trip, increments a counter and after "BATTERY_REPORT_DAY" counts a battery report will be sent as a heartbeat signal.
     * Else a battery report will be sent after every "BATTERY_REPORT_BY_IRT_CYCLE" motion trips.
     *
     */
    
     //Sensor 21, erster PIR Sensor
    
    #define MY_RADIO_NRF24 //MySensor Library auf NRF24 Funkmodul einstellen, muss vor MySensor.h Initialisierung geschehen
    // Define Node ID
    #define MY_NODE_ID 21
    #define MY_PARENT_NODE_ID 50 //Repeater Node 1!
    #define MY_PARENT_NODE_IS_STATIC
    
    //Batterysensor
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    int oldBatteryPcnt = 0;
    #define CHILD_ID_BATT 7
     
    #include <MySensors.h>
    #include <SPI.h>
    #include <Vcc.h>
    
    
    unsigned long SLEEP_TIME = 86400000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 1   // Id of the sensor child
    #define BATTERY_REPORT_DAY 2   // Desired heartbeat(battery report) interval when inactive. 
    #define BATTERY_REPORT_BY_IRT_CYCLE 10  // 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.9
    #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;
    
    //Battery
    MyMessage msgbatt(CHILD_ID_BATT,V_VOLTAGE);
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    
        //Batterysensor
         // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Motion Sensor Keller_1", "1.0");
    
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
        
        //Battery
        present(CHILD_ID_BATT,V_VOLTAGE);
    }
    
    void loop()
    {
        //Batterysensor
      // get the battery Voltage
       /*int sensorValue = analogRead(BATTERY_SENSE_PIN);
       #ifdef DEBUG
       #endif
       
       // 1M, 470K divider across battery and using internal ADC ref of 1.1V
       // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
       // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
       // 3.44/1023 = Volts per bit = 0.003363075
       //float batteryV  = sensorValue * 0.003363075;
       int batteryPcnt = sensorValue / 10;
         
         sendBatteryLevel(batteryPcnt);
         wait(500);
         send(msgbatt.set(batteryPcnt));
         wait(500);
        */
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
            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);  // Sleep 3s to make sure everything is stable before we start to sleep with interrupts.
    
        // Sleep until interrupt comes in on motion sensor. Send update every 24 hours.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    void sendBatteryReport() {
          float p = vcc.Read_Perc(VCC_MIN, VCC_MAX, true);
          int batteryPcnt = static_cast<int>(p);
          sendBatteryLevel(batteryPcnt);
    }
    


  • I know this is an old topic, but it seems tried and true, so.. How is everyone's experience with this design sofar? Has it been reliable? How far has the 24 month battery life claim held up?

    I've been looking for a detection node that I could use for various tasks around the house (Motion detect, reed switch detect, even a simple door bell). But with a plain arduino pro mini I keep running into abysmal battery life. However this setup seems to handle a year on some AA batteries quite easily?

    If I can get some confirmation on the reliability on these, I can pull the trigger on producing a handful of these slimnodes. 😉


  • Hardware Contributor

    @Sven-0
    Fun to see this old topic again. And also the coincidence, since my visits here have been rare for a long time. 😞
    Anyway, I'm running a few slimnodes since the beginning and have both good and bad experiences. In general, the battery lifetime is your least concern. Instead I have had issues with sensors, sensitivity, switch contact corrosion, mechanical robustness, wifi interference, repaeter, gateway, controller, waf, kids, animals, etc, etc.
    Regarding this particular PIR slimnode it's very stable, but it is not universal for every situation due to the limited range and missing sinsitivity adjustment. E.g I can't use it too near my basement windows due to the moving cold air. And in my living room I have sun reflections to deal with.
    I suggest you start by building a testnode to check if it works for your conditions.🎰
    A recent PIR-slimnode battery life example; My hallway one died last week after 33 months and around 6000 trips/month.💪


Log in to reply
 

Suggested Topics

  • 8
  • 7
  • 1
  • 3
  • 1
  • 1

20
Online

11.4k
Users

11.1k
Topics

112.7k
Posts