[null, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://2.bp.blogspot.com/-mgrTovRbU04/WcytuUSephI/AAAAAAAAOvU/23cM8FJZJWEDKaEi3pDESxc0j7Wd5DP5wCKgBGAs/s320/20170920_221246.jpg", "src": "https://2.bp.blogspot.com/-mgrTovRbU04/WcytuUSephI/AAAAAAAAOvU/23cM8FJZJWEDKaEi3pDESxc0j7Wd5DP5wCKgBGAs/s320/20170920_221246.jpg", "rendered_width": 240, "rendered_height": 320}, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://3.bp.blogspot.com/-VGMf3rzKS-I/WcytuZp6MLI/AAAAAAAAOvU/DjISX_ja3K0o-SCU0YXbLND84xZpDPKzgCKgBGAs/s320/20170920_221314.jpg", "src": "https://3.bp.blogspot.com/-VGMf3rzKS-I/WcytuZp6MLI/AAAAAAAAOvU/DjISX_ja3K0o-SCU0YXbLND84xZpDPKzgCKgBGAs/s320/20170920_221314.jpg", "rendered_width": 240, "rendered_height": 320}, null, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://3.bp.blogspot.com/-b0dv5gu9gzQ/Wcy8bFb5LmI/AAAAAAAAOvk/R6zxvpgIfGwchmvTEyOu1UBfX6R1YrbCACLcBGAs/s640/remote1.png", "src": "https://3.bp.blogspot.com/-b0dv5gu9gzQ/Wcy8bFb5LmI/AAAAAAAAOvk/R6zxvpgIfGwchmvTEyOu1UBfX6R1YrbCACLcBGAs/s640/remote1.png", "formatted_filename": "remote", "rendered_width": 640, "rendered_height": 52}, null, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://4.bp.blogspot.com/-k9yPlJQtpow/Wcd7LPvwe3I/AAAAAAAAOqI/NJc3_pwhY4sz2nXPk7cfgTx1ihfSCKnBwCPcBGAYYCw/s640/20170924_022957.jpg", "src": "https://4.bp.blogspot.com/-k9yPlJQtpow/Wcd7LPvwe3I/AAAAAAAAOqI/NJc3_pwhY4sz2nXPk7cfgTx1ihfSCKnBwCPcBGAYYCw/s640/20170924_022957.jpg", "rendered_width": 640, "rendered_height": 480}, null, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://3.bp.blogspot.com/-QgubW22m_Kk/Wcg7mNgry3I/AAAAAAAAOsA/KsEfWy2v28w7BthWpmWRtJ6Xt24GWxlVACPcBGAYYCw/s320/20170924_161058.jpg", "src": "https://3.bp.blogspot.com/-QgubW22m_Kk/Wcg7mNgry3I/AAAAAAAAOsA/KsEfWy2v28w7BthWpmWRtJ6Xt24GWxlVACPcBGAYYCw/s320/20170924_161058.jpg", "rendered_width": 240, "rendered_height": 320}, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://4.bp.blogspot.com/-Knrivuyct-w/Wcg_7qc6WvI/AAAAAAAAOsg/QLEU-RzqdS4lwgUiDd6Zt36p-KJw-qrgQCPcBGAYYCw/s320/20170924_162922.jpg", "src": "https://4.bp.blogspot.com/-Knrivuyct-w/Wcg_7qc6WvI/AAAAAAAAOsg/QLEU-RzqdS4lwgUiDd6Zt36p-KJw-qrgQCPcBGAYYCw/s320/20170924_162922.jpg", "rendered_width": 240, "rendered_height": 320}, {"document_url": "http://blog.kevinbrianchen.com/2017/09/", "unformatted_src": "https://4.bp.blogspot.com/-3TYddeQUhZ8/WchEMRJh5FI/AAAAAAAAOsM/uLJHhBrkH5Uwn1GEUQ-wwFi7erF5xnw7gCPcBGAYYCw/s320/20170924_164734.jpg", "src": "https://4.bp.blogspot.com/-3TYddeQUhZ8/WchEMRJh5FI/AAAAAAAAOsM/uLJHhBrkH5Uwn1GEUQ-wwFi7erF5xnw7gCPcBGAYYCw/s320/20170924_164734.jpg", "rendered_width": 320, "rendered_height": 240}, null, null, null, null, null, null, null]

Cloning My Gate Opener

I just moved into a new gated complex; unfortunately, the HOA provided only 2 gate openers (for 4 of us), and they charge a ridiculous $100 for each additional remote. I thought this would be a good opportunity to see if I could clone the remote for a bit cheaper :). I found a bunch of helpful resources online; some particularly useful ones were:

