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. Doorbell node

Doorbell node

Scheduled Pinned Locked Moved Development
6 Posts 4 Posters 2.6k Views 1 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.
  • Sander StolkS Offline
    Sander StolkS Offline
    Sander Stolk
    wrote on last edited by
    #1

    Not quite sure how to do this but I think I'm on the right way.
    I've got my doorbell connected to a Nano with a normal radio.
    This node is a repeater because I will use it for more functions (Gasmeter, temp or even more stuff) but nothing planned at this moment.

    This node detects that my doorbell is pressed and switches a directly connected relay for 500 ms to my Siemens Gigaset. This time cannot be longer because the Gigaset will enable DECT Handset learning and people can link new handsets to my basestation. Pushing this button will cause all my DECT phones to ring a internal ringtone to announce that somebody is at the door. The doorbell-switch-pressed-message is a button / light switch in my gateway / controller. Triggering this button / switch will start a script what sends a photo with a piece of text that somebody is at my door and wants my attention.

    The following challenge is a real headache:

    I want the button pressed signal to the gateway only once per 10 seconds. So when somebody pushes the button 30 times within 10 seconds only 1 message will be send and the relay can only switch once during this time otherwise it will cancel the current "doorbell-signal". Hence a cooldown timer is a solution. I don't know how to do this.

    The relay is not necessary in my controller so I will leave it standalone in the sketch. This means that if my gateway / controller is offline for some reason the Gigaset will sound to announce somebody at my door that wants my attention.

    So the challenge is the cooldown-timer but preserving the repeater functionality. I would like to switch the relay directly after the first push because otherwise it takes 10 seconds longer and people will be annoyed.

    I'm totally clueless how to do this. Is there somebody that can point me in the right direction? Or have an example maybe?

    1 Reply Last reply
    0
    • F Offline
      F Offline
      fleinze
      wrote on last edited by
      #2

      calling the millis(); function will return a time variable in milli seconds. Save it into a variable and compare it to the current value later to see how much time has passed.

      1 Reply Last reply
      0
      • dakkyD Offline
        dakkyD Offline
        dakky
        wrote on last edited by dakky
        #3

        Hmm simply sleeping for 30secs after sending a bell message is not enough? the other sensors did not seem to be timing critical?#

        EDIT: a i see you need the repeating capabilities. so sleeping might be a problem. then u need to calculate a time diff

        Controller: Raspberry Pi 2 :: Openhab2 :: with @TimO MySensors Binding
        Gateway: Arduino MEGA 2560 R3 :: W5100 :: Ethernet GW

        Software: MySensors 2.0development

        1 Reply Last reply
        0
        • H Offline
          H Offline
          Heizelmann
          wrote on last edited by Heizelmann
          #4

          Something like that:

          long ringSendtAt;
          boolean isRinging;
          void setup() {
            ringSendtAt = millis() - 10000;
            ...
          }
          
          
          void loop() {
            ...
            if ( isRinging && millis()- ringSendtAt > 10000)
              sendRingingMessage();
              ringSendtAt = millis();
            }
            ...
          
          1 Reply Last reply
          1
          • Sander StolkS Offline
            Sander StolkS Offline
            Sander Stolk
            wrote on last edited by
            #5

            Thanks @Heizelmann ! It helped me out a lot!

            I've created this script with a button leaving the relay out:

            #include <MySensor.h>
            #include <SPI.h>
            #include <Bounce2.h>
            
            #define CHILD_ID 12
            #define BUTTON_PIN 2  // Arduino Digital I/O pin for button/reed switch\
            #define RELAY_1 4
            
            MySensor gw;
            Bounce debouncer = Bounce(); 
            int oldValue=-1;
            
            // Change to V_LIGHT if you use S_LIGHT in presentation below
            MyMessage msg(CHILD_ID,V_TRIPPED);
            
            long buttonpushed;
            long ringSendAt;
            long timenu;
            
            // Define 10 seconds of cooltime
            ringerdelay = 10000;
            
            void setup()  
            {  
              gw.begin(NULL,9,true);
            
             // Setup the button
              pinMode(BUTTON_PIN,INPUT);
              // Activate internal pull-up
              digitalWrite(BUTTON_PIN,HIGH);
            
              // Setup the button
              pinMode(RELAY_1,OUTPUT);
              // Activate internal pull-up
              digitalWrite(RELAY_1,HIGH);  
              
              // After setting up the button, setup debouncer
              debouncer.attach(BUTTON_PIN);
              debouncer.interval(5);
              
              // Register binary input sensor to gw (they will be created as child devices)
              gw.present(CHILD_ID, S_DOOR);
              
              // If startup has taken place set the intial values because otherwise the doorbell will ring after powerloss
              if (buttonpushed == NULL || buttonpushed > 1 || ringSendAt == NULL || ringSendAt > 1) {
                 buttonpushed = millis();
                 ringSendAt = millis();
            }
            }
            
            void loop() 
            {
              debouncer.update();
              // Get the update value
              int value = debouncer.read();
            
            // Time now to check for a difference
            timenu = millis();
             // Check the if the current time is bigger the the button pushed and the current time with a 10 second time-out to prevent ringing again
             if (timenu > buttonpushed && timenu > buttonpushed + ringerdelay) {
              // I only want to fire the relay when the value of the button hits the pushed state
              if (value == 0) {
                 // Setting the time when the button is pressed
                 buttonpushed = millis();
                 //Serial.print("Ding dong!");
                 //Serial.println();
                 // Send message on to gateway
                 gw.send(msg.set(1));
                 // Switch the relay for 0,5 second
                 digitalWrite(RELAY_1,LOW);
                 delay(500);
                 digitalWrite(RELAY_1,HIGH);
                 // Send message off to gateway
                 gw.send(msg.set(0));
                 // Set the value always to 1 because I only want to fire it when pressed and not when released.
                 oldValue = 1;
              }
            }
            }```
            1 Reply Last reply
            0
            • H Offline
              H Offline
              Heizelmann
              wrote on last edited by
              #6

              Some optimization to check:

              • ringerdelay needs to be defined with a type
              • if condition in setup() not necessary initialize buttonpushed and ringSendAt unconditioned
              • normalize logic in if (timenu > buttonpushed && timenu > buttonpushed + ringerdelay) to if (timenu > buttonpushed + ringerdelay), it is the same
              • variable timenu not necessary use millis() directly: if (millis() > buttonpushed + ringerdelay)
              • on relay initialisation the two comments are wrong
              1 Reply Last reply
              1
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              17

              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