After a long and tedious war with this doorbell (current causalities: two dead arduinos, 1 dead relay and one dead optocoupler) I decided to stop trying to be too smart for my own good and do it in a way I can understand.
The bell has two circuits. one is 9v ac that comes from a transformer inside the wall. this goes through a rectifier and buck converter into the arduino (yes, I know the buck converter is not needed. However, it works and without it two arduinos died on me). Ringing the doorbell ground pin 3. The sketch then activate the relay that close the original circuit.
It is almost completely wire wrapped as I had to undo and redo the circuit so many times.
It is hosted inside a standard surface mount power/light switch box with blank plate.
As Marry Poppins said "A thing of beauty is a joy forever!"
Isn't it nice with everything covered?
Here is the sketch:
// Doorbell sensor
// to ring, ground pin 3. connect the relay that close the original circuit to pin 4
//
#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
#define RELAY_PIN 4 // Arduino Digital I/O pin bell relay
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(RELAY_PIN,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
Serial.println(value);
gw.send(msg.set(value==HIGH ? 0 : 1));
if (value == 0) {
Serial.println("activating rely for 1 sec");
digitalWrite(RELAY_PIN, HIGH);
delay(1000);
digitalWrite(RELAY_PIN, LOW);
}
oldValue = value;
}
}
Please feel free to comment - I am actually a bit disappointed that I didn't manage to do this the "right way" but it seems that the doorbell circuit is not "real" dc but half rectified AC. This is just a guess - I don't have the equipment to check this . As such it destroys components nicely, especially mechanical relays....
The downside of doing it this way is that the doorbell will not ring if the arduino dies. well, they can always knock, can't they?