#fishtweet

Please note this project is 100% idle as I no longer have fish tanks available to me.  A friend is building an aquaponics green house – I hope to post more on the McYork blog page about possible adventures there.

Does your fish tank tweet?  This one will.  This project has been inspired as a learning experience.  I am not sure how the idea first came to me but it was just silly enough to say “ok that’s got to be done”.

How do you enable a fish tank to tweet?

The first step is to develop some parameters.  What will this really do?  It would be great if a hardware device could be attached to a fish tank… and that device could send tweets to Twitter.  Could the fish send a tweet themselves?  Maybe just start with a few buttons.  When pressed send out simple tweets?  When no tweets are sent sent for a while – this device could tweet spontaneously.  Button #1 might tweet “Thank you for feeding us” – fish are always hungry, #2 might tweet “Thank you for the water change”.  If left alone for a day maybe a tweet like “Hey we are getting hungry now!”.

You’d want to know more about the fish, right?  So how about adding a temperature sensor so each tweet could have a mini environment status too?  What about a light sensor?  What would a vibration sensor pick up?  Ok, add all those on and see if it can be made to work.

Parts were ordered.

Board with I2C connections
Board with I2C connections

Time passes.

Parts as they arrived were tested one at a time and a few in combination.  If memory serves the first items to arrive were the Arduino Duemilanove and the light sensor.  So those were tested.  Then the Arduino Ethernet Shield at a great store (due to impatience getting the best of me I went to a real store – and they are indeed great)  and I was able to send out the first few tweets from real hardware.  I found an old hobby servo and played with that for a while too (it may be incorporated later).

I was given a number of old phones… these have LCD displays in them.  Feature creep!

Yes I’ll need to figure out how to attach one of those displays to the project!  It turns out I learned about I2C protocol and how it could be used to reduce the number of dedicated pins needed for a display.  Looking through many web pages I found an I2C to LCD package and felt it was worth giving it a try – and bonus it has 5 additional inputs that can be read as buttons or switches too.

This is where you read “feature creep part 2”.  Parts were ordered.  Time passes.

There is sample code on the site where the I2C device came from.  This would test the displays from these old phones.  They did not work.  The displays had what looked like the correct number of pins but none of the sample code would get me any joy.  Time to look at this in a little more detail.  How does one figure out what pin in what?  Fortunately for me the main chip on the back of the LCD is easy enough to identify.  So I look up on the web now to read up on the HD44780A00 chip.  Some people don’t go this far – they just “ask the web” in some forum.  Persevere and you will learn cool things.  You often find the PDF with all the specs of a chip.  Even a light read will give you insight into how the chip enables the LCD display to do its real work.

Pin out of the HD447800A00 in hand, time to trace a few wires.  Testing pins to the chip for conductivity with my multimeter I found the data lines.  Odd they looked like they were shifted all one pin over.  This would not leave room for the standard GND pin on a common display.  Further testing showed me that all the pins were shifted one position. The GND pin was not on the end it should have been but rather moved to the other end.

Easy now all I had to do was insert the display shifted by one pin, and run a jumper around for the GND and maybe it will work!  By this point I had pulled down sample code from the Arduino site and had a bread boad setup to drive all the pins (the I2C would be next once I had some solid proof the LCD would work at all).

The I2C worked great once I figured out the resistors properly (for the bus).  It was clear that if this LCD driver had 5 additional inputs… I should use them.  If you did not think this was geeky enough – now it turns very geeky.

Let’s use the 5 inputs with toggle switches.  5 in a row.  Lined up like that we could assign them each a binary value.  You could toggle in a binary code with the 5 switches and then EXECUTE the code with a button. So now we have something like 32 commands we can give the device.  Imagine how chatty the fish will be when they have 32 different things they can say.  Personalized tweets!

“Thank you, Mark, for feeding us”

“Thank you, Michael, for the water change”

Bought toggle switch on the way home that day!  Wired them up and it worked.  The sample code for the LCD device also was aware of the buttons.  The values were on the display before I knew it.  This will work for sure.

By now I started to ask myself “how will all this be put together?”.  You are starting to get to know me more when I say… LASER cut metal and plastic had been something I had been DYING to have an excuse to try out.  No not buy a LASER (but that would be cool).  Design then order on-line.  I had a site all picked out from bookmarks from the past (knowing I use it someday).

