Raspberry Pi I/O Expander Board

To simplify using the the MCP23017 I/O Expander on the Raspberry Pi I’ve made a little plug in board using a  Slice of Pi from Ciseco. The Slice of Pi is a handy little PCB that plugs directly onto the Raspberry Pi’s GPIO pins and gives a convenient row of labelled standard 0.1 inch (2.54mm) headers for the built in GPIO, SPI and I2C pins, a small prototyping area and optionally headers for plugging in an XBee style wireless devices such as the XRF, XBee, RN-XV etc. It’s not expensive at £3.90 plus postage either. (Update 27/7/12 – Ciseco are now doing an MCP23017 specific board called the Slice of PI/O, here is a comparison of the two)

I’ve fitted a 28 pin DIL socket to it for the MCP23017 and connected power and the SCL and SDA pins from the Pi as well as the required lines to switch it on and set the I2C address (fixed to 0x20). I’ve also added two sets of 0.1″ headers for the 16 I/O pins.

The result is a simple plug in expander board that can provide up to 16 inputs or outputs that can sink or source up to 25mA each, more than the 16mA of the Pi’s own GPIO pins and safer, the MCP23017 costs less than £1 and if you do accidentally blow it up and can just be popped out and a new one popped in. Along with the Python tools I’m working on I’m hoping this will be useful to help provide a simple, low cost and relatively safe way for people to experiment with connecting other hardware to the Raspberry Pi.

Here’s the layout of the board and the required connections as well as pictures of the front and back of the finished board:
Note: Make sure pins 15,16,17 of the MCP23017 all connected to ground (the 3 pins top left of the diagram, shown linked in blue).

  

Using it

I’ve tried to make this a simple step by step guide but I didn’t take notes when doing it so it has been done from memory, please let me know if I’ve left anything out or if something isn’t clear.

To use this you will need a Raspberry Pi with the Debian Squeeze distro and a kernel that supports I2C.  Update 28/7/12: If you are using the new Raspbian image this is much easier and doesn’t need a replacement kernel, see the instructions in this comment below.

You can get the source for a suitable kernel here or you can use one that I’ve already compiled by copying this kernel.img to /boot and extract this modules tar.gz file to /lib/modules/

eg.

wget http://nathan.chantrell.net/downloads/raspberry_pi/3.2.18+/kernel.img
wget http://nathan.chantrell.net/downloads/raspberry_pi/3.2.18+/3.2.18+_modules.tar.gz
sudo chown root:root kernel.img

sudo mv kernel.img /boot/
tar zxvf 3.2.18+_modules.tar.gz
sudo chown -R root:root 3.2.18+

sudo mv 3.2.18+ /lib/modules/

To get the I2C device driver to load on boot you will need to edit /etc/modules and add new line containing i2c-dev. Otherwise you can do sudo modprobe i2c-dev to load it manually each time you boot the Pi.

Reboot now so that you are using the new kernel and install the i2c-tools package with:

 sudo apt-get install i2c-tools

To give your regular user account permission to use the expander add it to the i2c group with:

 sudo adduser your-userid i2c

and you should now be able to do i2cdetect -y 0 (use i2cdetect -y 1 if you have one of the new revision 2 Raspberry Pis with mounting holes and marked as made in the UK) and see the expander is located at address 0x20 as below:

nsc@raspberrypi:~$ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

A previous post explained how you can go on to use i2c-tools to control the MCP23017 or read on to find out how you can use the Python tools I’m working on. So far they are only working for output but I plan on extended them to cover input as well.

 

Command Line Tool

To use my Python command line tool you will need to install the python-smbus python module with:

sudo apt-get install python-smbus

then download my script and make it executable with: chmod +x mcp23017.py

Note: If you are using one of the new revision 2 Raspberry Pis you will need to change the line bus = smbus.SMBus(0) to bus = smbus.SMBus(1)

To test it connect an LED with the cathode (short leg) to ground and the anode (long leg) connected via a resistor to the port marked GPA0 in the diagram above. To calculate the resistor required for your LED see this page or if you don’t know the resistors specification a 220 Ohm resistor should be safe for a 3mm or 5mm LED.

