How I Converted A Driveway Gate Into A Smart Gate Using A Raspberry Pi
As my fourth year of university began, I set a goal to improve an existing system using what I’ve learned so far in my Computer Science degree. While it’s reasonably straightforward to create something from scratch, adding to an existing system can be difficult, especially when somebody else has built it. After a few days of brainstorming, I was inspired by this:
For some context, what you’re looking at is an automatic driveway gate. My parents live on a gated property, and this is how vehicles get in and out. The purpose of having a gated property is to prevent deer (which are abundant in this area) from eating your plants. Deer really don’t care about that though, and can jump up to eight feet high, so you’re better off just sharing your garden, but I digress.
While talking to my parents about the gate and my intention to improve it, they told me they wished they could open and close the gate from anywhere in the world. This would prove useful in many situations such as getting packages delivered while they’re out of town.
There are 5 different ways you can open the driveway gate.
- Using a remote button (within range), similar to a garage door opener.
- Driving a (heavy) vehicle in front of the gate on the house side, which will trigger a pressure cable and open the gate for sixty seconds.
- Using the street side intercom to enter the master pin.
- As a visitor, pressing the illuminated button on the street side intercom will make the landline phones ring, which can then be answered by the homeowner. The homeowner can then enter one of three commands:
- 1 — Open the gate for 60 seconds
- 2 — Open the gate indefinitely
- 3 — Close the gate
5. Picking up a landline phone in the house and dialing *7 will connect you to the gate control system. Once the connection is made, one of the commands listed above can be made.
My first task was to figure out which gate control system model my parents have, and reading through all 58 pages of the manual. The model is a DoorKing 1812 Access Plus, and as for the manual… Well, let’s just say to become a gate installer you need to have some sort of technical background. The system is very customizable, and there’s quite a lot of features, so the manual is vague on a few things.
Eventually, I learned that the control system could be accessed from any cell phone in the world simply by dialing the landline phone number, great! All I had to do was change one setting — How many rings until the gate system “answers” the phone. From the factory, this value is set to six rings, and since my parent’s landline goes to voicemail at five rings, it was inaccessible by default.
After changing the value to four, I was able to connect to the gate system from my cell phone by dialing the landline number, and waiting for four rings. Once the system “answered”, I put in the master pin, and was then connected to the intercom system on the street side of the gate. At this point, I could talk to whoever was there, and input any command, such as “1” to open the gate.
There was a big issue though. Since the control system was now answering phone calls after four rings, it was impossible for a call to go to voicemail, since the fifth ring never happens. Whoever called the landline and got no answer would be redirected to absolute silence, unable to leave a voicemail.
I’m guessing whoever was in charge of coming up with new features for this model was listening to customer feedback from previous models. The 1812 Classic installation manual even acknowledges having to make the choice between having your answering machine work, or being able to remotely access the gate. Thus, the feature was added to the functional spec, and even the final list of features!
After searching the entire manual and what seemed like the entire internet, I have concluded that this feature does not exist anywhere besides the feature list and gateideas01.txt on the product designer’s computer.
Unfortunately, the engineers working on this product realized that this was pretty much impossible. How would the gate control system detect when the homeowner wants to bypass the answering machine when the control system hasn’t picked up the call? In my parents’ case, they use a voicemail service rather than an answering machine. The call is ‘redirected’ to a central voicemail server offered by the phone provider. There is no possible way for the gate control system to answer the call at that point.
I had to figure out another way to open the gate by interfacing with one of the five methods described above. My first thought was to have a Raspberry Pi control a servo motor that pushes the button on my remote, but that’s really hacky. My next thought was to have a Pi controlling a radio transmitter which imitates the remote, but the system is most likely protected from replay attacks so it might be difficult. Not to mention, it doesn’t provide enough control. I wanted to be able to send explicit commands such as “Open”, or “Close”, rather than toggle commands. If the gate is already open and it receives a signal, it will close. If the gate is already in the process of opening or closing, it will stop. As much as I love the ingenuity of hacky solutions, I couldn’t stop thinking that there must be a better way to do this.
After a bit of research, I came across Dual-tone multi-frequency signalling.
“The DTMF system uses a set of eight audio frequencies transmitted in pairs to represent 16 signals, represented by the ten digits, the letters A to D, and the symbols # and *. As the signals are audible tones in the voice frequency range, they can be transmitted through electrical repeaters and amplifiers, and over radio and microwave links, thus eliminating the need for intermediate operators on long-distance circuits.”
Have you ever called a business and heard something akin to “For sales, please press 1”? The system on the other end of the line is utilizing DTMF signaling.
It turns out that most landline phones in North America are DTMF capable. To test this, I generated a dual tone recording for the sequence “*7 1”, indicating a connection to the control system, a short pause, and then opening the gate. I picked a landline receiver off the hook and played the tones from my computer speakers. It sounded like this.
The gate proceeded to open, and my born in ’96 mind was blown.
Back in the 90s, Radio Shack sold something called a “Pocket Tone Dialer” which allowed storage of up to 33 phone numbers. If you still had a rotary phone, or if you wanted to use a pay phone without touching gross buttons, you could simply play the DTMF tones associated with one of your contacts through the receiver. I’m sure it looked really cool at the time.
Back to the gate, the DTMF tones gave me a great idea. All I had to do was output DTMF tones from a Raspberry Pi through a landline. My idea was to solder an aux cable to an RJ9 cable, which would effectively turn my Pi into a headset. Sadly, there’s no way (that I know of) to “pick up” and “hang up” the receiver using only DTMF tones. Not to mention, there are regulations in Canada which prohibit modifying radio equipment, so there may be regulations regarding telephony equipment and I’d rather not get into that for this project.
I accepted defeat and asked around for possible solutions on tech support forums. Someone recommended looking into the USR5637 USB Modem. This would allow me to execute Hayes commands through USB from my Raspberry Pi. There’s cheaper USB Modems available (this one was $100CAD after shipping from Amazon), but it’s known for working well with Linux and the support documents are great, so the decision was easy.
After a week of anticipation, it finally arrived. Setting it up was straightforward, I followed this guide to interface with the device using the Pi terminal, and the official user guide to learn the commands. With a few exceptions, Hayes commands are usually started with “AT”. For example, if you wanted to dial “*7”, wait 1 second, then hang up, you would execute:
The D after AT stands for Dial, and the comma is interpreted as a delay of n seconds, defined in S-Register 8.
You may think the H after AT means “Hang up”, but it actually controls “Hook functions”. We can either do H0 to “hang up — on hook”, or H1 to “pick up — off hook”. Executing ATH is interpreted as ATH0, which is what we did above.
By default, the delay variable in S-Register 8 is 2 seconds, but we want 1 second, so execute:
For this project, that’s all I needed. There are other useful commands which I’ll be using for future projects. For example, it can be set up to answer automatically after n rings. Using the audio functionality, you could create your own voicemail system using nothing but this product and a Raspberry Pi!
The next step was to interface with the modem using Python, which can easily be done using pySerial. I used code from this Github repo.
At first, my idea was to host a web server on the Pi which could be accessed from any device to trigger commands by pressing buttons on the website. Although this solution is free, my parents would most likely never use it if they had to open their phone’s browser, navigate to the Pi’s public ip address, (e.g. 18.104.22.1680), and then press a button. Instead, I decided on using Twilio Programmable SMS.
I deposited $20 into my account and “purchased” a local phone number for $1/month. The cost to receive or send a text from this number is $0.0075, so 1.5 cents to receive a text and send one back.
Using the Twilio API with Python is pretty simple. I decided on using the Webhooks method. Webhooks are user-defined HTTP callbacks, which Twilio uses to let your application know when a text or call is received. Since I won’t be calling the phone number, I disabled the functionality to avoid paying for usage when telemarketers call.
The idea is to setup a web server that receives HTTP requests (usually a POST or a GET) from Twilio. These requests contain data about the text or call, such as the phone number and the content (for SMS). When the request is received for a text message, a response can be sent back.
In my Python code, I load a JSON config file which contains a list of ‘whitelisted’ phone numbers. When a request is received, it first checks if the sender’s phone number is ‘whitelisted’. If it is, check the content for the command. As a refresher, here are the commands:
- 1: Open the gate for 60 seconds
- 2: Open the gate indefinitely
- 3: Close the gate
If the content matches a command, the matching AT command is executed. If it succeeds, a response is sent back to the sender confirming that the gate is being open or closed.
After some serious testing, I gave the Twilio phone number to my parents and they tried it out. It worked! Once the text has been sent, it takes about 5 seconds for the gate to start opening.
I decided to take it a step further. Wouldn’t it be nice to have the gate open automatically when I’m driving home and turn onto my parent’s road? After some experimentation with Geofencing using Tasker, I came to the sad conclusion that this really isn’t worth it.
Geofencing requires usage of location services on your phone. Unfortunately, this uses a lot of battery power, so you wouldn’t want the geofence monitor to be checking your location too often. Usually, this isn’t a problem. If you have a geofence trigger that turns on your phone’s wifi when you get home, it doesn’t matter if it’s a few minutes late.
After testing the geofence with normal settings (every 60 seconds), I found it to be very inconsistent. Sometimes the gate would start opening too early (using a larger radius with a 60 second interval) and put my car at risk of being closed on by the gate. Other times it would open too late (using a smaller radius with a 60 second interval). In the worst case, I arrived in front of the gate and waited 50 seconds before the gate opened. If I’ve arrived at the gate and it hasn’t started opening yet, I might as well use the garage door opener in my car, which defeats the purpose of the geofence. Obviously, I could have the geofence monitor check more often, but I noticed while testing this that my battery depleted very fast.
There are other ways to do this. You can have a larger radius geofence which is checked every 60 seconds. When triggered, a smaller radius geofence monitor will turn on and start checking every 5 seconds. This is completely possible using Tasker and AutoLocation (a plugin for Tasker). This solves the battery usage issue, but it still needs some experimentation with radius sizes and intervals to get it working perfectly. After driving around the neighborhood at 3AM for an hour, probably looking very suspicious, I decided to let it wait for another day.
Before I gave up on automation, I added a Google Assistant routine to my Google Home account. This allows me to say “OK, Google. Open the gate”, which triggers a text message to open the gate. Not as automatic as geofencing, but it works while I’m arriving and departing. Additionally, I could open the gate for a guest using my voice. I haven’t gotten to that level of laziness just yet, but I’ll let you know when I do, using voice commands of course.
In the future, I’d like to have a fully ‘smart’ home, using mostly DIY modules such as the one I’ve talked about today. Products such as Nest and Philips Hue can be replicated using a few hundred lines of code, a Raspberry Pi, and some soldering skills. Obviously they don’t look as fancy, but it’s something you can be proud of.