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. Troubleshooting
  3. Prevent Relay from triggering on power loss or broker reboot

Prevent Relay from triggering on power loss or broker reboot

Scheduled Pinned Locked Moved Troubleshooting
22 Posts 8 Posters 8.3k Views 8 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.
  • Daniel OliveiraD Offline
    Daniel OliveiraD Offline
    Daniel Oliveira
    wrote on last edited by
    #13

    Hi,

    I'm not an expert and honestly I didn't read all the comments, but to avoid the relay to change status on reboots would not be a simpler solution to add a "flip-flop" mechanism that will "save" the last sate for some minutes?

    Best regards

    MySensors rules my home :)

    1 Reply Last reply
    0
    • rhuehnR Offline
      rhuehnR Offline
      rhuehn
      wrote on last edited by
      #14

      Hello @Boots33

      The Reed switch should NOT have any effect on the relay. ( It shouldn't anyways, it only senses open / closed

      From my understanding here:

      https://home-assistant.io/components/mysensors/

      It needs to be done in the loop function:

      Present the sensor’s S_TYPE.
      Send at least one initial value per V_TYPE. In version 2.0 of MySensors this has to be done in the loop function. See below for an example in 2.0 of how to make sure the initial value has been received by the controller.

      Below is an example from that page:

      /*
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * http://www.mysensors.org/build/relay
       */
      
      #define MY_DEBUG
      #define MY_RADIO_NRF24
      #define MY_REPEATER_FEATURE
      #define MY_NODE_ID 1
      #include <SPI.h>
      #include <MySensors.h>
      #include <Bounce2.h>
      
      #define RELAY_PIN  5
      #define BUTTON_PIN  3
      #define CHILD_ID 1
      #define RELAY_ON 1
      #define RELAY_OFF 0
      
      Bounce debouncer = Bounce();
      bool state = false;
      bool initialValueSent = false;
      
      MyMessage msg(CHILD_ID, V_STATUS);
      
      void setup()
      {
        pinMode(BUTTON_PIN, INPUT_PULLUP);
        debouncer.attach(BUTTON_PIN);
        debouncer.interval(10);
      
        // Make sure relays are off when starting up
        digitalWrite(RELAY_PIN, RELAY_OFF);
        pinMode(RELAY_PIN, OUTPUT);
      }
      
      void presentation()  {
        sendSketchInfo("Relay+button", "1.0");
        present(CHILD_ID, S_BINARY);
      }
      
      void loop()
      {
        if (!initialValueSent) {
          Serial.println("Sending initial value");
          send(msg.set(state?RELAY_ON:RELAY_OFF));
          Serial.println("Requesting initial value from controller");
          request(CHILD_ID, V_STATUS);
          wait(2000, C_SET, V_STATUS);
        }
        if (debouncer.update()) {
          if (debouncer.read()==LOW) {
            state = !state;
            // Send new state and request ack back
            send(msg.set(state?RELAY_ON:RELAY_OFF), true);
          }
        }
      }
      
      void receive(const MyMessage &message) {
        if (message.isAck()) {
           Serial.println("This is an ack from gateway");
        }
      
        if (message.type == V_STATUS) {
          if (!initialValueSent) {
            Serial.println("Receiving initial value from controller");
            initialValueSent = true;
          }
          // Change relay state
          state = (bool)message.getInt();
          digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
          send(msg.set(state?RELAY_ON:RELAY_OFF));
        }
      }
      

      I was just following some guidelines to use HASS+ My Sensors together.

      Boots33B 1 Reply Last reply
      0
      • rhuehnR rhuehn

        Hello @Boots33

        The Reed switch should NOT have any effect on the relay. ( It shouldn't anyways, it only senses open / closed

        From my understanding here:

        https://home-assistant.io/components/mysensors/

        It needs to be done in the loop function:

        Present the sensor’s S_TYPE.
        Send at least one initial value per V_TYPE. In version 2.0 of MySensors this has to be done in the loop function. See below for an example in 2.0 of how to make sure the initial value has been received by the controller.

        Below is an example from that page:

        /*
         * Documentation: http://www.mysensors.org
         * Support Forum: http://forum.mysensors.org
         *
         * http://www.mysensors.org/build/relay
         */
        
        #define MY_DEBUG
        #define MY_RADIO_NRF24
        #define MY_REPEATER_FEATURE
        #define MY_NODE_ID 1
        #include <SPI.h>
        #include <MySensors.h>
        #include <Bounce2.h>
        
        #define RELAY_PIN  5
        #define BUTTON_PIN  3
        #define CHILD_ID 1
        #define RELAY_ON 1
        #define RELAY_OFF 0
        
        Bounce debouncer = Bounce();
        bool state = false;
        bool initialValueSent = false;
        
        MyMessage msg(CHILD_ID, V_STATUS);
        
        void setup()
        {
          pinMode(BUTTON_PIN, INPUT_PULLUP);
          debouncer.attach(BUTTON_PIN);
          debouncer.interval(10);
        
          // Make sure relays are off when starting up
          digitalWrite(RELAY_PIN, RELAY_OFF);
          pinMode(RELAY_PIN, OUTPUT);
        }
        
        void presentation()  {
          sendSketchInfo("Relay+button", "1.0");
          present(CHILD_ID, S_BINARY);
        }
        
        void loop()
        {
          if (!initialValueSent) {
            Serial.println("Sending initial value");
            send(msg.set(state?RELAY_ON:RELAY_OFF));
            Serial.println("Requesting initial value from controller");
            request(CHILD_ID, V_STATUS);
            wait(2000, C_SET, V_STATUS);
          }
          if (debouncer.update()) {
            if (debouncer.read()==LOW) {
              state = !state;
              // Send new state and request ack back
              send(msg.set(state?RELAY_ON:RELAY_OFF), true);
            }
          }
        }
        
        void receive(const MyMessage &message) {
          if (message.isAck()) {
             Serial.println("This is an ack from gateway");
          }
        
          if (message.type == V_STATUS) {
            if (!initialValueSent) {
              Serial.println("Receiving initial value from controller");
              initialValueSent = true;
            }
            // Change relay state
            state = (bool)message.getInt();
            digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            send(msg.set(state?RELAY_ON:RELAY_OFF));
          }
        }
        

        I was just following some guidelines to use HASS+ My Sensors together.

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

        @rhuehn Ahh... I use Domoticz so was unaware of HA's need for the extra code to register the node.

        So the problem you face is then likely the code below the registration code.
        This code is using the bouncer instance which you have connected to your reed switch and then sends a message to change the state of your relay.

        if (debouncer.update()) {
            if (debouncer.read()==LOW) {
              state = !state;
              // Send new state and request ack back
              send(msg.set(state?RELAY_ON:RELAY_OFF), true);
            }
          }
        

        So if you could can you try these 2 changes to your code and see if we are any close to the desired result :)
        I have changed the initial code slightly to just sen an off state for the switch. It should make no difference as all you are needing is an initial response from the sensor.
        I have also commented out the bouncer code

         if (!initialValueSent) {
            Serial.println("Sending initial value");
            //send(msg.set(state?RELAY_ON:RELAY_OFF));
            send(msg.set(RELAY_OFF));
            Serial.println("Requesting initial value from controller");
            request(CHILD_ID_REL, V_STATUS);
            wait(2000, C_SET, V_STATUS);
          }
          /*
          if (debouncer.update()) {
            if (debouncer.read()==LOW) {
              state = !state;
              // Send new state and request ack back
              send(msg.set(state?RELAY_ON:RELAY_OFF), true);
            }
          }
         */
        

        Then change your receive code to

        void receive(const MyMessage &message) {
          if (message.isAck()) {
             Serial.println("This is an ack from gateway");
          }
          if (message.type == V_STATUS) {
            if (!initialValueSent) {
              Serial.println("Receiving initial value from controller");
              initialValueSent = true;
            }
        /*    // Change relay state
            state = (bool)message.getInt();
            digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
            //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
            delay( TOGGLE_INTERVAL );
            digitalWrite( RELAY_PIN, RELAY_OFF );
            // Store state in eeprom
            saveState(message.sensor, message.getBool());
            send(msg.set(state?RELAY_ON:RELAY_OFF));
          }
        */
        
        else if (message.sensor == CHILD_ID_REL && message.getBool == true) {
            digitalWrite(RELAY_PIN, RELAY_ON);
            //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
            wait( TOGGLE_INTERVAL );
            digitalWrite( RELAY_PIN, RELAY_OFF );               //turn relay off
            send(msg.set(false), false);                       // send off state to controller, no ack requested
         }  
        }
        
        
        1 Reply Last reply
        0
        • BrydenB Offline
          BrydenB Offline
          Bryden
          wrote on last edited by
          #16

          What type of relay are you using?

          My guess is a LOW TRIGGER relay, which is bad for this task.

          If you are using a low trigger relay the fault is in the hardware not the code.

          The microcontroller takes time to reboot and enable a high to keep the relay open.

          When you loose power, your microcontroller is going to take time to reboot,
          But I bet your power supply is going to instantly give power to your relay board,
          hence there is a small period in time where there is a ground on your pin before the initial setup of the pin to high in the microcontroller, causing your relay to trigger.

          This is why I hate low trigger relays, they are useless when it comes to power interrupts and you're trusting your house security to them.

          My suggestions to test my theory, then you will know where your fault lies.

          throw an LED on your relay out to light up when switched high, Apply power to your microcontroller and see how long it takes for the relay to turn on.

          Why do people use low level relays?
          Output pins are generally 3.3v, that's not enough voltage to trigger most high level relays, using a low level trigger overcomes this.

          Use a high level relay, but you will need a transistor circuit to feed it 5v as the 3.3v generally wont trigger the relay with a high output.

          hopefully my rant helps

          Boots33B 1 Reply Last reply
          0
          • BrydenB Offline
            BrydenB Offline
            Bryden
            wrote on last edited by
            #17

            I noticed on my ESP8266-01b that it does power surge a voltage during initial power up as well, also bad for a high level relay

            1 Reply Last reply
            0
            • BrydenB Bryden

              What type of relay are you using?

              My guess is a LOW TRIGGER relay, which is bad for this task.

              If you are using a low trigger relay the fault is in the hardware not the code.

              The microcontroller takes time to reboot and enable a high to keep the relay open.

              When you loose power, your microcontroller is going to take time to reboot,
              But I bet your power supply is going to instantly give power to your relay board,
              hence there is a small period in time where there is a ground on your pin before the initial setup of the pin to high in the microcontroller, causing your relay to trigger.

              This is why I hate low trigger relays, they are useless when it comes to power interrupts and you're trusting your house security to them.

              My suggestions to test my theory, then you will know where your fault lies.

              throw an LED on your relay out to light up when switched high, Apply power to your microcontroller and see how long it takes for the relay to turn on.

              Why do people use low level relays?
              Output pins are generally 3.3v, that's not enough voltage to trigger most high level relays, using a low level trigger overcomes this.

              Use a high level relay, but you will need a transistor circuit to feed it 5v as the 3.3v generally wont trigger the relay with a high output.

              hopefully my rant helps

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

              @Bryden thanks for your input. In the code the relay is switched high for on and low for off so it should not be the type of relay to cause problems . Worth checking though.

              1 Reply Last reply
              0
              • BrydenB Offline
                BrydenB Offline
                Bryden
                wrote on last edited by
                #19

                check to see if the output pins are having any voltage applied on initial boot as well.
                As mentioned I had an esp8266-01b on my desk here, and when power was applied I saw voltage on one of the gpio's intermittently.

                1 Reply Last reply
                0
                • rhuehnR Offline
                  rhuehnR Offline
                  rhuehn
                  wrote on last edited by
                  #20

                  Hey guys! Thanks so very much for all the great comments. I haven't replied in a few days as I wanted to go back to the drawing board..... I didn't like that sketch, the sleep functions, etc etc.... It didn't also make sense clearly based on everyone's feedback ( Sorry I am just getting started with IDE... ) So, based on that, I've come up with the following, and if you could comment, modify where I messed up, it would be greatly appreciated. This sketch seems to work, and keep state on power LOSS. There's a relay for the garage door ( trigger, PIN 4 ), a reed switch to detect if the door is open or closed ( PIN 2 ), a DHT for Temp / Humidity ( PIN 7 ), and a PIR ( PIN 3 ) for motion activated events. Below is the sketch, and would really appreciate any great feedback.

                  Thanks again!

                  
                  #define MY_DEBUG
                  #define MY_RADIO_NRF24
                  #define MY_REPEATER_FEATURE
                  #define MY_NODE_ID 50
                  
                  #include <SPI.h>
                  #include <MySensors.h>
                  #include <Bounce2.h>
                  #include <DHT.h>
                  
                  #define RELAY_1  4  // 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 TOGGLE_INTERVAL 350
                  
                  #define CHILD_ID_SW 2
                  #define BUTTON_PIN  2  // Arduino Digital I/O pin for button/reed switch
                  
                  // Sleep time between sensor updates (in milliseconds)
                  // Must be >1000ms for DHT22 and >2000ms for DHT11
                  static const uint64_t UPDATE_INTERVAL = 60000;
                  
                  // Force sending an update of the temperature after n sensor reads, so a controller showing the
                  // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
                  // the value didn't change since;
                  // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
                  static const uint8_t FORCE_UPDATE_N_READS = 10;
                  
                  float lastTemp;
                  float lastHum;
                  uint8_t nNoUpdatesTemp;
                  uint8_t nNoUpdatesHum;
                  bool metric = true;
                  
                  #define CHILD_ID_HUM 10
                  #define CHILD_ID_TEMP 11
                  #define HUMIDITY_SENSOR_DIGITAL_PIN 7
                  
                  // Set this offset if the sensor has a permanent small offset to the real temperatures
                  #define SENSOR_TEMP_OFFSET -1
                  
                  #define CHILD_ID_PIR 3
                  #define PIR_PIN 3
                  
                  byte StatePIR=0;
                  byte oldStatePIR=0;
                  
                  Bounce debouncer = Bounce(); 
                  int oldValue=-1;
                  
                  MyMessage msgSw(CHILD_ID_SW,V_TRIPPED);
                  MyMessage msgHum(CHILD_ID_HUM, V_HUM); // 1
                  MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); // 0
                  MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
                  
                  DHT dht;
                  
                  void before()
                  {
                      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                          // Then set relay pins in output mode
                          pinMode(pin, OUTPUT);
                          // Set relay to last known state (using eeprom storage)
                          digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
                      }
                  }
                  
                  void setup()
                  {
                  
                    dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // set data pin of DHT sensor
                    if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
                      Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
                    }
                    // Sleep for the time of the minimum sampling period to give the sensor time to power up
                    // (otherwise, timeout errors might occure for the first reading)
                    sleep(dht.getMinimumSamplingPeriod());
                  
                    pinMode(PIR_PIN, INPUT_PULLUP);
                    // Setup the button
                    pinMode(BUTTON_PIN,INPUT);
                    // Activate internal pull-up
                    digitalWrite(BUTTON_PIN,HIGH);
                  
                    // After setting up the button, setup debouncer
                    debouncer.attach(BUTTON_PIN);
                    debouncer.interval(5);
                  }
                  
                  void presentation()
                  {
                      // Send the sketch version information to the gateway and Controller
                      sendSketchInfo("Garage Multi Sensor", "1.0");
                  
                      for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                          // Register all sensors to gw (they will be created as child devices)
                          present(sensor, S_BINARY);
                          present(CHILD_ID_SW, S_DOOR);
                          present(CHILD_ID_HUM, S_HUM);
                          present(CHILD_ID_TEMP, S_TEMP);
                          present(CHILD_ID_PIR, S_MOTION);
                  
                          metric = getConfig().isMetric;
                      }
                  }
                  
                  void loop()
                  {
                  
                  StatePIR=digitalRead(PIR_PIN);
                    if (StatePIR != oldStatePIR) {
                      oldStatePIR=StatePIR;
                      send(msgPir.set(StatePIR ? "ON" : "OFF"));
                    
                    // Force reading sensor, so it works also after sleep()
                    dht.readSensor(true);
                  
                    // Get temperature from DHT library
                    float temperature = dht.getTemperature();
                    if (isnan(temperature)) {
                      Serial.println("Failed reading temperature from DHT!");
                    } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
                      // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
                      lastTemp = temperature;
                      if (!metric) {
                        temperature = dht.toFahrenheit(temperature);
                      }
                      // Reset no updates counter
                      nNoUpdatesTemp = 0;
                      temperature += SENSOR_TEMP_OFFSET;
                      send(msgTemp.set(temperature, 1));
                  
                      #ifdef MY_DEBUG
                      Serial.print("T: ");
                      Serial.println(temperature);
                      #endif
                    } else {
                      // Increase no update counter if the temperature stayed the same
                      nNoUpdatesTemp++;
                    }
                  
                    // Get humidity from DHT library
                    float humidity = dht.getHumidity();
                    if (isnan(humidity)) {
                      Serial.println("Failed reading humidity from DHT");
                    } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
                      // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
                      lastHum = humidity;
                      // Reset no updates counter
                      nNoUpdatesHum = 0;
                      send(msgHum.set(humidity, 1));
                  
                      #ifdef MY_DEBUG
                      Serial.print("H: ");
                      Serial.println(humidity);
                      #endif
                    } else {
                      // Increase no update counter if the humidity stayed the same
                      nNoUpdatesHum++;
                    }
                  
                  }
                  
                    debouncer.update();
                    // Get the update value
                    int value = debouncer.read();
                  
                    if (value != oldValue) {
                       // Send in the new value
                       send(msgSw.set(value==HIGH ? 1 : 0));
                       oldValue = value;
                    }
                  }
                  
                  void receive(const MyMessage &message)
                  {
                      // We only expect one type of message from controller. But we better check anyway.
                      if (message.type==V_STATUS) {
                          // Change relay state
                          digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                          //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
                          delay( TOGGLE_INTERVAL );
                          digitalWrite( RELAY_1, 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());
                      }
                  }
                  
                  B 1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    djzang
                    wrote on last edited by
                    #21

                    I'm wondering if its not your code that is bringing the PIN high momentarily during boot up but the device or boot loader itself. Try flashing it with blank code and power cycle it and see if it triggers the relay still. If it does then you may need to put a pullup resistor on the pin to prevent it from happening.

                    1 Reply Last reply
                    0
                    • rhuehnR rhuehn

                      Hey guys! Thanks so very much for all the great comments. I haven't replied in a few days as I wanted to go back to the drawing board..... I didn't like that sketch, the sleep functions, etc etc.... It didn't also make sense clearly based on everyone's feedback ( Sorry I am just getting started with IDE... ) So, based on that, I've come up with the following, and if you could comment, modify where I messed up, it would be greatly appreciated. This sketch seems to work, and keep state on power LOSS. There's a relay for the garage door ( trigger, PIN 4 ), a reed switch to detect if the door is open or closed ( PIN 2 ), a DHT for Temp / Humidity ( PIN 7 ), and a PIR ( PIN 3 ) for motion activated events. Below is the sketch, and would really appreciate any great feedback.

                      Thanks again!

                      
                      #define MY_DEBUG
                      #define MY_RADIO_NRF24
                      #define MY_REPEATER_FEATURE
                      #define MY_NODE_ID 50
                      
                      #include <SPI.h>
                      #include <MySensors.h>
                      #include <Bounce2.h>
                      #include <DHT.h>
                      
                      #define RELAY_1  4  // 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 TOGGLE_INTERVAL 350
                      
                      #define CHILD_ID_SW 2
                      #define BUTTON_PIN  2  // Arduino Digital I/O pin for button/reed switch
                      
                      // Sleep time between sensor updates (in milliseconds)
                      // Must be >1000ms for DHT22 and >2000ms for DHT11
                      static const uint64_t UPDATE_INTERVAL = 60000;
                      
                      // Force sending an update of the temperature after n sensor reads, so a controller showing the
                      // timestamp of the last update doesn't show something like 3 hours in the unlikely case, that
                      // the value didn't change since;
                      // i.e. the sensor would force sending an update every UPDATE_INTERVAL*FORCE_UPDATE_N_READS [ms]
                      static const uint8_t FORCE_UPDATE_N_READS = 10;
                      
                      float lastTemp;
                      float lastHum;
                      uint8_t nNoUpdatesTemp;
                      uint8_t nNoUpdatesHum;
                      bool metric = true;
                      
                      #define CHILD_ID_HUM 10
                      #define CHILD_ID_TEMP 11
                      #define HUMIDITY_SENSOR_DIGITAL_PIN 7
                      
                      // Set this offset if the sensor has a permanent small offset to the real temperatures
                      #define SENSOR_TEMP_OFFSET -1
                      
                      #define CHILD_ID_PIR 3
                      #define PIR_PIN 3
                      
                      byte StatePIR=0;
                      byte oldStatePIR=0;
                      
                      Bounce debouncer = Bounce(); 
                      int oldValue=-1;
                      
                      MyMessage msgSw(CHILD_ID_SW,V_TRIPPED);
                      MyMessage msgHum(CHILD_ID_HUM, V_HUM); // 1
                      MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); // 0
                      MyMessage msgPir(CHILD_ID_PIR, V_TRIPPED);
                      
                      DHT dht;
                      
                      void before()
                      {
                          for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                              // Then set relay pins in output mode
                              pinMode(pin, OUTPUT);
                              // Set relay to last known state (using eeprom storage)
                              digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF);
                          }
                      }
                      
                      void setup()
                      {
                      
                        dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); // set data pin of DHT sensor
                        if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) {
                          Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!");
                        }
                        // Sleep for the time of the minimum sampling period to give the sensor time to power up
                        // (otherwise, timeout errors might occure for the first reading)
                        sleep(dht.getMinimumSamplingPeriod());
                      
                        pinMode(PIR_PIN, INPUT_PULLUP);
                        // Setup the button
                        pinMode(BUTTON_PIN,INPUT);
                        // Activate internal pull-up
                        digitalWrite(BUTTON_PIN,HIGH);
                      
                        // After setting up the button, setup debouncer
                        debouncer.attach(BUTTON_PIN);
                        debouncer.interval(5);
                      }
                      
                      void presentation()
                      {
                          // Send the sketch version information to the gateway and Controller
                          sendSketchInfo("Garage Multi Sensor", "1.0");
                      
                          for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) {
                              // Register all sensors to gw (they will be created as child devices)
                              present(sensor, S_BINARY);
                              present(CHILD_ID_SW, S_DOOR);
                              present(CHILD_ID_HUM, S_HUM);
                              present(CHILD_ID_TEMP, S_TEMP);
                              present(CHILD_ID_PIR, S_MOTION);
                      
                              metric = getConfig().isMetric;
                          }
                      }
                      
                      void loop()
                      {
                      
                      StatePIR=digitalRead(PIR_PIN);
                        if (StatePIR != oldStatePIR) {
                          oldStatePIR=StatePIR;
                          send(msgPir.set(StatePIR ? "ON" : "OFF"));
                        
                        // Force reading sensor, so it works also after sleep()
                        dht.readSensor(true);
                      
                        // Get temperature from DHT library
                        float temperature = dht.getTemperature();
                        if (isnan(temperature)) {
                          Serial.println("Failed reading temperature from DHT!");
                        } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) {
                          // Only send temperature if it changed since the last measurement or if we didn't send an update for n times
                          lastTemp = temperature;
                          if (!metric) {
                            temperature = dht.toFahrenheit(temperature);
                          }
                          // Reset no updates counter
                          nNoUpdatesTemp = 0;
                          temperature += SENSOR_TEMP_OFFSET;
                          send(msgTemp.set(temperature, 1));
                      
                          #ifdef MY_DEBUG
                          Serial.print("T: ");
                          Serial.println(temperature);
                          #endif
                        } else {
                          // Increase no update counter if the temperature stayed the same
                          nNoUpdatesTemp++;
                        }
                      
                        // Get humidity from DHT library
                        float humidity = dht.getHumidity();
                        if (isnan(humidity)) {
                          Serial.println("Failed reading humidity from DHT");
                        } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) {
                          // Only send humidity if it changed since the last measurement or if we didn't send an update for n times
                          lastHum = humidity;
                          // Reset no updates counter
                          nNoUpdatesHum = 0;
                          send(msgHum.set(humidity, 1));
                      
                          #ifdef MY_DEBUG
                          Serial.print("H: ");
                          Serial.println(humidity);
                          #endif
                        } else {
                          // Increase no update counter if the humidity stayed the same
                          nNoUpdatesHum++;
                        }
                      
                      }
                      
                        debouncer.update();
                        // Get the update value
                        int value = debouncer.read();
                      
                        if (value != oldValue) {
                           // Send in the new value
                           send(msgSw.set(value==HIGH ? 1 : 0));
                           oldValue = value;
                        }
                      }
                      
                      void receive(const MyMessage &message)
                      {
                          // We only expect one type of message from controller. But we better check anyway.
                          if (message.type==V_STATUS) {
                              // Change relay state
                              digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF);
                              //Keep the relay on for the amount of time defined by TOGGLE_INTERVAL
                              delay( TOGGLE_INTERVAL );
                              digitalWrite( RELAY_1, 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());
                          }
                      }
                      
                      B Offline
                      B Offline
                      Ben Andrewes
                      wrote on last edited by
                      #22

                      @rhuehn I know this is an old post but I had a similar issue which I solved by inserting a line in my sketch to pull the pin high before setting it as output

                        digitalWrite(RELAY_1_PIN , HIGH);  //stops relays cycling state during boot
                        digitalWrite(RELAY_2_PIN , HIGH);  //stops relays cycling state during boot
                        
                        pinMode(RELAY_1_PIN , OUTPUT);
                        pinMode(RELAY_2_PIN , OUTPUT);
                      
                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      10

                      Online

                      11.7k

                      Users

                      11.2k

                      Topics

                      113.0k

                      Posts


                      Copyright 2019 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