How To: 2 Door Chime Automation Hack (Thanks @petewill)



  • Hi,

    This project, I aimed to have my door bell system connected to my home automation system. This was for two reasons. 1) I wanted a way to know if anyone was at my door without me being home ex. delivery truck driver. Alternatively, I play to place some Wifi cameras outside, and it would be nice to get a snapshot of whoever opens the door. The code is based off @petewill Doorbell Automation Hack (http://forum.mysensors.org/topic/2064/how-to-doorbell-automation-hack), and has been added a second door bell/relay and gw.send commands to the controller.

    This is my very first Arduino project outside of just download and go from the site so if there are any bugs please leave a detailed report and I will see what I can do. I just finished this on a breadboard, and plan to install it before tomorrow night (halloween) to see how many ghouls I get 🙂 . I will take some pictures of the completed build. See wiring diagram below as well.

    All was tested using MySensors Library V1.5 on Domoticz v2.3530

    Version 1.0 - Initial Release
    MySensors_2Door_Chime_bb.png

    Here is the code.

    /*
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     *  * 
     * Version 2.0 - ResentedPoet
     * 
     * Based on original concept/code by @petewill for 1 Door bell chime. See original thread
     * http://forum.mysensors.org/topic/2064/how-to-doorbell-automation-hack
     * This sketch is used to control a front and back doorbell ring with relays as well as send an
     * alert when the buttons are pressed. For front door, Connect the button to ground and digital
     * pin 3.  The relay controlling the doorbell is conntected to pin 4. For rear door bell
     * connect second button to ground and digital pin 5. The relay controlling that pin goes 
     * to pin 6.
      */
    
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define NODE_ID AUTO // or set to AUTO if you want gw to assign a NODE_ID for you.
    
    #define DOORBELLF_PIN  3      // Arduino Digital I/O pin number for the front doorbell button 
    #define RELAYF_PIN  4         // Arduino Digital I/O pin number for the front door chime relay 
    #define DOORBELLF_CHILD_ID 0  //ID of the  front doorbell
    #define SWITCHF_CHILD_ID 1    // Id of the switch that will control front doorbell sound
    #define RELAYF_ON 1
    #define RELAYF_OFF 0
    #define DOORBELLB_PIN  5      // Arduino Digital I/O pin number for the back doorbell button 
    #define RELAYB_PIN  6         // Arduino Digital I/O pin number for the back door chime relay 
    #define DOORBELLB_CHILD_ID 2  //ID of the back doorbell
    #define SWITCHB_CHILD_ID 3    // Id of the switch that will control front doorbell sound
    #define RELAYB_ON 1
    #define RELAYB_OFF 0
    
    Bounce debouncerF = Bounce();
    Bounce debouncerB = Bounce();
    
    MySensor gw;
    MyMessage switchMsgF(SWITCHF_CHILD_ID, V_LIGHT);
    MyMessage doorbellMsgF(DOORBELLF_CHILD_ID, V_TRIPPED);
    MyMessage switchMsgB(SWITCHB_CHILD_ID, V_LIGHT);
    MyMessage doorbellMsgB(DOORBELLB_CHILD_ID, V_TRIPPED);
    
    unsigned int doorbellFDelay = 1000; // interval at which to keep the front doorbell button sensor triggered (milliseconds). This is used to stop people (kids) from pressing it too often
    unsigned int ringFTime = 450; //How long the front doorbell relay is on (in milliseconds)
    unsigned long doorbellFMillis;  //Used to keep track of the last front doorbell button press
    unsigned long doorbellFTimer;  //Used to keep track of front doorbell ring time
    byte doorbellFPreviousVal;  //Used to keep track of front doorbell button pressed state
    boolean ringDoorbellF;  //Used to initiate the ring front doorbell if statement
    boolean doorbellFSound; //Used to keep track if the front doorbell should sound or be silent.  Value recieved from doorbell on/off switch
    boolean doorbellFOff = true;  //Used to keep track of front doorbell ring state
    
    unsigned int doorbellBDelay = 1000; // interval at which to keep the back doorbell button sensor triggered (milliseconds). This is used to stop people (kids) from pressing it too often
    unsigned int ringBTime = 450; //How long the back doorbell relay is on (in milliseconds)
    unsigned long doorbellBMillis;  //Used to keep track of the last back doorbell button press
    unsigned long doorbellBTimer;  //Used to keep track of back doorbell ring time
    byte doorbellBPreviousVal;  //Used to keep track of back doorbell button pressed state
    boolean ringDoorbellB;  //Used to initiate the ring back doorbell if statement
    boolean doorbellBSound; //Used to keep track if the back doorbell should sound or be silent.  Value recieved from doorbell on/off switch
    boolean doorbellBOff = true;  //Used to keep track of back doorbell ring state
    
    void setup()
    {
      gw.begin(incomingMessage, NODE_ID);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("2 Door bell/chime Monitor", "1.0");
    
      // Setup the button and activate internal pull-up
      pinMode(DOORBELLF_PIN, INPUT_PULLUP);
      pinMode(DOORBELLB_PIN, INPUT_PULLUP);
    
      // After setting up the button, setup debouncer
      debouncerF.attach(DOORBELLF_PIN);
      debouncerB.attach(DOORBELLB_PIN);
      debouncerF.interval(5);
      debouncerB.interval(5);
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(SWITCHF_CHILD_ID, S_LIGHT);
      gw.present(DOORBELLF_CHILD_ID, S_MOTION);
      gw.present(SWITCHB_CHILD_ID, S_LIGHT);
      gw.present(DOORBELLB_CHILD_ID, S_MOTION);
    
      // Make sure relays are off when starting up
      digitalWrite(RELAYF_PIN, RELAYF_OFF);
      digitalWrite(RELAYB_PIN, RELAYB_OFF);
      // Then set relay pins in output mode
      pinMode(RELAYF_PIN, OUTPUT);
      pinMode(RELAYB_PIN, OUTPUT);
    
      // Set doorbellSound to last known state (using eeprom storage)
      doorbellFSound = gw.loadState(SWITCHF_CHILD_ID);
      doorbellBSound = gw.loadState(SWITCHB_CHILD_ID);
    }
    
    void loop()
    {
      gw.process();
        unsigned long currentMillis = millis();
      //Check to see if front doorbell button was pushed.
      if (currentMillis - doorbellFMillis > doorbellFDelay) //used to stop front doorbell from being pressed too frequently
      {
        debouncerF.update();
        // Read doorbell button value
        byte doorbellFDetect = !debouncerF.read();//read, then reverse the value so it will send correct trigger state to controller
    
        if (doorbellFDetect != doorbellFPreviousVal)
        {
          //Serial.print("doorbellFDetect Value: ");
          //Serial.println(doorbellFDetect);
          if (doorbellFDetect == 1)
          {
            ringDoorbellF = true;
            doorbellFTimer = currentMillis;
            gw.send(doorbellMsgF.set(doorbellFDetect?"1":"0"));  // Send tripped value to gw
          }
          doorbellFMillis = currentMillis;
          doorbellFPreviousVal = doorbellFDetect;
        }
      }
    
      if (ringDoorbellF)
      {
        if (doorbellFSound)
        {
          if (doorbellFOff)
          {
            digitalWrite(RELAYF_PIN, RELAYF_ON);
            //Serial.println("Front Doorbell sounded.");
            doorbellFOff = false;
          }
          else
          {
            if (currentMillis - doorbellFTimer > ringFTime)
            {
              ringDoorbellF = false;
              digitalWrite(RELAYF_PIN, RELAYF_OFF);
              //Serial.println("Front Doorbell off.");
              doorbellFOff = true;
            }
          }
        }
      }
      //Check to see if back doorbell button was pushed.
      if (currentMillis - doorbellBMillis > doorbellBDelay) //used to stop back doorbell from being pressed too frequently
      {
        debouncerB.update();
        // Read doorbell button value
        byte doorbellBDetect = !debouncerB.read();//read, then reverse the value so it will send correct trigger state to controller
    
        if (doorbellBDetect != doorbellBPreviousVal)
        {
          //Serial.print("doorbellBDetect Value: ");
          //Serial.println(doorbellBDetect);
          if (doorbellBDetect == 1)
          {
            ringDoorbellB = true;
            doorbellBTimer = currentMillis;
            gw.send(doorbellMsgB.set(doorbellBDetect?"1":"0"));  // Send tripped value to gw
          }
          doorbellBMillis = currentMillis;
          doorbellBPreviousVal = doorbellBDetect;
        }
      }
    
      if (ringDoorbellB)
      {
        if (doorbellBSound)
        {
          if (doorbellBOff)
          {
            digitalWrite(RELAYB_PIN, RELAYB_ON);
            //Serial.println("Back Doorbell sounded.");
            doorbellBOff = false;
          }
          else
          {
            if (currentMillis - doorbellBTimer > ringBTime)
            {
              ringDoorbellB = false;
              digitalWrite(RELAYB_PIN, RELAYB_OFF);
              //Serial.println("Back Doorbell off.");
              doorbellBOff = true;
            }
          }
        }
      }
    }
    
      void incomingMessage(const MyMessage & message) {
        // We only expect one type of message from controller. But we better check anyway.
        if (message.isAck()) {
          Serial.println("This is an ack from gateway");
        }
    
        if (message.type == V_LIGHT) {
          // Change relay state
          doorbellFSound = message.getBool();
          // Store state in eeprom
          gw.saveState(SWITCHF_CHILD_ID, doorbellFSound);
    
        if (message.type == V_LIGHT) {
          // Change relay state
          doorbellBSound = message.getBool();
          // Store state in eeprom
          gw.saveState(SWITCHB_CHILD_ID, doorbellBSound);
    
          // Write some debug info
          Serial.print("Incoming change for sensor:");
          Serial.print(message.sensor);
          Serial.print(", New status: ");
          Serial.println(message.getBool());
        }
      }
      }
    


  • Hijacking post#2 for updates/revision log:

    Version 2.2 - Released 17-July-2016

    • Updated code for MySensors 2.0 release. Slight change to CHILD_ID's to make the flow of code easier. Requires MySensors 2.0 and debounce2 library. See Reply 9 in this thread for more information.

    Version 2.1 (skipped 2.0 😉 Released 7-March-2016

    • Re-write of code to deal with disconnect/power interruption issues found during daily use. LINK
    • Removed second chime mute switch and combined both into one.
    • Updated code and references to Library API v1.5

    Version 1.0.1 - Corrected wiring diagram. Pull-up resistors were misplaced. Thanks @korttoma for pointing out the mistake.

    Version 1.0 - Initial Release. (31-Oct-2015)

    • Based off Door Bell Hack/Automation by @petewill Code has been modified to add a second motion sensor/relay/button for front and rear door chime. All credit for original idea goes to him.
    • For my system I had to add gw.send commands for Domoticz compatibility. May not be required, let me know if any bugs are caused.
    • System is based off standard North American door chime system, and therefore uses standard 120VAC/15A for most power calculations/components. Adjust as necessary for your locale/situation.
    • Currently there is a small bug where a duplicate light switch is created, and has control over both front and rear door bell chimes. For now, only add one of the two light switch devices to your home automation system, and it will control both.
    • Any bugs, please leave a detailed report and I will do my best to fix/solve this. This is my first Arduino program, and currently have 3 months experience in programming. 🙂

  • Hero Member

    I think you misplaced the pull-up resistors. If you connect according to your picture you Will short your 5V by the buttons.

    It should be like this right:
    p-up.jpg



  • Hi @korttoma

    You are right, I did misplace those pull-up resistors on the diagram. I will update the original post with a proper fix.

    Thank you, much appreciated. 🙂



  • I like the idea ... adding to my to-do list 🙂

    Offtopic, I know and sorry but, what do you guys use to do this draws??? ... I'm using PCB Designer which is cool but not that cool ... 📄



  • Hi @Dave-Dan

    I'm using Fritzing right now to do my drawings. I'm hoping to soon start moving on to KiCad to do more PCB designs as well. I would suggest starting with Fritzing first, as there are plenty of easy to install custom libraries/parts for Arduino parts that makes it easy to start.



  • Thank you!



  • Here is an updated code for the doorbell. Still for two door chime system, updated for API version 1.5.4 and re-wrote from scratch.

    Let me know if there are any issues.

    Version 2.1 of the code:

    /*
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 2.1 - Derrick Rockwell (Drock1985) 
     * - Complete Re-write of code to provide better flow/structure. 
     * Version 2.0 - ResentedPoet
     * 
     * Based on original concept/code by @petewill for 1 Door bell chime. See original thread
     * http://forum.mysensors.org/topic/2064/how-to-doorbell-automation-hack
     * This sketch is used to control a front and back doorbell ring with relays as well as send an
     * alert when the buttons are pressed. For front door, Connect the button to ground and digital
     * pin 3.  The relay controlling the doorbell is conntected to pin 4. For rear door bell
     * connect second button to ground and digital pin 5. The relay controlling that pin goes 
     * to pin 6.
     */
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define NODE_ID 2                   // or set to AUTO if you want gw to assign a NODE_ID for you.
    #define FRONT_DOOR_BUTTON  3        // Arduino Digital I/O pin number for the front doorbell button 
    #define FRONT_CHIME_RELAY  4        // Aduino Digital I/O pin number for the front door chime relay
    #define CHILD_ID_0 0                // Child ID for the front doorbell sensor
    #define BACK_DOOR_BUTTON 5          // Arduino Digital I/O pin number for the back doorbell button
    #define BACK_CHIME_RELAY 6          // Aduino Digital I/O pin number for the back door chime relay
    #define CHILD_ID_1 1                // Child ID for the back doorbell sensor
    #define CHILD_ID_2 2                // Child ID for the mute option
    #define CHIME_MUTE_STATE            // Used to hold value of door chime mute funtion. 
    #define CHIME_OFF 0                 // Variable to define ring the chime
    #define CHIME_ON 1
    #define FRONT_CHIME_RELAY_ON LOW    // Variable for front chime. Reverse low/high if relay pin set different
    #define FRONT_CHIME_RELAY_OFF HIGH  // Variable for front chime. Reverse low/high if relay pin set different
    #define BACK_CHIME_RELAY_ON LOW     // Variable for front chime. Reverse low/high if relay pin set different
    #define BACK_CHIME_RELAY_OFF HIGH   // Variable for front chime. Reverse low/high if relay pin set different
    
    Bounce debouncerF = Bounce();
    Bounce debouncerB = Bounce();
    
    boolean CHIME_MUTE = 1;
    
    MySensor gw;
    MyMessage msg(CHILD_ID_2, CHIME_MUTE);
    
    MyMessage frontDoorbell(CHILD_ID_0, V_TRIPPED);
    MyMessage backDoorbell(CHILD_ID_1, V_TRIPPED);
    MyMessage chimeMute(CHILD_ID_2, V_STATUS);
    int pestTimeout = 4000;               // Delay between registered button presses. Stops button mashers ;) Set to whatever delay you want.
    unsigned long previousMillis=0;       // Tracks time since last door chime button press
    
    void setup() {
    
      gw.begin(incomingMessage, NODE_ID);
    
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("2 Door bell/chime Monitor", "2.1");
    
      // Setup the button and activate internal pull-up
      pinMode(FRONT_DOOR_BUTTON, INPUT);
      pinMode(BACK_DOOR_BUTTON, INPUT);
      digitalWrite(FRONT_DOOR_BUTTON, HIGH);
      digitalWrite(BACK_DOOR_BUTTON, HIGH);
      
      // After setting up the button, setup debouncer
      debouncerF.attach(FRONT_DOOR_BUTTON);
      debouncerB.attach(BACK_DOOR_BUTTON);
      debouncerF.interval(5);
      debouncerB.interval(5);
    
      // Register all sensors to gw (they will be created as child devices)
      gw.present(CHILD_ID_0, S_MOTION);
      gw.present(CHILD_ID_1, S_MOTION);
      gw.present(CHILD_ID_2, S_LIGHT);
      gw.send(msg.set(CHILD_ID_2, CHIME_MUTE));
      
    
      // Make sure relays are off when starting up
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_OFF);
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(FRONT_CHIME_RELAY, OUTPUT);
      pinMode(BACK_CHIME_RELAY, OUTPUT);
    
    }
    
    void loop() {
      gw.process();
      unsigned long currentMillis = millis();
      debouncerF.update();
      debouncerB.update();
      int valueF = debouncerF.read();
      int valueB = debouncerB.read();
    //Front Doorbell
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueF != HIGH && CHIME_MUTE == 1) {
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_ON);
      gw.send(frontDoorbell.set(1));
      gw.wait(50);
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_OFF);
      gw.send(frontDoorbell.set(0));
      previousMillis = currentMillis;
    }
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueF != HIGH && CHIME_MUTE == 0) {
      gw.send(frontDoorbell.set(1));
      gw.wait(50);;
      gw.send(frontDoorbell.set(0));
      previousMillis = currentMillis;
    }
    //Back Doorbell
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueB != HIGH && CHIME_MUTE == 1) {
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_ON);
      gw.send(backDoorbell.set(1));
      gw.wait(450);
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_OFF);
      gw.send(backDoorbell.set(0));
      previousMillis = currentMillis;
    }
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueB != HIGH && CHIME_MUTE == 0) {
      gw.send(backDoorbell.set(1));
      gw.wait(50);
      gw.send(backDoorbell.set(0));
      previousMillis = currentMillis;
    }
    }
    void incomingMessage(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_STATUS) {
         // Change relay state
         CHIME_MUTE = message.getBool();
         gw.send(msg.set(CHILD_ID_2, CHIME_MUTE?CHIME_ON:CHIME_OFF));
         // Store state in eeprom
         gw.saveState(CHILD_ID_2, CHIME_MUTE);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    


  • Update 17-July-2016 Sensor v2.2 MySensors 2.0 Update

    I have updated the code in the latest post for the release of MySensors 2.0! Not much has changed, just the calls. All of the same functionality is kept. Since MySensors 2.0 does not include any external libraries, you will need to manually add the debounce 2 library to your Arduino IDE/MySensors2 setup. The official GitHub repo is located here. Install it the same as any Arduino Library.

    Any comments or questions please ask.

    V2.2 Sketch:

    /*
     * The MySensors Arduino library handles the wireless radio link and protocol
     * between your home built sensors/actuators and HA controller of choice.
     * The sensors forms a self healing radio network with optional repeaters. Each
     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
     * network topology allowing messages to be routed to nodes.
     *
     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
     * Copyright (C) 2013-2015 Sensnology AB
     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
     *
     * Documentation: http://www.mysensors.org
     * Support Forum: http://forum.mysensors.org
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation.
     *
     *******************************
     *
     * REVISION HISTORY
     * Version 2.2 - Removed MySensors 1.5 code and replaced with MySensors 2.0
     * Version 2.1 - Derrick Rockwell (Drock1985) 
     * - Complete Re-write of code to provide better flow/structure. 
     * Version 2.0 - ResentedPoet
     * 
     * Based on original concept/code by @petewill for 1 Door bell chime. See original thread
     * http://forum.mysensors.org/topic/2064/how-to-doorbell-automation-hack
     * This sketch is used to control a front and back doorbell ring with relays as well as send an
     * alert when the buttons are pressed. For front door, Connect the button to ground and digital
     * pin 3.  The relay controlling the doorbell is conntected to pin 4. For rear door bell
     * connect second button to ground and digital pin 5. The relay controlling that pin goes 
     * to pin 6.
     */
     // Enable debug prints
    // #define MY_DEBUG
    
    // Enable and select radio type attached
    #define MY_RADIO_NRF24
    //#define MY_RADIO_RFM69
    #define MY_NODE_ID 2     //or use AUTO to have your home controller assign it for you.
    #define MY_REPEATER_FEATURE // Enabled repeater feature for this node. Comment out if you do not want repeater function
    #include <MySensors.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define FRONT_DOOR_BUTTON  3        // Arduino Digital I/O pin number for the front doorbell button 
    #define FRONT_CHIME_RELAY  4        // Aduino Digital I/O pin number for the front door chime relay
    #define CHILD_ID_FRONT 0                // Child ID for the front doorbell sensor
    #define BACK_DOOR_BUTTON 5          // Arduino Digital I/O pin number for the back doorbell button
    #define BACK_CHIME_RELAY 6          // Aduino Digital I/O pin number for the back door chime relay
    #define CHILD_ID_BACK 1                // Child ID for the back doorbell sensor
    #define CHILD_ID_MUTE 2                // Child ID for the mute option
    #define CHIME_MUTE_STATE            // Used to hold value of door chime mute funtion. 
    #define CHIME_OFF 0                 // Variable to define ring the chime
    #define CHIME_ON 1
    #define FRONT_CHIME_RELAY_ON LOW    // Variable for front chime. Reverse low/high if relay pin set different
    #define FRONT_CHIME_RELAY_OFF HIGH  // Variable for front chime. Reverse low/high if relay pin set different
    #define BACK_CHIME_RELAY_ON LOW     // Variable for front chime. Reverse low/high if relay pin set different
    #define BACK_CHIME_RELAY_OFF HIGH   // Variable for front chime. Reverse low/high if relay pin set different
    
    Bounce debouncerF = Bounce();
    Bounce debouncerB = Bounce();
    
    boolean CHIME_MUTE = 1;
    
    MyMessage msg(CHILD_ID_MUTE, CHIME_MUTE);
    
    MyMessage frontDoorbell(CHILD_ID_FRONT, V_TRIPPED);
    MyMessage backDoorbell(CHILD_ID_BACK, V_TRIPPED);
    MyMessage chimeMute(CHILD_ID_MUTE, V_LIGHT);
    int pestTimeout = 4000;               // Delay between registered button presses. Stops button mashers ;) Set to whatever delay you want.
    unsigned long previousMillis=0;       // Tracks time since last door chime button press
    
    void setup() {
    
      // Setup the button and activate internal pull-up
      pinMode(FRONT_DOOR_BUTTON, INPUT);
      pinMode(BACK_DOOR_BUTTON, INPUT);
      digitalWrite(FRONT_DOOR_BUTTON, HIGH);
      digitalWrite(BACK_DOOR_BUTTON, HIGH);
      
      // After setting up the button, setup debouncer
      debouncerF.attach(FRONT_DOOR_BUTTON);
      debouncerB.attach(BACK_DOOR_BUTTON);
      debouncerF.interval(5);
      debouncerB.interval(5);
    
      // Make sure relays are off when starting up
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_OFF);
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_OFF);
      // Then set relay pins in output mode
      pinMode(FRONT_CHIME_RELAY, OUTPUT);
      pinMode(BACK_CHIME_RELAY, OUTPUT);
    }
    
    void presentation()  {
      // Send the sketch version information to the gateway and Controller
      sendSketchInfo("2 Door Chime Sensor", "2.2");
    
      // Register all sensors to gw (they will be created as child devices)
      present(CHILD_ID_FRONT, S_MOTION);
      present(CHILD_ID_BACK, S_MOTION);
      present(CHILD_ID_MUTE, S_LIGHT);
      send(chimeMute.set(1));
    }
    void loop() {
      unsigned long currentMillis = millis();
      debouncerF.update();
      debouncerB.update();
      int valueF = debouncerF.read();
      int valueB = debouncerB.read();
    //Front Doorbell
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueF != HIGH && CHIME_MUTE == 1) {
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_ON);
      send(frontDoorbell.set(1));
      wait(50);
      digitalWrite(FRONT_CHIME_RELAY, FRONT_CHIME_RELAY_OFF);
      send(frontDoorbell.set(0));
      previousMillis = currentMillis;
    }
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueF != HIGH && CHIME_MUTE == 0) {
      send(frontDoorbell.set(1));
      wait(50);;
      send(frontDoorbell.set(0));
      previousMillis = currentMillis;
    }
    //Back Doorbell
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueB != HIGH && CHIME_MUTE == 1) {
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_ON);
      send(backDoorbell.set(1));
      wait(450);
      digitalWrite(BACK_CHIME_RELAY, BACK_CHIME_RELAY_OFF);
      send(backDoorbell.set(0));
      previousMillis = currentMillis;
    }
    
    if ( ((unsigned long)(currentMillis - previousMillis) >= pestTimeout) && valueB != HIGH && CHIME_MUTE == 0) {
      send(backDoorbell.set(1));
      wait(50);
      send(backDoorbell.set(0));
      previousMillis = currentMillis;
    }
    }
    void receive(const MyMessage &message) {
      // We only expect one type of message from controller. But we better check anyway.
      if (message.isAck()) {
         Serial.println("This is an ack from gateway");
      }
    
      if (message.type == V_LIGHT) {
         // Change relay state
         CHIME_MUTE = message.getBool();
         send(msg.set(CHILD_ID_MUTE, CHIME_MUTE?CHIME_ON:CHIME_OFF));
         // Store state in eeprom
         saveState(CHILD_ID_MUTE, CHIME_MUTE);
        
         // Write some debug info
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(", New status: ");
         Serial.println(message.getBool());
       } 
    }
    

Log in to reply
 

Suggested Topics

  • 8
  • 1
  • 1
  • 1
  • 3
  • 2

9
Online

11.4k
Users

11.1k
Topics

112.7k
Posts