Introduction: Raspberry Pi Zero Garage Door Opener Hardware

About: I don't blog a lot, but when I spend a lot of time trying to figure something out, either professionally or personally, I try to sum it up. Also check out my blog detailing my newest efforts to keep my autom…

One of the inspirations for this project was the fine instructable at Raspberry Pi 3 Garage Door Opener, along with several others found on the Internet. Not being a seasoned electronics person, I did a whole lot of additional research on ways to interface with the Raspberry Pi and learned a lot about the importance of resistors with LED bulbs and with all GPIO wiring. I also learned about the benefits of pull-up and pull-down hardware circuits vs. the built-in Pi functionality.

Because this garage door project really is a multi-part process comprising Pi hardware, software, and installation with your garage door opener(s) I thought I would first focus on the Pi hardware, since it is needed for every other step.

My approach is to be very basic, acting as a summary of the learning I did to be able to complete the hardware. It will start out with some information, and then we will build circuits on a breadboard. Every step will refine our design and knowledge, culminating in building a permanent hardware solution to interface the Pi with a relay and reed sensors.

Additionally, unlike some other projects, I decided to use a Raspberry Pi Zero W, which I got on sale some time ago but still was sitting unused on my desk. The upside is that, while prototyping, if I damaged any of the GPIO circuits it was cheap and easy to replace and keep prototyping. The downside is that it has only an ARMv6 processor so some things, like Java, are not going to be usable.

The other thing I decided to do was to create my own add-on board for the circuitry, so should I need to change or replace my Pi, as long as the pinouts are the same, the board should easily be plugged into the new Pi. This hopefully will minimize a rat's nest of wiring.

My assumptions are:

  • You are comfortable soldering
  • You already know how to use basic terminal commands on the Raspberry Pi
  • You are using Raspbian Buster or newer.
  • You have some interface to the Pi command line; either with a dedicated monitor, keyboard, etc. AND/OR using SSH.
  • You are familiar with the basic concept of electrical circuit design; for example, you know the difference between power and ground and you understand the concept of a short-circuit. If you can put a new outlet in your home, you should be able to follow along.


