If you’ve been interested in hacking and tinkering for a while, you’ve probably heard of UART or Universal Asynchronous Receiver-Transmitter. Arduino devices have become popular amongst tinkerers and circuit benders nowadays and the Arduino UNO is dirt cheap. Aside from the LED blinking and Servo motors control, Arduino UNO has a great feature some people don’t even know about – it can be used as a UART to USB adapter.
Most wireless routers have a few pads on the motherboard to which you can solder. They are called debug pins, debug pads, UART pads or simply serial ports. Of course, good luck finding a laptop with a real serial port nowadays. To interface with these pins and therefore to transmit and receive data from and to the router, you’d need to somehow pipe the data to USB. Solutions to this problem do exist – the so-called UART to USB converters or adapters. There are also badges providing such features with the ability to change the power output (3V, 5V, etc.). Of course, these do cost from a few dollars to a few dozens. So what can you do to interface with a router’s debug pads if you don’t have an FTDI adapter? Well, make one!
As I mentioned, Arduinos have the capacity to act like one. You normally connect the Arduino board to USB, so here’s your pipe, right? Well, not really. First, you need to get rid of the microcontroller because it would get in the way. There are many methods you can employ to do that, with physically taking off the chip being the worst one. We’re gonna use a simple yet effective one. The bridge.
The bridge method is simple. You take a male to male Arduino cable and bridge together the RESET and the GND. This will take the Atmel microcontroller out of the board and leave your FTDI to do its job. Now, we need to understand how the connection should look like.
The Arduino UNO has a Pin 0 and a Pin 1 labeled TX > and < RX. Pin 0 is RX or receive and Pin 1 is TX or Transmit. You would want to cross-connect them. By this, I mean that the RX of your Arduino should go to the TX of your router and the TX of your Arduino to the RX of the router, otherwise, both devices will try to transmit and receive on the same lines and it won’t work.
Mind the power!
Routers don’t run on high voltage! Most routers would run on approximately 3.5V. Having it connected to 5V might damage it permanently (or until you find the fried component and solder a replacement in – yeah, good luck with that) so please mind the power. Your Arduino is capable to provide power via the VCC pins. There are a +5V pin and a +3V pin on the Arduino board. If in doubt, use the +3V one first, although, I would highly recommend checking the schematics of the router first as you can easily FRY the router and I am not responsible for your damages.
Do not connect both the power adapter that came with the router and the power from Arduino. You will most likely fry the hell out of that router. Use either the Arduino for the power or the wall adapter, not both. Would probably be a good idea to measure the voltage first if you are planning to use a lab power supply. The following image shows which Arduino pins will be involved. I marked them with RED.
The exact order of the pins may vary and on most of the routers, it is not labeled so you must find which pin is TX, which is RX and which are VCC and GND. Goodling the schematics of your model certainly helps in many cases. For this example, we are going to use a TP-Link TL WR841N(D) which is a very common inexpensive router that can easily be flashed with OpenWRT or other open source firmware.
Let’s get to the action, I came to do damage!
So after popping up the plastic lid of the router, we have a PCB exposed. As we established, our demonstration model is TP-Link TL WR841N(D). Let’s see what we can find at a first look. The brain of this router seems to be QCA9533-BL3A by Qualcomm, it seems to have a single off-the-shelf SDRAM chip, a Winbond W9425G6KH-5 which appears to be 256Mb and the bootloader seems to be a version of U-Boot, this may come in handy down the road if we want to flash an open source firmware to the machine. For now, let’s just get a working serial output.
You can find information on the UART pinout of your router by either taking a look at data sheets, schematics or by using a multimeter. In my case, the order is from the top: VCC, GND, RX, and TX as shown in the photo below.
So after we’ve established which pad represents what, connect them to the Arduino device. In my case, I won’t solder anything. The male Arduino cables have pins on the ends and I can simply poke them into the holes. Be sure to not short circuit stuff tho. I will connect the VCC to the 3.3V pin of the Arduino, the GND to one of the GND pins of the Arduino, the TX of the router to the RX of the Arduino and the RX of the router to the TX of the Arduino. Then, I bridge the RESET and one of the GNDs of the Arduino to make it act like a UART to USB converter and we’re done. Connect it to USB, pop your favorite serial monitor (on macOS I use the built-in “screen”, on anything else I use Putty) and be amazed. The connection should look something akin to this.
Okay, so now it is the time to pop a connection. For this to work, we will need a few things in place. One, make sure you know the baud speed for your router. Mine operates at 9600 during U-Boot phase, then the kernel quickly changes it to 115200 so I will use the former. Also, you will need to disable flow control. On macOS, if you are using “screen” you can pass the “-ixoff” argument after the baud to disable this. Putty has a setting for it. Also, on Putty, set the Parity to “None”.
Since I’ll be doing this on my Mac, I first have to make sure that my Arduino IDE is installed (available for free on the official Arduino Website) and then I have to locate its serial port. This could be quite tricky. macOS doesn’t have a “Device Manager” like Windows does, so we need to use a terminal command. The command is “ls /dev/tty.*” or “ls /dev/cu.*”, depending on how is the Arduino registering itself. More than one device will appear. You can exclude them by running the command with the board connected and then running the command again without the Arduino connected. The one that disappears is the Arduino. In my case, the board identifies itself as “/dev/cu.usbmodem621”.
Now that I know how my Arduino is identifying itself to the computer, it’s time to build the command in terminal. It will look like this: “screen /dev/cu.usbmodem621 115200 -ixoff”. I make sure that everything is properly connected and I press enter, and bam!
As you can see, if your connections are correct, you should see a full debug output from your router. This can be used to pop a shell, flash the firmware, dump memory, control OpenWRT console and so on and so forth. I am sure you can find a use for it. By the way, congratulations on getting started with hardware tinkering 🙂