So I recently discovered how the price of entry into enterprise grade networking equipment had come down. It used to be to get into enterprise gear you either spent lots of money or settled for last generation equipment. Since I am lucky enough to have gigabit fiber internet run to my house, I really needed a full gigabit system to not be wasting money.
Prior to getting the gigabit fiber, I ran a series of DD-WRT powered routers. Initially Linksys, upgrading every few years for better wifi. Most recently, just before getting the fiber Internet, I bought a TP-Link Archer C9. The wifi coverage of the C9 was pretty good. With DD-WRT it was a great router for the Comcast cable Internet I was running.
The fiber service, through Centurylink utilizes PPPoE and VLAN tagging. I bought the Zyxel router that Centurylink recommended to avoid monthly fees, and it was only $100. However, I immediately wanted to get ride of the Zyxel and use my trusty C9.
The problem with the C9, and one I'd never even considered to look at before, was that it cannot route a full gigabit connection. After running a new Cat6E line from the fiber's entry to my router I found that the C9 can only route about 500Mbps. So the performance, after the headaches of getting the C9 to natively connect to Centurylink, was subpar for my new system.
So I settled in to using the C9 as an access point only, with the Zyxel as the Internet router and DHCP server.
Fast forward a few years, and in my eBay searching and rampant worshipping at the alter of the Almighty Google, I discover the options of enterprise-grade wifi access points (APs). I was drawn to the Unqiuiti Unifi line for cost, features, and appearance.
I started by getting an older generation Unquity AP. It supports up to WiFi N speeds. Ubiquiti just requires you to run their provisioning software on a computer on the network. You really only need the Unifi software for setup, but you are encouraged (by Ubiquiti and me) to keep it running for monitoring purposes. The software is available for Windows, Mac, and Linux. Since I run Linux, the availability of native Linux compatibility is a must for me.
The physical installation of the access point is literally plug and play. It uses 24v passive power over ethernet, which means you run a single Cat5 cable to the AP and the power supply for the AP sits between your network switch and the AP. Newer versions, and the ones I ended up installing, are full PoE compliant, so no PoE injector needed if you run it off a PoE switch.
The software is relatively simple to set up. I found it to be far easier to use than DD-WRT and had just as many features, with a lot more polish.
The great thing about the Unifi system is it allows some nice monitoring features and adding an AP is dead simple. It's the latter that comes really nice. Find a dead spot in your house? Plug in a second (or third, it'll scale to hundreds of APs if not thousands) AP and provision it. The software does all the rest for you. You can fine tune what channel you're running if you want, and there are many tweaking options, but it really is simple. When I finally got my current generation UAP-AC-PRO APs, I was up and running in minutes. Running the wires and screwing the mounts to the ceiling took ages longer than the software configuration.
The early encouraging experience with their APs led me to look at finally for once replacing that Zyxel ISP router. The Zyxel was good speed-wise and had many nice features that simple consumer routers usually don't. I just like to have control of my network.
With the need to have a Internet router that can handle true gigabit speeds, my options were narrowed. I'd been planning on running a Linux or *BSD based router using an older computer. I even had a small form factor machine and purchased a couple of low profile Intel NICs to put in it. I tried a couple of them out, and they provide an endless amount of power and options, but for me the configuration tweaking was a bit much. I wanted simple but powerful.
I eventually settled on the Ubiquiti EdgeRouter line. Since I was planning on running some PoE APs, I put a bid on a very well priced EdgeRouter POE and won it.
Installing the EdgeRouter was dead simple. Setting up the PPPoE and the VLAN tagging was so simple that I didn't expect it to actually work when I plugged it into the fiber ONT. It did though. Soon it had pulled an IP and was happily chugging away. Setting up the DHCP server, DHCP reservations, and port forwarding were simple as well.
My only complaint with using Ubiquiti's software and hardware is that they don't yet have a unified system. They cater to several markets. The Unifi line of APs and routers (called security gateways, which appear to be firewalls as well) are for the SOHO market, while the EdgeOS (of which the EdgeRouter is a part) are in a different tier. They go all the way up to what they call AirFiber, which is carrier-scale and grade equipment for networking separate buildings or carrier back ends.
It would be nice to have a unified software system that could work with all of their products. As it is, they are so set and forget that you really only need to log into them to touch base every once and a while, look for firmware updates, and make sure there are no errors flagged.
So in conclusion, I full heartedly recommend Ubiquiti networking equipment. I bought all mine second hand off eBay and have been very pleased with it. Even at full retail, the equipment is well worth the cost. The UAP-AC-PRO retails for around $130, which is just a bit more than I paid for that Archer C9 router a few years ago. The configuration, options, and expandability are worth the slightly higher price of admission.
Wednesday, April 25, 2018
Thursday, March 23, 2017
IR to IP Bridge with Arduino
Looks like I've been away for a while...Well it's worth it, cause I searched high and low for something to accomplish this and came up empty.
I recently got rid of my Harmony remotes (which had seen 10+ years of faithful service) in exchange for a URC control system. It always felt like the Harmony was getting in my way in an attempt to be helpful (like Clippy, that obnoxious little paperclip MS put on us). In contrast, URC is very straight forward for someone with a little programming knowledge. I love them!
One this they allow is for amazing customization and total house control. Once I got the basics of the IR and base stations figured out, I started to fully integrate the home controls. HDMI matrix in the equipment closet, each of the four main level televisions connected to it with each room's remote able to talk to each room's RF base station.
Then it hit me! The only thing I need to really be inside the "home of tomorrow" is remote-based control of my lights. Already having a robust Insteon system powered by the incomparable ISY-994i, I finally used the ISY's IR receiving.
Loading the 40 pre-built IR codes into the URC remote's CCP software was a breeze. Then making a program on the ISY to look for those IR signals and turn on or off the appropriate lights was simple enough. I already was using tabletop controllers and Insteon's wireless keypads to do this, but now I have one remote to do it all. You could easily have it dim the lights when you press play and raise them when you pause for that cool theater effect.
Once this was working, I somehow caught wind that Roku (my set top box of choice) allows for a lot of fine grained IP control. You can remotely query which apps are installed, which one is currently running, send remote key presses, or (and this is where I salivated) make it launch a particular program.
One thing the Roku's do not have is a super full featured remote. The included remotes are simple and have few buttons. They do have a couple (depends on model) direct app access buttons (Netflix, Amazon, etc.) but they have yet to come out with a remote that allows quick access to the apps that I use most often (Plex, or more accurately Plex RARFlix, and PS Vue). Roku's network control guide gives you the framework to launch whichever app you desire, but only through an http POST request. URC's "Complete Control" series, which is what I use as a DIY guy, do not have IP control. Their higher end, and fully locked down, "Total Control" do, but that wouldn't be DIY and wouldn't be fun.
Luckily for me, the ISY has a networking module from which you can send HTTP POST and GET requests. Combine that with an IR trigger and voila, I've got direct access to my favorite Roku apps. However, for some reason the ISY wasn't liking to learn new remote codes for me. So I was limited to the 40 in-built codes. This quickly was dwindled once I started to play.
What I really needed at this point is an IR-to-IP device. My Google-fu skills are tip top, but I wasn't able to find anything, other than possibly an irTrans device. Those were fairly expensive for what I'd want and would have to come from the EU.
So what I present here is an Arduino powered IR receiving, IP command sending device. It'll take whichever IR command you want to use and, upon receiving it, send an HTTP command over the network.
The hardware is simple. Arduino of your choice (I initially used an UNO clone, but moved to a Mega for more memory), an ethernet shield, and an IR receiver.
Anyone who's worked with Arduino should be able to understand the code. IR receiver needs to have the data pin plugged in to pin 8 on the Arduino in my example.
Here's the code:
----------Code Starts Here--------------
#include <SPI.h>
#include <Ethernet.h>
#include <IRremote.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC Address of the Arduino
char rokutheater[] = "192.168.1.254"; //IP Address of the target device
EthernetClient client;
IPAddress ip(192, 168, 1, 250); //IP Address of the Arduino
//IPAddress gateway(192, 168, 1, 1); //Uncomment if you need Internet access
//IPAddress subnet(255, 255, 0, 0);
int RECV_PIN = 8; //Pin the IR Receiver is on
#define TheaterPlex 2397 //IR code when the desired IR remote button is pressed
#define TheaterPlex2 349
#define TheaterPSVue 2372
#define TheaterPSVue2 324
#define TheaterHome 52275
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Ethernet.begin(mac, ip);
Serial.begin(9600);
Serial.println("Serial Output Begun");
Serial.print("My IP address: ");
ip = Ethernet.localIP();
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(ip[thisByte], DEC);
Serial.print(".");
}
irrecv.enableIRIn();
}
void loop()
{
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) { //Branch off to the correct subroutine based on the received code
//Theater
case TheaterPlex:
TheaterRoomPlex();
break;
case TheaterPSVue:
TheaterRoomPSVue();
break;
case TheaterPlex2:
TheaterRoomPlex();
break;
case TheaterPSVue2:
TheaterRoomPSVue();
break;
case TheaterHome:
TheaterRoomHome();
break;
}
Serial.println(value); // Sends the received IR button code to the serial monitor, helpful to find new keys or otherwise debug
irrecv.resume(); // Ready to receive the next command/value
}
}
//-------------------THEATER-------------------------
void TheaterRoomPlex(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /launch/13535 HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("Plex on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
void TheaterRoomPSVue(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /launch/93374 HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("PS Vue on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
void TheaterRoomHome(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /keypress/Home HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("Going Home on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
----------End Code------------
You'll need both the Arduino Ethernet library (found here) and shirriff's IR Remote library .(found here)
Any IR Receiver will work, but I used the YwRobot IR Receiver breakout board out of convenience like this one. I also used a generic Arduino Ethernet shield. I'd imagine with a little tweaking, you could use an ESP8266 or a wifi shield too. That'll probably be my next step.
I also used a generic Arduino UNO R3 at first, which the above code compiles to use 56% of program storage and 44% of ram. Using a Mega2560 clone, it compiles to use about 7% storage and 11% ram. So if you're only going to use it for a few commands an UNO is capable, but I only wanted to build the device once, so I went with Mega.
Now, to just find someone who is good at programming and making websites. Ideally, I wouldn't have to hook it to a computer to program it. Would be nice to use the SD card functionality to serve up a web page that would display received IR codes and allow you to create new commands to send when a code is received. I would think that this would be fairly easy, but beyond my basic skills. I guess this leaves me plenty of room to continue to tinker.
Meanwhile, I've now been using it, shoehorned into a plastic project box, for a week to test its function. It has operated flawlessly thus far. Even by my standards I'm impressive sometimes!
UPDATE 07/01/2018
For some reason this past week this system quit working on me. For some reason, the Rokus suddenly stopped liking the formatting of the HTTP POST messages in my code.
After some troubleshooting, I stumbled across the solution. Remove (or comment out) these two lines in each section of your code:
client.println("Host: www.arduino.cc");
client.println("User-Agent: arduino-ethernet");
I've updated the code above to reflect these changes. Not sure why this change was necessary. So if you used my code, you need to update the Arduino a bit.
At least it's an easy/quick change.
I recently got rid of my Harmony remotes (which had seen 10+ years of faithful service) in exchange for a URC control system. It always felt like the Harmony was getting in my way in an attempt to be helpful (like Clippy, that obnoxious little paperclip MS put on us). In contrast, URC is very straight forward for someone with a little programming knowledge. I love them!
One this they allow is for amazing customization and total house control. Once I got the basics of the IR and base stations figured out, I started to fully integrate the home controls. HDMI matrix in the equipment closet, each of the four main level televisions connected to it with each room's remote able to talk to each room's RF base station.
Then it hit me! The only thing I need to really be inside the "home of tomorrow" is remote-based control of my lights. Already having a robust Insteon system powered by the incomparable ISY-994i, I finally used the ISY's IR receiving.
Loading the 40 pre-built IR codes into the URC remote's CCP software was a breeze. Then making a program on the ISY to look for those IR signals and turn on or off the appropriate lights was simple enough. I already was using tabletop controllers and Insteon's wireless keypads to do this, but now I have one remote to do it all. You could easily have it dim the lights when you press play and raise them when you pause for that cool theater effect.
Once this was working, I somehow caught wind that Roku (my set top box of choice) allows for a lot of fine grained IP control. You can remotely query which apps are installed, which one is currently running, send remote key presses, or (and this is where I salivated) make it launch a particular program.
One thing the Roku's do not have is a super full featured remote. The included remotes are simple and have few buttons. They do have a couple (depends on model) direct app access buttons (Netflix, Amazon, etc.) but they have yet to come out with a remote that allows quick access to the apps that I use most often (Plex, or more accurately Plex RARFlix, and PS Vue). Roku's network control guide gives you the framework to launch whichever app you desire, but only through an http POST request. URC's "Complete Control" series, which is what I use as a DIY guy, do not have IP control. Their higher end, and fully locked down, "Total Control" do, but that wouldn't be DIY and wouldn't be fun.
Luckily for me, the ISY has a networking module from which you can send HTTP POST and GET requests. Combine that with an IR trigger and voila, I've got direct access to my favorite Roku apps. However, for some reason the ISY wasn't liking to learn new remote codes for me. So I was limited to the 40 in-built codes. This quickly was dwindled once I started to play.
What I really needed at this point is an IR-to-IP device. My Google-fu skills are tip top, but I wasn't able to find anything, other than possibly an irTrans device. Those were fairly expensive for what I'd want and would have to come from the EU.
So what I present here is an Arduino powered IR receiving, IP command sending device. It'll take whichever IR command you want to use and, upon receiving it, send an HTTP command over the network.
The hardware is simple. Arduino of your choice (I initially used an UNO clone, but moved to a Mega for more memory), an ethernet shield, and an IR receiver.
Anyone who's worked with Arduino should be able to understand the code. IR receiver needs to have the data pin plugged in to pin 8 on the Arduino in my example.
Here's the code:
----------Code Starts Here--------------
#include <SPI.h>
#include <Ethernet.h>
#include <IRremote.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //MAC Address of the Arduino
char rokutheater[] = "192.168.1.254"; //IP Address of the target device
EthernetClient client;
IPAddress ip(192, 168, 1, 250); //IP Address of the Arduino
//IPAddress gateway(192, 168, 1, 1); //Uncomment if you need Internet access
//IPAddress subnet(255, 255, 0, 0);
int RECV_PIN = 8; //Pin the IR Receiver is on
#define TheaterPlex 2397 //IR code when the desired IR remote button is pressed
#define TheaterPlex2 349
#define TheaterPSVue 2372
#define TheaterPSVue2 324
#define TheaterHome 52275
IRrecv irrecv(RECV_PIN);
decode_results results;
void setup()
{
Ethernet.begin(mac, ip);
Serial.begin(9600);
Serial.println("Serial Output Begun");
Serial.print("My IP address: ");
ip = Ethernet.localIP();
for (byte thisByte = 0; thisByte < 4; thisByte++) {
// print the value of each byte of the IP address:
Serial.print(ip[thisByte], DEC);
Serial.print(".");
}
irrecv.enableIRIn();
}
void loop()
{
if (irrecv.decode(&results)) {
unsigned int value = results.value;
switch(value) { //Branch off to the correct subroutine based on the received code
//Theater
case TheaterPlex:
TheaterRoomPlex();
break;
case TheaterPSVue:
TheaterRoomPSVue();
break;
case TheaterPlex2:
TheaterRoomPlex();
break;
case TheaterPSVue2:
TheaterRoomPSVue();
break;
case TheaterHome:
TheaterRoomHome();
break;
}
Serial.println(value); // Sends the received IR button code to the serial monitor, helpful to find new keys or otherwise debug
irrecv.resume(); // Ready to receive the next command/value
}
}
//-------------------THEATER-------------------------
void TheaterRoomPlex(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /launch/13535 HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("Plex on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
void TheaterRoomPSVue(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /launch/93374 HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("PS Vue on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
void TheaterRoomHome(){
client.stop();
if (client.connect(rokutheater, 8060)) {
Serial.println("connecting...");
client.println("POST /keypress/Home HTTP/1.1");
// client.println("Host: www.arduino.cc");
// client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
Serial.print("Going Home on Theater Roku");
delay(500);
} else {
Serial.println("connection failed");
}
}
----------End Code------------
You'll need both the Arduino Ethernet library (found here) and shirriff's IR Remote library .(found here)
Any IR Receiver will work, but I used the YwRobot IR Receiver breakout board out of convenience like this one. I also used a generic Arduino Ethernet shield. I'd imagine with a little tweaking, you could use an ESP8266 or a wifi shield too. That'll probably be my next step.
I also used a generic Arduino UNO R3 at first, which the above code compiles to use 56% of program storage and 44% of ram. Using a Mega2560 clone, it compiles to use about 7% storage and 11% ram. So if you're only going to use it for a few commands an UNO is capable, but I only wanted to build the device once, so I went with Mega.
Now, to just find someone who is good at programming and making websites. Ideally, I wouldn't have to hook it to a computer to program it. Would be nice to use the SD card functionality to serve up a web page that would display received IR codes and allow you to create new commands to send when a code is received. I would think that this would be fairly easy, but beyond my basic skills. I guess this leaves me plenty of room to continue to tinker.
Meanwhile, I've now been using it, shoehorned into a plastic project box, for a week to test its function. It has operated flawlessly thus far. Even by my standards I'm impressive sometimes!
UPDATE 07/01/2018
For some reason this past week this system quit working on me. For some reason, the Rokus suddenly stopped liking the formatting of the HTTP POST messages in my code.
After some troubleshooting, I stumbled across the solution. Remove (or comment out) these two lines in each section of your code:
client.println("Host: www.arduino.cc");
client.println("User-Agent: arduino-ethernet");
I've updated the code above to reflect these changes. Not sure why this change was necessary. So if you used my code, you need to update the Arduino a bit.
At least it's an easy/quick change.
Thursday, March 26, 2015
RFID Garage Door Opener with Arduino
This week I took a leap to add RFID access to my garage door. This was largely spurred by how flaky my manufacturer's wireless keypad is for my opener in the cold weather. I wanted something hard wired, and I knew RFID was fairly cheap to add to Arduino. And it's freaking awesome!
This setup isn't network aware, so you cannot monitor the status of the garage door or add/remove keyfobs remotely. You're getting short on digital pins on a standard UNO/Leonardo, so you'd probably want a Mega if that was something you wanted. I will probably add that in the future. I've never done WiFi with the Arduino, so this would be a good opportunity. I'll probably also look at adding a real time clock module so I can permit access only within certain windows (such as giving spare fobs/cards to family but only allowing entry during the day).
First you'll need an Arduino. I've used both UNOs and Leonardos with this build and they both work great. You'll also need an RC-522 reader, available on Amazon and eBay. This is easy to integrate with Arduino. Extra cards/fobs are also nice, and you'll want to get ones that work with "Mifare" in the 13.56Mhz band. These are also available for cheap in bulk from the 'Bay.
You'll also want to use some sort of relay or transistor as your output. In this case I used a regular Arduino-compatable relay module. I liked that it gives me an audible click for testing purposes, but a solid state relay or transistor would do just as well to trigger a garage door opener (which just momentarily touches two wires together).
I took my code and inspiration from miguelbalboa's GitHub. His code uses a single RGB led for feedback, which I found works the best. I tried paring this down to two leds, but you really want all three.
Hook the pins up as follows:
* 3.3V on Arduino to the 3.3V on the RFID reader.
* Pin 9 on Arduino to RST on RFID.
* Pin 10 on Arduino to SDA on RFID.
* Pin 11 on Arduino to MOSI on RFID.
* Pin 12 on Arduino to MISO on RFID.
* Pin 13 on Arduino to SCK on RFID.
* Red LED to Arduino Pin 7
* Green LED to Arduino Pin 6
* Blue LED to Arduino Pin 5
* Finally, your output relay on Arduino Pin 4
* There's an option for a reset button to be used on Pin 3. This reset button will wipe the memory of all cards, so you can start fresh. This is nice when you're first playing with things.
The code from Miguel is annotated to allow for both common anode or common cathode RGB LEDs.
First time you boot it up, watch your serial console in the Arduino IDE to make sure you know what's going on. The first card you scan becomes the "master" card that puts the system into program mode (where you can add or remove cards).
Once you scan a master card, put the system into program mode. All three colors will flash in sequence. Now begin scanning additional cards. A successful "add" will be followed by two green flashes. If the card is already part of the system, then scanning it again removes it. Successful removal is indicated by two blue flashes. You'll see this written verbosely in the serial console. The LED feedback is needed once you install it in the field.
Cards are stored in the ATmega's EEPROM and so will survive a loss of power. This EEPROM has a limited number of writes (about 100k), but can be read unlimitedly. Realistically you could add and remove cards in normal usage for years before you hit the write limit.
I breadboarded mine, with an LED hooked up to the output to see how well it operated.
Then it went into a case I had lying around.
In the right photo you can see the two relay module at the bottom.
I used a Rugged Circuits Aussie Shield to connect everything up in the finished product. This was just easier than soldering a prototype shield, which would have been much cheaper. This is a great product to use, and in the future will be much easier to repurpose than a soldered up protoshield.
The wires coming into the case include the five control wires for the RFID reader and the four wires for the RGB feedback LEDs. There's also two wires that tie into the garage door opener's button circuit. I made the wiring harness myself, which is why the level of craftsmanship is so unbelievably high.
I have intentionally left the reset button off the physical build (but in the software). This means that to reset (erase all the memorized cards, including the master) the system, you need to manually jumper pin 3 to ground. To me, this works, since I don't want someone who is clicking buttons to accidentally reset everything.
You'll also notice that I used a separate box for the "brains" of the system, the Arduino and relay. My initial inclination was to shove this all into a single gang box with only a power wire and the garage door triggers coming in/out. My wife insisted that it be "hack proof", so I put the smarts (and the garage hook ups) on the inside. If you take off the wall plate outside, in order to hack into the system you'd still need to simulate the RFID board (protocol and the correct key codes).
I hotglued the RFID board directly to a plastic faceplate. This doesn't seem to interfere too much with the signal, but you do have only a couple of millimeters range to begin with. You basically need to touch the fob to the plate to get a read. This is a little more awkward with the credit card style than it is with a keyfob.
Here's the finished outdoor portion, with my wiring harness fed through a hole into the garage. The box (initially surface mounted) has been recessed into the garage trim.
The blue is intentionally dim. I put an extra resistor on that part of the circuit when I put the recessed box together so that it wasn't a bright blue beacon for the neighborhood. The green and red are of "normal" brightness to give a clear indication of a read.
Overall this was a simple build, since it doesn't involve network access or a RTC. However, since it doesn't use those you get a rather "dumb" appliance. This can be good, since it seems like the more functionality you add, the more points of failure you encounter. I'm also only using one output. I've got an extra relay that might find some usage in the future.
This setup isn't network aware, so you cannot monitor the status of the garage door or add/remove keyfobs remotely. You're getting short on digital pins on a standard UNO/Leonardo, so you'd probably want a Mega if that was something you wanted. I will probably add that in the future. I've never done WiFi with the Arduino, so this would be a good opportunity. I'll probably also look at adding a real time clock module so I can permit access only within certain windows (such as giving spare fobs/cards to family but only allowing entry during the day).
First you'll need an Arduino. I've used both UNOs and Leonardos with this build and they both work great. You'll also need an RC-522 reader, available on Amazon and eBay. This is easy to integrate with Arduino. Extra cards/fobs are also nice, and you'll want to get ones that work with "Mifare" in the 13.56Mhz band. These are also available for cheap in bulk from the 'Bay.
You'll also want to use some sort of relay or transistor as your output. In this case I used a regular Arduino-compatable relay module. I liked that it gives me an audible click for testing purposes, but a solid state relay or transistor would do just as well to trigger a garage door opener (which just momentarily touches two wires together).
![]() |
| RC-522, with right angle pins (included) soldered on |
Hook the pins up as follows:
* 3.3V on Arduino to the 3.3V on the RFID reader.
* Pin 9 on Arduino to RST on RFID.
* Pin 10 on Arduino to SDA on RFID.
* Pin 11 on Arduino to MOSI on RFID.
* Pin 12 on Arduino to MISO on RFID.
* Pin 13 on Arduino to SCK on RFID.
* Red LED to Arduino Pin 7
* Green LED to Arduino Pin 6
* Blue LED to Arduino Pin 5
* Finally, your output relay on Arduino Pin 4
* There's an option for a reset button to be used on Pin 3. This reset button will wipe the memory of all cards, so you can start fresh. This is nice when you're first playing with things.
The code from Miguel is annotated to allow for both common anode or common cathode RGB LEDs.
First time you boot it up, watch your serial console in the Arduino IDE to make sure you know what's going on. The first card you scan becomes the "master" card that puts the system into program mode (where you can add or remove cards).
Once you scan a master card, put the system into program mode. All three colors will flash in sequence. Now begin scanning additional cards. A successful "add" will be followed by two green flashes. If the card is already part of the system, then scanning it again removes it. Successful removal is indicated by two blue flashes. You'll see this written verbosely in the serial console. The LED feedback is needed once you install it in the field.
Cards are stored in the ATmega's EEPROM and so will survive a loss of power. This EEPROM has a limited number of writes (about 100k), but can be read unlimitedly. Realistically you could add and remove cards in normal usage for years before you hit the write limit.
I breadboarded mine, with an LED hooked up to the output to see how well it operated.
Then it went into a case I had lying around.
In the right photo you can see the two relay module at the bottom.
I used a Rugged Circuits Aussie Shield to connect everything up in the finished product. This was just easier than soldering a prototype shield, which would have been much cheaper. This is a great product to use, and in the future will be much easier to repurpose than a soldered up protoshield.
The wires coming into the case include the five control wires for the RFID reader and the four wires for the RGB feedback LEDs. There's also two wires that tie into the garage door opener's button circuit. I made the wiring harness myself, which is why the level of craftsmanship is so unbelievably high.
I have intentionally left the reset button off the physical build (but in the software). This means that to reset (erase all the memorized cards, including the master) the system, you need to manually jumper pin 3 to ground. To me, this works, since I don't want someone who is clicking buttons to accidentally reset everything.
You'll also notice that I used a separate box for the "brains" of the system, the Arduino and relay. My initial inclination was to shove this all into a single gang box with only a power wire and the garage door triggers coming in/out. My wife insisted that it be "hack proof", so I put the smarts (and the garage hook ups) on the inside. If you take off the wall plate outside, in order to hack into the system you'd still need to simulate the RFID board (protocol and the correct key codes).
I hotglued the RFID board directly to a plastic faceplate. This doesn't seem to interfere too much with the signal, but you do have only a couple of millimeters range to begin with. You basically need to touch the fob to the plate to get a read. This is a little more awkward with the credit card style than it is with a keyfob.
Here's the finished outdoor portion, with my wiring harness fed through a hole into the garage. The box (initially surface mounted) has been recessed into the garage trim.
The blue is intentionally dim. I put an extra resistor on that part of the circuit when I put the recessed box together so that it wasn't a bright blue beacon for the neighborhood. The green and red are of "normal" brightness to give a clear indication of a read.
Overall this was a simple build, since it doesn't involve network access or a RTC. However, since it doesn't use those you get a rather "dumb" appliance. This can be good, since it seems like the more functionality you add, the more points of failure you encounter. I'm also only using one output. I've got an extra relay that might find some usage in the future.
Tuesday, February 3, 2015
Today I remembered why I don't like Windows
Over the last five years or so I've really grown to love Linux as my day to day operating system of choice. I switched to Ubuntu back at the 9.04 release and haven't really looked back. As the other computers in the house started to experience issues, I replaced the bloated, slow, virus infested Windows installs with linux. I've come to like the Linux Mint variety and use my desktop of choice, Mate. After playing the the bleeding edge versions I now stick with the long term support (LTS) releases.
I even replaced Windows on my wife's laptop some years back, initially just on a live USB stick, to see if she liked it and it did everything for her. Since it did, it brought life back to an old, slow laptop. She's since gotten a Acer C720 Chromebook, which is awesome for her needs (internet consumption) and paying bills and writing up a resume.
There's only one computer left in the house running Windows, the home theater PC in my theater room. It remains on Windows mostly out of laziness and because I tend to believe if it's working, not to fix it. It has been running Windows 7 for about five years and has been running well and without major issues. It runs my Plex desktop app which is really all I use, plus the occasional look at a trailer or video on Youtube.
I was this latter use that led me to discover that my antivirus protected Windows computer, protected by a well respected antivirus brand I might add, was infected with some form of virus. The virus made it terribly difficult to use the internet, as it opened extra browser windows, redirected links, and conducted all sorts of other hyjinks with my system.
I even replaced Windows on my wife's laptop some years back, initially just on a live USB stick, to see if she liked it and it did everything for her. Since it did, it brought life back to an old, slow laptop. She's since gotten a Acer C720 Chromebook, which is awesome for her needs (internet consumption) and paying bills and writing up a resume.
There's only one computer left in the house running Windows, the home theater PC in my theater room. It remains on Windows mostly out of laziness and because I tend to believe if it's working, not to fix it. It has been running Windows 7 for about five years and has been running well and without major issues. It runs my Plex desktop app which is really all I use, plus the occasional look at a trailer or video on Youtube.
I was this latter use that led me to discover that my antivirus protected Windows computer, protected by a well respected antivirus brand I might add, was infected with some form of virus. The virus made it terribly difficult to use the internet, as it opened extra browser windows, redirected links, and conducted all sorts of other hyjinks with my system.
So I checked that my antivirus was operating, it was, and the definitions were up to date, supposedly there were no updates, but the date was more than a year old. I came to find out that my antivirus now required a subscription to get new definitions. This is ridiculous to me, to pay through perpetuity for basic security. Aside from being connected to the internet, this computer is really used for nothing by watching movies. If Windows hadn't been so full of holes, I don't see how it could have become infected.
Anywho, I loaded the free AVG antivirus which discovered the viruses, removed the offending files, and after a couple of reboots, I was virus free. I then went into the installed programs to find that whatever virus I'd become infected with had installed about four programs that I didn't want, need, or even know what they do. So I got rid of those in short order.
What this taught me was that I need to keep a better watch on this system, I hardly ever do any maintenance on it, so I'm partially to blame here. But it also reminded me how I haven't had to deal with any of these virus related issues on any of my Linux-based systems. I also, while sitting watching a progress bar cross very slowly on the only source of entertainment in the room, remembered how great and easy the remote administration options are in Linux. I set up all my systems to allow secure shell (SSH) access, so I can access them all remotely from my main desktop. I update them all multiple times a week and use this access to do all my troubleshooting from the comfort of my office chair.
In spite of how little I like dealing with typical Windows issues, today's problem was relatively easy to fix, and I was up and running again in about an hour, virus free. I was really tempted to just blow the Windows installation off the drive and fully convert to Linux. However, I didn't, partly out of my aforementioned laziness, but mostly because I think I like still having one bare metal Windows (i.e. not a virtual machine) computer in the house. If for no other reason than to keep my Windows troubleshooting and repair skills in shape. Because there's no end to the complaints and issues people bring up with their Windows computers. :-)
Seagate ST2000DM001 are really crap
As a followup to my earlier article about tearing apart one of the Seagate ST3000DM001 3TB hard drives, I can now say they are one of the worst drives I've ever used.
A couple years back, when the 3TB drives were first hitting the streets in reasonable prices, I decided to upgrade my file server. I'd collected a large number of 1TB drives over time that I wanted to consolidate to a single 4x3TB drive stack.
The price on the Seagate drives was the best at the time, though I'd had better luck in the past with Western Digital drives, I decided to save a few bucks. Not only that, Seagate is a Minnesota company. I like to support local businesses.
While I was in money-saving mode, I opted to go with external drives as my donors, since they were cheaper than the bare drives (why is that? it's absurd). I tore four external drives apart to get my donors for my server expansion/consolidation.
Fast forward some time, one of the Seagate's failed. Not unusual for hard drives to fail. In the past, I'd simply submit it to the manufacturer for a replacement and operate off a backup in the meantime. However, apparently since these were originally external drives (Seagate branded mind you) they were considered OEM and not covered by Seagate. I'd late find out all four drives were similarly denied replacement.
I replaced that first failed drive with a WD 3TB and got things back up and running. About 9 months later I had another of the Seagates fail. I was able to replace it (with a WD) and get my data back, since I'd fully prepared for a single drive failure. What I could not recover from was the back-to-back failure of the remaining two Seagates in my server. In the span of a week, three of these drives failed, with the loss of all data on them.
Now, I've discovered some similar stories of pre-mature failure of these drives. There's a firmware update that I was hopeful would help, but the software failed to recognize the drives after their failure.
I noticed that the drives were very hot (in their well ventilated case with "automatic" fans), much hotter than the WD drives above and below them. Now, I can't say whether they were hot as part of the failure or if the heat hastened their demise. What I can say is that four of four drives failed (three in a span of days). I've had drives, from a variety of manufacturers, fail over the years. What I have not had was every drive from one place fail (and at once!).
I cannot in good conscience recommend these drives for anything you hold dear (and copying 3TB of anything takes a good bit of time, so....).
On a side note, I bought WD Green drives (having used them for years and found them to be solid performers), but after reading this, think I will choose Reds in the future.
A couple years back, when the 3TB drives were first hitting the streets in reasonable prices, I decided to upgrade my file server. I'd collected a large number of 1TB drives over time that I wanted to consolidate to a single 4x3TB drive stack.
The price on the Seagate drives was the best at the time, though I'd had better luck in the past with Western Digital drives, I decided to save a few bucks. Not only that, Seagate is a Minnesota company. I like to support local businesses.
While I was in money-saving mode, I opted to go with external drives as my donors, since they were cheaper than the bare drives (why is that? it's absurd). I tore four external drives apart to get my donors for my server expansion/consolidation.
Fast forward some time, one of the Seagate's failed. Not unusual for hard drives to fail. In the past, I'd simply submit it to the manufacturer for a replacement and operate off a backup in the meantime. However, apparently since these were originally external drives (Seagate branded mind you) they were considered OEM and not covered by Seagate. I'd late find out all four drives were similarly denied replacement.
I replaced that first failed drive with a WD 3TB and got things back up and running. About 9 months later I had another of the Seagates fail. I was able to replace it (with a WD) and get my data back, since I'd fully prepared for a single drive failure. What I could not recover from was the back-to-back failure of the remaining two Seagates in my server. In the span of a week, three of these drives failed, with the loss of all data on them.
Now, I've discovered some similar stories of pre-mature failure of these drives. There's a firmware update that I was hopeful would help, but the software failed to recognize the drives after their failure.
I noticed that the drives were very hot (in their well ventilated case with "automatic" fans), much hotter than the WD drives above and below them. Now, I can't say whether they were hot as part of the failure or if the heat hastened their demise. What I can say is that four of four drives failed (three in a span of days). I've had drives, from a variety of manufacturers, fail over the years. What I have not had was every drive from one place fail (and at once!).
I cannot in good conscience recommend these drives for anything you hold dear (and copying 3TB of anything takes a good bit of time, so....).
On a side note, I bought WD Green drives (having used them for years and found them to be solid performers), but after reading this, think I will choose Reds in the future.
Sunday, September 7, 2014
ATtiny85 and ATtiny84 DIY Programming Shield
To program an ATtiny85 or ATtiny84, smaller microcontroller brothers to the ATmega328 used in the Arduino, you can use a dedicated ISP programmer, or breadboard the chips and use an Arduino. I used the latter technique, but as I wanted an easier and more reliable way to work with a handful of chips for multiple projects, I decided to build my own programmer shield.
The Omega-MP, which I bought on eBay, is a great shield to program the ATtiny85 (and many other chips) but didn't support the ATtiny84, so my shield here will support only the ATtiny85 and 84.
Here's a Fritzing diagram of how it's wired. Ignore the labeling of the 14-pin connector. That should represent the 14-pin DIP of the ATtiny84. Pin 1 for both chips is to the left and down (yellow lead on the 85 and red on the 84). The Fritzing program didn't have an exact representation of the prototyping shield I used, so the actual wiring and the diagram will be different in practice. I used a cheap prototyping shield that's readily available on Amazon or other retailers' websites. Use a 10uF capacitor between the ground and reset pin of the host Arduino.
Here's the pinout diagram for the chips: ATtiny Pinouts and ISP Guide
I followed the linked diagram to initially breadboard my chips and then to wire up the shield. I used DIP sockets for the completed shield, but ZIF sockets would probably work well too (but take up a lot more room).
Here's my completed shield, with crappy soldering and all!
I ran the wires for the ATtiny84's 14-pin DIP socket on the bottom, tying them into the Arduino pins. I then routed the ATtiny85's 8-pin DIP socket on top, tying them in to the shared pins alongside the 14-pin socket.
This shield will program one (at a time, won't do two chips at once) ATtiny85 or ATtiny84. It'll also work with related chips from those families, but I don't know why you'd want to use an ATtiny25 or 45, or the 24 or 84 as the price difference at the hobbyist level is nil, but since they are pin identical to their siblings with more memory, they will work.
The Omega-MP, which I bought on eBay, is a great shield to program the ATtiny85 (and many other chips) but didn't support the ATtiny84, so my shield here will support only the ATtiny85 and 84.
Here's a Fritzing diagram of how it's wired. Ignore the labeling of the 14-pin connector. That should represent the 14-pin DIP of the ATtiny84. Pin 1 for both chips is to the left and down (yellow lead on the 85 and red on the 84). The Fritzing program didn't have an exact representation of the prototyping shield I used, so the actual wiring and the diagram will be different in practice. I used a cheap prototyping shield that's readily available on Amazon or other retailers' websites. Use a 10uF capacitor between the ground and reset pin of the host Arduino.
Here's the pinout diagram for the chips: ATtiny Pinouts and ISP Guide
I followed the linked diagram to initially breadboard my chips and then to wire up the shield. I used DIP sockets for the completed shield, but ZIF sockets would probably work well too (but take up a lot more room).
Here's my completed shield, with crappy soldering and all!
![]() |
| Completed Shield on an UNO R3 |
![]() |
| Top View |
![]() |
| Bottom View |
This shield will program one (at a time, won't do two chips at once) ATtiny85 or ATtiny84. It'll also work with related chips from those families, but I don't know why you'd want to use an ATtiny25 or 45, or the 24 or 84 as the price difference at the hobbyist level is nil, but since they are pin identical to their siblings with more memory, they will work.
Friday, September 5, 2014
Control Stop Light with an ATtiny85 or Arduino
One of my first projects with Arduino was to provide a little automation to an old stop light (and crosswalk signal) I had out in the garage. I'd already wired them to individual switches (good for games of "red light, green light"), but the allure of having it operate light a real light (green, then yellow briefly, then red, repeat) was too great. Arduino seemed like the perfect fit.
Of course, the Arduino can't switch anything high voltage nor high amperage. So you'll need to use a relay. I am a big fan of the cheap relay boards like these. For a regular stop light, you'll need three individuals or a four in one. I used a four in one relay board and a two in one separate board for the crosswalk lights. I stuffed it all in a plastic enclosure box. Don't undertake the high voltage part of this project without a firm understanding of the risks involved. This post isn't about high voltage relays or how to integrate them with the Arduino, so I'll assume you know how to do that. Follow along if you want to build a stop light simulator with 5mm LEDs, the same principles apply.
I recently wanted to find a way to experiment with using an ATtiny (baby brother of the ATmega microcontroller in the Arduino). I picked up some ATtiny85 and ATtiny84 chips off an eBay vendor. The ATiny can be programmed, with a new library, in the Arduino IDE, are much cheaper than an ATmega ($1.3/ea for the ATtiny85 vs $2.30 for the ATmega328p, and $5+ if you don't want it shipped from China), but are limited in the number of input/output options. The ATtiny runs slower (internal clock, the ATmega uses an external), uses less energy, and comes in a bare chip form factor (need some soldering skills to get beyond the breadboard phase). Here's a good comparison of the two chips.
Since the ATtiny chips run off 5v I planned on using a commodity USB power supply. Since the ATtiny85 has an internal clock chip, it's easier to build a circuit (no external crystal). My original stop light controller was powered by an Arduino Micro (about $20). So I wanted this new controller to be smaller and cheaper. My total cost to replace the Micro was about $3.
Since I used only 5 outputs and no inputs for my light controller, the ATtiny85 is about the smallest and cheapest of the Atmel chips that will do the job.
First, to program the chip. I used a programmer shield, but you can use some hookup wire and do it yourself or build your own shield. Follow these directions if you want to take that route.
Here's the code:
"
int Walk = 3;
int DontWalk = 4;
int Green = 0;
int Yellow = 1;
int Red = 2;
void setup()
{
pinMode(Walk, OUTPUT);
pinMode(DontWalk, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(Yellow, OUTPUT);
pinMode(Red, OUTPUT);
}
void loop()
{
//HIGH = ON, LOW = OFF
digitalWrite(Walk, LOW);
digitalWrite(DontWalk, LOW);
digitalWrite(Green, LOW);
digitalWrite(Yellow, LOW);
digitalWrite(Red, LOW);
digitalWrite(Green, HIGH);
digitalWrite(Walk, HIGH);
delay(800);
digitalWrite(Walk, LOW);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(200);
digitalWrite(Green, LOW);
digitalWrite(Yellow, HIGH);
delay(350);
digitalWrite(Yellow, LOW);
digitalWrite(Red, HIGH);
delay(1200);
}
"
Now to breadboard it. Follow this pinout guide to wire it up. Here I used LEDs to take the place of the relay outputs to see if it looked like a stop light and to test my timings. Since my relays are triggered by a "high" signal, when the LED is on, the relay would be triggered to send the high voltage to the light.
It works! Now to solder.
Now back out to the garage to plug it in to the relays and the lights.
Here is the final, ready to be buttoned up project.
This photo shows the dramatic size reduction you can realize switching from the already small Arduino Micro to a basic ATtiny85 on some perfboard.
Provided you don't need a bunch of inputs/outputs the ATtiny might be a cost, and perhaps more importantly size, effective solution.
Here's the Fritzing diagram:
Of course, the Arduino can't switch anything high voltage nor high amperage. So you'll need to use a relay. I am a big fan of the cheap relay boards like these. For a regular stop light, you'll need three individuals or a four in one. I used a four in one relay board and a two in one separate board for the crosswalk lights. I stuffed it all in a plastic enclosure box. Don't undertake the high voltage part of this project without a firm understanding of the risks involved. This post isn't about high voltage relays or how to integrate them with the Arduino, so I'll assume you know how to do that. Follow along if you want to build a stop light simulator with 5mm LEDs, the same principles apply.
![]() |
| ATtiny 85 |
Since the ATtiny chips run off 5v I planned on using a commodity USB power supply. Since the ATtiny85 has an internal clock chip, it's easier to build a circuit (no external crystal). My original stop light controller was powered by an Arduino Micro (about $20). So I wanted this new controller to be smaller and cheaper. My total cost to replace the Micro was about $3.
Since I used only 5 outputs and no inputs for my light controller, the ATtiny85 is about the smallest and cheapest of the Atmel chips that will do the job.
First, to program the chip. I used a programmer shield, but you can use some hookup wire and do it yourself or build your own shield. Follow these directions if you want to take that route.
![]() |
| Program it! |
"
int Walk = 3;
int DontWalk = 4;
int Green = 0;
int Yellow = 1;
int Red = 2;
void setup()
{
pinMode(Walk, OUTPUT);
pinMode(DontWalk, OUTPUT);
pinMode(Green, OUTPUT);
pinMode(Yellow, OUTPUT);
pinMode(Red, OUTPUT);
}
void loop()
{
//HIGH = ON, LOW = OFF
digitalWrite(Walk, LOW);
digitalWrite(DontWalk, LOW);
digitalWrite(Green, LOW);
digitalWrite(Yellow, LOW);
digitalWrite(Red, LOW);
digitalWrite(Green, HIGH);
digitalWrite(Walk, HIGH);
delay(800);
digitalWrite(Walk, LOW);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(50);
digitalWrite(DontWalk, LOW);
delay(50);
digitalWrite(DontWalk, HIGH);
delay(200);
digitalWrite(Green, LOW);
digitalWrite(Yellow, HIGH);
delay(350);
digitalWrite(Yellow, LOW);
digitalWrite(Red, HIGH);
delay(1200);
}
"
Now to breadboard it. Follow this pinout guide to wire it up. Here I used LEDs to take the place of the relay outputs to see if it looked like a stop light and to test my timings. Since my relays are triggered by a "high" signal, when the LED is on, the relay would be triggered to send the high voltage to the light.
It works! Now to solder.
![]() | |
| Top of the board |
![]() |
| Bottom, my lackluster soldering skills... |
Here is the final, ready to be buttoned up project.
Provided you don't need a bunch of inputs/outputs the ATtiny might be a cost, and perhaps more importantly size, effective solution.
Here's the Fritzing diagram:
Subscribe to:
Posts (Atom)


















