Simulating a button push on a garage door remote

Hey everyone, I'm very new to Arduino and I want to make an app controlled, remote garage door opener. What I was thinking is that the best approach would be to simulate a button press by wiring an existing remote to arduino, which would be controlled by a phone app.
From what I gather this approach is feasible by wiring a relay to the button which controls the garage door.
The garage door remote works on 433.92 MHz with rolling code. After pairing any of the buttons can be used to open/close the garage door (he only uses the top one). One press starts the motor to open the garage door, another press stops the motor, another press starts the motor to roll back the garage door. Measuring with the multimeter the connected points on the top button I get roughly 5V.
How should I go about this? Attached are the photos of the garage door remote pcb.


  • It would be best to draw out the switch circuit by looking at the PCB.

  • A peanut type relay(s) will work.

  • A MOSFET or BJT might work but you will need to experiment.

How about

?

A switch either does, or does not, provide a continuous path for electrons.

A set of normally open relay contacts can go one each to the two sides of the existing switch.

There should be no other electrical connection.

This is the easiest and safest if not the most elegant or smallest solution. As @LarryD points out, with a bit of investigation it is probable that a transistor (BJT or MOSFET or part of an optoisolator) could be used, turned on and off by the Arduino and providing the same continuity that the relay would.

a7

Hint: Not all garage door controllers are the same. The easiest method would be to place a NO (Normally Open) relay across the wall button contacts. You can test this by shorting the two wires to see if the garage door responds. If it does, you're good to go. However, some newer controllers exchange information between the button and the opener, so a simple button won't work. In that case, you can modify a remote by connecting the relay contacts across the switch contacts in the remote.

I chose a relay because it’s the easiest solution and requires no advanced electronics knowledge. The relay can be mounted in any convenient location. You will need to provide power, while the remote battery should last about a year under normal use, the Arduino will require a consistent power source.

Hey everyone, thank you for the great suggestions. I went with soldering a relay directly to the board of the garage door key (red is connected to NO on the relay / - side on the key and black to COM on the relay / + on the key). I am using Arduino UNO R4 WiFi (for future control from a phone app). It works great with this code:

void setup() {
  // put your setup code here, to run once:
  pinMode(7, OUTPUT);     // connected to S terminal of Relay
 
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(7, LOW);   // LOW means on
  delay(300);

  digitalWrite(7, HIGH);    // HIGH means off
  delay(10000);
}

When it executes, the relay activates and the LED on the key PCB flashes (so I assume I "pressed the button"). To test that the key actually sends an RF signal I bought a CC1101 transceiver and connected it like this:


Now I would like to somehow see if when the "button is pressed" by the relay, there is actually something going on. I tried a library for this transceiver but it gives me nothing but errors when I tried to run the "ch_19_cc1101_tx" example in the library.(ELECHOUSE CC1101 Arduino library download)

How could I check if the key is actually doing something (aside from the LED flashing)?
As it stands this is the real implementation.

I tried to make a sketch how its connected but I dont know if its correct.

Does the garage door open? That is the best test.

1 Like

Hey, it worked amazing! One loop of the arduino code the garage door opened, the second it stopped and the third it reversed! So working as intended.
Now onto controlling it through a phone app, do you guys have any pointers I can take? I would like it to be an app on the home screen that opens an UI where there would be a button to "control" the garage door.

Easiest way would probably be arduino as web server for single page with button. Then make a widget for that page or build some web app.

Hey everyone, finally got around to do it and as @kmin suggested I went with the web server page with a button. For that I just took the code for a web server example and added the lines for setting the relay.

I have added a dedicated IP from the router so the arduino always has the same IP.
I will play around with adding an actual button and some background/icon (for quick access from phone home screen).
However the big issue is that every time the arduino is powered on and the web server is setting up, the relay is set, which means the garage door opens. Obviously this cannot work like this (What if the power goes off/on during the night? The garage door would be open the whole night.)
Do you guys have any solution on how to prevent the setting of the relay when the arduino is setting up and would only respond to input on the site?

The current code is as follows:

/*
  WiFi Web Server LED Blink

  A simple web server that lets you blink an LED via the web.
  This sketch will print the IP address of your WiFi module (once connected)
  to the Serial Monitor. From there, you can open that address in a web browser
  to turn on and off the LED_BUILTIN.

  If the IP address of your board is yourAddress:
  http://yourAddress/H turns the LED on
  http://yourAddress/L turns it off

  This example is written for a network using WPA encryption. For
  WEP or WPA, change the WiFi.begin() call accordingly.

  Circuit:
  * Board with NINA module (Arduino MKR WiFi 1010, MKR VIDOR 4000 and Uno WiFi Rev.2)
  * LED attached to pin 9

  created 25 Nov 2012
  by Tom Igoe

  Find the full UNO R4 WiFi Network documentation here:
  https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples#simple-webserver
 */

#include "WiFiS3.h"

#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;                 // your network key index number (needed only for WEP)
int relayPin = 7;

int led =  LED_BUILTIN;
int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  Serial.begin(9600);      // initialize serial communication
  pinMode(led, OUTPUT);      // set the LED pin mode
  pinMode(relayPin, OUTPUT);

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();                           // start the web server on port 80
  printWifiStatus();                        // you're connected now, so print out the status
}


void loop() {
  WiFiClient client = server.available();   // listen for incoming clients
  digitalWrite(relayPin, HIGH); 
  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out to the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("<p style=\"font-size:7vw;\">Click <a href=\"/H\">here</a> turn the LED on<br></p>");
            client.print("<p style=\"font-size:7vw;\">Click <a href=\"/L\">here</a> turn the LED off<br></p>");
            
            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
          digitalWrite(relayPin, LOW); 
          delay(300);
          digitalWrite(relayPin, HIGH); 
          digitalWrite(LED_BUILTIN, LOW);
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, HIGH);                // GET /L turns the LED off
          digitalWrite(relayPin, LOW); 
          delay(300);
          digitalWrite(relayPin, HIGH); 
          digitalWrite(LED_BUILTIN, LOW);
        }
      }
      
    }
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}

I don't know your board, but try like this:

void setup() {
  Serial.begin(9600);      // initialize serial communication
  pinMode(led, OUTPUT);      // set the LED pin mode
  pinMode(relayPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
....

Unfortunately that didnt work.
My board is the Arduino UNO R4 WiFi.

What I did to solve this issue was I took out setting of the pinMode out of Setup into its own function that I call every time I click on the button.
I dont think its a good solution but it works.

You can try in your setup, write the pin HIGH before setting it output.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.