Building a DIY WiFi-Enabled MightyMule Gate Opener

Rather than purchasing an expensive WiFi-enabled smart gate opener, build one yourself with a few dollars in components – I’ll show you how.

When we purchased our house it came with a very nice aluminum gate for the driveway that had been installed by a previous owner. It wasn’t a particularly useful thing for us — we didn’t have any particularly good reason to keep the gate closed, and to do so would require us to constantly get in/out of the car to open/close it manually.

When we got our new dog Hercules, I decided that it was time to make it useful so we bought an automatic gate opener – a Mighty Mule MM360. Now that it’s installed we can keep the gate closed all the time (allowing us to let the dog out in the backyard without risk of him running away).

As part of the standard package it comes with a wireless receiver and transmitter very similar to a garage door opener. That was great for the car, but now that the gate was closed all the time we discovered a few problems:

  1. The only way to open the gate was using the remote, which lived in the car. This meant if one of us left the house in the car the other couldn’t open or close the gate from inside the property.
  2. Even if the car was in the driveway, there was no way for us to open the gate from the outside of the property (say we went for a walk).

Now of course the company that makes Mighty Mule gate openers has a whole store full of accessories to solve all of these obvious limitations for us (if you’re willing to spend the money of course). But I figured there must be a better way and it turns out I was correct — I just built my own!

Looking at their accessories, I focused in on two of them that seemed to provide a solution to the problems I wanted to solve. The first was opening and closing the gate from within the property, but without using the remote. For these purposes there is part number FM132 which looked awful similar to a simple momentary push button doorbell you mounted on the inside of the property, behind the gate. The second problem to solve was opening the gate from outside the property. Looking at their accessories, I could solve by purchasing a couple of part number FM135 (a $20 dollar remote for the gate) for everyone in the house’s keys. I didn’t want to have to carry my keys to go on a walk though (not to mention spend $60 dollars in keyfobs) so I kept digging and I discovered part number FM138. It was an intriguing, although very expensive ($165), accessory that detected a vehicle trying to exit and automatically opened the gate for you. What intrigued me wasn’t the accessory itself, but rather if the control board of the gate opener perhaps provided something I could hook into with a DIY device.

With this in mind I dug through the Installation Instructions that came with the gate. Buried in the back, I found this very useful diagram that described how each of the various accessories connected to the control board module of the gate:

A diagram describing how the various accessories are connected to the control board of a Mighty Mule gate opener.

