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.

    https://codebender.cc/sketch:178705

    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 😉

    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


 

298
Online

7.5k
Users

8.4k
Topics

90.3k
Posts