Doorbell hack



  • Hi!

    Im using a modified version of the Door/Window sketch. I have a random 433mhz doorbell at my door and a arduino nano 3.0 with radio and 433mhz receiver connected.

    I have managed to make the node send this message every time the doorbell is pressed

    gw.send(msg.set(value == HIGH ? 1 : 0));
    

    Nothing happends in the Vera edge UI tho. I would like to make it so that when doorbell is pushed, same thing happends like when you open the door in the original sketch (red color in Vera UI when door open)

    here is full code;

     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    int oldValue = -1;
    int bell = -251;
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
    
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
    
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
    
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
    
    
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    
    }
    
    static unsigned long count = 0;
    
    void loop()
    {
      if (mySwitch.available()) {
    
        int value = mySwitch.getReceivedValue();
        if (value == bell) {
        // Send in the new value
        gw.send(msg.set(value== HIGH ? 1 : 0));
        oldValue = 1;
        
    
        
      }
    
        mySwitch.resetAvailable();
        count = 0;
      }
      else {
        if (++count == 0) Serial.println("no activity");
      }
    
      
    }
    

    Any Ideas how I can just make the message so it triggers "door sensor" in my UI?


  • Admin

    Guess you'll also have to send/restore the tripped value after some time?



  • @hek said:

    Guess you'll also have to send/restore the tripped value after some time?

    Yes, that would be ideal. First problem for me is how to change tripped value without using the actual magnetic sensor..



  • This post is deleted!


  • Below is my working sketch. Could somebody help clean it up? I made this sketch by combining two sketches and removing some parts from each.

    /*
    
    
     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    int oldValue = -1;
    int bell = -251;     // This is the value that my 433mhz doorbell sends out when button is pushed
    
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
    
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
    
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
    
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
    
    
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    
    }
    
    static unsigned long count = 0;
    
    void loop()
    {
      if (mySwitch.available()) {
    
        int value = mySwitch.getReceivedValue(); // This is where 433mhz signal are recieved
        if (value == bell) {
        // Send in the new value
        gw.send(msg.set("1"));  // Gives doorbell status tripped
        
        
        delay(5000);
        gw.send(msg.set("0"));  // Gives doorbell status not tripped
      }
    
        mySwitch.resetAvailable();
        count = 0;
      }
      else {
        if (++count == 0) Serial.println("no activity");
      }
    
      
    }
    
    
    

  • Contest Winner

    not tested, but I'd look to do it like this... with non-blocking code in case of a second press of the doorbell within the 5second timeout:

    /*
     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    const int bell = -251;     // This is the value that my 433mhz doorbell sends out when button is pushed
    boolean tripped = false;
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    }
    
    void loop()
    {
      if (mySwitch.available())
      {
        tripped = (mySwitch.getReceivedValue() == bell);
        if (tripped)
        {
          gw.send(msg.set("1"));
          timerStart = millis();
          Serial.println(F("Ding Dong!!"));
        }
        mySwitch.resetAvailable();  //<<<<<<<<<< I think you want this here... I looked at the library on GitHub
      }
      if (tripped && millis() - timerStart > 5000UL)
      {
        gw.send(msg.set("0"));
        Serial.println(F("no activity"));
        tripped = false;
      }
    }
    

    again, I could not test it...



  • @BulldogLowell said:

    not tested, but I'd look to do it like this... with non-blocking code in case of a second press of the doorbell within the 5second timeout:

    /*
     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    const int bell = -251;     // This is the value that my 433mhz doorbell sends out when button is pushed
    boolean tripped = false;
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    }
    
    void loop()
    {
      if (mySwitch.available())
      {
        tripped = (mySwitch.getReceivedValue() == bell);
        if (tripped)
        {
          gw.send(msg.set("1"));
          timerStart = millis();
          Serial.println(F("Ding Dong!!"));
        }
      }
      if (tripped && millis() - timerStart > 5000UL)
      {
        gw.send(msg.set("0"));
        Serial.println(F("no activity"));
        tripped = false;
      }
      mySwitch.resetAvailable();// i am not familiar with your library, so I'm not sure where this would go... or if you even need it with the non-blocking code.
    }
    

    again, I could not test it...

    Thank you! Looks much better. I will test later today when its not 31 celsius outside 🙂


  • Contest Winner

    @msebbe

    OK, I reviewed the arduino library and it looks like mySwitch.resetAvailable(); belonged higher in the code, so I edited it. You may want to be wary of that.



  • @BulldogLowell said:

    @msebbe

    OK, I reviewed the arduino library and it looks like mySwitch.resetAvailable(); belonged higher in the code, so I edited it. You may want to be wary of that.

    Ok thanks for your effort 👍

    When compiling I get this error below. I think this should be quiet easy to fix but I dont understand this language yet 😕

    sketch_jul03a.ino: In function 'void loop()':
    sketch_jul03a:49: error: 'timerStart' was not declared in this scope
    sketch_jul03a:54: error: 'timerStart' was not declared in this scope
    'timerStart' was not declared in this scope
    

  • Contest Winner

    @msebbe

    try inserting:

    unsigned long timerStart;
    

    to the header in the next line following:

    boolean tripped = false;
    


  • @BulldogLowell said:

    unsigned long timerStart;

    Thanks that worked, however nothing happends when I test by using the door bell. I will investigate this when I get home on monday and stick to my old sketch until then .


  • Contest Winner

    and you cn try this:

    /*
     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    const int bell = -251;     // This is the value that my 433mhz doorbell sends out when button is pushed
    boolean tripped = false;
    unsigned long timerStart;
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    }
    
    void loop()
    {
      if (mySwitch.available())
      {
        tripped = (mySwitch.getReceivedValue() == bell);
        if (tripped)
        {
          gw.send(msg.set(true));
          timerStart = millis();
          Serial.println(F("Ding Dong!!"));
        }
        mySwitch.resetAvailable();  //<<<<<<<<<< I think you want this here... I looked at the library on GitHub
      }
      if (tripped && millis() - timerStart > 5000UL)
      {
        gw.send(msg.set(false));
        Serial.println(F("no activity"));
        tripped = false;
      }
    }
    


  • @BulldogLowell said:

    and you cn try this:

    /*
     this is set up for a 4 pin recv unit GND DATA DATA VCC
     plug GND into D2, DATA into D3 and D4, and VCC into D5
    */
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    #include <RCSwitch.h>
    RCSwitch mySwitch = RCSwitch();
    
    #define CHILD_ID 3
    #define VCC_PIN 5 // source 5V up to 40mA from this pin
    #define GND_PIN 2 // sink up to 40mA on this pin
    #define DATA_PIN 3 // external int 1 on Uno
    
    MySensor gw;
    const int bell = -251;     // This is the value that my 433mhz doorbell sends out when button is pushed
    boolean tripped = false;
    unsigned long timerStart;
    // Change to V_LIGHT if you use S_LIGHT in presentation below
    MyMessage msg(CHILD_ID, V_TRIPPED);
    
    void setup()
    {
      gw.begin();
    
      // Register binary input sensor to gw (they will be created as child devices)
      // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
      // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
      gw.present(CHILD_ID, S_DOOR);
      // 433mhz Part
      pinMode(DATA_PIN, INPUT);
      // just leave D4 tristated
      pinMode(GND_PIN, OUTPUT);
      digitalWrite(GND_PIN, LOW);
      pinMode(VCC_PIN, OUTPUT);
      digitalWrite(VCC_PIN, HIGH);
      mySwitch.enableReceive(1);  // Receiver on interrupt 1 => that is pin D3
    }
    
    void loop()
    {
      if (mySwitch.available())
      {
        tripped = (mySwitch.getReceivedValue() == bell);
        if (tripped)
        {
          gw.send(msg.set(true));
          timerStart = millis();
          Serial.println(F("Ding Dong!!"));
        }
        mySwitch.resetAvailable();  //<<<<<<<<<< I think you want this here... I looked at the library on GitHub
      }
      if (tripped && millis() - timerStart > 5000UL)
      {
        gw.send(msg.set(false));
        Serial.println(F("no activity"));
        tripped = false;
      }
    }
    

    Hmm, still nothing. It seems to be the 433mhz reciver part that is not working.


Log in to reply
 

Suggested Topics

0
Online

11.2k
Users

11.1k
Topics

112.5k
Posts