MySensors 2.x - 1 RELAY AND 1 PIR simple combination



  • Dear all,
    I been working successfully in this kind of projects following your instructions and using your basic sketches for about 4 months. Now I have the need to combine 2 different sensors in the same program, which I had not had to do before. .
    I have reviewed many topics related but none has a simple example (the "hello world") to take it as a base and develop more complex things.
    I have also read the documentation of how to combine schemes but the truth is that I found it a little bit confusing.
    Without more things to say, I would like to count on your generous help telling me what is the problem in my scheme where a RELAY connected to PIN2 and a PIR connected to the PIN3 of an NANO arduino are combined.
    In my domoticz if both devices are reported, but the funny thing is that I can not trigger the RELAY, although the update from PIR arrives without issue.

    The scheme is:

    ++++++++++++++++++++++++++++++++++++++++++++++++++++

    #define MY_DEBUG
    #define MY_BAUD_RATE 38400
    #define MY_RADIO_NRF24
    
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    #define MY_RF24_CHANNEL 115
    #define MY_RF24_DATARATE RF24_250KBPS
    #define MY_RF24_BASE_RADIO_ID 0x00,0xFC,0xE1,0xA8,0xA8
    
    #define MY_NODE_ID 164
    #include <SPI.h>
    #include <MySensors.h>
    
    
    
    #define RELAY_PIN 2  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON 1  // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    uint32_t SLEEP_TIME = 10000; // Sleep time between reports (in milliseconds)
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    #define CHILD_ID 2   // Id of the sensor child
    
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            //Always starts OFF
            digitalWrite(pin, RELAY_OFF);
        }
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void setup()
    {
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Relay_PLUS_PIR", "1.0");
    
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_LIGHT);
        }
            // Register all sensors to gw (they will be created as child devices)
        present(CHILD_ID, S_MOTION);
    }
    
    
    void loop()
    {
        // Read digital motion value
        bool tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
    
        Serial.println(tripped);
        send(msg.set(tripped?"1":"0"));  // Send tripped value to gw
    
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
        sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_LIGHT) {
            // Change relay state
            digitalWrite( RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            //digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }
    

    ++++++++++++++++++++++++++++++++++++++++++++++++++++

    Now, from Mosquitto MQTT running on the Domoticz machine, this is the log when I try to trigger the RELAY:

    +++++++++++++++++++++++++++++++++++++++++++++++++++
    Dec 13 10:16:17 DEBUG TSF:MSG:READ,164-164-0,s=2,c=1,t=16,pt=0,l=1,sg=0:0
    Dec 13 10:16:17 DEBUG GWT:TPS:TOPIC=domoticz/in/MyMQTT/164/2/1/0/16,MSG SENT
    Dec 13 10:16:19 DEBUG TSM:READY:NWD REQ
    Dec 13 10:16:19 DEBUG TSF:MSG:SEND,0-0-255-255,s=255,c=3,t=20,pt=0,l=0,sg=0,ft=0,st=OK:
    Dec 13 10:16:20 DEBUG GWT:IMQ:TOPIC=domoticz/out/MyMQTT/164/1/1/0/2, MSG RECEIVED
    Dec 13 10:16:20 DEBUG !TSF:MSG:SEND,0-0-164-164,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=NACK:1
    Dec 13 10:16:21 DEBUG GWT:IMQ:TOPIC=domoticz/out/MyMQTT/164/1/1/0/2, MSG RECEIVED
    Dec 13 10:16:21 DEBUG !TSF:MSG:SEND,0-0-164-164,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=NACK:0

    ++++++++++++++++++++++++++++++++++++++++++++++++++

    But on the serial console in Arduino, there is no activity receiving.

    Then, when the PIR connected to the arduino detects motion the line in serial console are:

    ++++++++++++++++++++++++++++++++++++++++++++++++++

    40932 TSF:MSG:SEND,164-164-0-0,s=2,c=1,t=16,pt=0,l=1,sg=0,ft=0,st=OK:1
    40951 MCO:SLP:MS=10000,SMS=0,I1=1,M1=1,I2=255,M2=255
    40965 MCO:SLP:TPD
    40970 MCO:SLP:WUP=1

    ++++++++++++++++++++++++++++++++++++++++++++++++++

    and on Mosquitto:

    +++++++++++++++++++++++++++++++++++++++++++++++++

    Dec 13 10:19:37 DEBUG TSF:MSG:READ,164-164-0,s=2,c=1,t=16,pt=0,l=1,sg=0:1
    Dec 13 10:19:37 DEBUG GWT:TPS:TOPIC=domoticz/in/MyMQTT/164/2/1/0/16,MSG SENT

    +++++++++++++++++++++++++++++++++++++++++++++++++

    By the way, If I test the RELAY and PIR in sketch separately they work correctly.

    Thanks in advance.

    Alfredo


  • Mod

    Welcome to the forum @asalas

    st=NACK and the exclamation mark in

    DEBUG !TSF:MSG:SEND,0-0-164-164,s=1,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=NACK:1
    

    indicates that the gateway does not receive acknowledgement that the node received the message. You can use the log parser to help understand the log.

    The reason the node does not receive the message is that he node is sleeping. When a node is sleeping, it can not receive messages.

    The easiest way in you case is to remove the sleep() line and add an if clause to only send a message if tripped changes value.



  • Thank you mfalkvidd, I did it and it is working well now!.

    For those who want a simple solution and as future reference, here is my simple code:

    #define MY_DEBUG
    #define MY_BAUD_RATE 38400
    #define MY_RADIO_NRF24
    
    #define MY_RF24_PA_LEVEL RF24_PA_HIGH
    #define MY_RF24_CHANNEL 115
    #define MY_RF24_DATARATE RF24_250KBPS
    #define MY_RF24_BASE_RADIO_ID 0x00,0xFC,0xE1,0xA8,0xA8
    
    #define MY_NODE_ID 164
    #include <SPI.h>
    #include <MySensors.h>
    
    #define RELAY_PIN 2  // Arduino Digital I/O pin number for first relay (second on pin+1 etc)
    #define NUMBER_OF_RELAYS 1 // Total number of attached relays
    #define RELAY_ON  1 // GPIO value to write to turn on attached relay
    #define RELAY_OFF 0 // GPIO value to write to turn off attached relay
    
    
    #define RELAY_CHILD_ID 1   // Id of the sensor child RELAY
    #define MOTION_CHILD_ID 2   // Id of the sensor child MOTION
    
    
    
    #define DIGITAL_INPUT_SENSOR 3   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
    uint32_t SLEEP_TIME = 10000; // Sleep time between reports (in milliseconds)..NOT USED ANYMORE BECAUSE IT TURNS OFF THE NODE AND IT CAN'T RECEIVE RELAY REMOTE TRIGGERING ORDER
    
    boolean lastMotion = false;
    
    // Initialize motion message
    MyMessage msg(MOTION_CHILD_ID, V_TRIPPED);
    
    void before()
    {
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Then set relay pins in output mode
            pinMode(pin, OUTPUT);
            //Always starts OFF
            digitalWrite(pin, RELAY_OFF);
        }
        pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
    }
    
    void setup()
    {
    
    }
    
    void presentation()
    {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("Relay_PLUS_PIR", "1.0");
    
        for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
            // Register all sensors to gw (they will be created as child devices)
            present(sensor, S_LIGHT);
        }
            // Register all sensors to gw (they will be created as child devices)
        present(MOTION_CHILD_ID, S_MOTION);
    }
    
    
    void loop()
    {
        // Read digital motion value
        bool motion = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
        if (lastMotion != motion) {
          lastMotion = motion;
          Serial.println(motion);
          send(msg.set(motion?"1":"0"));  // Send tripped value to gw
        }
        // Sleep until interrupt comes in on motion sensor. Send update every two minute.
       //  NOT USED
        // sleep(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), CHANGE, SLEEP_TIME);
      //  NOT USED
    }
    
    void receive(const MyMessage &message)
    {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.type==V_LIGHT) {
            // Change relay state
            digitalWrite( RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            //digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF);
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            // Write some debug info
            Serial.print("Incoming change for sensor:");
            Serial.print(message.sensor);
            Serial.print(", New status: ");
            Serial.println(message.getBool());
        }
    }
    

    Regards!


 

360
Online

8.1k
Users

9.0k
Topics

95.4k
Posts