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. Development
  3. 433MHz Motion Sensor sketch

433MHz Motion Sensor sketch

Scheduled Pinned Locked Moved Development
433 motion sensor
13 Posts 3 Posters 4.5k Views 4 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.
  • N niccodemi

    @BartE yes, I tried. If I change delay to wait the sketch compiles and I can upload it. After node receives 433 sensor input node sends out tripped value 1 and then stops responding (I have to reboot it). I guess the issue is because of using "wait(1000)" outside of void loop function?

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

    @niccodemi I just had a better look @ your code. I think the issue is that your try to wait in an interrupt service routine (ISR) this is "killing" for most processors. showOldCod() is called from an interrupt.

    Better is to keep the time in and ISR as short as possible. So just remember you did received a trigger and and leave the routine.
    Something like this (not tested but should give an idea)

    /*
    433MHz Motion Sensor
     * Setup:
     * - connect a 433MHz receiver on digital pin 2.
     *
     * MySensor note: This example has not yet been adopted but can be used as an example
     * of receiving 433Mhz stuff. 
     * 
     * One idea could be to echo received 433 codes back to gateway to be able to pick up and
     * handle data over there.
     *
    */
    #define MY_DEBUG
    
    #define MY_RADIO_NRF24
    
    #include <RemoteReceiver.h>
    #include <InterruptChain.h>
    #include <SPI.h>
    #include <MySensor.h>
    
    unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
    
    //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
    #define CHILD_ID_1 1   // Id of the sensor child
    #define CHILD_ID_2 2   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg1(CHILD_ID_1, V_TRIPPED);
    MyMessage msg2(CHILD_ID_2, V_TRIPPED);
    
    unsigned long newCodeReceived = 0;
    
    void setup() {
      Serial.begin(115200);
    
      // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
      RemoteReceiver::init(-1, 2, showOldCode);
    
      // On interrupt, call the interrupt handlers of remote and sensor receivers
      InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
      Serial.print("433 Motion Sensor");
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("433 Motion Sensor", "1.0");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_1, S_MOTION);
      present(CHILD_ID_2, S_MOTION);
    }
    
    void loop() {
       // You can do other stuff here!
      // shows the received code sent from an old-style remote switch
           if(newCodeReceived == 510217) {
              send(msg1.set("1"));  // Send tripped value to gw 
              wait(1000);
              send(msg1.set("0"));
              newCodeReceived = 0;
          }
          if(newCodeReceived == 354240) {
              send(msg2.set("1"));  // Send tripped value to gw 
              wait(1000);
              send(msg2.set("0"));
              newCodeReceived = 0;
          }
    }
    
    void showOldCode(unsigned long receivedCode, unsigned int period) {
      // Print the received code.
      Serial.print("Code: ");
      Serial.print(receivedCode);
      Serial.print(", period: ");
      Serial.print(period);
      Serial.println("us.");
    
      // Read digital motion value
      //boolean tripped = receivedCode; 
       newCodeReceived = receivedCode;
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
      //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
    }
    

    BTW it is also not a good practice to wait with in the loop, it is better to save a time-stamp with millis(), keep looping and check if we were active for 1 second, something like this

    unsigned long timeTrigger1 = 0;
    unsigned long timeTrigger2 = 0;
    
    void loop() {
          // shows the received code sent from an old-style remote switch
          if(newCodeReceived == 510217) {
              if (timeTrigger1 == 0) {
                  send(msg1.set("1"));  // Send tripped value to gw 
              }
              newCodeReceived = 0;
              timeTrigger1 = millis();
          }
          if (timeTrigger1 > 0 && (millis() - timeTrigger1) > 1000) {
             // Not tripped for over 1 second tell the GW
             send(msg1.set("0"));
             timeTrigger1 = 0;
          }
          
          if(newCodeReceived == 354240) {
              if (timeTrigger2 == 0) {
                     send(msg2.set("1"));  // Send tripped value to gw 
              }
              newCodeReceived = 0;
              timeTrigger2 = millis();
          }
          if (timeTrigger2 > 0 && (millis() - timeTrigger2) > 1000) {
             // Not tripped for over 1 second tell the GW
             send(msg1.set("0"));
             timeTrigger2 = 0;
          }
          
          // Give some time to MySensor  to procces messages
          wait(10);
    }
    

    This solution has 2 side effects:

    1. It keeps being triggered if your motion sensor was tripped again with in the second
    2. it is now able to detect and handle 2 triggers at the same time (which is not the case in the original example)
    mfalkviddM 1 Reply Last reply
    0
    • BartEB BartE

      @niccodemi I just had a better look @ your code. I think the issue is that your try to wait in an interrupt service routine (ISR) this is "killing" for most processors. showOldCod() is called from an interrupt.

      Better is to keep the time in and ISR as short as possible. So just remember you did received a trigger and and leave the routine.
      Something like this (not tested but should give an idea)

      /*
      433MHz Motion Sensor
       * Setup:
       * - connect a 433MHz receiver on digital pin 2.
       *
       * MySensor note: This example has not yet been adopted but can be used as an example
       * of receiving 433Mhz stuff. 
       * 
       * One idea could be to echo received 433 codes back to gateway to be able to pick up and
       * handle data over there.
       *
      */
      #define MY_DEBUG
      
      #define MY_RADIO_NRF24
      
      #include <RemoteReceiver.h>
      #include <InterruptChain.h>
      #include <SPI.h>
      #include <MySensor.h>
      
      unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
      
      //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
      #define CHILD_ID_1 1   // Id of the sensor child
      #define CHILD_ID_2 2   // Id of the sensor child
      
      // Initialize motion message
      MyMessage msg1(CHILD_ID_1, V_TRIPPED);
      MyMessage msg2(CHILD_ID_2, V_TRIPPED);
      
      unsigned long newCodeReceived = 0;
      
      void setup() {
        Serial.begin(115200);
      
        // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
        RemoteReceiver::init(-1, 2, showOldCode);
      
        // On interrupt, call the interrupt handlers of remote and sensor receivers
        InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
        Serial.print("433 Motion Sensor");
      }
      
      void presentation()  {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("433 Motion Sensor", "1.0");
      
        // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID_1, S_MOTION);
        present(CHILD_ID_2, S_MOTION);
      }
      
      void loop() {
         // You can do other stuff here!
        // shows the received code sent from an old-style remote switch
             if(newCodeReceived == 510217) {
                send(msg1.set("1"));  // Send tripped value to gw 
                wait(1000);
                send(msg1.set("0"));
                newCodeReceived = 0;
            }
            if(newCodeReceived == 354240) {
                send(msg2.set("1"));  // Send tripped value to gw 
                wait(1000);
                send(msg2.set("0"));
                newCodeReceived = 0;
            }
      }
      
      void showOldCode(unsigned long receivedCode, unsigned int period) {
        // Print the received code.
        Serial.print("Code: ");
        Serial.print(receivedCode);
        Serial.print(", period: ");
        Serial.print(period);
        Serial.println("us.");
      
        // Read digital motion value
        //boolean tripped = receivedCode; 
         newCodeReceived = receivedCode;
      
          // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
        //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
      }
      

      BTW it is also not a good practice to wait with in the loop, it is better to save a time-stamp with millis(), keep looping and check if we were active for 1 second, something like this

      unsigned long timeTrigger1 = 0;
      unsigned long timeTrigger2 = 0;
      
      void loop() {
            // shows the received code sent from an old-style remote switch
            if(newCodeReceived == 510217) {
                if (timeTrigger1 == 0) {
                    send(msg1.set("1"));  // Send tripped value to gw 
                }
                newCodeReceived = 0;
                timeTrigger1 = millis();
            }
            if (timeTrigger1 > 0 && (millis() - timeTrigger1) > 1000) {
               // Not tripped for over 1 second tell the GW
               send(msg1.set("0"));
               timeTrigger1 = 0;
            }
            
            if(newCodeReceived == 354240) {
                if (timeTrigger2 == 0) {
                       send(msg2.set("1"));  // Send tripped value to gw 
                }
                newCodeReceived = 0;
                timeTrigger2 = millis();
            }
            if (timeTrigger2 > 0 && (millis() - timeTrigger2) > 1000) {
               // Not tripped for over 1 second tell the GW
               send(msg1.set("0"));
               timeTrigger2 = 0;
            }
            
            // Give some time to MySensor  to procces messages
            wait(10);
      }
      

      This solution has 2 side effects:

      1. It keeps being triggered if your motion sensor was tripped again with in the second
      2. it is now able to detect and handle 2 triggers at the same time (which is not the case in the original example)
      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #5

      @BartE you mean "it is now able to detect", right?

      BartEB 1 Reply Last reply
      0
      • mfalkviddM mfalkvidd

        @BartE you mean "it is now able to detect", right?

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

        @mfalkvidd yes you're right i will update my post

        1 Reply Last reply
        1
        • N Offline
          N Offline
          niccodemi
          wrote on last edited by niccodemi
          #7

          @BartE thank you. I modified sketch (the one with millis) and it works great. How would I enable sleep mode with interrupt?

          Eventually I plan to add more motion sensors and I think it would be better to use array. This is my first attempt and below is how far I got but obviously something is missing because I cannot compile it; I get error: "msg" cannot be used as function

          /*
          433MHz Motion Sensor
           * Setup:
           * - connect a 433MHz receiver on digital pin 2.
           *
           * MySensor note: This example has not yet been adopted but can be used as an example
           * of receiving 433Mhz stuff. 
           * 
           * One idea could be to echo received 433 codes back to gateway to be able to pick up and
           * handle data over there.
           *
          */
          #define MY_DEBUG
          
          #define MY_RADIO_NRF24
          
          #include <RemoteReceiver.h>
          #include <InterruptChain.h>
          #include <SPI.h>
          #include <MySensor.h>
          
          unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
          
          //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
          #define noMotion 4
          const int RFCODE[] = {354240, 123654, 123789, 123954};  
          #define CHILD_ID 1   // Id of the sensor child
          
          // Initialize motion message
          MyMessage msg[noMotion];
          
          unsigned long newCodeReceived = 0;
          
          void setup() {
            Serial.begin(115200);
            // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
            RemoteReceiver::init(-1, 2, showOldCode);
            // On interrupt, call the interrupt handlers of remote and sensor receivers
            InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
            Serial.print("433 Motion Sensor");
            wait(30);
              // initialize Motion sensors 
            for (int i=1; i<=noMotion; i++){
              msg[i].sensor = i;          // initialize messages
              // Change to V_LIGHT if you use S_LIGHT in presentation below
              msg[i].type = V_TRIPPED;
          }
          }
          void presentation()  {
            // Send the sketch version information to the gateway and Controller
            sendSketchInfo("433 Motion Sensor", "1.0a");
          
            // Register all sensors to gw (they will be created as child devices)
            for (int i=1; i<=noMotion; i++) {
            present(i, S_MOTION);
            wait(30);
          }
          }
          
          unsigned long timeTrigger1 = 0;
          //unsigned long timeTrigger2 = 0;
          
          void loop() {
                for (int i=1; i<=noMotion; i++) {
                // shows the received code sent from an old-style remote switch
                if(newCodeReceived == RFCODE[i]) {
                    if (timeTrigger1 == 0) {
                        send(msg(i).set("1"));  // Send tripped value to gw 
                    }
                    newCodeReceived = 0;
                    timeTrigger1 = millis();
                }
                if (timeTrigger1 > 0 && (millis() - timeTrigger1) > 1000) {
                   // Not tripped for over 1 second tell the GW
                   send(msg(i).set("0"));
                   timeTrigger1 = 0;
                }      
                // Give some time to MySensor  to procces messages
                wait(10);
          }
          }
          
          void showOldCode(unsigned long receivedCode, unsigned int period) {
            // shows the received code sent from an old-style remote switch
            // Print the received code.
            Serial.print("Code: ");
            Serial.print(receivedCode);
            Serial.print(", period: ");
            Serial.print(period);
            Serial.println("us.");
          
            // Read digital motion value
             newCodeReceived = receivedCode;
             sendHeartbeat();
              // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
            //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
          }
          
          1 Reply Last reply
          0
          • N Offline
            N Offline
            niccodemi
            wrote on last edited by
            #8

            I figured out array and the sketch works. As final thing I would like to enable sleep-time and Heartbeat message once node wakes up.

            /*
            433MHz Multi Motion Sensor
             * Setup:
             * - connect a 433MHz receiver on digital pin 2.
             * - type appropriate RF codes into array
            */
            #define MY_DEBUG
            
            #define MY_RADIO_NRF24
            
            #include <RemoteReceiver.h>
            #include <InterruptChain.h>
            #include <SPI.h>
            #include <MySensor.h>
            
            unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
            
            //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
            #define noMotion 4                                                                                                     //number of sensors
            const unsigned long RFCODE[] = {354240, 354222, 354216, 354214};              //RF433 codes
            #define CHILD_ID 1   // Id of the sensor child
            
            // Initialize motion message
            MyMessage msg[noMotion];
            
            unsigned long newCodeReceived = 0;
            
            long previousMillis = 0;
            long interval = 120000;                                          //interval at which to send Heartbeat
            
            void setup() {
              Serial.begin(115200);
              // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
              RemoteReceiver::init(-1, 2, showOldCode);
              // On interrupt, call the interrupt handlers of remote and sensor receivers
              InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
              Serial.print("433 Motion Sensor");
              wait(30);
                // initialize Motion sensors 
              for (int i=0; i<noMotion; i++){
                msg[i].sensor = i;          // initialize messages
                // Change to V_LIGHT if you use S_LIGHT in presentation below
                msg[i].type = V_TRIPPED;
            }
            }
            void presentation()  {
              // Send the sketch version information to the gateway and Controller
              sendSketchInfo("433 Motion Sensor", "1.0b");
              wait(50);
              // Register all sensors to gw (they will be created as child devices)
              for (int i=0; i<noMotion; i++) {
              present(i, S_MOTION);
              wait(50);
            }
            }
            
            unsigned long timeTrigger1 = 0;
            
            void loop() {
                  for (int i=0; i<noMotion; i++) {
                  // shows the received code sent from an old-style remote switch
                  unsigned long value = RFCODE[i];
                  if(newCodeReceived == value) {
                      if (timeTrigger1 == 0) {
                          send(msg[i].set("1"));  // Send tripped value to gw 
                      }
                      newCodeReceived = 0;
                      timeTrigger1 = millis();
                  }
                  if (timeTrigger1 > 0 && (millis() - timeTrigger1) > 1000) {
                     // Not tripped for over 1 second tell the GW
                     send(msg[i].set("0"));
                     timeTrigger1 = 0;
                  }      
                  // Give some time to MySensor  to procces messages
                  wait(10);
            }
            {
            unsigned long currentMillis = millis();
            if(currentMillis - previousMillis > interval) {
                     sendHeartbeat();
                     previousMillis = currentMillis;
                     }
                     }
            }
            
            void showOldCode(unsigned long receivedCode, unsigned int period) {
              // shows the received code sent from an old-style remote switch
              // Print the received code.
              Serial.print("Code: ");
              Serial.print(receivedCode);
              Serial.print(", period: ");
              Serial.print(period);
              Serial.println("us.");
            
              // Read digital motion value
               newCodeReceived = receivedCode;
                // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
              //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
            }
            
            BartEB 1 Reply Last reply
            0
            • N niccodemi

              I figured out array and the sketch works. As final thing I would like to enable sleep-time and Heartbeat message once node wakes up.

              /*
              433MHz Multi Motion Sensor
               * Setup:
               * - connect a 433MHz receiver on digital pin 2.
               * - type appropriate RF codes into array
              */
              #define MY_DEBUG
              
              #define MY_RADIO_NRF24
              
              #include <RemoteReceiver.h>
              #include <InterruptChain.h>
              #include <SPI.h>
              #include <MySensor.h>
              
              unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
              
              //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
              #define noMotion 4                                                                                                     //number of sensors
              const unsigned long RFCODE[] = {354240, 354222, 354216, 354214};              //RF433 codes
              #define CHILD_ID 1   // Id of the sensor child
              
              // Initialize motion message
              MyMessage msg[noMotion];
              
              unsigned long newCodeReceived = 0;
              
              long previousMillis = 0;
              long interval = 120000;                                          //interval at which to send Heartbeat
              
              void setup() {
                Serial.begin(115200);
                // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
                RemoteReceiver::init(-1, 2, showOldCode);
                // On interrupt, call the interrupt handlers of remote and sensor receivers
                InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
                Serial.print("433 Motion Sensor");
                wait(30);
                  // initialize Motion sensors 
                for (int i=0; i<noMotion; i++){
                  msg[i].sensor = i;          // initialize messages
                  // Change to V_LIGHT if you use S_LIGHT in presentation below
                  msg[i].type = V_TRIPPED;
              }
              }
              void presentation()  {
                // Send the sketch version information to the gateway and Controller
                sendSketchInfo("433 Motion Sensor", "1.0b");
                wait(50);
                // Register all sensors to gw (they will be created as child devices)
                for (int i=0; i<noMotion; i++) {
                present(i, S_MOTION);
                wait(50);
              }
              }
              
              unsigned long timeTrigger1 = 0;
              
              void loop() {
                    for (int i=0; i<noMotion; i++) {
                    // shows the received code sent from an old-style remote switch
                    unsigned long value = RFCODE[i];
                    if(newCodeReceived == value) {
                        if (timeTrigger1 == 0) {
                            send(msg[i].set("1"));  // Send tripped value to gw 
                        }
                        newCodeReceived = 0;
                        timeTrigger1 = millis();
                    }
                    if (timeTrigger1 > 0 && (millis() - timeTrigger1) > 1000) {
                       // Not tripped for over 1 second tell the GW
                       send(msg[i].set("0"));
                       timeTrigger1 = 0;
                    }      
                    // Give some time to MySensor  to procces messages
                    wait(10);
              }
              {
              unsigned long currentMillis = millis();
              if(currentMillis - previousMillis > interval) {
                       sendHeartbeat();
                       previousMillis = currentMillis;
                       }
                       }
              }
              
              void showOldCode(unsigned long receivedCode, unsigned int period) {
                // shows the received code sent from an old-style remote switch
                // Print the received code.
                Serial.print("Code: ");
                Serial.print(receivedCode);
                Serial.print(", period: ");
                Serial.print(period);
                Serial.println("us.");
              
                // Read digital motion value
                 newCodeReceived = receivedCode;
                  // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
                //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
              }
              
              BartEB Offline
              BartEB Offline
              BartE
              Contest Winner
              wrote on last edited by BartE
              #9

              @niccodemi This looks good.

              One remark the timeTrigger variable should also become an array. When 2 sensors are triggered with your implementation only 1 sensor will be reseted the other will remain active.

              N 1 Reply Last reply
              0
              • BartEB BartE

                @niccodemi This looks good.

                One remark the timeTrigger variable should also become an array. When 2 sensors are triggered with your implementation only 1 sensor will be reseted the other will remain active.

                N Offline
                N Offline
                niccodemi
                wrote on last edited by
                #10

                @BartE thanks. Second sensor actually wouldn't even trigger while the first one was triggered (1 second).

                Would you know how to enable sleep-time in this sketch? I tried defining Interrupt on pin 2 but I get strange results (RF codes are randomly received and messages are rarely sent).

                /*
                433MHz Multi Motion Sensor
                 * Setup:
                 * - connect a 433MHz receiver on digital pin 2.
                 * - type appropriate RF codes into array, define noMotion and timetrigger1
                */
                #define MY_DEBUG
                
                #define MY_RADIO_NRF24
                
                #include <RemoteReceiver.h>
                #include <InterruptChain.h>
                #include <SPI.h>
                #include <MySensor.h>
                
                //unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
                
                //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
                #define noMotion 4                                                           //number of sensors
                const unsigned long RFCODE[] = {354240, 354222, 354216, 354214};              //RF433 codes
                #define CHILD_ID 1   // Id of the sensor child
                
                // Initialize motion message
                MyMessage msg[noMotion];
                
                unsigned long newCodeReceived = 0;
                
                long previousMillis = 0;
                long interval = 120000;                                          //interval at which to send Heartbeat
                
                void setup() {
                  Serial.begin(115200);
                  // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
                  RemoteReceiver::init(-1, 2, showOldCode);
                  // On interrupt, call the interrupt handlers of remote and sensor receivers
                  InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
                  Serial.print("433 Motion Sensor");
                  wait(30);
                    // initialize Motion sensors 
                  for (int i=0; i<noMotion; i++){
                    msg[i].sensor = i;          // initialize messages
                    // Change to V_LIGHT if you use S_LIGHT in presentation below
                    msg[i].type = V_TRIPPED;
                }
                }
                void presentation()  {
                  // Send the sketch version information to the gateway and Controller
                  sendSketchInfo("433 Motion Sensor", "1.0b");
                  wait(50);
                  // Register all sensors to gw (they will be created as child devices)
                  for (int i=0; i<noMotion; i++) {
                  present(i, S_MOTION);
                  wait(50);
                }
                }
                
                unsigned long timeTrigger1[] = {0, 0, 0, 0};                // same as noMotion
                
                void loop() {
                      for (int i=0; i<noMotion; i++) {
                      // shows the received code sent from an old-style remote switch
                      unsigned long value = RFCODE[i];
                      if(newCodeReceived == value) {
                          if (timeTrigger1[i] == 0) {
                              send(msg[i].set("1"));  // Send tripped value to gw 
                          }
                          newCodeReceived = 0;
                          timeTrigger1[i] = millis();
                      }
                      if (timeTrigger1[i] > 0 && (millis() - timeTrigger1[i]) > 1000) {
                         // Not tripped for over 1 second tell the GW
                         send(msg[i].set("0"));
                         timeTrigger1[i] = 0;
                      }      
                      // Give some time to MySensor  to procces messages
                      wait(10);
                }
                {
                unsigned long currentMillis = millis();
                if(currentMillis - previousMillis > interval) {
                         sendHeartbeat();
                         previousMillis = currentMillis;
                         }
                         }
                }
                
                void showOldCode(unsigned long receivedCode, unsigned int period) {
                  // shows the received code sent from an old-style remote switch
                  // Print the received code.
                  Serial.print("Code: ");
                  Serial.print(receivedCode);
                  Serial.print(", period: ");
                  Serial.print(period);
                  Serial.println("us.");
                
                  // Read digital motion value
                   newCodeReceived = receivedCode;
                    // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
                  //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
                }
                
                BartEB 1 Reply Last reply
                0
                • N niccodemi

                  @BartE thanks. Second sensor actually wouldn't even trigger while the first one was triggered (1 second).

                  Would you know how to enable sleep-time in this sketch? I tried defining Interrupt on pin 2 but I get strange results (RF codes are randomly received and messages are rarely sent).

                  /*
                  433MHz Multi Motion Sensor
                   * Setup:
                   * - connect a 433MHz receiver on digital pin 2.
                   * - type appropriate RF codes into array, define noMotion and timetrigger1
                  */
                  #define MY_DEBUG
                  
                  #define MY_RADIO_NRF24
                  
                  #include <RemoteReceiver.h>
                  #include <InterruptChain.h>
                  #include <SPI.h>
                  #include <MySensor.h>
                  
                  //unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
                  
                  //#define INTERRUPT 2 // Usually the interrupt = pin -2 (on uno/nano anyway)
                  #define noMotion 4                                                           //number of sensors
                  const unsigned long RFCODE[] = {354240, 354222, 354216, 354214};              //RF433 codes
                  #define CHILD_ID 1   // Id of the sensor child
                  
                  // Initialize motion message
                  MyMessage msg[noMotion];
                  
                  unsigned long newCodeReceived = 0;
                  
                  long previousMillis = 0;
                  long interval = 120000;                                          //interval at which to send Heartbeat
                  
                  void setup() {
                    Serial.begin(115200);
                    // Interrupt -1 to indicate you will call the interrupt handler with InterruptChain
                    RemoteReceiver::init(-1, 2, showOldCode);
                    // On interrupt, call the interrupt handlers of remote and sensor receivers
                    InterruptChain::addInterruptCallback(0, RemoteReceiver::interruptHandler);
                    Serial.print("433 Motion Sensor");
                    wait(30);
                      // initialize Motion sensors 
                    for (int i=0; i<noMotion; i++){
                      msg[i].sensor = i;          // initialize messages
                      // Change to V_LIGHT if you use S_LIGHT in presentation below
                      msg[i].type = V_TRIPPED;
                  }
                  }
                  void presentation()  {
                    // Send the sketch version information to the gateway and Controller
                    sendSketchInfo("433 Motion Sensor", "1.0b");
                    wait(50);
                    // Register all sensors to gw (they will be created as child devices)
                    for (int i=0; i<noMotion; i++) {
                    present(i, S_MOTION);
                    wait(50);
                  }
                  }
                  
                  unsigned long timeTrigger1[] = {0, 0, 0, 0};                // same as noMotion
                  
                  void loop() {
                        for (int i=0; i<noMotion; i++) {
                        // shows the received code sent from an old-style remote switch
                        unsigned long value = RFCODE[i];
                        if(newCodeReceived == value) {
                            if (timeTrigger1[i] == 0) {
                                send(msg[i].set("1"));  // Send tripped value to gw 
                            }
                            newCodeReceived = 0;
                            timeTrigger1[i] = millis();
                        }
                        if (timeTrigger1[i] > 0 && (millis() - timeTrigger1[i]) > 1000) {
                           // Not tripped for over 1 second tell the GW
                           send(msg[i].set("0"));
                           timeTrigger1[i] = 0;
                        }      
                        // Give some time to MySensor  to procces messages
                        wait(10);
                  }
                  {
                  unsigned long currentMillis = millis();
                  if(currentMillis - previousMillis > interval) {
                           sendHeartbeat();
                           previousMillis = currentMillis;
                           }
                           }
                  }
                  
                  void showOldCode(unsigned long receivedCode, unsigned int period) {
                    // shows the received code sent from an old-style remote switch
                    // Print the received code.
                    Serial.print("Code: ");
                    Serial.print(receivedCode);
                    Serial.print(", period: ");
                    Serial.print(period);
                    Serial.println("us.");
                  
                    // Read digital motion value
                     newCodeReceived = receivedCode;
                      // Sleep until interrupt comes in on motion sensor. Send update every two minute. 
                    //sleep(INTERRUPT,CHANGE, SLEEP_TIME);
                  }
                  
                  BartEB Offline
                  BartEB Offline
                  BartE
                  Contest Winner
                  wrote on last edited by BartE
                  #11

                  @niccodemi sleep() will bring the processor actual to sleep e.g. several large parts of the process actually will stop working to save battery life.

                  So data is not processed anymore causing the strange RF results. Using wait() is better is this case but will not save any battery lifetime.
                  Golden rule on this MySensors forum is batteries are only useful for a sensor which only broadcast and NOT is meant to receive data. Your sketch uses both so better us a power adapter.

                  1 Reply Last reply
                  0
                  • N Offline
                    N Offline
                    niccodemi
                    wrote on last edited by niccodemi
                    #12

                    @BartE noted, I didn't actually plan to run this node off a battery but I thought it was a good practice to use sleep() (with interrupt) in nodes which are not expecting messages from gw.

                    One more thing: if using array when presenting children

                    present(i, S_MOTION);
                    

                    messages are sent to gw one after another and even with only 4 children at least one gets usually lost. Is there alternative to this?

                    present(1, S_MOTION);
                      wait(50);
                      present(2, S_MOTION);
                      wait(50);
                      present(3, S_MOTION);
                      wait(50);
                      present(4, S_MOTION);
                      wait(50);
                    
                    BartEB 1 Reply Last reply
                    0
                    • N niccodemi

                      @BartE noted, I didn't actually plan to run this node off a battery but I thought it was a good practice to use sleep() (with interrupt) in nodes which are not expecting messages from gw.

                      One more thing: if using array when presenting children

                      present(i, S_MOTION);
                      

                      messages are sent to gw one after another and even with only 4 children at least one gets usually lost. Is there alternative to this?

                      present(1, S_MOTION);
                        wait(50);
                        present(2, S_MOTION);
                        wait(50);
                        present(3, S_MOTION);
                        wait(50);
                        present(4, S_MOTION);
                        wait(50);
                      
                      BartEB Offline
                      BartEB Offline
                      BartE
                      Contest Winner
                      wrote on last edited by
                      #13

                      @niccodemi this issue i reported more often in MySenors forum adding a delay (or better wait()) is the solution.

                      It should not be a problem because this presentation function is only called once at start up

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


                      28

                      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