Multi Motion Detectors



  • Is it possible to run multiple motion detectors like I have here? It compiles but will it work? I will build and test but I want to know if it looks legit. I'm trying to run a Dallas temp sensor also where do I put the reading and sleep code in the loop? or separate?

    /**
     Based On: http://www.mysensors.org/build/relay
     Modded By DrJeff 
     This Node is for 2 relays controlled remotely, and 1 Relay 
     controlled locally via switch, 2 Motion detectors (possibly 3 motion)
     */ 
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define RELAY_1  4  // Arduino Digital I/O pin number for relay
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define TOP_SWITCH  5  // Arduino Digital I/O pin number for button
    #define BOTTOM_SWITCH  6  // Arduino Digital I/O pin number for button
    #define CHILD_ID 1   // Id of the sensor child
    #define RELAY_ON 0
    #define RELAY_OFF 1
    // added motion
    #define Motion_1 3
    #define Motion_2 7
    #define INTERRUPT Motion_1-2
    #define INTERRUPT Motion_2-2
    uint8_t lastMotion_1 = 0;
    uint8_t lastMotion_2 = 0;
    
    #define MOTION_CHILD_1 2
    #define MOTION_CHILD_2 3
    
    #define NODE_ID 35
    unsigned long previousMillis = 0; // last time update //see http://stackoverflow.com/questions/10773425/performing-a-function-after-x-time for more details on this
    unsigned long motionDelay = 10000; // interval at which to keep motion sensor trippped (milliseconds).  Used to prevent too frequent updates to Vera. 
    
    Bounce debouncer = Bounce(); 
    int oldValue=0;
    bool state;
    MySensor gw;
    MyMessage msg(CHILD_ID,V_LIGHT);
    MyMessage motionStatus_1(MOTION_CHILD_1, V_TRIPPED);
    MyMessage motionStatus_2(MOTION_CHILD_2, V_TRIPPED);
    
    void setup()  
    {  
      gw.begin(incomingMessage, NODE_ID, true);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("Closet Node", "1.0");
    
     // Setup the button
      pinMode(TOP_SWITCH,INPUT);
      pinMode(BOTTOM_SWITCH,INPUT);
      // Activate internal pull-up
      digitalWrite(TOP_SWITCH,HIGH);
      digitalWrite(BOTTOM_SWITCH,HIGH);
      
      // After setting up the button, setup debouncer
      debouncer.attach(TOP_SWITCH);
      debouncer.interval(5);
      debouncer.attach(BOTTOM_SWITCH);
      debouncer.interval(5);
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID, S_LIGHT);
      gw.present(MOTION_CHILD_1, S_MOTION);
      gw.present(MOTION_CHILD_2, S_MOTION);
    
      // Make sure relays are off when starting up
      //digitalWrite(RELAY_1, RELAY_OFF); 
      // Then set relay pins in output mode
      pinMode(RELAY_1, OUTPUT);   
      pinMode(Motion_1, INPUT);
      pinMode(Motion_2, INPUT);
      
      // Set relay to last known state (using eeprom storage) 
    
     //removed next 2 lines no like remember last state defaults to on then controller thinks its off 2015-08-19 JW
      state = gw.loadState(CHILD_ID);
      digitalWrite(RELAY_1, state?RELAY_ON:RELAY_OFF);
    }
    
    
    /*
    *  Example on how to asynchronously check for new messages from gw
    */
    void loop() 
    {
      gw.process();
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
      if (value != oldValue && value==0) {
          gw.send(msg.set(state?false:true), true); // Send new state and request ack back
      }
      oldValue = value;
      
    } 
     
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_LIGHT) {
         // Change relay state
         state = message.getBool();
         digitalWrite(RELAY_1, state?RELAY_ON:RELAY_OFF);
         // Store state in eeprom
        
         gw.saveState(CHILD_ID, state);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
     // Read digital motion value For first motion detector
       unsigned long currentMillis = millis();
      
         if(currentMillis - previousMillis > motionDelay){
          uint8_t motionDetect = digitalRead(Motion_1);
      
          if(motionDetect != lastMotion_1){
    //        Serial.print("motionDetect Value: ");
    //        Serial.println(motionDetect);
            //gw.send(motionStatus_1.set(motionDetect));  // Send tripped value to gw
            gw.send(motionStatus_1.set(motionDetect?"1":"0"));  // Send tripped value to gw
            if(motionDetect == 1){
              previousMillis = currentMillis;  //"Tripped" delay 
            }
            else{
              previousMillis = currentMillis - motionDelay + 1000; //"Not tripped" delay for 1 second to stop rapid "not tripped" and "tripped" updates to Vera
            }
      
             lastMotion_1 = motionDetect; 
    		}
         }
    		 // Read digital motion value For second motion detector
      // unsigned long currentMillis = millis();
      
         if(currentMillis - previousMillis > motionDelay){
          uint8_t motionDetect = digitalRead(Motion_2);
      
          if(motionDetect != lastMotion_2){
    //        Serial.print("motionDetect Value: ");
    //        Serial.println(motionDetect);
            //gw.send(motionStatus_2.set(motionDetect));  // Send tripped value to gw
            gw.send(motionStatus_2.set(motionDetect?"1":"0"));  // Send tripped value to gw
            if(motionDetect == 1){
              previousMillis = currentMillis;  //"Tripped" delay 
            }
            else{
              previousMillis = currentMillis - motionDelay + 1000; //"Not tripped" delay for 1 second to stop rapid "not tripped" and "tripped" updates to Vera
            }
      
             lastMotion_2 = motionDetect; 
    		}
    		
    	}
    }
    
    

    Any comments suggestions welcomed please.


  • Admin

    No sleeping if you expect messages from the controller.



  • I need some help with this code, I can not find how to use 2 relays. I think I did it wrong here they are controlled in sync not separate. Also my motion is not working at all, is it the pin location for the interrupt? After this works I want 1 more Motion attached.

    I Love this codebender.cc it is awesome!


  • Contest Winner

    Hi DrJeff,

    you need to check if the message you got was for the first or second relay/child. I did something similar recently for a two channel dimmer. However I wanted also to be able to set both channels at once. So in the following exapmle child 0 means set on both channels, and 1 or 2 at the appropriate channel.

    Maybe my code excerpt can help you.

     if (message.type == V_LIGHT || message.type == V_DIMMER) {
    	  if (message.sensor <= 2){
    		  //0: All Dimmers
    		  //1: LED 1
    		  //2: LED 2
    		  //  Retrieve the power or dim level from the incoming request message
    		  int requestedLevel = atoi( message.data );
    		  
    		  // Adjust incoming level if this is a V_LIGHT variable update [0 == off, 1 == on]
    		  requestedLevel *= ( message.type == V_LIGHT ? 100 : 1 );
    		  
    		  if ((message.sensor == 1) || (message.sensor == 0)){
    			fadeLEDToLevel( requestedLevel, LED1_PIN );
    			// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
    			gw.send(Light1Msg.set(requestedLevel > 0 ? 1 : 0));
    			gw.send(Dimmer1Msg.set(requestedLevel) );
    		  }
    		  if ((message.sensor == 2) || (message.sensor == 0)){
    			fadeLEDToLevel( requestedLevel, LED2_PIN );
    			// Inform the gateway of the current DimmableLED's SwitchPower1 and LoadLevelStatus value...
    			gw.send(Light2Msg.set(requestedLevel > 0 ? 1 : 0));
    			gw.send(Dimmer2Msg.set(requestedLevel) );
    		  }
    		  if (message.sensor == 0){
    			  gw.send(Light0Msg.set(requestedLevel > 0 ? 1 : 0));
    			  gw.send(Dimmer0Msg.set(requestedLevel) );
    		  }
    	  }```


  • @Dirk_H said:

    message.sensor == 1

    This was what I needed! Thanks :wink:

    Now I have 3 Motion 2 switches, Now try to smash a DHT on here and fix the Vera reporting of changes made locally.
    I updated the code above.



  • Relay Pins not updating when switched locally any one know why this is in Vera UI5. I lose the On and Off status. The NODE is sending this :

    35;2;1;0;2;1761607681
    35;2;1;0;2;1761607680
    

    So there is a problem with my code somewhere. I have another node that does this. Why?

    The code is in the first post above.

    Also where is there an example of a scene controller with regular buttons? Not using a library with a keypad.



  • @Dirk_H

    Could you please post your 2 led output dimmer sketch? Been trying to copy the example one from the page, and I know I'm having an issue with the message, just not sure where.


  • Contest Winner

    @drock1985 What exactly do you need? In the project I mentioned is currently some more stuff with some dirty hacks I don't want necessarily to share ;)

    I think you only need the incoming message handler, or do you need more?



  • Hi @Dirk_H

    I was having problems with the message handling. I tried to run two instances of gw.begin thinking it would work. Solved it in this thread with a little help.

    Question though: how did you set up a third dimmer to control both?

    http://forum.mysensors.org/topic/2523/help-with-2-led-dimmer-sketch-can-t-compile-not-sure-why-exactly


  • Contest Winner

    @drock1985
    Hi good to hear that you found it out. I just made a third channel and in the message handler i react on both dimmer channels if a message with the third sensor is incoming (in my case sensor 0 for both channels; 1/2 for sepearte channels)

    However maybe its better to do the coupling of the channels in your home-automation.. I did it this way because maybe I want to build a remote and it should have the possiblity to set both channels with one mysensors message.

    regards
    DirkH


Log in to reply
 

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