---------------------------------------------------------------------------------------------
A few of the geeks that I
Mr mightyOhm is also the admin of the Asus Wireless Router Hacks Flickr Pool. Check out a few of the cool things he and others have done with the wl-520gu.
Not to be out done, LadyAda hacked her 520gu and ported her tweet-a-watt xBee code in a 5 hour hack fest. That's her router picture over on the right. Click it and see a brief description of her efforts. She mentions this project on twitter and on flicker but I haven't seen it on her blog. I've been messing with Xbees lately and ladyada's hack is just what i need.
I've been thinking about a tweet-a-temperature project that would monitor my pool temperature and tweet it every so often during the summer months. While I'm toiling away in the office, I could get SMS spam telling how great life is outside work.
Or maybe a tweet-a-lert that let's me know when my super-sekret door has been opened. Or a tweet-a-stalk when a victim with Nike+ shoes runs by a sensor.
Let's lay down the foundation for a tweet-a-whatever (tweet-a-w/e) project by hooking an Xbee to the router and installing a Python client that tweets whatever is received.
Yes, this seems to be very similar to ladyada's tweet-a-watt port. I'm shamelessly copying the hard work of mightyOhm and adafruit to set this up. What's my value-add? I'll ramble a lot and tell you about all my dead-ends.
We'll take a wl-520gu router, install openWrt firmware and configure it as a wireless client to my existing house wireless network. Using the 520gu's serial port, I'll hook up an Xbee in an Adafruit adapter. Next, install Python on an automount USB drive and write a client that reads incoming Xbee data and does the tweet.
So I ordered a wl-520gu from newegg and eventually pretty much followed mightyOhm's instruction for installing header pins on the serial port and installing OpenWrt.
If you've read any of my other ramblings on this blog, you know already that I'm not very original and sometimes not very smart. But I'm decent at
Let's first talk about the stupid things I did so you can avoid the mistakes in life that I have made.
- Both mightyOhm and ladyada used OpenWrt by first flashing dd-wrt and then OpenWrt. Me? I choose to use tomato firmware instead because I wanted built-in USB support and the description of its feature sounded great. And because I wanted to waste 3 nights trying to configure it in wireless client mode. I'm not saying tomato is bad, I'm just saying that I struggled big time and I couldn't find many online tips. I finally said "uncle" and followed the mightyOhm's way and installed openWrt. And had it working in under a half-hour.
- Installing a four-pin header isn't a hard thing. All I had to do was remove 4 blobs of solder and then solder in a header. So ... Why did I somehow brick my router? I was super duper careful removing the blobs (without a de-solder-er iron or a bulb) and then was careful soldering in the pins. I only applied heat for a max of 5 seconds and let it cool for about 5-10 seconds before re-attempting. Yet I did it. After I finished the header, the darn thing wouldn't boot. Nothing, dead to the world. No reset, no LED action, nada. I cussed for a day or two and then ordered a new one from newegg. Before I de-blobbed the new one, I ran down to Rat Shack and bought a desoldering bulb. 20 minutes later, I had a working router - with header pins. Lesson? If at first you don't succeed, spend more money.
- With the default Asus firmware still installed, I found that logging in via telnet, the user/password was root/admin. Via the browser at 192.168.1.1:80, the user/password was admin/admin. Kinda odd, but maybe this tip will save you some hair.
On the 1st router that I bricked, I installed new firmware first, then tried to install the headers. On my working router, I did headers first, then firmware. I don't think it really matters what order you do this. But I ruined a $59 router, so you trusting me?
So do your own thing and follow mightyOhm's excellent instructions. Get headers on the serial port, install openWrt, and meet me back here in a few.
Back already? Good, you should have a router with OpenWrt that acts like a wireless client on your network. You should be able to wirelessly connect via telnet as well as via the serial port.
Yeah, I know the picture over there is kinda blurry but it's the best camera I have (donations accepted). If the picture was clear, you would see that I'm using a USB TTL-232 cable to talk to the router from a USB port to the router's shiny new headers. mightyOhm's picture on this page was very helpful for the pin-outs.
As is, the OpenWrt's filesystem is pretty cramped. There's not much space available to install extras such as Python. I had an extra Sandisk Cruzer laying around so I setup the router to automount the USB stick on /opt.
From either the serial line or a wireless telnet (my preference),
- Edit opkg config file to use kamikazi 8.09 packages.
- # vi /etc/opkg.conf
- Set the first line to this:
- src/gz snapshots http://downloads.openwrt.org/kamikaze/8.09/brcm-2.4/packages
- # opkg update
- # opkg install kmod-usb-core
- # opkg install kmod-usb-ohci
- # opkg install kmod-usb-storage
- # opkg install kmod-fs-vfat
- # opkg install kmod-fs-ext3
I want to install Python libraries and other extras on the USB drive so we'll need this auto-mounted at boot time. I couldn't locate clear instructions on this but here's what worked for me. Using tips from this place, I did:
- Create a mount point
- # mkdir /opt
- Create an /etc/rc.d/S11mount file with macsat.com contents from this page.
- NOTE: macsat's page references this as /etc/init.d/S11mount. For my version to work, I did not put it in init.d but instead put it in rc.d
- # vi /etc/rc.d/S11mount
- Paste in macsat's example S11mount content. My file version can be found here.
- change the MOUNT_DEVICE0 statement to match your device. My USB stick was exactly the same as his example.
- Edit opkg config file to create an alternative destination for packages
- # vi /etc/opkg.conf
- Add this line:
- dest opt /opt
- My copy of the opkg.conf file is here.
- export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/opt/usr/bin:/opt/usr/sbin
- export LD_LIBRARY_PATH=/lib:/usr/lib:/opt/usr/lib:/opt/lib
At this point, we have a flashed wl-520gu router with OpenWrt, headers soldered to serial port, and configured to mount a USB stick to opt at bootup. Let's keep mushing on.
The line that we added to the top of our opkg.conf file
- src/gz snapshots http://downloads.openwrt.org/kamikaze/8.09/brcm-2.4/packages
- # opkg update
- # opkg -d opt install python
- # python -V
Python 2.5.4Using the AdaFruit Xbee Adapter that I blogged about last year, the next step is to simply hook it up to the 4-pin serial headers. This is the easiest step of all. 4 wires, hook 'em up.
Since OpenWrt uses the serial port /dev/tts for console login, we need to modify the /etc/inittab file. All this takes is to comment out the tts line:
- wl-520gu GND -> Xbee GND
- wl-520gu 3V -> Xbee 3V
- wl-520gu TX -> Xbee RX
- wl-520gu RX -> Xbee TX
#tts/0::askfirst:/bin/ash --login
I'm using Python for the client app, so we need to install the pySerial module from SourceForge. Create a temp folder on /opt, CD to it, download pySerial, unzip, untar, and install
- # mkdir /opt/temp
- # cd /opt/temp
- # wget http://downloads.sourceforge.net/pyserial/pyserial-2.4.tar.gz
- # gunzip pyserial-2.4.tar.gz
- # tar xvf pyserial-2.4.tar
- # python setup.py install
reader.py
I've modified the reader.py quite a bit so that it tweets the received data, but the version above simply echoes the data to the terminal.
#!/usr/bin/env python import serial, time SERIALPORT = "/dev/tts/0" # the com/serial port the XBee is connected to BAUDRATE = 9600 # the baud rate we talk to the xbee TIMEOUT = 0.5 # the timeout to wait for buffer fill NUMCHARS = 140 # the number of characters to attempt to read at once # open up the FTDI serial port to get data transmitted to xbee print 'opening serial port ' + SERIALPORT ser = serial.Serial(SERIALPORT, BAUDRATE, timeout=TIMEOUT) ser.open() try: print 'entering read loop' while 1 > 0: data = ser.read(NUMCHARS) if len(data) > 0: print "Read " + data finally: print 'closing serial port' ser.close
Run it like this:
# python reader.pySend the Xbee data from another Xbee and watch it print.
Alright, I'm stopping and will pick up the story in my next entry. Look at this picture to see where we're going.
- Update: I've wrapped up this story in tweet-a-w/e foundation
What do you think? Leave a comment.