Digital Aquarium

For this project, I used an arduino, tilt sensor, photocell, and LOLshield to create a digital aquarium. At rest, the fish sits peacefully in its tank. If the tank is disturbed, the water flows and the fish swims around. The fish can also be fed food by placing your hand at the opening of the tank.


Fish at rest


Food dropping in

The animation was created using the LOLshield theater. A photo cell was used to control the food animation, and the tilt sensor for the fish swimming.

The video in this post is a slight upgrade to what I showed in class. The animation was originally kind of confusing, because the water flow didn’t include the fish and wasn’t at the same height as the “fish at rest” position. I tweaked it so that the fish swam around when the tank was disturbed, which usually is what happens when you shake/tap a fish tank.

To make this project a bit better, I need to fix a couple of the dead LEDs that are on the board. I’d also like to change the interior of the tank; maybe framing the LOL shield in a castle, and placing the castle on gravel/marbles and using blue tissue paper. The vase does look better than my first enclosure though. It was a plastic cube, see below.


#include <Charliplexing.h> //Imports the library, which needs to be

byte line = 0; //Row counter
char buffer[10];
int value;

int buttonPin = A4; // the number of the pushbutton pin
int photoPin = A5; // photocell pin
int val = 0; // value of photocell input
int buttonState = 0; // variable for reading the pushbutton status

void setup()
{
 Serial.begin(9600);
 LedSign::Init(); //Initializes the screen
 // initialize the LED pin as an output:

// initialize the pushbutton pin as an input:
 pinMode(buttonPin, INPUT);
 pinMode(photoPin, INPUT);
}

void loop(){
 // read the state of the pushbutton value:
 buttonState = digitalRead(buttonPin);
 val = analogRead(photoPin);
 Serial.println(val);

// check if the pushbutton is pressed.
 // if it is, the buttonState is HIGH:
 if (val <=600){
 eat();
 }

 if (buttonState == HIGH) {
 Serial.println("look at fish");

delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);

 }
 else {
 Serial.println("sea is flowing");

delay(700);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(9284);
 DisplayBitMap(13926);
 DisplayBitMap(16383);
 delay(700);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(2184);
 DisplayBitMap(11468);
 DisplayBitMap(16383);
 delay(700);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(4369);
 DisplayBitMap(6553);
 DisplayBitMap(16383);
 delay(700);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 delay(700);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(2184);
 DisplayBitMap(3276);
 DisplayBitMap(16383);

 }
}

void DisplayBitMap(int lineint)
{
 //int data[9] = {95, 247, 123, 511, 255, 1, 5, 31, 15};

 //for(line = 0; line < 9; line++) {
 for (byte led=0; led<14; ++led) {
 if (lineint & (1<<led)) {
 LedSign::Set(led, line, 1);
 } else {
 LedSign::Set(led, line, 0);
 }
 }

 line++;
 if(line >= 9) line = 0;
}

void eat()
{
 delay(100);
 DisplayBitMap(16);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(16);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1108);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9846);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(16);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(29);
 DisplayBitMap(30);
 DisplayBitMap(13);
 delay(100);
 DisplayBitMap(0);
 DisplayBitMap(0);
 DisplayBitMap(1092);
 DisplayBitMap(9830);
 DisplayBitMap(16383);
 DisplayBitMap(0);
 DisplayBitMap(13);
 DisplayBitMap(30);
 DisplayBitMap(13);
}