and then try the following to make GPA0 high (ie. 5v) and turn the LED on:

 ./mcp23017.py -b a -o 0 -s high

you should get a response of  “Output GPA0 changed to high” and the LED will turn on. To turn it off:

 ./mcp23017.py -b a -o 0 -s low

 

Web Interface:

To use the initial version of the web interface that I’m working on then you will also need the python-smbus package so if you didn’t install that above do so now:

sudo apt-get install python-smbus

next install the apache webserver:

sudo apt-get install apache2

I got an error that Apache failed to start as there is no www-data group, you can fix this with:

sudo addgroup www-data
sudo adduser www-data www-data

Now install mod-wsgi with:

sudo apt-get install libapache2-mod-wsgi

enable the module with:

sudo a2enmod wsgi

and then edit /etc/apache2/sites-available/default and under the <Directory /var/www/> section add ExecCGI to the end of the Options line and before </Directory> add AddHandler wsgi-script .wsgi so it reads:

<Directory /var/www/>
 Options Indexes FollowSymLinks MultiViews ExecCGI
 AllowOverride None
 Order allow,deny
 allow from all
 AddHandler wsgi-script .wsgi
</Directory>

Start apache with /etc/init.d/apache2 start or if it was already running reload it with /etc/init.d/apache2 reload

Next you will need to add the apache user (www-data on Debian) to the i2c group with:

sudo adduser www-data i2c

Then download my mcp23017.wsgi script and copy to /var/www/

Note: If you are using one of the new revision 2 Raspberry Pis you will need to change the line bus = smbus.SMBus(0) to bus = smbus.SMBus(1)

To test it use a web browser to go to http://ip.of.raspberry.pi/mcp23017.wsgi eg. http://127.0.0.1/mcp23017.wsgi if you are doing it locally on the Pi itself.

Select which bank you want to operate A or B, which output 0-7 and whether you want to set it high or low and click submit, eg. to set GPA0 high select A, 0 and high.

Hopefully I’ve not missed any steps out there but let me know if I have.

 

Python Library (to do)

Once I’ve got some code done for inputs I’m going to have a look at turning all this into a Python library to make it easier to integrate into your own programs.

 

UPDATE 10/6/12: For more information on using I2C devices at different voltages with the Raspberry Pi and how to use this board with an external supply see this post.

