We have an old garage door control system with key fobs and button control board attached to the wall in the garage. My wife, sometimes leave the garage door open on her way out in the mornings. I know she's in a hurry to get to work, but I’m lazy to get out of bed and close the garage door behind her. So, I thought - why not connect the garage door to our home WiFi and control it with Google Home Assistance?
First, I went online and googled for an off-the-shelf option, but it was ridiculously expensive (a whopping $180 from the same manufacturer as the existing system). Then I searched on Aliexpress, and it was cheaper - around $20. But then thoughts crossed my mind, like: what if this AliExpress one doesn't work? what if it can't understand the existing system's radio signal? etc., etc.,. So, I decided to build my own, as I had a couple of ESP32 boards lying around.
I removed and disassembled the wall control switch. It has a microcontroller, two push buttons, and a LED. I guess one of the buttons is for synchronizing with the Main control board, and the second is for opening and closing the garage door. I inspected how this Open/Close push button is interfaced with the microcontroller. it is connected to one of the GPIOs and pulled up to VCC with a pull-up resistor (please see the image 1 and image 3). Whenever push button is pressed, the voltage on the GPIO is pulled to ground. The microcontroller senses the change in the GPIO state and sends an RF signal to the main control board to activate the motor and open/close the door.
After years of thinking, I came up with the brilliant idea of controlling this push button from an external controller in parallel with the existing system. I decided to use ESP32C3-mini dev board with 1.28inch round display (I had purchased it from AliExpress for home automation projects), it has WiFi, BLE, USB-C, and a connector for a LiPo battery.
I soldered two wires, one to one end of the push button (which connects to the microcontroller) and the second to the ground pin. I connected these two wires to one of the ESP32's GPIO (configured as Open-Drain) and ground. Connecting the ground pins is necessary to ensure valid voltage levels on the GPIO. Please see the connection diagram below. Image 1 shows existing connection, and Image 2 shows how the push button is connected to ESP32.
Image 1: Existing wall control board, button interface.
Image 2: Push button interfaced to ESP32
In Image 1, the push button is connected to pin P0.0 on the onboard microcontroller, with an external pull-up resistor tied to VCC. Whenever the push button is pressed, P0.0 is pulled to ground, causing a change in the input level from HIGH to LOW. When the button is released, P0.0 is pulled back up to VCC (LOW to HIGH). This pulse triggers the microcontroller to send an RF signal to the main control board to open or close the garage door.
In image 2, the push button is also connected to ESP32's IO pin 8 and GND. The IO pin is configured as Open-Drain, allowing a logic HIGH to be defined by the VCC of the other board when the pin is set HIGH from the ESP32.
Image 3, Existing wall control board disassembled and soldered wires across push button SW2 to connect to ESP32
Image 4, ESP32 IO connection. IO8 and Gnd.
ESP32 is programmed with MicroPython and used ArduinoIOTCloud python client framework to talk to Arduino Cloud App. I added a new board definition in the MicroPython ports for ESP32 folder for my ESP32C3 round display board, derived from ESP32_GENERIC_C3.
For Arduino IOT cloud, I followed their "Getting Started with Arduino Cloud for ESP32" guide. I created a "Thing" (device), defined its variables, and built a dashboard for setting/getting those variables. The credentials required to talk to Arduino Cloud from the ESP32 were generated when creating the device in the cloud; I stored that information in a seperate python file (secrets.py) on the ESP32's flash. secrets.py also contains the Wi-Fi credentials needed to connect the ESP32 to my local network. You can see the full project files in my GitHub repo.
To compile the project, copy the directory "ESP32C3_GarageDoor" into MicroPython's ports/esp32/ directory and use the make command "make BOARD=ESP32C3_GarageDoor" from within ports/esp32. Make sure you've installed and configured the ESP-IDF tools and MicroPython before compiling. Please see this page to how to install and configure them.
Once Arduino cloud is configured, add the device to Google Home by following the guide, "Google Home, Arduino Documentation".
After configuring Arduino Cloud, integrating it with Google Home, and programming the ESP32, the final step is to connect the ESP32 to the wall control switch and test everything.
The ESP32 is connected to the wall switch via two wires using male connector pins (see image 5). The ESP32 is powered using a power bank and usb-c cable.
The ESP32 is programmed to display a message on the screen whenever the garage door is controlled using Google Voice Assistant. Please see the demo video attached below.
Image 5, connecting esp32 with external battery and the wall switch
Demo video, Garage door control using Google Voice assistant
In the demo video, you can see the ESP32 displaying the message "Opening the garage" and "Closing the garage" when I asked my google mini (located in the living room) to control the garage door. I wish I could have recorded the Google Mini's response, but unfortunately, the living room is quite far from the garage, so I wasn't able to record its response to the voice commands.
When I say, "Hey, Google Open the Garage", Google Assistant sends the command to Arduino Cloud, which in turn forwards the command to the ESP32. The ESP32 is programmed using the Asyncio library to efficiently handle cloud commands, update the GUI display, and control the push button.
I loved how the whole setup turned out and how seamlessly the integration between Arduino Cloud and Google Home, and the ESP32 with MicroPython worked. I honestly didn't expect it to be this easy to control the wall switch using a simple GPIO pin from the ESP32.
I'm really glad I chose to build my own solution - it feels great to see the project completed and functioning in real life. It's incredibly satisfying to use something I built from scratch in my daily routine.