How to connect standard wired doorbell into BigClown ecosystem?

The issue that short doorbell press may not generate event and long press generate multiple is because the code that is reading button does software debouncing.

Pushbuttons often generate spurious open/close transitions when pressed, due to mechanical and physical issues: these transitions may be read as multiple presses in a very short time fooling the program.
https://www.arduino.cc/en/Tutorial/Debounce

This is also nice article with image, you dont need to read or undrestand the code becuase everyone’s debounce code is different Debouncing a switch - Protostack

Here’s the image of signal in time that you can see on oscilloscope when you use the mechanical button

The issue is that since the optocoupler is getting 50 Hz AC signal because the doorbell transformer is not rectified to DC. This gives us imaginary 25 presses of button per second (50Hz / 2) and thats why sometimes its not recognized as button press and sometimes the single long doorbell press is recognized as multiple button presses.

We have to ways to solve it:

  • Hardware
  • Software

Hardware solution

This is my preffered way because you and everyone else could use the stock firmware without any change. You would need to add two more electronic parts to your circuit - diode and capacitor.

So between the transformer and resistor-optocoupler you put this Diode an Smoothing capacitor (ignore the RL resistor in the image below)

The type of diode dont care so much. You can theoretically use also LED as a diode. The capacitor can be ceramic or electrolytic with values somewhere un uF (microfarads). Just be careful because electrolytics have polarity and the MINUS pin is marked with ‘-’ on the package.

By this “half wave rectifier” the optocoupler will be on all the time and the Core Module will see one single long press of the button. This way you would recognize how many someone pressed the doorbell.

Software solution

This would need basicaly replace the bc_button with simple few lines of code. So the pseudocode could look like

#include <application.h>

void application_init(void)
{
    bc_gpio_init(BC_GPIO_BUTTON);
    bc_gpio_set_mode(BC_GPIO_BUTTON, BC_GPIO_MODE_INPUT);
    // The Core Module has hardware pull-down on BUTTON BOOT PIN so next call is commented
    //bc_gpio_set_pull(BC_GPIO_BUTTON, BC_GPIO_PULL_DOWN);

  ... init of radio and other stuff .....
}

void application_task()
{
    uint8_t button_state = bc_gpio_get_input(BC_GPIO_BUTTON);
    if(button_state)
{
    bc_radio_pub_push_button(0);  // send parameter zero
    bc_scheduler_plan_current_relative(5000);   // sleep the task for 5 seconds - change this to your taste
} else {
    // The button is not pressed
    // Repeat this task again after 50 ms - higher is better for battery but you can miss the ring signal
    // so 50-100 ms seems reasonable to me
    bc_scheduler_plan_current_relative(50);
}


}

Take a look at the “How to: GPIO” in the docs, its basicaly what I’ve copied above.
https://www.bigclown.com/doc/firmware/how-to-gpio-pins/

Also you can start and edit the wireless button kit project which is the skeleton you’ll need
https://github.com/bigclownlabs/bcf-kit-wireless-push-button/blob/master/app/application.c

Final thoughts

I would be interested if you’ll be able to fix it by that half wave rectifier. Let me know if you would like to try that way. In case you’ll decide for software solution, I’ll try to do the same setup as you and test the code if you run in some issues.

You’ve written that your understanding is limited, but I’ve tried my best to find basic articles and explain it all as simple as I could. I feel that this is the right way because I feel that you’re happy that you have it working so I thought you could learn more. It’s not that complicated if you don’t put math to it :wink:

Let me know what you think. Martin