The site was great – it had help files and templates and made the work easy.  One problem.  The part was going to cost maybe $25 to make and $80+ more to ship.  Umm – maybe that’s normal?  Well if you live in Canada and the part comes from New Zealand – guess what – shipping is crazy expensive.

So now I knew I had to find a solution closer to home.  A little searching and I found http://www.pololu.com/.  They have a custom cutting service and they were exactly what I had imagined a great service would be. I was so waiting for the mail that week.

Nothing happened over night.  Let’s be clear here.  This project from day one until when I got to the point where the hardware was 1.0 ready – it’s been a year!  For a while I had to pack it all up, for a while I was waiting on parts, for a while I was skiing and not so active with a soldering iron.  Add to that – this only gets worked on in spare time on sunny days when I can enjoy the front deck – so rarely.

One last item.  I felt a project like this needed some sort of blinking light.  How else would you know it is on, thinking, and watching the fish.  Once I learned about I2C I started to see all sorts of products.  BlinkM jumped out as a “gotta try one of those”.  Played with it for a while.  Tested it out.  Still not sure how to use it.  Now it is wired up and mounted in a cool old lamp holder steam punk like thing.

Everything along the way was assembled one part at a time.  Some re-dos and oops that’s backwards, but over time and at this point I declared the hardware project to be done.  So I dug up some old Ethernet code and had the hardware tweet this milstone.

Now #fishtweet it is a software project!

Um one little problem… One inovation along the way was to hook the Execute button to pin 2 (Interrupt 0) of the Arduino.  Have you heard of bounce?  Well the button I used has a good chunk of bounce.  I attacked this is software for a few days, then became frustrated by the limitations and assumption that were needed to make a clean button press.  Can I de-bounce in hardware?  Apparently, but how.  I got my basic understanding here and then slightly overwhelmed went to my favourite local electronics store to ask, “really how do I do this de-bounce thing the easy way”.

I am sure it is a hack (because I am sure I did not fully understand the answer) but I did get 2 resistors and a capacitor – wired them up and – all the bounce was gone.  I am trying to learn this program fritzing to document the little things (if not the whole project).  When I get the time… I’ll have some proper diagrams of the as built project if I can.

Here in the story I declare the hardware project really over.

Let’s start on software.

The code I used to text and fix the button de-bounce will make a good base.  The project’s core interaction element with humans is the button.

Here is the final code that worked for button testing.

//Execute button is on  pin 2 interrupt 0
 const int button = 2;          // Interrupt  connected button on digital pin 2
 const int button_interrupt = 0; //  digital pin 2 has interrupt value 0
// inside an interrupt  service routine you need to assume a volatile variable
 int volatile  isr_state = false;
int button_press = false;
// uncomment  this line to turn on compiled DEBUG serial data.
 // #define DEBUG
 #ifdef  DEBUG
 long temp;
 #endif
void setup() {
 //init the  Execute button to be an input and activate the pullup in chip
pinMode(button,  INPUT);           // set pin to input
 digitalWrite(button,  HIGH);       // turn on pullup resistors
//attach the ISR for pin  2 (int0) to button_isr()
 attachInterrupt(button_interrupt,button_isr,FALLING);
//  attach to the serial port at this speed
 Serial.begin(19200);
}
//  this is all there is in the interrupt service routine (ISR)
 // just  set that fact that we were here to true in the ist_state variable
 void  button_isr() {
 isr_state = true;
 }
void loop() {
 //  when in debug mode I like to kow the length of time the mail loop takes  top tp bottom
 // so I can tune it for speed (some day).
 #ifdef  DEBUG
 temp = millis();
 #endif
// did the ISR_trigger?   If so clear the isr_state variable and set
 // the button press state  to true
 if (isr_state) {
 button_press = true;
 isr_state = false;
 }
// if the button was pressed do some  work here
 if (button_press) {
 #ifdef DEBUG
 Serial.print("Loop time: ");
 Serial.print(millis() - temp);
 #else
 Serial.print(millis());
 #endif
 Serial.print("\n");
 button_press = false;
 }
} 

Leave a Reply