Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. General Discussion
  3. pir trigger must start delay

pir trigger must start delay

Scheduled Pinned Locked Moved General Discussion
16 Posts 4 Posters 3.1k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • DickD Offline
    DickD Offline
    Dick
    wrote on last edited by
    #1

    Is there anyone who can me help with the next step in getting this sensor to work. It is a combi of 3 relays, motion sensor and 2 temps. All works now but if the Motion is triggered it starts the SLEEP_TIME. but in this period I cannot use the buttons to activate the relays. How can I only stop the motion trigger (for a period of time) without affecting the test of the sensors.

    DickD m26872M 2 Replies Last reply
    0
    • DickD Dick

      Is there anyone who can me help with the next step in getting this sensor to work. It is a combi of 3 relays, motion sensor and 2 temps. All works now but if the Motion is triggered it starts the SLEEP_TIME. but in this period I cannot use the buttons to activate the relays. How can I only stop the motion trigger (for a period of time) without affecting the test of the sensors.

      DickD Offline
      DickD Offline
      Dick
      wrote on last edited by
      #2

      Here the code to make it more clear

      @Dick said in pir trigger must start delay:

      Is there anyone who can me help with the next step in getting this sensor to work. It is a combi of 3 relays, motion sensor and 2 temps. All works now but if the Motion is triggered it starts the SLEEP_TIME. but in this period I cannot use the buttons to activate the relays. How can I only stop the motion trigger (for a period of time) without affecting the test of the sensors.

      // 2x binary switch + dallas temp example 
      // Connect button or door/window reed switch between 
      // digitial I/O pin 4,5 (BUTTON_PIN_4/BUTTON_PIN_5 below) and GND.
      // Connect dallas temp sensor to digital pin 3
      
      #include <MySensor.h>
      #include <SPI.h>
      #include <Bounce2.h>
      #include <DallasTemperature.h>
      #include <OneWire.h>
      #define DIGITAL_MOTION_SENSOR 2
      #define CHILD_ID_MOTION 6
      #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
      #define MAX_ATTACHED_DS18B20 16
      #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
      #define RELAY_OFF 1
      
      Bounce motionsDebouncer = Bounce();
      
      int lastMOTION;
      unsigned long SLEEP_TIME = 60000;
      
      
      OneWire oneWire(ONE_WIRE_BUS);
      DallasTemperature sensors(&oneWire);
      MySensor gw;
      
      #define noRelays 3
      const int relayPin[] = {A3, A4, A5}; //  switch around pins to your desire
      const int buttonPin[] = {6, 7, 8}; //  switch around pins to your desire
      
      class Relay             // relay class, store all relevant data (equivalent to struct)
      {
      public: 
        int buttonPin;                    // physical pin number of button
        int relayPin;                     // physical pin number of relay
        byte oldValue;                    // last Values for key (debounce)
        boolean relayState;               // relay status (also stored in EEPROM)
      };
      
      Relay Relays[noRelays];
      Bounce debouncerRELAY[noRelays];
      MyMessage msgRELAY[noRelays];
      
      
      float lastTemperature[MAX_ATTACHED_DS18B20];
      int numSensors=0;
      boolean receivedConfig = false;
      boolean metric = true; 
      MyMessage msg(0,V_TEMP);
      MyMessage msgMOTION(CHILD_ID_MOTION, V_TRIPPED);
      
      void setup()  
      {  
        sensors.begin();
        //gw.begin();
        gw.begin(incomingMessage, AUTO, true);
        gw.sendSketchInfo("Motion/Temp/relay", "1.0");
        numSensors = sensors.getDeviceCount();
        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) 
        {   
          gw.present(i, S_TEMP);
        }
      
      
       
      pinMode(DIGITAL_MOTION_SENSOR, INPUT_PULLUP);      // sets the motion sensor digital pin as input
        motionsDebouncer.attach(DIGITAL_MOTION_SENSOR);
        motionsDebouncer.interval(10);
        // Register all sensors to gw (they will be created as child devices)
        gw.present(CHILD_ID_MOTION, S_MOTION, "Motion needs presentation", true);
      
         for (int i = 0; i < noRelays; i++)
        {
          Relays[i].buttonPin = buttonPin[i];              // assign physical pins
          Relays[i].relayPin = relayPin[i];
          msgRELAY[i].sensor = i;                                   // initialize messages
          msgRELAY[i].type = V_LIGHT;
          debouncerRELAY[i] = Bounce();                        // initialize debouncer
          debouncerRELAY[i].attach(buttonPin[i]);
          debouncerRELAY[i].interval(5);
          pinMode(Relays[i].buttonPin, INPUT_PULLUP);
          pinMode(Relays[i].relayPin, OUTPUT);
          Relays[i].relayState = gw.loadState(i);                               // retrieve last values from EEPROM
          digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
          gw.send(msgRELAY[i].set(Relays[i].relayState ? true : false));                 // make controller aware of last status
          gw.present(i, S_LIGHT);                               // present sensor to gateway
          delay(250);
      
        }
          
      }
      void loop() 
      {
      gw.process(); 
      
      for (byte i = 0; i < noRelays; i++)
        {
          debouncerRELAY[i].update();
          byte value = debouncerRELAY[i].read();
          if (value != Relays[i].oldValue && value == 0)
          {
            Relays[i].relayState = !Relays[i].relayState;
            digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF);
            gw.send(msgRELAY[i].set(Relays[i].relayState ? true : false));
            gw.saveState( i, Relays[i].relayState );
          }                 // save sensor state in EEPROM (location == sensor number)
      
          Relays[i].oldValue = value;
        }
        
        if ( motionsDebouncer.update()) {
          int value = motionsDebouncer.read();
          Serial.println( "PIR " + (String)value );
          gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
          
      // Sleep until interrupt comes in on motion sensor. Send update.
        gw.sleep(DIGITAL_MOTION_SENSOR, CHANGE, SLEEP_TIME);
        }
      
         
       
        
        updateTemperature(30);// update time in seconds
        
      }
      
      void updateTemperature(int frequency)
      {
        static unsigned long lastUpdateTime;
        if (millis() - lastUpdateTime >= frequency * 1000UL)
        {
          sensors.requestTemperatures(); 
          for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) 
          {
            float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
            if (lastTemperature[i] != temperature && temperature != -127.00) 
            {
              gw.send(msg.setSensor(i).set(temperature,1));
              lastTemperature[i]=temperature;
            }
          }
          lastUpdateTime += frequency * 1000UL;
        }
      }
      
      void incomingMessage(const MyMessage &message)
      {
      
        if (message.type == V_LIGHT)
        {
          if (message.sensor < noRelays)            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
          {
            Relays[message.sensor].relayState = message.getBool();
            digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
            gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
          }
        }
      //gw.wait(50);
      
      }
      
      
      1 Reply Last reply
      0
      • gohanG Offline
        gohanG Offline
        gohan
        Mod
        wrote on last edited by
        #3

        During sleep you can only wake it up by using the interrupts of pins 2 and 3. Is it a battery powered node?

        1 Reply Last reply
        0
        • DickD Dick

          Is there anyone who can me help with the next step in getting this sensor to work. It is a combi of 3 relays, motion sensor and 2 temps. All works now but if the Motion is triggered it starts the SLEEP_TIME. but in this period I cannot use the buttons to activate the relays. How can I only stop the motion trigger (for a period of time) without affecting the test of the sensors.

          m26872M Offline
          m26872M Offline
          m26872
          Hardware Contributor
          wrote on last edited by m26872
          #4

          @Dick You should use a non-blocking code. Replace your if ( motionsDebouncer.update()) {...} with an updateMotion(SLEEP_TIME); which could be something like

          void updateMotion(unsigned long blockedMotionTime)
          {
            static unsigned long lastUpdateTime;
            if (millis() - lastUpdateTime >= blockedMotionTime)
            {
          	  if ( motionsDebouncer.update()) {
          		int value = motionsDebouncer.read();
          		Serial.println( "PIR " + (String)value );
          		gw.send( msgMOTION.set( value ), true );
          		lastUpdateTime += blockedMotionTime;
          	  }
            }  
          }
          

          Never use sleep if you want to listen for incoming messages. wait is not good either since you expect button press. Buttons could use an interruptpin if needed, but it looks like your not on battery.

          DickD 2 Replies Last reply
          1
          • m26872M m26872

            @Dick You should use a non-blocking code. Replace your if ( motionsDebouncer.update()) {...} with an updateMotion(SLEEP_TIME); which could be something like

            void updateMotion(unsigned long blockedMotionTime)
            {
              static unsigned long lastUpdateTime;
              if (millis() - lastUpdateTime >= blockedMotionTime)
              {
            	  if ( motionsDebouncer.update()) {
            		int value = motionsDebouncer.read();
            		Serial.println( "PIR " + (String)value );
            		gw.send( msgMOTION.set( value ), true );
            		lastUpdateTime += blockedMotionTime;
            	  }
              }  
            }
            

            Never use sleep if you want to listen for incoming messages. wait is not good either since you expect button press. Buttons could use an interruptpin if needed, but it looks like your not on battery.

            DickD Offline
            DickD Offline
            Dick
            wrote on last edited by
            #5

            @m26872
            thanks for the short lesson. I change the code it test it.

            1 Reply Last reply
            1
            • m26872M m26872

              @Dick You should use a non-blocking code. Replace your if ( motionsDebouncer.update()) {...} with an updateMotion(SLEEP_TIME); which could be something like

              void updateMotion(unsigned long blockedMotionTime)
              {
                static unsigned long lastUpdateTime;
                if (millis() - lastUpdateTime >= blockedMotionTime)
                {
              	  if ( motionsDebouncer.update()) {
              		int value = motionsDebouncer.read();
              		Serial.println( "PIR " + (String)value );
              		gw.send( msgMOTION.set( value ), true );
              		lastUpdateTime += blockedMotionTime;
              	  }
                }  
              }
              

              Never use sleep if you want to listen for incoming messages. wait is not good either since you expect button press. Buttons could use an interruptpin if needed, but it looks like your not on battery.

              DickD Offline
              DickD Offline
              Dick
              wrote on last edited by
              #6

              @m26872 I implemented the function but it does not work. I also read more about the NON BLOCKING code. is new for me. At the moment the pir pin give no reaction. nothing happend with the new function. The relays and temp sensors are working fine. Any idea to get it work so I can see a working example so I can use it in my other sensors.

              m26872M 1 Reply Last reply
              0
              • DickD Dick

                @m26872 I implemented the function but it does not work. I also read more about the NON BLOCKING code. is new for me. At the moment the pir pin give no reaction. nothing happend with the new function. The relays and temp sensors are working fine. Any idea to get it work so I can see a working example so I can use it in my other sensors.

                m26872M Offline
                m26872M Offline
                m26872
                Hardware Contributor
                wrote on last edited by
                #7

                @Dick I'm no code expert, but I would make the two lastUpdateTime-variables as global ones and initialize them with 0.

                DickD 1 Reply Last reply
                0
                • m26872M m26872

                  @Dick I'm no code expert, but I would make the two lastUpdateTime-variables as global ones and initialize them with 0.

                  DickD Offline
                  DickD Offline
                  Dick
                  wrote on last edited by
                  #8

                  @m26872 it is all new for me this solution. How can I make them global?? that means outside the function? is that the only thing I have to do?

                  m26872M 1 Reply Last reply
                  0
                  • DickD Dick

                    @m26872 it is all new for me this solution. How can I make them global?? that means outside the function? is that the only thing I have to do?

                    m26872M Offline
                    m26872M Offline
                    m26872
                    Hardware Contributor
                    wrote on last edited by
                    #9

                    @Dick Since they are 'static' I think you only need to initialize them with 0 , maybe not even that. I simply dont know. Your problem could be something else too. Sorry.

                    DickD 1 Reply Last reply
                    0
                    • m26872M m26872

                      @Dick Since they are 'static' I think you only need to initialize them with 0 , maybe not even that. I simply dont know. Your problem could be something else too. Sorry.

                      DickD Offline
                      DickD Offline
                      Dick
                      wrote on last edited by
                      #10

                      @m26872 No Problem. I continue reading. If someone else knows what to do please reply.

                      1 Reply Last reply
                      0
                      • BartEB Offline
                        BartEB Offline
                        BartE
                        Contest Winner
                        wrote on last edited by BartE
                        #11

                        @Dick said in pir trigger must start delay:

                        Replace this piece of code

                          if ( motionsDebouncer.update()) {
                             int value = motionsDebouncer.read();
                             Serial.println( "PIR " + (String)value );
                             gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                             
                         // Sleep until interrupt comes in on motion sensor. Send update.
                           gw.sleep(DIGITAL_MOTION_SENSOR, CHANGE, SLEEP_TIME);
                           }
                        

                        with something like this

                        if (blockMotionTimer == 0) {
                        {
                            if (motionsDebouncer.update()) {
                                int value = motionsDebouncer.read();
                                Serial.println( "PIR " + (String)value );
                                gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                                blockMotionTimer = (millis() + SLEEP_TIME);
                           } else {
                                motionsDebouncer.update(); // dummy update to prevent false trigger after timer expires 
                                if (blockMotionTimer < millis()) {
                                    blockMotionTimer = 0;
                                }
                           }
                        }
                        

                        Add this line at the top of your sketch (just below SLEEP_TIME)

                        unsigned long blockMotionTimer = 0;
                        
                        DickD 1 Reply Last reply
                        0
                        • BartEB BartE

                          @Dick said in pir trigger must start delay:

                          Replace this piece of code

                            if ( motionsDebouncer.update()) {
                               int value = motionsDebouncer.read();
                               Serial.println( "PIR " + (String)value );
                               gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                               
                           // Sleep until interrupt comes in on motion sensor. Send update.
                             gw.sleep(DIGITAL_MOTION_SENSOR, CHANGE, SLEEP_TIME);
                             }
                          

                          with something like this

                          if (blockMotionTimer == 0) {
                          {
                              if (motionsDebouncer.update()) {
                                  int value = motionsDebouncer.read();
                                  Serial.println( "PIR " + (String)value );
                                  gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                                  blockMotionTimer = (millis() + SLEEP_TIME);
                             } else {
                                  motionsDebouncer.update(); // dummy update to prevent false trigger after timer expires 
                                  if (blockMotionTimer < millis()) {
                                      blockMotionTimer = 0;
                                  }
                             }
                          }
                          

                          Add this line at the top of your sketch (just below SLEEP_TIME)

                          unsigned long blockMotionTimer = 0;
                          
                          DickD Offline
                          DickD Offline
                          Dick
                          wrote on last edited by
                          #12

                          @BartE Hi Bart thanks for the solution but hopefully you can help me with the last hurdle:
                          I added your solution, after starting the node I can activate the PIR once (it state change from 1 to 0) and stays in 0 and will not change anymore.
                          Here the code as it is now

                          // 2x binary switch + dallas temp example 
                          // Connect button or door/window reed switch between 
                          // digitial I/O pin 4,5 (BUTTON_PIN_4/BUTTON_PIN_5 below) and GND.
                          // Connect dallas temp sensor to digital pin 3
                          
                          #include <MySensor.h>
                          #include <SPI.h>
                          #include <Bounce2.h>
                          #include <DallasTemperature.h>
                          #include <OneWire.h>
                          #define DIGITAL_MOTION_SENSOR 2
                          #define CHILD_ID_MOTION 6
                          #define ONE_WIRE_BUS 3 // Pin where dallase sensor is connected 
                          #define MAX_ATTACHED_DS18B20 16
                          #define RELAY_ON 0                      // switch around for realy HIGH/LOW state
                          #define RELAY_OFF 1
                          
                          Bounce motionsDebouncer = Bounce();
                          
                          int lastMOTION;
                          unsigned long SLEEP_TIME = 3600;
                          unsigned long blockMotionTimer = 0;
                          
                          
                          OneWire oneWire(ONE_WIRE_BUS);
                          DallasTemperature sensors(&oneWire);
                          MySensor gw;
                          
                          #define noRelays 3
                          const int relayPin[] = {A3, A4, A5}; //  switch around pins to your desire
                          const int buttonPin[] = {6, 7, 8}; //  switch around pins to your desire
                          
                          class Relay             // relay class, store all relevant data (equivalent to struct)
                          {
                          public: 
                            int buttonPin;                    // physical pin number of button
                            int relayPin;                     // physical pin number of relay
                            byte oldValue;                    // last Values for key (debounce)
                            boolean relayState;               // relay status (also stored in EEPROM)
                          };
                          
                          Relay Relays[noRelays];
                          Bounce debouncerRELAY[noRelays];
                          MyMessage msgRELAY[noRelays];
                          
                          
                          float lastTemperature[MAX_ATTACHED_DS18B20];
                          int numSensors=0;
                          boolean receivedConfig = false;
                          boolean metric = true; 
                          MyMessage msg(0,V_TEMP);
                          MyMessage msgMOTION(CHILD_ID_MOTION, V_TRIPPED);
                          
                          void setup()  
                          {  
                            sensors.begin();
                            //gw.begin();
                            gw.begin(incomingMessage, AUTO, true);
                            gw.sendSketchInfo("Motion/Temp/relay", "1.0");
                            numSensors = sensors.getDeviceCount();
                            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) 
                            {   
                              gw.present(i, S_TEMP);
                            }
                          
                          
                           
                          pinMode(DIGITAL_MOTION_SENSOR, INPUT_PULLUP);      // sets the motion sensor digital pin as input
                            motionsDebouncer.attach(DIGITAL_MOTION_SENSOR);
                            motionsDebouncer.interval(400);
                            // Register all sensors to gw (they will be created as child devices)
                            gw.present(CHILD_ID_MOTION, S_MOTION, "Motion needs presentation", true);
                          
                             for (int i = 0; i < noRelays; i++)
                            {
                              Relays[i].buttonPin = buttonPin[i];              // assign physical pins
                              Relays[i].relayPin = relayPin[i];
                              msgRELAY[i].sensor = i;                                   // initialize messages
                              msgRELAY[i].type = V_LIGHT;
                              debouncerRELAY[i] = Bounce();                        // initialize debouncer
                              debouncerRELAY[i].attach(buttonPin[i]);
                              debouncerRELAY[i].interval(5);
                              pinMode(Relays[i].buttonPin, INPUT_PULLUP);
                              pinMode(Relays[i].relayPin, OUTPUT);
                              Relays[i].relayState = gw.loadState(i);                               // retrieve last values from EEPROM
                              digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
                              gw.send(msgRELAY[i].set(Relays[i].relayState ? true : false));                 // make controller aware of last status
                              gw.present(i, S_LIGHT);                               // present sensor to gateway
                              delay(250);
                          
                            }
                              
                          }
                          void loop() 
                          {
                          gw.process(); 
                          
                          for (byte i = 0; i < noRelays; i++)
                            {
                              debouncerRELAY[i].update();
                              byte value = debouncerRELAY[i].read();
                              if (value != Relays[i].oldValue && value == 0)
                              {
                                Relays[i].relayState = !Relays[i].relayState;
                                digitalWrite(Relays[i].relayPin, Relays[i].relayState ? RELAY_ON : RELAY_OFF);
                                gw.send(msgRELAY[i].set(Relays[i].relayState ? true : false));
                                gw.saveState( i, Relays[i].relayState );
                              }                 // save sensor state in EEPROM (location == sensor number)
                          
                              Relays[i].oldValue = value;
                            }
                            
                            if (blockMotionTimer == 0) {
                          {
                              if (motionsDebouncer.update()) {
                                  int value = motionsDebouncer.read();
                                  Serial.println( "PIR " + (String)value );
                                  gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                                  blockMotionTimer = (millis() + SLEEP_TIME);
                             } else {
                                  motionsDebouncer.update(); // dummy update to prevent false trigger after timer expires 
                                  if (blockMotionTimer < millis()) {
                                      blockMotionTimer = 0;
                                  }
                             }
                          }
                            }
                          
                             
                           
                            
                            updateTemperature(30);// update time in seconds
                            
                          }
                          
                          void updateTemperature(int frequency)
                          {
                            static unsigned long lastUpdateTime;
                            if (millis() - lastUpdateTime >= frequency * 1000UL)
                            {
                              sensors.requestTemperatures(); 
                              for (int i=0; i<numSensors && i< MAX_ATTACHED_DS18B20; i++) 
                              {
                                float temperature = static_cast<float>(static_cast<int>((gw.getConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                                if (lastTemperature[i] != temperature && temperature != -127.00) 
                                {
                                  gw.send(msg.setSensor(i).set(temperature,1));
                                  lastTemperature[i]=temperature;
                                }
                              }
                              lastUpdateTime += frequency * 1000UL;
                            }
                          }
                          
                          void incomingMessage(const MyMessage &message)
                          {
                          
                            if (message.type == V_LIGHT)
                            {
                              if (message.sensor < noRelays)            // check if message is valid for relays..... previous line  [[[ if (message.sensor <=noRelays){ ]]]
                              {
                                Relays[message.sensor].relayState = message.getBool();
                                digitalWrite(Relays[message.sensor].relayPin, Relays[message.sensor].relayState ? RELAY_ON : RELAY_OFF); // and set relays accordingly
                                gw.saveState( message.sensor, Relays[message.sensor].relayState ); // save sensor state in EEPROM (location == sensor number)
                              }
                            }
                          //gw.wait(50);
                          
                          }
                          
                          `
                          1 Reply Last reply
                          0
                          • BartEB Offline
                            BartEB Offline
                            BartE
                            Contest Winner
                            wrote on last edited by BartE
                            #13

                            @Dick mm look like a } on the wrong line. The } on line 126 should move up between line 119 and 120
                            (and there are 2 additional brackets)

                            The result should look like this

                            
                            if (blockMotionTimer == 0) {
                                if (motionsDebouncer.update()) {
                                    int value = motionsDebouncer.read();
                                    Serial.println( "PIR " + (String)value );
                                    gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                                    blockMotionTimer = (millis() + SLEEP_TIME);
                               }
                            } else {
                                    motionsDebouncer.update(); // dummy update to prevent false trigger after timer expires 
                                    if (blockMotionTimer < millis()) {
                                        blockMotionTimer = 0;
                                    }
                            }
                            
                            
                            DickD 1 Reply Last reply
                            0
                            • BartEB BartE

                              @Dick mm look like a } on the wrong line. The } on line 126 should move up between line 119 and 120
                              (and there are 2 additional brackets)

                              The result should look like this

                              
                              if (blockMotionTimer == 0) {
                                  if (motionsDebouncer.update()) {
                                      int value = motionsDebouncer.read();
                                      Serial.println( "PIR " + (String)value );
                                      gw.send( msgMOTION.set( value ), true ); // Also it might need inverted value
                                      blockMotionTimer = (millis() + SLEEP_TIME);
                                 }
                              } else {
                                      motionsDebouncer.update(); // dummy update to prevent false trigger after timer expires 
                                      if (blockMotionTimer < millis()) {
                                          blockMotionTimer = 0;
                                      }
                              }
                              
                              
                              DickD Offline
                              DickD Offline
                              Dick
                              wrote on last edited by
                              #14

                              @BartE It works fine. Now I try to understand how it works, have found already some documentation about this item. again thanks!

                              BartEB 1 Reply Last reply
                              0
                              • DickD Dick

                                @BartE It works fine. Now I try to understand how it works, have found already some documentation about this item. again thanks!

                                BartEB Offline
                                BartEB Offline
                                BartE
                                Contest Winner
                                wrote on last edited by
                                #15

                                @Dick nice to hear

                                How it works:

                                As long as 'blockMotionTimer' is zero the motion debouncer is being monitored for any change.
                                When a PIR-change is detected the blockMotionTimer gets the value of the Arduino's internal milliseconds timer + the delay in milliseconds one want to wait.
                                This happes on this line: "blockMotionTimer = (millis() + SLEEP_TIME);"
                                See more about the millis() here

                                The blockMotionTimer is set back to zero the when mills() reaches the value set for time-out done with this check "if (blockMotionTimer < millis()) {" , and because the blockMotionTimer is non-zero the PIR value will not be checked during this period.

                                Expert note: since the milliseconds counter is returned in an unsigned long it will carry over one moment in time. Since Arduino stores it's ulong in 32 bits this means a carry over each 2^32 thus 4294967296 milliseconds. This is approx. every 50 days (49,71 days) So in theory this mechanism could result in a wrong (very short) delay, when timer is started precisely with the SLEEP_TIME period just before these 49,71 days. The result of millis() + SLEEP_TIME will then carry over and is immediate smaller than millis() on the next check. So be aware that this check if (blockMotionTimer > (millis() - SLEEP_TIME)) can result in a death-lock when blockMotionTimer = millis(); was set on the wrong moment in time.

                                DickD 1 Reply Last reply
                                0
                                • BartEB BartE

                                  @Dick nice to hear

                                  How it works:

                                  As long as 'blockMotionTimer' is zero the motion debouncer is being monitored for any change.
                                  When a PIR-change is detected the blockMotionTimer gets the value of the Arduino's internal milliseconds timer + the delay in milliseconds one want to wait.
                                  This happes on this line: "blockMotionTimer = (millis() + SLEEP_TIME);"
                                  See more about the millis() here

                                  The blockMotionTimer is set back to zero the when mills() reaches the value set for time-out done with this check "if (blockMotionTimer < millis()) {" , and because the blockMotionTimer is non-zero the PIR value will not be checked during this period.

                                  Expert note: since the milliseconds counter is returned in an unsigned long it will carry over one moment in time. Since Arduino stores it's ulong in 32 bits this means a carry over each 2^32 thus 4294967296 milliseconds. This is approx. every 50 days (49,71 days) So in theory this mechanism could result in a wrong (very short) delay, when timer is started precisely with the SLEEP_TIME period just before these 49,71 days. The result of millis() + SLEEP_TIME will then carry over and is immediate smaller than millis() on the next check. So be aware that this check if (blockMotionTimer > (millis() - SLEEP_TIME)) can result in a death-lock when blockMotionTimer = millis(); was set on the wrong moment in time.

                                  DickD Offline
                                  DickD Offline
                                  Dick
                                  wrote on last edited by
                                  #16

                                  @BartE What an extended answere. Here I can do something with. Good learning stuff.

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  21

                                  Online

                                  11.7k

                                  Users

                                  11.2k

                                  Topics

                                  113.1k

                                  Posts


                                  Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • MySensors
                                  • OpenHardware.io
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular