Tuesday, September 21, 2010

Hacking the WRT54G(L) Serial Port

or "How to Get Your Router to Talk to Your Arduino"

Two weeks ago was another De Anza electronics swap meet, so my father and I went for a day of digging through boxes of junk trying to find something actually worth money.  I hit the jackpot with a WRT54Gv2, which was before LinkSys switched that line over to VxWorks and started the WRT54GL line to continue the Linux-based line.

As the saying goes - If it's electronic, we can hack it.  If it runs Linux, it's really easy.

The WRT54 motherboard breaks out two 115k 3.3V serial ports.  A classic first hack is to solder on headers, and install a daughter board with a RS232 driver, and a DB-9 port on the outside of the case.  I'm thinking about eventually doing this, but for my first experiment, I kept the serial port at TTL levels and fed it into my Arduino to print on an HD44780 LCD screen.

Video:
 
 Errata: I'm talking about volts at the end.  The Arduino runs at 5 [volts].
Note that the Arduino board is just there as a convenient 5V power supply for the ATMega on the breadboard (which is running Arduino software, and is therefore still technically an Arduino-based platform).

The WRT54G runs at 3.3V, which means its serial port runs at the same.  Ideally, I would have the AVR running at 3V as well, but none of my LCD screens would run at 3V, so I VERY CAREFULLY kept the two systems at different voltages.  Since I am only passing information from the WRT54G to the Arduino, the difference between a 3V high and a 5V high signal is insignificant.  Going the other direction would require a voltage divider at the very least to keep the 5V from the AVR from doing very unfriendly things to the WRT mobo.

Specs:
WRT54Gv2 running Tomato 1.28
The serial port 0-out is JP1-pin 4 and runs at (115200, 8, N, 1)
I used pin 10 on the same jumper as a ground reference
The serial ports are /dev/tts/0 and /dev/tts/1, and can be treated just like every other file in *nix.
The demo command I demonstrated in the video was:
# echo "This is a test message" > /dev/tts/0
Source code running on Arduino.

