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. Multiple Relays + Motion sketch, fully customizable, optional timer, manual override

Multiple Relays + Motion sketch, fully customizable, optional timer, manual override

Scheduled Pinned Locked Moved Development
24 Posts 11 Posters 8.0k Views 13 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.
  • markjgabbM Offline
    markjgabbM Offline
    markjgabb
    wrote on last edited by
    #2

    awesome work...this sketch is brilliant....

    what happens if you retrigger motion before timer runs out?
    will it always handle a restart of the timer correctly?

    HenryWhiteH 1 Reply Last reply
    0
    • markjgabbM markjgabb

      awesome work...this sketch is brilliant....

      what happens if you retrigger motion before timer runs out?
      will it always handle a restart of the timer correctly?

      HenryWhiteH Offline
      HenryWhiteH Offline
      HenryWhite
      wrote on last edited by
      #3

      @markjgabb said in Multiple Relays + Motion sketch, fully customizable, optional timer, manual override:

      awesome work...this sketch is brilliant....

      what happens if you retrigger motion before timer runs out?
      will it always handle a restart of the timer correctly?

      Yes, the timer will be reset.

      1 Reply Last reply
      1
      • markjgabbM Offline
        markjgabbM Offline
        markjgabb
        wrote on last edited by
        #4

        confirmed, im now running this is my office, works perfectly every time

        i have it set to a motion sensor that covers most of the room...
        one relay controls the lights...the other controls my soldering iron perfect work

        1 Reply Last reply
        0
        • A Offline
          A Offline
          AndreD
          wrote on last edited by
          #5

          How to send the relay to the gateway every 30 seconds?

          HenryWhiteH 1 Reply Last reply
          0
          • A AndreD

            How to send the relay to the gateway every 30 seconds?

            HenryWhiteH Offline
            HenryWhiteH Offline
            HenryWhite
            wrote on last edited by
            #6

            @AndreD said in Multiple Relays + Motion sketch, fully customizable, optional timer, manual override:

            How to send the relay to the gateway every 30 seconds?

            Why would you need that?

            1 Reply Last reply
            0
            • A Offline
              A Offline
              AndreD
              wrote on last edited by
              #7

              Suppose.
              We have a server + gateway + relay module 1 + relay module 2 ..... all relays are on.
              There is a power failure at the relay module ..... the relays turned off.
              The server status is old, not correct.
              The recording of the status of the relay in memory is not acceptable.

              gohanG 1 Reply Last reply
              0
              • A Offline
                A Offline
                AndreD
                wrote on last edited by
                #8

                person
                Next problem....
                Anybody know how edit sketch for relays to add itrms to send repeate update status to gateway? I want eliminate problem when node start and change status , but gateway is disabled. And after gateway will be enable show in my Domoticz old status/last memory before disable gateway. But after this node has changed status and this status is not show in Domoticz after run. I want to work it as Z-Wave. Z-wave has always actual status. Is any chance to also MySensors Gateway and not has always actual status ?

                1 Reply Last reply
                0
                • A AndreD

                  Suppose.
                  We have a server + gateway + relay module 1 + relay module 2 ..... all relays are on.
                  There is a power failure at the relay module ..... the relays turned off.
                  The server status is old, not correct.
                  The recording of the status of the relay in memory is not acceptable.

                  gohanG Offline
                  gohanG Offline
                  gohan
                  Mod
                  wrote on last edited by
                  #9

                  @AndreD actually the relay state is restored to last state as the node is rebooted. I don't see where is the problem

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    AndreD
                    wrote on last edited by
                    #10

                    то gohan
                    Example.

                    1. The server turned on the relay at 11 hours 00 minutes.
                      2.In 11-02 minutes. Alarm with relay module power.
                      3.In 11-05 minutes the server sends a command to turn off the relay.
                    2. in 11-30 minutes. The power to the relay module resumes. (Relay Enabled)
                    3. Server status is off (Relay is on)
                    4. The result - the neighbors below are happy to repair: (

                    Question. How to request real relay status from the server.

                    Boots33B 1 Reply Last reply
                    0
                    • A AndreD

                      то gohan
                      Example.

                      1. The server turned on the relay at 11 hours 00 minutes.
                        2.In 11-02 minutes. Alarm with relay module power.
                        3.In 11-05 minutes the server sends a command to turn off the relay.
                      2. in 11-30 minutes. The power to the relay module resumes. (Relay Enabled)
                      3. Server status is off (Relay is on)
                      4. The result - the neighbors below are happy to repair: (

                      Question. How to request real relay status from the server.

                      Boots33B Offline
                      Boots33B Offline
                      Boots33
                      Hero Member
                      wrote on last edited by
                      #11

                      @AndreD have a look here for a bit of info on requesting status.

                      1 Reply Last reply
                      0
                      • B Offline
                        B Offline
                        Ben Andrewes
                        wrote on last edited by
                        #12

                        I'm having trouble getting Domoticz to see any more than 1 relay. I've tried the MySensors example basic relay sketch and no luck. Then I tried this one (which is amazing btw as I want to have a PIR independent of the relays) and the same problem.

                        I've tried to present the sensors individually without the FOR statement, and added a delay between presentation in case that was an issue, also I've tried different output pins on the Arduino, and I've tried multiple boards... Nothing has worked

                        I am very much an enthusiastic amateur, so any advice on what to try next much appreciated

                        Thanks in advance

                        ? 1 Reply Last reply
                        0
                        • B Ben Andrewes

                          I'm having trouble getting Domoticz to see any more than 1 relay. I've tried the MySensors example basic relay sketch and no luck. Then I tried this one (which is amazing btw as I want to have a PIR independent of the relays) and the same problem.

                          I've tried to present the sensors individually without the FOR statement, and added a delay between presentation in case that was an issue, also I've tried different output pins on the Arduino, and I've tried multiple boards... Nothing has worked

                          I am very much an enthusiastic amateur, so any advice on what to try next much appreciated

                          Thanks in advance

                          ? Offline
                          ? Offline
                          A Former User
                          wrote on last edited by
                          #13

                          @Ben-Andrewes My domoticz instance behaves weirdly with relay sketches too. Maybe you can find some help here: https://forum.mysensors.org/topic/7101/domoticz-relay-node-doesn-t-show-up-in-devices/21

                          B 1 Reply Last reply
                          0
                          • ? A Former User

                            @Ben-Andrewes My domoticz instance behaves weirdly with relay sketches too. Maybe you can find some help here: https://forum.mysensors.org/topic/7101/domoticz-relay-node-doesn-t-show-up-in-devices/21

                            B Offline
                            B Offline
                            Ben Andrewes
                            wrote on last edited by Ben Andrewes
                            #14

                            @thierryd Thanks for the reply. In case it helps anyone I ended up individually defining and presenting the relays and their parameters within the sketch rather than using the FOR statement and it worked fine.

                            1 Reply Last reply
                            0
                            • gohanG Offline
                              gohanG Offline
                              gohan
                              Mod
                              wrote on last edited by
                              #15

                              Did you try to add a small delay in the presentation?

                              1 Reply Last reply
                              0
                              • B Offline
                                B Offline
                                Ben Andrewes
                                wrote on last edited by
                                #16

                                @gohan - yep added wait(100) between each sensor. To be honest I made a number of small changes without re-uploading and testing between so I'm not sure what solved it... Oh well, at least it works now :)

                                1 Reply Last reply
                                0
                                • O Offline
                                  O Offline
                                  Ostoja
                                  wrote on last edited by
                                  #17

                                  Hello! Sorry for my english. This sketch works fine. But I still need to add a temperature sensor ds18b20. If I add a temperature sensor, the sketch stops working. Please help. I'm new to both Arduino and Mysensors. Many thanks!!!

                                  rejoe2R 1 Reply Last reply
                                  0
                                  • O Ostoja

                                    Hello! Sorry for my english. This sketch works fine. But I still need to add a temperature sensor ds18b20. If I add a temperature sensor, the sketch stops working. Please help. I'm new to both Arduino and Mysensors. Many thanks!!!

                                    rejoe2R Offline
                                    rejoe2R Offline
                                    rejoe2
                                    wrote on last edited by
                                    #18

                                    @ostoja Please add your code. Most likely you just transfered the DS18x20-Code into the relay sketch including the sleep() at the end of the loop().
                                    If you did it that way: This had been discussed here several times, you have to change the code into a so-called non-bocking loop().

                                    Controller: FHEM; MySensors: 2.3.1, RS485,nRF24,RFM69, serial Gateways

                                    O 1 Reply Last reply
                                    1
                                    • rejoe2R rejoe2

                                      @ostoja Please add your code. Most likely you just transfered the DS18x20-Code into the relay sketch including the sleep() at the end of the loop().
                                      If you did it that way: This had been discussed here several times, you have to change the code into a so-called non-bocking loop().

                                      O Offline
                                      O Offline
                                      Ostoja
                                      wrote on last edited by Ostoja
                                      #19

                                      @rejoe2, MANY thanks for answer! Relay don't work in Domoticz :white_frowning_face:

                                      // Enable and uncomment attached radio type
                                      #define MY_RADIO_NRF24
                                      //#define MY_TRANSPORT_WAIT_READY_MS 1      // uncomment this to enter the loop() and setup()-function even when the node cannot be registered to gw
                                      
                                      //----------------------- Relay and Motion Sensor Configuration -----------------------
                                      #define MOTION                                                    // un-comment to enable motion sensing
                                      #define NUMBER_OF_RELAYS  1                                       // Total number of attached relays. Must be equal to total number of elements in array below!
                                      const int RELAYS[]                  =     {4};                    // digital pins of attached relays
                                      const int MOTION_ACTIVATED_RELAYS[] =     {1,  0};                // 1 to trigger the relay through motion, 0 to not trigger. Array length must correspond to RELAYS[] array.
                                      const long ON_TIMES[]               =     {300, 0};               // Specify for each element in MOTION_ACTIVATED_RELAYS, how long the specified relay should be active in seconds.
                                      #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 MOTION_PIN        3                                       // The digital input pin of the motion sensor
                                      #define MOTION_CHILD_ID   10                                      // Set the child id of the motion sensor
                                      bool ack = 1;                                                     // set this to 1 if you want destination node to send ack back to this node
                                      
                                      //----------------------- DO NOT CHANGE -----------------------------
                                      #include <MySensors.h>
                                      MyMessage motion_msg(MOTION_CHILD_ID, V_TRIPPED);                 // Initialize motion message
                                      unsigned long trigger_millis[NUMBER_OF_RELAYS];                   // Used for the timer
                                      bool lastTripped = 0;                                             // Used to store last motion sensor value
                                      bool manual_override = 1;                                         // if this gets set to 1 (e.g. by a switch or a command from the gateway), motion triggering of relays is deactivated
                                      MyMessage relay_msg;                                              // Initialize relay message
                                      
                                      
                                      #include <DallasTemperature.h>
                                      #include <OneWire.h>
                                      
                                      #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
                                      
                                      #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 
                                      #define MAX_ATTACHED_DS18B20 16
                                      unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
                                      OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                                      DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                                      float lastTemperature[MAX_ATTACHED_DS18B20];
                                      int numSensors=0;
                                      bool receivedConfig = false;
                                      bool metric = true;
                                      // Initialize temperature message
                                      MyMessage msg(0,V_TEMP);
                                      
                                      void before()
                                      
                                        
                                      
                                      {
                                        // Startup up the OneWire library
                                        sensors.begin();
                                        int i;
                                        for (int sensor = 1, i = 0; sensor <= NUMBER_OF_RELAYS; sensor++, i++) {
                                          // set relay pins to output mode
                                          pinMode(RELAYS[i], OUTPUT);
                                          // Restore relay to last known state (using eeprom storage)
                                          digitalWrite(RELAYS[i], loadState(sensor) ? RELAY_ON : RELAY_OFF);
                                        }
                                        // set motion pin to output mode, if MOTION is defined
                                      #ifdef MOTION
                                        pinMode(MOTION_PIN, INPUT);
                                      #endif
                                      }
                                      
                                      void setup()
                                      {
                                        // requestTemperatures() will not block current thread
                                        sensors.setWaitForConversion(false);
                                      #ifdef MOTION
                                        // give the motion sensor some time to settle
                                        Serial.println("Starting up. Please wait 8 seconds...");
                                        delay(8000);
                                      #endif
                                      }
                                      
                                      void presentation()
                                      {
                                        // Send the sketch version information to the gateway and Controller
                                        sendSketchInfo("Relay/Motion", "1.0");
                                      
                                        // Fetch the number of attached temperature sensors  
                                        numSensors = sensors.getDeviceCount();
                                      
                                        // Present all sensors to controller
                                        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                                           present(i, S_TEMP);
                                        }
                                      
                                        // Register all sensors to gw (they will be created as child devices)
                                        for (int sensor = 1; sensor <= NUMBER_OF_RELAYS; sensor++) {
                                          present(sensor, S_BINARY, "Relay", ack);
                                        }
                                      #ifdef MOTION
                                        present(MOTION_CHILD_ID, S_MOTION, "Motion Sensor", ack);
                                      #endif
                                      
                                      }
                                      
                                      void loop()
                                      {
                                      
                                        // Fetch temperatures from Dallas sensors
                                        sensors.requestTemperatures();
                                      
                                        // query conversion time and sleep until conversion completed
                                        int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                                        // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
                                        sleep(conversionTime);
                                      
                                        // Read temperatures and send them to controller 
                                        for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
                                       
                                          // Fetch and round temperature to one decimal
                                          float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                                       
                                          // Only send data if temperature has changed and no error
                                          #if COMPARE_TEMP == 1
                                          if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
                                          #else
                                          if (temperature != -127.00 && temperature != 85.00) {
                                          #endif
                                       
                                            // Send in the new temperature
                                            send(msg.setSensor(i).set(temperature,1));
                                            // Save new temperatures for next compare
                                            lastTemperature[i]=temperature;
                                          }
                                        }
                                        sleep(SLEEP_TIME);
                                      #ifdef MOTION
                                        if (!manual_override) {
                                          // Read digital motion value
                                          bool tripped = digitalRead(MOTION_PIN) == HIGH;
                                      
                                          if (lastTripped != tripped) {
                                            Serial.print("New Motion State: ");
                                            Serial.println(tripped);
                                            // Send tripped value to gw
                                            send(motion_msg.set(tripped ? "1" : "0"));
                                            lastTripped = tripped;
                                      
                                            // Change relay states, send new state to gw and store state in eeprom
                                            if (tripped == 1) {
                                              for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                                if (MOTION_ACTIVATED_RELAYS[i] == 1) {
                                                  digitalWrite(RELAYS[i], RELAY_ON);
                                                  relay_msg_constructor(i + 1, V_STATUS);
                                                  send(relay_msg.set(RELAY_ON));
                                                  trigger_millis[i] = millis();
                                                  Serial.print("Relay ");
                                                  Serial.print(RELAYS[i]);
                                                  Serial.println(" turned on");
                                                  saveState(i, 1);
                                                }
                                              }
                                            }
                                          }
                                      
                                          for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                            if (tripped == 1 and MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                              trigger_millis[i] = millis();
                                            }
                                            if ((trigger_millis[i] + ON_TIMES[i] * 1000 < millis()) and MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                              digitalWrite(RELAYS[i], RELAY_OFF);
                                              relay_msg_constructor(i + 1, V_STATUS);
                                              send(relay_msg.set(RELAY_OFF));
                                              Serial.print("Relay ");
                                              Serial.print(RELAYS[i]);
                                              Serial.println(" turned off");
                                              saveState(i, 0);
                                              trigger_millis[i] = 0;
                                            }
                                          }
                                        }
                                        else {
                                          bool tripped = digitalRead(MOTION_PIN) == HIGH;
                                          if (lastTripped != tripped) {
                                            Serial.print("New Motion State: ");
                                            Serial.println(tripped);
                                            // Send tripped value to gw
                                            send(motion_msg.set(tripped ? "1" : "0"));
                                            lastTripped = tripped;
                                          }
                                          for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                            if (MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                              trigger_millis[i] = 0;                            // reset running timers
                                            }
                                          }
                                        }
                                      #endif
                                      }
                                      
                                      void receive(const MyMessage &message)
                                      {
                                        // Handle incoming relay commands
                                        if (message.type == V_STATUS) {
                                          // Change relay state
                                          if (RELAYS[message.sensor - 1]) {
                                            digitalWrite(RELAYS[message.sensor - 1], message.getBool() ? RELAY_ON : RELAY_OFF);
                                      
                                            // Store state in eeprom
                                            saveState(message.sensor - 1, message.getBool());
                                            // Write some debug info
                                            Serial.print("Incoming change for sensor:");
                                            Serial.print(message.sensor);
                                            Serial.print(", New status: ");
                                            Serial.println(message.getBool());
                                          }
                                        }
                                      
                                        // Handle incoming manual override/bypass of motion sensor
                                        if (message.type == V_ARMED and message.sensor == 0) {
                                          manual_override = message.getBool();
                                          Serial.print("Manual Override: ");
                                          Serial.println(manual_override);
                                        }
                                      }
                                      
                                      void relay_msg_constructor(int sensor, uint8_t type)
                                      {
                                        relay_msg.setSensor(sensor);
                                        relay_msg.setType(type);
                                      }
                                      
                                      dirkcD 1 Reply Last reply
                                      0
                                      • O Offline
                                        O Offline
                                        Ostoja
                                        wrote on last edited by
                                        #20

                                        I commented out the "sleep", but when I press the relay switch in Domoticz, it does not work:white_frowning_face:

                                        dirkcD 1 Reply Last reply
                                        0
                                        • O Ostoja

                                          @rejoe2, MANY thanks for answer! Relay don't work in Domoticz :white_frowning_face:

                                          // Enable and uncomment attached radio type
                                          #define MY_RADIO_NRF24
                                          //#define MY_TRANSPORT_WAIT_READY_MS 1      // uncomment this to enter the loop() and setup()-function even when the node cannot be registered to gw
                                          
                                          //----------------------- Relay and Motion Sensor Configuration -----------------------
                                          #define MOTION                                                    // un-comment to enable motion sensing
                                          #define NUMBER_OF_RELAYS  1                                       // Total number of attached relays. Must be equal to total number of elements in array below!
                                          const int RELAYS[]                  =     {4};                    // digital pins of attached relays
                                          const int MOTION_ACTIVATED_RELAYS[] =     {1,  0};                // 1 to trigger the relay through motion, 0 to not trigger. Array length must correspond to RELAYS[] array.
                                          const long ON_TIMES[]               =     {300, 0};               // Specify for each element in MOTION_ACTIVATED_RELAYS, how long the specified relay should be active in seconds.
                                          #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 MOTION_PIN        3                                       // The digital input pin of the motion sensor
                                          #define MOTION_CHILD_ID   10                                      // Set the child id of the motion sensor
                                          bool ack = 1;                                                     // set this to 1 if you want destination node to send ack back to this node
                                          
                                          //----------------------- DO NOT CHANGE -----------------------------
                                          #include <MySensors.h>
                                          MyMessage motion_msg(MOTION_CHILD_ID, V_TRIPPED);                 // Initialize motion message
                                          unsigned long trigger_millis[NUMBER_OF_RELAYS];                   // Used for the timer
                                          bool lastTripped = 0;                                             // Used to store last motion sensor value
                                          bool manual_override = 1;                                         // if this gets set to 1 (e.g. by a switch or a command from the gateway), motion triggering of relays is deactivated
                                          MyMessage relay_msg;                                              // Initialize relay message
                                          
                                          
                                          #include <DallasTemperature.h>
                                          #include <OneWire.h>
                                          
                                          #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No
                                          
                                          #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected 
                                          #define MAX_ATTACHED_DS18B20 16
                                          unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
                                          OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
                                          DallasTemperature sensors(&oneWire); // Pass the oneWire reference to Dallas Temperature. 
                                          float lastTemperature[MAX_ATTACHED_DS18B20];
                                          int numSensors=0;
                                          bool receivedConfig = false;
                                          bool metric = true;
                                          // Initialize temperature message
                                          MyMessage msg(0,V_TEMP);
                                          
                                          void before()
                                          
                                            
                                          
                                          {
                                            // Startup up the OneWire library
                                            sensors.begin();
                                            int i;
                                            for (int sensor = 1, i = 0; sensor <= NUMBER_OF_RELAYS; sensor++, i++) {
                                              // set relay pins to output mode
                                              pinMode(RELAYS[i], OUTPUT);
                                              // Restore relay to last known state (using eeprom storage)
                                              digitalWrite(RELAYS[i], loadState(sensor) ? RELAY_ON : RELAY_OFF);
                                            }
                                            // set motion pin to output mode, if MOTION is defined
                                          #ifdef MOTION
                                            pinMode(MOTION_PIN, INPUT);
                                          #endif
                                          }
                                          
                                          void setup()
                                          {
                                            // requestTemperatures() will not block current thread
                                            sensors.setWaitForConversion(false);
                                          #ifdef MOTION
                                            // give the motion sensor some time to settle
                                            Serial.println("Starting up. Please wait 8 seconds...");
                                            delay(8000);
                                          #endif
                                          }
                                          
                                          void presentation()
                                          {
                                            // Send the sketch version information to the gateway and Controller
                                            sendSketchInfo("Relay/Motion", "1.0");
                                          
                                            // Fetch the number of attached temperature sensors  
                                            numSensors = sensors.getDeviceCount();
                                          
                                            // Present all sensors to controller
                                            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                                               present(i, S_TEMP);
                                            }
                                          
                                            // Register all sensors to gw (they will be created as child devices)
                                            for (int sensor = 1; sensor <= NUMBER_OF_RELAYS; sensor++) {
                                              present(sensor, S_BINARY, "Relay", ack);
                                            }
                                          #ifdef MOTION
                                            present(MOTION_CHILD_ID, S_MOTION, "Motion Sensor", ack);
                                          #endif
                                          
                                          }
                                          
                                          void loop()
                                          {
                                          
                                            // Fetch temperatures from Dallas sensors
                                            sensors.requestTemperatures();
                                          
                                            // query conversion time and sleep until conversion completed
                                            int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution());
                                            // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater)
                                            sleep(conversionTime);
                                          
                                            // Read temperatures and send them to controller 
                                            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {
                                           
                                              // Fetch and round temperature to one decimal
                                              float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.;
                                           
                                              // Only send data if temperature has changed and no error
                                              #if COMPARE_TEMP == 1
                                              if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) {
                                              #else
                                              if (temperature != -127.00 && temperature != 85.00) {
                                              #endif
                                           
                                                // Send in the new temperature
                                                send(msg.setSensor(i).set(temperature,1));
                                                // Save new temperatures for next compare
                                                lastTemperature[i]=temperature;
                                              }
                                            }
                                            sleep(SLEEP_TIME);
                                          #ifdef MOTION
                                            if (!manual_override) {
                                              // Read digital motion value
                                              bool tripped = digitalRead(MOTION_PIN) == HIGH;
                                          
                                              if (lastTripped != tripped) {
                                                Serial.print("New Motion State: ");
                                                Serial.println(tripped);
                                                // Send tripped value to gw
                                                send(motion_msg.set(tripped ? "1" : "0"));
                                                lastTripped = tripped;
                                          
                                                // Change relay states, send new state to gw and store state in eeprom
                                                if (tripped == 1) {
                                                  for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                                    if (MOTION_ACTIVATED_RELAYS[i] == 1) {
                                                      digitalWrite(RELAYS[i], RELAY_ON);
                                                      relay_msg_constructor(i + 1, V_STATUS);
                                                      send(relay_msg.set(RELAY_ON));
                                                      trigger_millis[i] = millis();
                                                      Serial.print("Relay ");
                                                      Serial.print(RELAYS[i]);
                                                      Serial.println(" turned on");
                                                      saveState(i, 1);
                                                    }
                                                  }
                                                }
                                              }
                                          
                                              for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                                if (tripped == 1 and MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                                  trigger_millis[i] = millis();
                                                }
                                                if ((trigger_millis[i] + ON_TIMES[i] * 1000 < millis()) and MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                                  digitalWrite(RELAYS[i], RELAY_OFF);
                                                  relay_msg_constructor(i + 1, V_STATUS);
                                                  send(relay_msg.set(RELAY_OFF));
                                                  Serial.print("Relay ");
                                                  Serial.print(RELAYS[i]);
                                                  Serial.println(" turned off");
                                                  saveState(i, 0);
                                                  trigger_millis[i] = 0;
                                                }
                                              }
                                            }
                                            else {
                                              bool tripped = digitalRead(MOTION_PIN) == HIGH;
                                              if (lastTripped != tripped) {
                                                Serial.print("New Motion State: ");
                                                Serial.println(tripped);
                                                // Send tripped value to gw
                                                send(motion_msg.set(tripped ? "1" : "0"));
                                                lastTripped = tripped;
                                              }
                                              for (int i = 0; i < NUMBER_OF_RELAYS; i++) {
                                                if (MOTION_ACTIVATED_RELAYS[i] == 1 and trigger_millis[i] != 0) {
                                                  trigger_millis[i] = 0;                            // reset running timers
                                                }
                                              }
                                            }
                                          #endif
                                          }
                                          
                                          void receive(const MyMessage &message)
                                          {
                                            // Handle incoming relay commands
                                            if (message.type == V_STATUS) {
                                              // Change relay state
                                              if (RELAYS[message.sensor - 1]) {
                                                digitalWrite(RELAYS[message.sensor - 1], message.getBool() ? RELAY_ON : RELAY_OFF);
                                          
                                                // Store state in eeprom
                                                saveState(message.sensor - 1, message.getBool());
                                                // Write some debug info
                                                Serial.print("Incoming change for sensor:");
                                                Serial.print(message.sensor);
                                                Serial.print(", New status: ");
                                                Serial.println(message.getBool());
                                              }
                                            }
                                          
                                            // Handle incoming manual override/bypass of motion sensor
                                            if (message.type == V_ARMED and message.sensor == 0) {
                                              manual_override = message.getBool();
                                              Serial.print("Manual Override: ");
                                              Serial.println(manual_override);
                                            }
                                          }
                                          
                                          void relay_msg_constructor(int sensor, uint8_t type)
                                          {
                                            relay_msg.setSensor(sensor);
                                            relay_msg.setType(type);
                                          }
                                          
                                          dirkcD Offline
                                          dirkcD Offline
                                          dirkc
                                          wrote on last edited by dirkc
                                          #21

                                          @ostoja said in Multiple Relays + Motion sketch, fully customizable, optional timer, manual override:

                                          // Present all sensors to controller
                                            for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) {   
                                               present(i, S_TEMP);
                                            }
                                          
                                            // Register all sensors to gw (they will be created as child devices)
                                            for (int sensor = 1; sensor <= NUMBER_OF_RELAYS; sensor++) {
                                              present(sensor, S_BINARY, "Relay", ack);
                                            }
                                          

                                          With this two "for" loops you set present(n) multiple times. in the first for() you start with 0 until MAX_ATTACHED_DS18B20-1, in the second for() you start with 1 until NUMBER_OF_RELAYS-1, so this will assign the sensors with identical IDs as the relays.
                                          I have not checked the internal code of this method, but I would think that you should better user a different range in the second for() loop starting at least with MAX_ATTACHED_DS18B20+1.

                                          Controller: Home Assistant & FHEM - Gateway: ESP8266wifi - MySensors: 2.3.2 (nRF24)

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


                                          19

                                          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