Depending on how dedicated you are to this project, you may start off with just the things needed at each step and go from there. Lots of these parts are available at your local electronics or DIY/Maker shop, but I have included Amazon links to improve the descriptions.

  • MakerSpot RPi Raspberry Pi Zero W Protoboard (to make the final HAT for the Pi)
  • 2 Channel DC 5V Relay Module (get a 1-channel if you have one door, 2 for 2 doors, etc.)
  • Overhead Door Switch, Normally Open (NO) (If at this time you just are prototyping and want to use some cheap reed switches to get started, that's fine)
  • Electronic Fun Kit Bundle (this contained all the resistors I needed, plus a breadboard and power unit for helping prototype and test and learn before I did the permanent board). If you have all of this already, make sure you have a few 10K, 1K, and 330 ohm resistors handy.
  • Breadboard Jumper Wires (any will do)
  • Soldering iron with small tip
  • Rosin-core solder
  • Soldering iron tip cleaner
  • Spare 9v power supply (to power the breadboard)
  • Cheap prototyping boards for soldering practice (optional)
  • Functioning Raspberry Pi Zero or Pi of your choice
  • Header pins for the Raspberry Pi (if yours does not have the header on it already)
  • Stacking headers for use on the protoboard HAT.
  • Small needle nose pliers
  • Jeweler's screwdriver kit
  • Small side cutters (for cutting wire after soldering)
  • Tweezers
  • Some small-gauge wire (I prefer solid-core) for use on the protoboard
  • A little silicone (if you choose to use 1.8mm surface mount LEDs instead of the ones supplied in the kit bundle)
  • I found that a magnifying lamp was super helpful to see the small soldering work

Step 1: Introduction to the Raspberry Pi GPIO

The main interface we will be using with the Raspberry Pi is the GPIO (General Purpose Input/Output).

Find your the proper pin diagram for your Pi here. This instructable will focus on the Pi Zero W v1.1.

We will be using only the green GPIO pins, avoiding the SDA, SCL, MOSI, MISO, etc pins. (I discovered that some GPIO pins have special purposes, one of the benefits of prototyping on a breadboard, so I stuck to GPIO pins 17 (pin #11), 27 (pin #13), and 12 (#32) as they were in good positions for my breadboard.

GPIO pins are designed to operate as digital (binary) switches; they exist logically as one of two states: 1 or zero. These states depend upon whether the pin supplies or receives voltage above a particular threshold (1) or supplies or receives voltage below a particular threshold. (We will talk about the thresholds later.)

It is important to note that, while the Raspberry Pi can supply both 5V and 3.3V (3V3), GPIO pins operate using up to 3.3V. More than that and you damage the GPIO and possibly the entire controller. (This is why we prototype on a breadboard, and use the cheapest Pi possible!)

The state of the pins can be manipulated either by software (output) or by other devices feeding in the state (input).

Let's give this a shot using some basic SYSFS commands. I'm not sure whether this requires WiringPi, but if you run into issues you may want to install it if you are using the minimal Raspbian image.

First, let's give ourselves access to GPIO 17:

sudo echo "17" > /sys/class/gpio/export

Now let's check the value of the GPIO:

sudo cat /sys/class/gpio/gpio17/value

The value should be zero.

At this point, the GPIO knows not whether it is input or output. As such, if you try to manipulate the GPIO value, you will receive "write error: Operation not permitted". So let's just tell the pin it is output:

sudo echo "out" > /sys/class/gpio/gpio17/direction

And now set the value to 1:

sudo echo "1" > /sys/class/gpio/gpio17/value

Check the value again to see...and the value should be 1.

Congratulations, you have just created an output GPIO and changed the state!

Now, there is a little more to it, but let's learn a few more things first.

Step 2: Understanding Resistors

So, you can look up resistors on Wikipedia, but what do they mean to us? Primarily they protect our components.

Remember when we talked about the GPIOs that they operate up to 3.3V? What that means is that if you give a GPIO pin more than that, you can fry it. Why is this important? Sometimes there are small surges in any circuit and if the maximum is 3.3V, any small hiccup can cause problems. Operating at the maximum voltage is a risky proposition.

This is especially true for LEDs. An LED will draw as much power as it can. Ultimately the LED will burn out, but the significant current draw can use up all the available power in a circuit, causing it to malfunction.

For example: what would happen if you put a fork into both prongs of an electrical outlet? There is little-to-no resistance, and you will blow the circuit breaker. (And probably hurt yourself in the process.) Why does the toaster not do this? Because its heating elements provide resistance, and as such does not draw the entire load of the circuit.

So how do we keep this from happening to an LED? By limiting the amount of current used to drive the LED using a resistor.

But what size resistor? Yeah, I read a few web articles and finally settled on a 330Ω resistor for 3.3V with an LED. You can read all their calculations and figure it out yourself, but I tested a few on a breadboard and 330 worked just fine. One reference I checked was on the Raspberry Pi forums, but a Google search will discover many more.

Likewise, the Pi GPIO pins need protection from overvoltage. Remember how I said that they use UP TO 3.3V? Well, a little less won't hurt. Most projects use 1KΩ resistors and I did the same. Again, you can calculate this yourself but this is a very popular choice. Again, the Raspberry Pi forums supply some information.

If you don't understand this completely, do some more reading. Or just follow the instructions. Whichever works for you.

Many resistors are labeled in the packaging but once you remove them, how can you tell them apart? The little colored stripes on the resistor can tell you.

Next, we'll wire up a simple LED on a breadboard with power to get things started.

Step 3: Wiring an LED

The first step is to wire an LED on the breadboard. Once we get that working safely, we will connect it to the Raspberry Pi and control it from the GPIO pin.

Hopefully your breadboard came with a power source for 3.3v. If not, you can wire everything up and connect it directly to the Pi.

Find an LED and wire it to the breadboard as shown using a 330Ω resistor. The longer leg of the LED is the anode, the shorter leg is the cathode. The anode connects to the 3.3V power while the cathode connects back to ground. The resistor can be either before the LED; it does not matter. Standard wire colors are:

  • Red = 5V
  • Orange = 3.3V
  • Black = ground

Once you have that breadboard wired and supply power, the LED should light up. Do not proceed unless you get this working.

Step 4: Connecting the LED to the GPIO

So now we have a working LED with a resistor. Now it's time to connect that LED to the Raspberry Pi. Our goal is to create an output GPIO and connect that GPIO to the LED so that when we ENABLE the GPIO, the LED will light up. Conversely, when we DISABLE the GPIO, the LED will turn off. (This will be used later as the circuit that will "press" the button to open the garage door.)

Remove the power from the breadboard and connect the Pi as shown. (It's best to do this while the Pi is powered down too.) We have connected the 3.3V supply from GPIO 17 and the ground to one of the ground pins.

Now boot the Pi and the LED should be off. Execute the same commands we did previously to set up the GPIO pin and output the value:

sudo echo "17" > /sys/class/gpio/export
sudo echo "out" > /sys/class/gpio/gpio17/direction
sudo cat /sys/class/gpio/gpio17/value

The value should be zero.

Now let's enable the GPIO:

sudo echo "1" > /sys/class/gpio/gpio17/value

This should turn on the LED. To turn off the LED, just disable the GPIO as follows:

sudo echo "0" > /sys/class/gpio/gpio17/value

One of the things that MAY happen is that, with enough interference or on/off cycles of the LED, you might notice that the LED remains slightly lit. There is a reason for this, and we'll talk about that in a future step.

Step 5: Using a Relay to Drive the LED

As stated in the previous step, the LED is a stand-in for the garage door "button." However, while the GPIO can power our LED, it cannot "press" our garage door button. A button press essentially just connects the two button terminals, in effect performing a button press. What you need to perform this "press" is a relay.

A relay is nothing more than a switch powered by something. In this case, our Raspberry Pi can tell the relay to "press" the garage door button. For our prototype, the Raspberry Pi will tell the relay to turn on the LED...just so we can test our circuit.

What we need to know about our relay:

  • The relay operates at 5V. This is the power only to operate the relay and is not used in any other part of the circuit.
  • We want to wire our relay as "normally open." That means that the relay remains open (not connecting the two wires, or "pressing the button", until activated.
  • This particular relay is activated when the GPIO supplies zero power to the 3.3V connector of the relay. Indeed, this seems backward. When 3.3V is supplied, the relay is released. Stick with us on this project and you'll see how this works.
  • The two relay terminal connections are completely separate from the Raspberry Pi. What this means is that you can switch a wire with any rated current because it receives its current from another power source. The simple tiny Raspberry Pi with 3.3V and 5V could indeed operate a relay that controls much larger voltage. This is how a tiny little button on your dashboard can run your large amperage draw heated seats.

So let's get started.

First, re-attach (but powered down) the external power unit for your breadboard. This power will run the LED circuit, while the Raspberry Pi controls the relay.

Next, create a break in the 3.3V line powering the LED. (With switches and relays, we always want to switch the "hot", not the ground.) These are indicated in orange and blue on the diagram.

Connect the Raspberry Pi as shown with 5V powering the relay, 3.3V acting as the switch, and the ground returning to the Raspberry Pi. In this example I have connected the 3.3V to GPIO 17. I recommend connecting a 1KΩ resistor to the GPIO wire as shown, to protect the GPIO from problems. (This was mentioned in the Resistors step.)

Power up the breadboard and now power up your Pi. The LED should be lit.

Now run the following commands on the Pi:

sudo echo "17" > /sys/class/gpio/export
sudo echo "out" > /sys/class/gpio/gpio17/direction
sudo cat /sys/class/gpio/gpio17/value

The value should be zero.

Now let's enable the GPIO:

sudo echo "1" > /sys/class/gpio/gpio17/value

This should turn off the LED.

Step 6: Adding a Pull-Up Resistor

At this point, all your stuff should be working. But there is one thing we haven't discussed about GPIOs, and that is the "floating" voltage that is possible based on the threshold we mentioned previously.

While GPIOs generally have two logical states (1 and zero), it determines these states based on whether it has voltage above or below the voltage threshold, as we mentioned in the GPIO section. But the problem in most GPIOs is the possiblilty of a "floating" voltage; in the case of the Raspberry Pi, somewhere between zero and 3.3V. This can occur from interference or from voltage rise/drop across a circuit.

We don't want a situation where our garage door button relay may just activate from floating voltage. Indeed, we want it to activate only when we tell it to.

Situations like this are solved by using pull-up and pull-down resistors to enforce a particular voltage and avoid the floating voltage. In our case, we want to make sure to supply voltage to prevent the relay from activating. So we need a pull-up resistor to bring voltage up above the threshold. (Thresholds are funny things...I tried reading about them and to see whether they were well defined and got a lot of information that was over my head, and some that seemed overly simple. Suffice it to say that with a multimeter I could see that the voltage was lower than 3.3V, but since everything worked as I prototyped it, I just moved on. Your mileage may vary, and this is why we breadboard this before soldering our final product.)

Sure, the Raspberry Pi has both internal pull-up and pull-down resistors you can set in code or at boot. However, it is highly susceptible to interference. While it is possible to use them, since we already are working with resistors in a circuit, it might be worth the stability to use the external.

More importantly, this creates the pull-up and adds enough voltage that the GPIO pin state defaults to 1 before the Pi initializes. Remember how our relay activated the LED was lit when we first initialized the Pi until we shut it off? Using the pull-up prevents the relay from activating at startup because the relay 3.3V input receives voltage at the same time the 5V input receives voltage. We also could do this in Pi configuration if we want, but again, since we are wiring with resistors anyway, it seems less vulnerable to operating system updates and distributions.

Different configurations may need different resistors, but a 10kΩ resistor worked with the relay I had. The LED on my relay was very dim at boot up, but the pull-up provided enough voltage to prevent activation of the relay.

Let's add a pull-up resistor to our circuit. In the breadboard diagram, I added a 10kΩ resistor between the 3.3V input on the relay and a 3.3V source.

Now we have a circuit suitable for "pressing" the garage door button; replacing the LED and 330Ω resistor with the actual button wires should be easy.

Step 7: Reed Switch Sensor

So great, we know what our circuit looks like to activate the garage door opener. However, wouldn't it be nice to know whether the garage door is closed, or whether it is open? To do that, you need at least one reed switch. Some projects recommend two, but they both are gonna use the same circuit design.

We are using a "normally open" (NO) reed switch configuration. That means that our circuit is open until the reed switch is within proximity of the magnet, which will close the circuit and allow electricity to flow.

The main differences between the sensor setup and the relay setup are:

  • The GPIO connected to the sensor is going to detect power, so it is going to be an input GPIO (while the relay used an output GPIO that supplied voltage)
  • Because the default state exists as normally open, that means that our circuit will not be active. As such, the GPIO state should be 0. Inversely to the concept of the pull-up resistor on the relay circuit, we will want to make sure our voltage is below the threshold when the circuit is open. This will require a pull-down resistor. This basically is the same as the pull-up, but connected to ground instead of power.

Much like the relay circuit, we are going to wire things on a breadboard before hooking it up to the Pi.

Let's use our powered breadboard and wire an LED, 330Ω resistor, and ground wire. Then hook up 3.3V to one side of the reed switch and a jumper from the other side of the reed switch to the LED. (If you have a reed switch that supports NO and NC, use the NO position.) Move the magnet away from the reed switch and turn on the breadboard power. The LED should remain off. Move the magnet toward the reed switch and the LED should illuminate. If it does the opposite, you have it wired for NC (normally closed)

Step 8: Connecting the Reed Switch to the Pi

So now that we have the circuit working without the Pi, we can remove the power from the breadboard and we will connect the Pi.

We'll use GPIO17 again because we already know where it is.

Much like the relay circuit, we are going to protect the GPIO pin with a 1KΩ resistor; however, we will be using a 10kΩ resistor to ground to create a pull-down.

Once we have wired everything, let's move the magnet away from the reed switch, boot the P,i and get ourselves to a command line and initialize the GPIO, noting that this time we are creating an input GPIO:

sudo echo "17" > /sys/class/gpio/export
sudo echo "in" > /sys/class/gpio/gpio17/direction
sudo cat /sys/class/gpio/gpio17/value

The value should be zero. Move the magnet to the reed switch. The LED light should light up, and the value is 1.

Voila! We've wired our reed switch to the Pi!

Step 9: Making a Permanent Solution on a Prototyping Board

Now that we know what our circuits should look like, it's time to solder a permanent version on a prototyping board. Since I am using a Pi Zero W, I obtained small proto boards.

I thought it would be good to use the Zero format and be able to stack one or more boards, an add-on module that Raspberry Pi calls HAT (Hardware Attached on Top). Well, technically since it doesn't have any type of EEPROM and doesn't register itself, it isn't a HAT but I gotta call it something. But the format mounts nicely and eliminates a rats nest of wiring, so that's nice.

The challenge is that the proto boards are kind of small, so you can't fit a lot on them. Also, none of the holes are connected in rows like the larger proto boards. While this may seem inconvenient, it actually is a lifesaver.

What I thought was that I could create a HAT for each garage door I wanted to control. This way, you could expand this project to fit your need.

On the proto board, I found that there was just enough room to create three circuits:

  1. relay circuit
  2. sensor circuit
  3. second sensor circuit

That's pretty good for any garage door project out there.

So what I did was use GPIO17 and 27 for the sensors, and GPIO12 for the relay. The really nice thing about this proto board is that you can wire to the GPIO without even touching the header. But yes, you will need to solder a stacking header in addition to your resistors (and, optionally, LEDs).

I pretty much re-created the circuits we prototyped on the board. You can tell that my soldering isn't perfect but it still works. (The next boards will be better since I have had practice.) I have an Aoyue 469 and just a hair above setting 4 was the best temperature based on recommendations for soldering the GPIO header.

I used the outer connected rows for ground and the inner for 3.3V. And I used the resistor wire to act as a bridge since we didn't have connected rows. The rest all are diagonal and sideways because that was the best way I could find to fit them on the board.

From L-R (looking at the front, the resistor side), the output pins I added are for the sensor GPIO wire, the second sensor GPIO wire, and the relay GPIO wire. Instead of wiring direct to the GPIO, which we could do from the header, these pins connect to all our resistors and, in the case of the sensors, I added in a microLED. (Note how the LED is in a completely separate loop, so if it burns out the circuit still works.)

Attached is a Fritzing file, but since Instructables is having issues with file uploads, I had to give it a false extension of "txt" in order to embed it.

Step 10: References