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:ATD*7,1ATHThe 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:ATS8=1For 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.
890), 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 seconds2: Open the gate indefinitely3: Close the gateIf 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.
The emoji feature is here to stayI 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.
You can look at the source code here.
A lot of useful information was found here.