Magnetic Door Switch with Buzzer



  • Hello everybody,
    I hope someone can help me.
    I have connected a magnetic door switch sensor and a buzzer with Arduino.
    Now I would like that when you open the door switch the buzzer starts until the door switch is closed again.

    I have combined the Door/Window/Button Sketch with my buzzer-Sketch, but unfortunately starts the buzzer when the Arduino starts and when the door switch is closed again.
    I want the buzzer only starts when opening the switches and so long until the switch is closed again and will stop again.

    Please help me, thank you in advance

    /**
     * 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.
     *
     *******************************
     *
     * DESCRIPTION
     *
     * Simple binary switch example 
     * Connect button or door/window reed switch between 
     * digitial I/O pin 3 (BUTTON_PIN below) and GND.
     * http://www.mysensors.org/build/binary
     */
    
    
    #include <MySensor.h>
    #include <SPI.h>
    #include <Bounce2.h>
    
    #define CHILD_ID 3
    #define BUTTON_PIN  3  // Arduino Digital I/O pin for button/reed switch
    
    int buzzPin= 2; // I/O-pin from buzzer connects here 
    
    const int wpm = 20; // Morse speed in WPM
    const int dotL = 1200/wpm; // Calculated dot-length
    const int dashL = 3*dotL; // Dash = 3 x dot
    const int sPause = dotL; // Symbol pause = 1 dot
    const int lPause = dashL; // Letter pause = 3 dots
    const int wPause = 7*dotL; // Word pause = 7 dots
    
    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);
    
    void setup()  
    {  
      gw.begin();
    
     // Setup the button
      pinMode(BUTTON_PIN,INPUT);
    
      pinMode(buzzPin,OUTPUT); // Set buzzer-pin as output
      
      // Activate internal pull-up
      digitalWrite(BUTTON_PIN, 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)
      // 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);  
    }
    
    
    //  Check if digital input has changed and send in new value
    void loop() 
    {
      debouncer.update();
      // Get the update value
      int value = debouncer.read();
     
      if (value != oldValue) {
         // Send in the new value
         gw.send(msg.set(value==HIGH ? 1 : 0));
         oldValue = value;
         
      dash();
      dot();
      dash();
      dot();  
      delay(lPause-sPause); // Subtracts pause already taken
      dash();
      dash();
      dot();
      dash();
      delay(wPause-sPause); // Subtracts pause already taken
            
      }
    } 
    
    void dot(){
    digitalWrite(buzzPin, LOW); // Tone ON
    delay(dotL); // Tone length
    digitalWrite(buzzPin, HIGH); // Tone OFF
    delay(sPause); // Symbol pause
    return;
    }
    
    void dash(){
    digitalWrite(buzzPin, LOW); // Tone ON
    delay(dashL); // Tone length
    digitalWrite(buzzPin, HIGH); // Tone OFF
    delay(sPause); // Symbol pause
    return;
    }
    

  • Mod

    I thnk it would be sufficient to add an if clause around the morse code stuff:

    if(value==HIGH){
      dash();
      dot();
      dash();
      dot();  
      delay(lPause-sPause); // Subtracts pause already taken
      dash();
      dash();
      dot();
      dash();
      delay(wPause-sPause); // Subtracts pause already taken
    }
    


  • Many thanks for your response !
    It works. :)
    But how can I change the code so that the morse code is played until the switch is closed again, because at the moment the morse code is played only once, when the switch is opened.



  • I have tried to solve this with INTERRUPT.
    But that does not work !

    #define INTERRUPT BUTTON_PIN-3
    

    and

    if (value==HIGH) {
           
      dash();
      dot();
      dash();
      dot();  
      delay(lPause-sPause); // Subtracts pause already taken
      dash();
      dash();
      dot();
      dash();
      delay(wPause-sPause); // Subtracts pause already taken
    
      gw.sleep(INTERRUPT,BUTTON_PIN-3, CHANGE);
    
        }
    

  • Mod

    Why use gw.sleep at all? You want to Arduino to stay awake so it can continue playing, right?

    Side note: Don't use BUTTON_PIN-3, use digitalPinToInterrupt(BUTTON_PIN). That makes the code easier to follow and avoids the risk of forgetting to update one definition but not the other.



  • you are absolutely right.
    I changed the code as follows:

    with HIGH the morse signal is played only once, therefore changed to LOW !

    // Activate internal pull-up
      
       // DigitalWrite (BUTTON_PIN, HIGH);
    
       digitalWrite (BUTTON_PIN, LOW);
    
    
    if (value == HIGH) {
    
       dash ();
       dot ();
       dash ();
       dot ();
       delay (lPause-sPause); // Subtracts break already taken
       dash ();
       dash ();
       dot ();
       dash ();
       delay (wPause-sPause); // Subtracts break already taken
    
       attachInterrupt (digitalPinToInterrupt (BUTTON_PIN), buzzer_stop, CHANGE);
             
         }
    
    
    void buzzer_stop() {
    digitalWrite(buzzPin, HIGH); // Tone OFF
    return;
    }
    
    void dot(){
    digitalWrite(buzzPin, LOW); // Tone ON
    delay(dotL); // Tone length
    digitalWrite(buzzPin, HIGH); // Tone OFF
    delay(sPause); // Symbol pause
    return;
    }
    
    void dash(){
    digitalWrite(buzzPin, LOW); // Tone ON
    delay(dashL); // Tone length
    digitalWrite(buzzPin, HIGH); // Tone OFF
    delay(sPause); // Symbol pause
    return;
    }
    
    
    
    

    But now works with a small error :
    the buzzer makes mose signal in an endless loop, however it is very quiet even though it actually is very noisy ?!



  • I found the mistake, now it's really loud :)

    Thank you so much.



  • @knipex Hi can you please post your working script?? I want the same functionality too. Thanks


  • Mod

    @knipex what was the mistake?


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.