Reviewing this diagram it appears there’s a decent chance the following is true:

  • The Push Button Control (FM132) really just does short out the connection named “Cycle” to ground (labeled as “Common”
  • The Vehicle Sensor (FM138) likely also simply shorts out the connections between the connection named “Exit” to “Common”

Now it was time to take out my Voltmeter and see if I could test my theories of how the control board worked. Measuring the voltages across both the “Cycle” and “Exit” connections to “Common” was about 12V DC. So far, so good! Next was to really test my theory by using a piece of wire to short out the connections. Sure enough all I needed to do to activate those features is create a connection between those leads. This meant, for starters, a simple doorbell was all I needed instead of the office FM132 part (a few minutes and an old doorbell I had laying around solved my first problem). It also meant building a WiFi enabled opener for the gate was going to be pretty straightforward as well.

For this project I decided to use an ESP8266-01 module. These modules are fantastic little WiFi enabled micro-controllers that can be programmed using the Arduino platform. Basically the idea is this: use the power provided by the control board of the gate to power my ESP8266-01, which in turn would trigger the “Exit” feature using a simple NPN transistor. An ESP8266-01 uses very little power, certainly no more than the Vehicle Sensor it is designated to power so this should work fine.

Parts List

ESP8266-01The Micro-controller
LD1117A33VA 3.3V voltage regulator to power the ESP8266-01
10uF capacitor, 100nF capacitorUsed as part of the wiring requirements of the LD1117A
1kOhm Resistor, 2N2222 NPN TransistorUsed to trigger the "Exit" feature of the gate via GPIO pin

Here’s a Schema of how the gate opener works:

The ESP8266-01 WiFi Gate Open Schematic

The ESP8266-01 module functions on 3.3v, and this is why we need an LD1117 voltage regulator to ensure we receive a nice stable supply from the input — especially since we really don’t know for certain how stable the power coming from the gate’s control board really is. When wiring up the ESP8266, 3.3V needs to be applied to the VCC, CH_PD, and RESET pins in order to function properly along with ground. We then hook the GPIO2 pin to a 1k resistor connected to the base pin of a 2N2222 NPN transistor. Finally, we attach the collector of the transistor to voltage in (“Exit” on the control board) and the emitter to “Common”. This will allow us to effectively “short” the connection between the “Exit” pin and “Common” any time we apply a voltage from our GPIO2 pin, trigging opening the my gate.

For a relatively compact circuit such as this, with a little patience we can design it on a board that takes up little room. In fact, it’s small enough to be wired in and live within the weatherproof casing of the gate itself!

The completed hardware for the WiFI enabled Gate Opener

I recommend when building your circuit board you use a 4 x 2 header, rather than soldering the ESP8266-01 directly to the board. This will allow you to remove the chip later to reprogram it, should it be necessary.

Speaking of programming, now that we’ve designed the hardware it’s time to program our ESP8266 as the wireless gate opener we need. As with all of the devices on This Smart House, we interface with our smart devices through the use of MQTT. In this case we will program our ESP8266 to connect to the MQTT server of our choice, and listen for an activation command on a topic of our choice. When received, we set the GPIO2 to HIGH for a moment to trigger the gate to open and then back to LOW again (just as if we had momentarily shorted the leads out with a wire). Here’s some code to get you started:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

#define AP_SSID "your-wifi-ssid"
#define AP_PASSWORD "your-wifi-password"
#define MQTT_BROKER "your.mqtt.host"
#define MQTT_BROKER_PORT 1883
#define MQTT_CLIENT_ID "gate-control"

#define MQTT_LISTEN_TOPIC "/gate/activate"
#define MQTT_STATUS_TOPIC "/gate/status"
#define SIGNAL_PIN 2 // GPIO 2

WiFiClient espClient;
PubSubClient client(espClient);

char msg[150];

/**
 * Set up the WiFi connection
 */
void setup_wifi() {

  // Connect to the WiFi network
  WiFi.begin(AP_SSID, AP_PASSWORD);
  
  // While we are waiting for the WiFi to connect
  // flash the status LED on the ESP8266 so there
  // is a visual indication of the module's status
  while (WiFi.status() != WL_CONNECTED) {

    digitalWrite(LED_BUILTIN, LOW);
    delay(250);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(250);

  }
  
  // Change the rate of flashing so that we know
  // the WiFi connection was successful
  for(int i = 0; i < 10; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
  }
}


/**
 * The callback used by the PubSubClient, and is called
 * when we receive a message on the trigging topic.
 */
void callback(char* topic, byte* payload, unsigned int length) {

  // We don't bother checking the topic, or payload
  // any message on the MQTT topic we've previously
  // subscribed to will open the gate.
  //
  // We trigger the gate open action by setting the SIGNAL_PIN
  // to HIGH for one second
  //
  // We also toggle the status pin, to indicate we've received
  // the message.
  digitalWrite(LED_BUILTIN, HIGH);
  digitalWrite(SIGNAL_PIN, HIGH);
  delay(1000);
  digitalWrite(SIGNAL_PIN, LOW);
  digitalWrite(LED_BUILTIN, LOW);

  // Publish that we've performed the action to the specified
  // MQTT topic
  client.publish(MQTT_STATUS_TOPIC, "activated");

}

/**
 * Connect / Reconnect to the MQTT server
 */
void reconnect() {

  // As long as we aren't connected, keep trying!

  while (!client.connected()) {
    
    if (client.connect(MQTT_CLIENT_ID)) {

      // Once we've connected to the MQTT server, subscribe
      // to the topic that will trigger our function
      
      client.subscribe(MQTT_LISTEN_TOPIC);

    } else {

      // Wait 5 seconds before retrying
      for(int i = 0; i < 5; i++){
        delay(1000);
      }
    }
  }
}

/**
 * Standard Setup function on boot
 */
void setup() {

  // Set the LED_BUILTIN (status LED) to OUTPUT
  pinMode(LED_BUILTIN, OUTPUT);
  // Set the SIGNAL_PIN to OUTPUT
  pinMode(SIGNAL_PIN, OUTPUT);

  // Turn off the signal pin
  digitalWrite(SIGNAL_PIN, LOW);
  // Turn off the status LED
  digitalWrite(LED_BUILTIN, LOW);

  // Flash the status LED to indicate we have started booting
  for(int i = 0; i < 5; i++) {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
  }

  // Set up the WiFi
  setup_wifi();

  digitalWrite(LED_BUILTIN, LOW);

  // Set up the MQTT settings, and announce we've booted to
  // the MQTT topic
  client.setServer(MQTT_BROKER, MQTT_BROKER_PORT);
  client.setCallback(callback);
  client.publish(MQTT_STATUS_TOPIC, "Booted");
}

/**
 * Our standard loop
 */
void loop() {

  // If MQTT isn't connect, try to connect to the MQTT server
  if (!client.connected()) {
    reconnect();
  }

  // Process any MQTT subscriptions topics that need processing
  client.loop();

}

Download this code from GitHub

Happy Coding!