everyone is making things that connect to twitter. the arduino environment makes it easy to interface hardware to the internet. this, plus a strong disdain for twitter, was all that was necessary to turn a joke into reality: a toilet that will post to twitter with every flush. hey, it's more useful and relevant than just about everything else on twitter!
i figured nobody would mind at the hacklab if i wired up the toilet, so off i went...
what could possibly go wrong?
there's really not a whole lot of hardware involved (so far):
the arduino ethernet interface is very simple (in theory). the shield is simple and quick to assemble, and the wiznet module just plugs in to it. the shield then attaches to the arduino.
there were a couple of modifications i needed to make. i added female connectors (such as the ones found on the arduino board itself) to the pin pass-through connectors; i don't know why any connectors didn't come with the shield. i also moved the reset wire to the same solder joint where it connects with the under-board pin, so that i could fit an entire row of connectors in.
i just attached the arduino to the wall using a couple of screws through the screw holes. no fancy enclosure, just the board, shield, and module, connected to power, ethernet, and (next up) the switch.
the arduino wired to the wall, complete with power and ethernet.
using a small bit of perfboard, i wired up a mercury tilt switch, and two resistors, as described in the well-known ladyada arduino tutorial. the board has three wires: one to connect to an arduino input pin, one to connect to +5V, and one to connect to ground. a 100 ohm resistor is connected to the input wire, and a 10K pull-down resistor to ground.
for a schematic, take a peek here.
i wrapped the board with switch in tape in order to prevent it from shorting on the metal flush lever, then used a zip tie and a piece of string to tie it on. it's attached in such a way that when the flush lever is pushed down, the switch is activated; this took a small amount of adjustment of the switch bulb on the board, but wasn't difficult.
the mercury switch connected to the flush lever.
this is where i learned about switch debouncing in an easy and over-exaggerated manner. pushing down the lever causes quite a bit of jiggling of the mercury in the bulb, and i didn't want it to send the go-ahead to post to twitter multiple times for each flush. using the button and debounce tutorials as my guide, i made sure that there was an adequate debounce time for reading from the switch input. in this case, since we're not worried about a toilet being flushed multiple times in quick succession, i used 3 seconds as the debounce time.
i'll admit it... i wanted to do this quickly. i assumed that someone on the interwebs had already written some code to do this, and in the spirit of open source, posted it for all to see.
i was right!
using this code as a template (of which some parts seem to have been borrowed from the arduino ethernet library reference), i was able to quickly generate the HTTP POST needed to send a message to twitter.
but, that's not to say it worked flawlessly the first time...
i'm sorry, i have to go debug the toilet...
my debugging environment. note the fancy toilet paper under the screwdriver.
so then i ran into a problem. the toilet was working.... sometimes. it would always read the switch input correctly, but it would often have problems posting the message to twitter.
i was able to identify a few distinct problems:
fortunately, the only extra networking equipment i could find for the ethernet connection was a hub, so it wasn't a big deal to fire up wireshark and do some packet sniffing.
(why did i need networking equipment in the first place? to share the network connection already wired in to the bathroom for the laser, of course.)
packet sniffing and googling led me to some observations:
it turns out these are issues that are being openly worked on now. etracer writes on the arduino forum about a solution to (most of) these issues here. specifically, he(?) revised the Client.cpp file from the ethernet library to fix issues with closing connections, which he posted here. replacing the official ethernet library code with this code (and deleting the compiled .o file to force it to recompile) fixed the issues with the four connection limit.
as for the buffering, the problem was discussed on the forum here, and phil/follower did a nice writeup and fix which he wrote about here. this isn't a huge concern because it doesn't need to be super fast or efficient, but it's good to know and understand why the network traffic was so crazy.
originally, the code had 8 different strings that it would randomly select from when posting to twitter. i decided these were getting old fast, and wanted to add a whole lot more. after bringing the number up to about 50, the arduino started exhibiting very odd behavior when i tried to get it to run. sometimes the LED connected to pin 13 would go crazy, sometimes it would display junk out the serial interface.
another quick bit of research using google, and i discovered the reason for this is that variable strings will generally go in the RAM section of memory, which is limited to 1k on the ATmega168. using too much memory here causes all sorts of not-so-fun things to happen. to fix this, the strings need to be put in the program memory. information on the memory types can be found here, while code examples of how to use the PROGMEM declaration to get variables into program memory can be found here.
...and with that, it works! flushing will trigger the arduino to fire off a random message to twitter, updating its status.
the possibilities are endless, and some sensors have been ordered and shipped. i hope they get here soon, as i'd like to expand the functionality of this project! right now, some ideas are:
i'll keep this page updated as the sensors are attached!
UPDATE 5/18/09: some sensors have arrived, now working on testing them!
questions, comments, "what the hell, you must have been really bored" messages, and the like are welcome: firstname.lastname@example.org.
and now, the information you've been waiting for. if you want to follow the hacklab.TOilet: hacklab.TOilet on twitter.
i'll be posting code as soon as i have a chance to clean it up, credit the parts i stole from tutorials and other people, and generally make it less embarassing and more presentable. which is very important when dealing with code that controls a toilet sensor. if it's not here soon (today is almost may 5, 2009), feel free to send me hate mail or surprise me with a hopper loaded shmooball launcher.
UPDATE: i didn't clean up the code yet but i'm also terrible
at doing this quickly, so here is what
i've got. note all the
stolenborrowed and credited
code. yes, it's ugly and embarassing, but this is what's made the toilet
if you'd like to leave a comment, please click here to go to the hacklab blog!
have a nice day!