20 comments:

  1. This is very timely - I've been building a Arduino-based controller for my remote ham station (turn the radio on/off, kill power if transmitter gets stuck on transmit, switch antennas, etc.) I could run this by sending serial commands from the computer in the remote hamshack, but that requires the PC to be working. My remote hamshack's internet router is a WRT-54Gv2 running DD-WRT. I went looking for info on how to hack a serial port on it to talk to the arduino, and Jackpot! Thanks for the ideas.

    ReplyDelete
  2. Perfect. With the brcm cross-compiler, you could also make a nicer interface than SSHing into the router and echoing things to the serial port, writing it in C or otherwise. Do note that the 0 serial port prints debug info during boot, so I would use the 1 port first for other projects.

    ReplyDelete
  3. Awesome demo. I'm doing the exact same thing to control 7 servos, a bunch of sensors, ip cam and motors in a robot with a logitech game pad. This might help you out with the 3.3 to 5V conversion.
    http://store.curiousinventor.com/spk-wrt/spk-wrt-serial-port-kit-for-wrt54g-router.html

    ReplyDelete
  4. @James: That kit is for converting to RS-232, which I already have the parts for, but that doesn't do me any good for 0,5V (RS-232 is -12,12V). All it'll really take is a divider network on the input to the router.

    ReplyDelete
  5. Ken:
    You've just landed a big one with that one. Nice job. I imagine you've read the pages our friend Mr. Whitby over in Oz has written on how to do that? Of course you have. But to get yours to talk to an Arduino, that's sweet. Now if you could get the two to do something, that would be worth diamonds.

    ReplyDelete
  6. @Gregg: Whitby definitely got me off the ground for this one. I like said in the post, I'm thinking about following his tutorial in the future if a specific need for it arises.

    ReplyDelete
  7. Here we are just about six months later and again an idea surfaces:
    Can your Arduino code be used for other things besides communicating with your WRT54GL?

    Granted that's the obvious one, but my router sadly isn't that guy, and I'm not ready for one here like it........

    ReplyDelete
  8. Pardon me, eighteen months later. Dratted time travel, gets me out of synch with modern local methods of keeping time.

    ReplyDelete
  9. The code does little more than listen on a serial port and display it on an LCD. It would work with anything with a serial port; computers, routers, Chumbys, other microcontrollers, etc.

    ReplyDelete
  10. You can use a Logic Level Converter for the TTL voltage difference. Available here: http://www.sparkfun.com/products/8745

    ReplyDelete
  11. What timing source are you using for your ATMega? Are you using a UART friendly frequency multiple or something else? Any serial errors at 115k? I'm trying to determine how accurate I need to be with my ATMega's timing because I'm going to be doing a lot of 115k serial communication between it and the WRT. 100% UART friendly resonators with built-in caps are hard to come by but the regular 16 Mhz or whatever are easy to get. Although at 16 Mhz the error is pretty high at 115200 baud, I don't know if that works or not, hence this question.

    ReplyDelete
  12. @Chris: I've used both 8MHz and 16MHz crystals to drive 115k serial before. For slower speeds I've gotten away with using the internal RC clock source, but as high as 115k that's out of the question.

    ReplyDelete
  13. argh! it's wrt54, not iPod :-)
    Kenneth, why can't you power your arduino from a 3.3v power supply? Wouldn't this make the whole life easier? I played with my ipod's connector. When I shorten pins 1 and 13 I can see some rubbish in minicom. Besides, when I shorten 12 and 13 pins I can see echo in minicom, so my ipod's serial port is there!
    I just wrote a small program for my attiny2313 to print out a string once a second to UART port, which is connected to iPod's RX. However, I can't see anything in minicom. Even rubbish. Is there any simple way to check if there's anything on the UART TX? (I don't have oscilloscope or logic analyzer).
    The thing is I am using 3.3V to power attiny. Could it affect the internal oscillator? Tomorrow I am going to get a 8MHz oscillator, but i just saw the previous comment by Chris. Are there any restrictions or special requirement if I am going to run serial communications at 9600 only? What's the correct way of connecting oscillator to the uC?

    ReplyDelete
  14. You can power the Arduino from 3.3V, but the Arduino board proper will sometimes get a little cranky if you're not running it at 5V (if memory serves; haven't tried this in years), and most HD44780 modules are strictly 5V, which was the limiting factor in this case.

    Seeing nothing on a serial monitor usually means you have mismatched baud rates. If the UART doesn't see correctly formed start, stop, and parity bits, it may throw the byte away entirely, so you need to make sure that you're setting both ends to the same baud rate (and sometimes round the other direction for your math for the AVR UART clock divider chain - 8MHz doesn't tend to divide evenly into UART speeds like 11.0592MHz does).

    The ATTiny2313 datasheet may have information on the stability of the RC oscillator vs voltage, but in any case the RC oscillator is simply less than ideal for asynchronous protocols. You will need to hook a 8MHz crystal between XTAL1 and XTAL2, or if you're using an external 8MHz oscillator, feed it into... whichever of the two happens to be the clock input, which should be stated in the first paragraph or so in the datasheet under "System Clock - Crystal Oscillator" and you will need to correctly reburn the AVR's fuses to use the newly available clock source.

    ReplyDelete
  15. is it possible to share serial port through TCP (with ser2net/socat etc) ?

    ReplyDelete
    Replies
    1. I would expect so. Once you get the tool chain running, either porting some sort of SLIP daemon, setting up ppp, or even writing your own protocol shouldn't be too hard. As far as I've tested it, it's a standard TTL serial port.

      Delete
  16. my WRT54G has 12v power adapter, what if i use the same adapter to power arduino and the router ? I want to power up both from same adapter.

    ReplyDelete
    Replies
    1. Sure. I bought a 5.5mmx2.1mm splitter on eBay and use one power supply to run several routers, switches, personal projects, etc. Just make sure not to overload the current rating.

      Delete
  17. This comment has been removed by the author.

    ReplyDelete
  18. Hey im trying to communicate with my serial port on my WRT54G v2 and am having difficulty, i have a MAX233 chip and wired everything up as per specs, but not seeing boot information on the terminal nor echo commands, please help going round in circles

    ReplyDelete