For the past few weeks I have been working on a DIY wireless clap sensor for my Home Assistant setup. The sensor can be used to turn lights on/off, switch TV channels, start household appliances and more. This post describes how I created the sensor and how to integrate it with Home Assistant.
For the hardware, I decided to use an NRF52-DK and an old analog microphone I had lying around. I connected the microphone to VDD and one of the analog pins (P0.31) on the NRF52-DK. I then connected the analog pin to ground through a 1.1 kΩ resistor. A picture of the hardware setup is shown below:
For the software, I used Zephyr, an open-source RTOS that supports a wide variety of microcontrollers. I used PlatformIO to set-up and compile the project.
I won't go into details on how the software works in this post, but the gist of it is that the program samples the microphone using the ADC and looks for sudden spikes in amplitude. If two successive spikes are detected, it is considered a valid clap and a value in memory is toggled. This value is exposed as a GATT characteristic and can therefore be accessed wirelessly over Bluetooth Low Energy (BLE). The source code for the sensor is available on GitHub.
To connect the sensor to Home Assistant, I used ble2mqtt, an open-source BLE to MQTT bridge that exposes BLE devices' GATT characteristics over MQTT. Since I run my whole Home Assistant setup on Docker, I created a Dockerfile that can be used to run ble2mqtt in a Docker container:
The Dockerfile is fairly straightforward, except for the last line. This line contains a short perl script that restarts the ble2mqtt process until the string "Found new device" is seen in the output. This was added because I had some issues where scanning didn't work until the process had been restarted a few times.
I use Docker Compose to manage all my Home Assistant related containers. I added the following to my docker-compose.yml file to include the ble2mqtt container in this setup:
Lines 8-9 of this file are important for the container to work properly. These lines ensure that the container has access to D-Bus, which is required to scan for Bluetooth devices.
To configure ble2mqtt I created a .json file containing the sensor's bluetooth MAC address, the UUIDs for the service and characteristic it exposes and the details for the MQTT server used by Home Assistant. An example configuration file is provided below:
With this configuration, ble2mqtt will connect to the clap sensor over BLE and publish the value of its GATT characteristic to the MQTT server Home Assistant uses. The only thing that remains is to make Home Assistant aware of this. This can be done by adding a "binary_sensor" directive to the Home Assistant configuration file:
After adding this to the configuration file and restarting everything, I was greeted with a new binary sensor in the Home Assistant dashboard. This sensor can be used like any other sensor in Home Assistant (for example in automations). The value of the sensor is toggled whenever a clap is detected.
That's it! Let me know in the comments if you found this post useful or if you have a similar setup!