63 thoughts on “Raspberry Pi I/O Expander Board

  1. hi

    quick question, you write there “To test it connect an LED with the cathode (short leg) to ground and the anode (long leg) connected via a resistor to the port marked GPA0″ why you don’t use the 3.3V instead of the 5V, so you need no resistor for the LED?

  2. Hi Cola, Depending on the LED you *might* get away without a resistor at 3v3 but it’s more to do with the current an LED can draw than the voltage supplied, simply speaking it’s possible for an LED to draw enough current to destroy itself. For a more detailed explanation have a look at: http://tinkerlog.com/2009/04/05/driving-an-led-with-or-without-a-resistor/

    The main reason I went with the 5v supply though is that you can only draw 50mA from the 3v3 pin on the Pi, not a lot when shared over a potential 16 outputs. The 5v pin on the other hand can supply whatever the input can less what the Pi and any peripherals are drawing, given a 1A supply this will typically leave you with around 300mA to play with. You can power the expander chip and the outputs with an external supply to get more or a different voltage but I wanted to keep it straightforward for now.

    Cheers,
    Nathan

  3. Turns out the production boards are being fitted with a 700mA polyfuse on the input so the elinux site is wrong on the current available from the 5v pin, the maximum is more likely to be in the region of 150-250mA, maybe less depending on the devices plugged into the Pi. More here.

  4. I’ve made the circuit, completed the Command Line Tool and Web Interface – it all works – Thank you.

    I can take my project forward in a few areas myself but, if you were posting details on inputting, it would be very useful.

  5. Looking for help on debugging. i2cdetect doesn’t see the expander.

    I got an error message when executing sudo mv kernel.img /boot/ something about failing to preserve ownership.

    dmesg gives [don’t know what this means but saw it in an RPi forum post – http://www.raspberrypi.org/phpBB3/viewtopic.php?f=44&t=10301

    bcm2708_i2c bcm2708_i2c.0: BSC0 Controller at 0x20205000 (irq 79)
    bcm2708_i2c bcm2708_i2c.1: BSC1 Controller at 0x20804000 (irq 79)

    but no

    bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)

    Have carefully checked breadboard connections.

    Any ideas?

  6. > I got an error message when executing sudo mv kernel.img /boot/ something about failing to preserve ownership.

    That’s nothing to worry about.

    > bcm2708_i2c bcm2708_i2c.0: BSC0 Controller at 0x20205000 (irq 79)
    > bcm2708_i2c bcm2708_i2c.1: BSC1 Controller at 0x20804000 (irq 79)

    That’s good.

    > bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)

    That’s ok too, I didn’t compile that kernel with SPI support.

    Have you done “modprobe i2c-dev” what happens when you do?

  7. Nathan,

    I changed the owner and group for the contents of lib/modules/3.2.18+ to root:root (they were both my user) and success, the expander appears just as you show above. Now to start flashing my LEDs!

  8. Crikey: me a total linux innocent got it to work! I used the SK Pang starter kit and your wiring from the May 19th post.

    A couple of ‘challenges’ though. First up, the ‘sudo mv’ commands in lines 3 and 5 of your linux command list did not work: suspected I needed to be in root, but had no idea what the root password was. Quick search of Pi forum (search ‘root password’) and on to the Wiki, supplied the answer: basically, the Debian distro does not have one (strange?) and you create one yourself! Created one, and as root, the mv commands were good.

    Second up, bit of confusion with ‘modprobe i2c-dev’. I needed ‘sudo’ before it to get it to work. Also, if you use modprobe, when rebooting (as in your following para), ‘sudo modprobe (etc)’ needs to be typed again, otherwise you get ‘not found’ errors. Obvious? Yeah, probably, but not to me initially! (I’m still wary of manually editing system files.)

    Have also noted the discussion on Pi and i2c voltages, so tried 3v3 from RPi P1-pin 1 to Vdd on the MCP23017. Worked fine, led a little less bright perhaps. Guess it would not work with a lot of leds, though.

    Now onto the led chaser project and trying to figure out what’s going on in your python script (I seem to have misplaced the brain cell holding bitwise operations.) And a tutorial for i2c, and …. it’s a fun beasty, this Pi!

  9. I got the MCP23017 working with 5V, but it runs REALLY hot – is this normal? I also tried to use the 3V3 instead, but it is not stable. i2cdetect shows either :

    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — — — — — — — — — — — — —
    10: — — — — — — — — — — — — — — — —
    20: — — — — — — — 27 — — — — — — — —
    30: — — — — — — — — — — — — — — — —
    40: — — — — — — — — — — — — — — — —
    50: — — — — — — — — — — — — — — — —
    60: — — — — — — — — — — — — — — — —
    70: — — — — — — — —

    or

    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — — — — — — — — — — — — —
    10: — — — — — — — — — — — — — — — —
    20: 20 — — — — — — — — — — — — — — —
    30: — — — — — — — — — — — — — — — —
    40: — — — — — — — — — — — — — — — —
    50: — — — — — — — — — — — — — — — —
    60: — — — — — — — — — — — — — — — —
    70: — — — — — — — —

    or sometimes a combination! Any ideas?

  10. Hi, why the terminal says :
    ./mcp23017.py: line 4: syntax error near unexpected token `newline’
    ./mcp23017.py: line 4: `’

    when I try to execute this: ./mcp23017.py -b b -o 7 -s high ?
    Many thanks!

  11. @Pine, Great, glad you got there and thanks for the feedback, really appreciate it. I’m guessing the error with copying the kernel over to /boot was “failed to preserve ownership”, if so it was actually copying the file but just warning that owner had been changed (to root in this case). I’ve updated the instructions to include a “chown” to explicitly change ownership to root before moving so you don’t get that (also fixes issue mentioned by Graeme above).

    Have also added sudo to the modprobe command, you’re correct that you will have to do that on each boot, that’s what I meant when I said if you want to load it on boot you need to edit /etc/modules. I think I’ve clarified that a bit now too.

    @Andy It shouldn’t run hot on 5v no, is there a short somewhere maybe?

    Have you got pins 15,16,17 of the MCP23017 all connected to ground (the 3 pins top left in my diagram), it’s easy to miss and if they were left floating (ie. not connected) that could explain the hardware address changing I suppose.

    @Federico How did you get the script onto the Pi? It sounds like you might have a Windows line ending in there, try copying it over again by running this on the Pi:
    wget https://raw.github.com/nathanchantrell/Python-MCP230XX/master/mcp23017.py

  12. it works!Thank you very much Nathan!
    Waiting for the inputs reading for completing your wonderful work!

  13. Ah yes, pins 15,16 and 17 were floating! It now works fine on 3V3 and the chip stays cool, but it still gets extremely hot when connected to the 5V pin on the PI (all other connections were the same). I guess I will stick to using the 3V3 supply. Thanks.

  14. Hi, Nathan, another question for you: i’ve bought a relay board from Ciseco Shop. Can I easily control that board through the mcp23017 controller? Many thanks,

  15. Nathan, glad the comments were useful.

    Do you know of a tutorial for python-smbus or smbus itself? The man pages and python help function are not too informative. I found a web page here http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc which gave a summary of the commands, and have managed to figure out the read_byte_data function – it basically seems to be:

    Aval = bus.read_byte_data(0x20,0x12)

    for GPA (assuming address = 0x20 and you’ve called the instance of smbus.SMBus(0) ‘bus’). For GPB change the second parameter to 0x13.

    Looking at the above page, there’s an intriguing range of other commands – block read/write, word read/write etc. And how to make the interupts work? I’ve looked at the data sheet for the mcp23017 but would appreciate something a little less terse!

  16. Nathan,

    “problem reading SD Status register” stopped my first SD card from booting. Just installed the Raspian image and this will not boot following your instructions to load a new kernel. Any thoughts?

  17. Just got round to trying the Raspbian image, the good news is the kernel already has i2c support built in so no need to replace the kernel & modules, all you need to do to enable i2c is:

    1. edit /etc/modprobe.d/raspi-blacklist.conf and comment out the line: blacklist i2c-bcm2708
    2. edit /etc/modules and add new line containing: i2c-dev

    Then you can jump straight to installing the i2c-tools in the instructions above.

    and for anyone using the Edimax EW-7811Un Wi-Fi adapter the script and driver in this post works fine on Raspbian:
    http://www.raspberrypi.org/phpBB3/viewtopic.php?f=26&t=6256&start=525

    The Raspbian raspi-config tool will be handy for people not familiar with Linux too. Great to see all this stuff getting easier so quickly.

    PS. Miles at Ciseco was kind enough to post me a few samples of the new Slice of PI/O board to try, I’ll update when I’ve got one built.

  18. Nathan,
    Do you know if there is an ic for ADC(analog to digital) with i2c that will work with raspberry pi? The other option is to all add an ADC to this IC ..
    Do you where i can get it?

  19. Hi Nathan,

    Thanks for the update on using i2c with the new Raspian image. I downloaded and burnt the image to SD card, and then attempted to follow your guidance above. A couple of ‘challenges’, so some clarifications for my fellow linux innocenti:
    1. to edit the two files (I used nano), you need to use sudo as prefix.
    2. sudo apt-get install i2c-tools failed for me with error http://mirrordirector.raspian.org/ …. (etcetera) 404 not found.
    Maybe the site & page was temporarily down, but the error message suggested trying ‘sudo apt-get update’ which I did, and there after ‘sudo apt-get install i2c-tools’ worked fine.
    So now my led-flashing (output) and button-pressing routines (input) work fine.

    From the little playing I’ve done, the Raspian distro looks to be an improvement over the original ‘wheezy’, so I’d recommend folks upgrade. It’s faster, there’s direct access from the desktop to python IDLEs and I’ve noticed less problems with missing keystrokes when typing (this was driving me mad!)

    Had to larf at the comment in the raspi-blacklist.conf file, tho’ that most people won’t need i2c so we’ll blacklist it! I cannot get my head around this attitude. Wonder what else has been hidden?

  20. Pine,
    I am getting a following after a i2cdetect -y 0. I have used the raspbain image and have followed all instructions. Can you tell what you
    did so I can follow your steps. I will recheck the wiring..

    pi@raspberrypi ~ $ i2cdetect -y 0
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — — — — — — — — — — — — —
    10: — — — — — — — — — — — — — — — —
    20: — — — — — — — — — — — — — — — —
    30: — — — — — — — — — — — — — — — —
    40: — — — — — — — — — — — — — — — —
    50: — — — — — — — — — — — — — — — —
    60: — — — — — — — — — — — — — — — —
    70: — — — — — — — —

    Thanks for any help

  21. pine/nathan,
    I just figure it out. i wired the SDA and SCL to the same pin on the chip. I now see the chip:

    pi@raspberrypi ~ $ i2cdetect -y 0
    0 1 2 3 4 5 6 7 8 9 a b c d e f
    00: — — — — — — — — — — — — —
    10: — — — — — — — — — — — — — — — —
    20: 20 — — — — — — — — — — — — — — —
    30: — — — — — — — — — — — — — — — —
    40: — — — — — — — — — — — — — — — —
    50: — — — — — — — — — — — — — — — —
    60: — — — — — — — — — — — — — — — —
    70: — — — — — — — —

    On to LED. I have 330ohms 1/2 watt. Does this resistor work or do I need 1/6 watt?

    Thanks for the help

    Rahul

  22. Nathan,
    Any chance you can look at SPI communication from raspberry pi using the MOIS, MISO, CLK and CS pins. i have an MCP3008(ADC) and am not able to read data from this IC…

    Thanks
    Rahul

  23. Great blog, any news on the input side… i have just got the MCP23017 working for output but would love input as well.

    Rich

  24. Hi Nathan, I’ve noticed a gotcha whic is probably prudent to mention which affects both your project and the Slice of PI / O. I constructed the dedicated board and then proceeded to test but couldn’t get it to show up using I2CDetect. Been soldering for 45 years plus so didn’t suspect my skills but didn’t re-flow each joint just in case. I noticed that I have one of the new made in UK boards (from Sony here in Wales) and whic is a revision 2 board. Remembered reading something On the pi blog, sure enough in Revision 2 boards they have swapped the Priimary and Secondary I2C channels, so for Revision 2 boards where it says a zero in the I2CDetect command in your text, this should now be a one I.e. I2CDetect -y 1

  25. Hi,

    it is normal that my MCP23017 change address after few minutes or if i use it ?

    i2cdetect -y 0

    change address 0x20, 0x25, 0x27 :(

    Miro

  26. Hi Nathan

    Great project – Got it working on both old and new Pi’s without any problems – (after changing changing smbus.SMBus(0) to bus = smbus.SMBus(1))- I have also got inputing working.

    However

    import getopt

    Can you explain why this is needed – I am new to Python and want to understand your program in detail
    Regards
    Nigel

  27. Nathan, thanks,

    now it is work perfect but it is strange because I bought prototype with MCP23017 and pins is not connected to the ground.

    thanks again,

    Miro

  28. Hi Pine,

    do you have button input implement in pythone ? I would like to implement button. Press the button and turn on the LED. Press button again and trun the LED off.

    Thanks,

    Miro

  29. GREAT blog, thank you :)

    So I’ve successfully built the LED Chaser project (as per the SKPang page) and now I’m tinkering with the individual LEDs using:

    ./mcp23017.py -b a -o 0 -s high

    I’m just trying to make different patterns / effects really.

    The question I have, can I safely “light” all 16 LEDs at the same time, or do I risk breaking something?

    Thanks again :)

  30. I see Adafruit have now got a Python library available for controlling the MCP230xx with support for inputs and outputs. More info here: http://learn.adafruit.com/mcp230xx-gpio-expander-on-the-raspberry-pi/using-the-library

    @Rich You probably want to run the MCP23017 from an external supply for that, the amount of available current on the Pi 5V output is going to depend on what else you have plugged into it, the power supply for the Pi and the polyfuse, it’s probably somewhere between 150 and 300mA so I think 16 LEDs will be pushing it.

  31. Miro (early Oct), sorry for delay – been busy doing Pi things! The latch button you want to make is not too difficult. There’s good articles on the basics under In Control in the MagPi on-line magazine (google it if you’ve not seen it) and issue 3 (I think) deals with button pushes and leds. You could adapt their code so that first button push sets a variable which turns an led on, then a seond push clears the variable, so the led turns off.

    Cheers, Pine

  32. Hi Nathan,

    Just loaded the latest Wheezy Raspian image (as it supposedly simplifies wifi connection), so I’m back looking at your pages remembering how to install 12c, smbus etc.

    One change I found: i2cdetect-y 0 now requires root account or to be prefixed by sudo.

    Wish they’d stop that ….!

  33. There is just one thing I don’t understand about this board. If the MCP23017 is powered at 5V, how can it connect to the RPi I2C pins without some form of level shifting? Nothing is mentioned about this in the writeup.

  34. HI,
    is it possible to connect and read values from 1-wire devices such as ds18b20 to I/O ports of this board?
    I’m planning to use this board with Seagate Dockstar for my SmartHouse project.

  35. Nathan,

    Many thanks for the reply and for the link to the article explaining why connection to the RPi is safe.

    I should have realised that SDA and SCL would be open drain with I2C being (what people of my generation call) a multi-drop bus.

    Again thanks for the reply and for the original article which I am confident will be of use to many.

    John.

  36. Hi Nathan,

    Thanks for writing this guide, it’s very helpful, though I’m having a little trouble at the end. I’ve followed the guide all the way but when I go to ip/mcp23017.wsgi I get a 500 internal server error whether I do it internally (from the pi itself using its 127.x.x.x ip) or externally (from my regular work station using a static ip assigned to the pi). Any idea where I might have forgotten something or screwed up to cause this to happen? As far as I know I’ve done everything exactly as written. It’s a rev 2 rPi if that helps.

    Thanks.

  37. Scratch the question, got it working, my boss had accidentally copied in some random code to the start of mcp23017. Took me forever to figure that one out! When in doubt, blame user error.

  38. Hi Nathan,
    Thanks for your excellent work! Sometimes when using your mcp23017.py script, the entire bank goes to low when just targeting one pin. Do you know why?

    Thanks.

  39. Ok I figured it out.
    I was able to fix the problem by moving the bus set to open from line 14&15 to line 75. It appears that if you try to open a bus for output on a newly initialized IC then it sets everything to low.

  40. I’m getting an error 404 Not Found on the libapache2-mod-wsgi install… any ideas where else I can get this from, or if it’s been updated?

    Great blog by the way. Thanks in advance!

  41. Perfect.. I did spot that in an earlier comment but I was trying “sudo apt-get update libapache2-mod-wsgi”

    Thanks for a great write up, and quick backup assistant to go with it!!!!

  42. i need more information around the web server to control the i2c , i not understand how i can control the i/o thanks

  43. I have a question, I am attempting to write a python code on a website to control my PC desk, I need numerous buttons to access the GPIO, can you help me get started.

    Regards Mike

  44. Hi,

    I am getting the below error when trying to set the gpio to high using this command:

    sudo ./mcp23017.py -b a -o 0 -s high

    Error:

    Traceback (most recent call last):
    File “./mcp23017.py”, line 14, in
    bus.write_byte_data(0x20,0x00,0x00) # Set all of bank A to outputs
    IOError: [Errno 5] Input/output error

    Any idea what might be causing this?

  45. So I’ve just tried to do another install on a new Pi, and for some reason I’m getting a 403 error when attempting to access the ‘mcp23017.wsgi’. I’ve tried from local on the pi, and from my laptop. Been over the tutorial lots of times, so I’m just wondering if something has changed in a newer apache release? Any help would be really appreciated!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.