I also found that someone does sell a premade cloner for this particular remote model ($25), but I didn't discover this until fairly far in this project (+ buying this would have been less fun).

Initial investigation

The first step was to open it up, since the outside didn't have any distinguishing marks. No dip switch for setting a code, and no FCC ID. However, I did find the manufacturer's name (Linear), and some searching got me to the ACT-31B product page, which explained that each remote was factory programmed with a unique code, and that the receiver needed to be programmed to accept individual remotes.

Some additional searching got me the FCC ID EF4 ACP00872, and I was able to look up the device in the FCC database, which provided a ton of information. Specifically, I found that the device transmits at 318 MHz and uses OOK modulation of the carrier wave and a kind of PPM for the data encoding. In addition, there was a block diagram, functional description, and even the entire schematic.

Extracting the code

Since I had a working remote and knew the schematic, I could have just used an oscilloscope to probe the signal pin for the code. Unfortunately, I don't have a scope (though should really get one), so I went for a more indirect, but fun, approach - an RTL-SDR. This let me extract the actual RF signal the remote transmits. Demodulated: As we can see, there is an initial sync pulse, followed by 23 data pulses. Each pulse is 1 ms, with one in each 6 ms period. This translates to the code 01001110010010110100010, if we assume that a pulse in the earlier half of the period means a 0. Of course, the actual value of the code doesn't matter, as long as we can reproduce it.

Transmitting the code

Because the remote uses 318 MHz instead of the more common frequency 315 MHz or 433 MHz, I couldn't just use a transmitter like this. I briefly considered building a transmitter from scratch, but it would be a little risky since I don't have much analog experience. Eventually. I decided to just buy another remote from ebay (~$10) and hack it to transmit the same code.

I desoldered the existing PIC microcontroller and wired up an ATtiny45. The initial breadboard prototype in all its janky glory: The code was pretty straightforward. Instead of messing with timers, I just used _delay_us() for simplicity. I fed the button input to INT0 and had the actual transmission in the external interrupt, so that I could have ATtiny stay in powered down mode until the button was pressed.

To debug / check my work, I used the RTL-SDR to look at the transmitted signal. One thing I did notice was that the ATtiny's internal clock seemed slightly fast (roughly 137/135). I wasn't sure if this would actually matter, but I corrected it by simply updating the F_CPU flag to 1014814 from 1000000. The final transmission:

As you can see, the signals are essentially the same. Time to do the real test!

Testing in prod

At this point it was like 2 a.m., but I was too excited to wait. I put the breadboard into a box with my laptop as a power source, and walked to the gate for an official test. And (a little surprisingly), it worked! I must have looked incredibly shady walking around after midnight with a box with wires hanging out, but it was worth it :)

Some cleanup

Finally, I moved the setup from the breadboard slightly more permanent setup. I taped up the pcb/wires with some electrical tape to avoid undesired contacts, cut some cutouts in the casing for the wires, and attached the ATtiny via a wirewrap socket. Not the most pretty solution, but I was working with the materials I currently had on hand. I put in an order for a few SOIC-8 ATTiny chips, which will let me fit the microcontroller directly inside the remote.

There was a small issue in terms of the power source; the original remote ran off of two 3V batteries, which is just slightly above the rated 5.5V max of the ATtiny. Fortunately, a simple solution was to just use a single 3V battery; this worked fine, and the remote's range was still reasonable. Posted by Kevin Chen at 3:15 AM 1 comment: