Project tutorial

Aquarium Controlling and Monitoring Using Arduino + 1Sheeld

ET fishbowl is a smart controlled robot that automatically feeds your fish at a given time and controls light, oxygen, filter & water level.

  • 1,744 views
  • 1 comment
  • 9 respects

Components and supplies

Apps and online services

About this project

Here is a smart, controlled fishbowl for beginners with full description in the video. The ET fishbowl is a smart, controlled robot that automatically feeds your fish at a given time and controls the light, oxygen, filter, water level, and can add or remove water all by itself using Arduino + 1Sheeld.

Full instructions are provided in the following video:

Functions

  • Control light
  • Control oxygen
  • Control filter
  • Auto-feeder (dropping fish food at a certain time)
  • Add and remove water
  • LCD display (read temperature and water level)

The auto-feeder is a really useful feature. You could use it if:

  • You are forgetful
  • Are busy and/or working all the time
  • Are on vacation and need to feed the fish when you aren't there.
  • Want the best care for your fishes.

All steps have been written in detail so as to make it as easy as possible for anyone to make this themselves!

Step 1: Materials and Project Details

Skills Required:

  • Experience with Arduino and electronics.
  • Experience with coding.

Materials:

  • An Arduino Board: I used ARDUINO UNO
  • 1Sheeld board
  • Smart phone
  • Bulb
  • 6 channel relay
  • Fishbowl
  • Filter
  • Servo motor
  • LM35
  • power supply 24v DC

Step 2: Download Arduino and 1Sheeld Application

Download the Arduino application from the following link: https://www.arduino.cc/en/Main/Software. And download the 1Sheeld application onto your smartphone from the play store.

Step 3: Download 1Sheeld Library

Download the 1Sheeld Library from the following link: https://1sheeld.com/downloads/

Step 4: Extract 1Sheeld Library Files

  • Extract 1Sheeld library files
  • Open Arduino libraries
  • Make a new folder
  • Rename it onesheeld
  • Past extracted 1Sheeld library files on it

Step 5: Select the Required Shields from 1Sheeld Application

  • TEXT_TO_SPEECH_SHIELD
  • VOICE_RECOGNIZER_SHIELD
  • GAMEPAD_SHIELD
  • TERMINAL_SHIELD
  • LCD_SHIELD
  • SLIDER_SHIELD
  • CLOCK_SHIELD

Initialize Arduino pins:

 int bulb_pin=13;               // connect relay_bulb to pin 13;
 int filter_pin=11;             // connect filter to pin 11;
 int oxygen_pin=4;              // connect oxygen_pin to pin 9; 

Initialize Arduino pins as (INPUT OR OUTPUT):

 pinMode(filter_pin,OUTPUT);    // Set the filter_pin as output;
 pinMode(oxygen_pin,OUTPUT);    // Set the filter_pin as output;
 pinMode(bulb_pin,OUTPUT);      // Set the bulb_pin as output; 

How to Control the Light, Oxygen and Filter

Using the Clock Shield

  • Select the required shield from 1Sheeld application in smart phone. We must define it in Arduino:
 #define INCLUDE_CLOCK_SHIELD
  • We must select hour, minute and second in Arduino:
 hour = Clock.getHours(); 
 minute = Clock.getMinutes(); 
 second = Clock.getSeconds();
 if(hour == xx && minute == xx && second == xx) //change hours, minute,second to the desired time;  
 {  
// code                   //fully described in the code;
 } 
if(hour == xx && minute == xx && second == xx )  //change hours, minute,second to the desired time;
 { 
//code                    //fully described in the code;
 } 

Using the Gamepad Shield

  • Select the required shield from 1Sheeld application in smart phone. Define it in Arduino code:
 #define INCLUDE_GAMEPAD_SHIELD
  • Open and close filter using the Orange button and close it again using the same button.
 if ( (GamePad.isOrangePressed()) && (change_button_state_O==0) )
  { 
open and close filter           / /  fully described in the code;
  }
  • Open and close bulb using the Red button and close it again using the same button.
 if ( GamePad.isRedPressed() && change_button_state_R==0) 
{
 open and close bulb      / /  fully described in the code
}
  • Open and close oxygen using the Green button and close it again using the same button.
 if ( GamePad.isGreenPressed() && change_button_state_G==0)
 { 
open and close oxygen         / /  fully described in the code
 } 

Using { VOICE_RECOGNIZER_SHIELD} and {TEXT_TO_SPEECH_SHIELD}

  • Select the required shield from 1Sheeld application in smart phone.
 #define INCLUDE_TEXT_TO_SPEECH_SHIELD 
 #define INCLUDE_VOICE_RECOGNIZER_SHIELD 
  • Choose Voice commands:
const char firstCommand[]="hello"; 
const char secondCommand[]="control servo";
const char thirdCommand[]="turn on light"; 
const char fourthCommand[]="turn off light"; 
const char fifthCommand[]="turn on filter";
const char sixthCommand[]="turn off filter"; 
const char oxygen_openCommand[]="turn on oxygen"; 
const char oxygen_closeCommand[]="turn off oxygen"; 
const char seventhCommand[]="add"; 
const char eighthCommand[]="remove"; 
const char ninthCommand[]="yes";
const char tenthCommand[]="no"; 
  • Set a certain individual function written by the user in the sketch to be called and run its functionality once a new command is given.
 VoiceRecognition.setOnNewCommand(&myFunction);
 void myFunction (char *commandSpoken)
 { 
// control light, oxygen and filter using voice recognition     / /  fully described in the code
 } 

How the Feeder Works

Using the Clock Shield

  • Select the required shield from 1sheeld application in smart phone. Define it in Arduino:
 #define INCLUDE_CLOCK_SHIELD 
  • We must select hour, minute and second in Arduino:
hour = Clock.getHours();  
minute = Clock.getMinutes(); 
second = Clock.getSeconds(); 
 if(hour == xx && minute == xx&& second == xx)  // change hours, minute,second to the desired time  
 { 
// code           / /  fully described in the code  (control servo position)</p><p>  
 } 
if(hour == xx && minute == xx && second == xx )      
 { 
//code           / /  fully described in the code   (control servo position)
 }  
  • Include servo library:
 #include <Servo.h>
  • Put a variable to store servo position:
 int pos = 0;                   // variable to store the servo position
  • Attach the servo on pin 9 to the servo object:
 myservo.attach(9);             // attaches the servo on pin 9 to the servo object

Using the Slider Shield

  • Select the required shield from 1Sheeld application in smart phone. Define it in Arduino code:
 #define INCLUDE_SLIDER_SHIELD
  • Set a certain individual function written by the user in the sketch to be called and run its functionality once a slider position is changed giving a new value.
 Slider.setOnValueChange(&servo);
  • Put the following function outside the loop:
 void servo (byte sliderValue) 
 {  
 pos=sliderValue*90/255;       // scale convert from (0 to 255) to (0 to 90 degree)  
 myservo.write(pos);          // tell servo to go to position in variable 'pos'    
 delay(2); 
} 

How to Use the LCD

We are using an LCD to show the degree of temperature and water level retrieved from the LM35 and water level sensors.

  • Select the required shield from 1Sheeld application in smart phone. Define it in Arduino code:
 #define INCLUDE_LCD_SHIELD
  • Initialize temperature pin:
 int tempPin = A0;              // lm35 temperature sensor is connected to pin A0
  • Initialize water level sensor pin:
 int water_sensor = A1;         // water level sensor is connected to pin A1
  • LCD code:
 LCD.setCursor(0,0);              //Set the cursor to begin writing from the first row and first column.
 LCD.print("temp = ");  
 int value = analogRead(tempPin);  
 float mv = ( value/1024.0)*5000; 
 float cel = mv/10;  LCD.setCursor(0,7);               // Set the cursor to begin writing from the first row and 8 column.  LCD.print(cel);                   // Print cel value 
 LCD.setCursor(1,0);               // Set the cursor to begin writing from the second row and first column.  
 LCD.print("water level= ");        // Print water level= .
 LCD.setCursor(1,12);             // Set the cursor to begin writing from the second row and column 13.  LCD.print( analogRead(A1));       // Print water level value .

How to Use the Pump

We are using a pump to add and remove water.

Using the Gamepad

  • Select the required shield from 1sheeld application in smart phone.
#define INCLUDE_GAMEPAD_SHIELD
  • Add and remove water using the up and down arrows.
if(GamePad.isUpPressed())             // start adding water
   {
   //code       / /  fully described in the code</p><p> 
   }
if(GamePad.isDownPressed())           // start removing water    
  {   
   //code       / /  fully described in the code
  }
  • Stop adding and removing water using the Blue button.
if ( GamePad.isBluePressed() )           // stop adding or removing water
{  
//code    / /  fully described in the code 
}

Using the Voice Recognizer

This is fully described in the code.

Code

ET_FISHBOWL.inoC/C++
#define CUSTOM_SETTINGS
#define INCLUDE_CLOCK_SHIELD
#define INCLUDE_TEXT_TO_SPEECH_SHIELD
#define INCLUDE_VOICE_RECOGNIZER_SHIELD
#define INCLUDE_GAMEPAD_SHIELD
#define INCLUDE_TERMINAL_SHIELD
#define INCLUDE_LCD_SHIELD
#define INCLUDE_SLIDER_SHIELD


#include <OneSheeld.h>         // Include 1Sheeld library
#include <Servo.h>             // Include  servo  library 
Servo myservo;                 // create servo object to control a servo 






int hour, minute, second;      // Define some variables for the date and time
int bulb_pin=13;               // connect relay_bulb to pin 13
int oxygen_pin = 12;           // connect oxygen pin to pin 12
int filter_pin=11;             // connect filter to pin 11
int pump_add=8;                // connect pump_add to pin 8
int pump_remove=7;             // connect pump_remove to pin 7
int tempPin = A0;              // lm35 temperature sensor is connected to pin A0
int number_of_liters;
int pos = 0;                   // variable to store the servo position 
int change_button_state_O=0;
int change_button_state_R=0;
int change_button_state_G=0;

/* Voice commands set by the user. */
const char firstCommand[]="hello";
const char secondCommand[]="control servo";
const char thirdCommand[]="turn on light";
const char fourthCommand[]="turn off light";
const char fifthCommand[]="turn on filter";
const char sixthCommand[]="turn off filter";
const char oxygen_openCommand[]="turn on oxygen";
const char oxygen_closeCommand[]="turn off oxygen";
const char seventhCommand[]="add";
const char eighthCommand[]="remove";
const char ninthCommand[]="yes";
const char tenthCommand[]="no";

void setup() 

{
     


  OneSheeld.begin();              // Start communication.
  LCD.begin();                    // Begin the LCD cursor at the first row and first column.
  Clock.queryDateAndTime();
  myservo.attach(9);              // attaches the servo on pin 9 to the servo object 
  myservo.write(0);               // intial servo position 

  pinMode(buttonPin,INPUT);       // Set the button_pin as input
  pinMode(push_button,INPUT);     // Set the button_pin as input
  pinMode(bulb_pin,OUTPUT);       // Set the bulb_pin as output
  pinMode(filter_pin,OUTPUT);     // Set the filter_pin as output
  pinMode(oxygen_pin,OUTPUT);     // Set the filter_pin as output
  pinMode(pump_add,OUTPUT);       // Set the pump_add as output
  pinMode(pump_remove,OUTPUT);    // Set the pump_remove as output
  pinMode(tempPin,INPUT);         // Set the tempPin as INPUT

  
}

void loop() 
{
VoiceRecognition.setOnNewCommand(&myFunction);   //myFunction exists under the loop function. This function will be invoked each time a new command is given

 Slider.setOnValueChange(&servo);

/* use these three functions to repeat every day */
  hour = Clock.getHours();
  minute = Clock.getMinutes();
  second = Clock.getSeconds();
  
/* in the next two IF statment we can use all our functions such as lighting bulb ,stop filter,etc...
   at a constant time  
*/
  if(hour == 17 && minute == 36 && second == 10 )  //first if statment
  {
   digitalWrite(bulb_pin,HIGH);          //open the bulb
   digitalWrite(filter_pin,LOW);         //close the filter
   digitalWrite(oxygen_pin,LOW);         //close the oxygen

  for(pos = 0; pos <= 90; pos += 1)      // servo goes from 0 degrees to 90 degrees 
  {                                      // in steps of 1 degree 
     myservo.write(pos);                 // tell servo to go to position in variable 'pos' 
     delay(2);                           // waits 2ms for the servo to reach the position 
    }  
    OneSheeld.delay(2500);               //wait 1000 ms = 1 secound to drop food, change the time and the servo angle according to the flow rate of food
    for(pos = 90; pos>=0; pos-=1)        // goes from 90 degrees to 0 degrees 
    {                                
     myservo.write(pos);                 // tell servo to go to position in variable 'pos' 
     delay(2);                           // waits 2ms for the servo to reach the position 
    } 

  }
  
  if(hour == 22 && minute == 30 && second == 50 )    //secound if statment
  {
    digitalWrite(bulb_pin,LOW);         //close the bulb
    digitalWrite(filter_pin,HIGH);      //open the filter
    digitalWrite(oxygen_pin,HIGH);      //open the oxygen


    OneSheeld.delay(50);
  }


//------------------------------------------------------------------------------------------------------------
//                                               control using gamepad
//------------------------------------------------------------------------------------------------------------
 if ( (GamePad.isOrangePressed()) && (change_button_state_O==0) )
  {
digitalWrite(filter_pin,HIGH);
change_button_state_O=1;                 // allow same button to open and close the filter
delay(150);
  }
  else if  ( (GamePad.isOrangePressed()) && (change_button_state_O==1) )
  {
digitalWrite(filter_pin,LOW);
change_button_state_O=0;                // allow same button to open and close the filter
delay(150);
  }
 //--------------------------------------------------------------------------------------------------------------
   if ( GamePad.isRedPressed() && change_button_state_R==0)
  {
    digitalWrite(bulb_pin,HIGH);
    change_button_state_R=1;      // allow same button to open and close the bulb
    delay(150);
  }
   else if  ( GamePad.isRedPressed() && change_button_state_R==1)
  {
    digitalWrite(bulb_pin,LOW);
    change_button_state_R=0;     // allow same button to open and close the bulb
    delay(150);
  } 
 //--------------------------------------------------------------------------------------------------------------
 if ( GamePad.isGreenPressed() && change_button_state_G==0)
  {
    digitalWrite(oxygen_pin,HIGH);
    change_button_state_G=1;                 // allow same button to open and close the oxygen
    delay(150);
  }
else if  ( GamePad.isGreenPressed() && change_button_state_G==1)
  {
    digitalWrite(oxygen_pin,LOW);
    change_button_state_G=0;                // allow same button to open and close the oxygen
    delay(150);
  }
 //--------------------------------------------------------------------------------------------------------------
   if ( GamePad.isBluePressed() )
  {
    digitalWrite(pump_add,LOW);
    digitalWrite(pump_remove,LOW);
    delay(150);
  }
 //--------------------------------------------------------------------------------------------------------------
    if(GamePad.isUpPressed())
    {
    digitalWrite(pump_add,HIGH);
    delay(150);

    }
//--------------------------------------------------------------------------------------------------------------
    if(GamePad.isDownPressed())
    {
    digitalWrite(pump_remove,HIGH);
    delay(150);

    }
//--------------------------------------------------------------------------------------------------------------

 
//------------------------------------------------------------------------------------------------------------
//                                        print temprature readings and water level on lcd
//------------------------------------------------------------------------------------------------------------
 LCD.setCursor(0,0);              //Set the cursor to begin writing from the first row and first column.
 LCD.print("temp = ");
 int value = analogRead(tempPin); 
 float mv = ( value/1024.0)*5000; 
 float cel = mv/10;
 LCD.setCursor(0,7);               // Set the cursor to begin writing from the first row and 8 column.
 LCD.print(cel);                   // Print cel value
 LCD.setCursor(1,0);               // Set the cursor to begin writing from the second row and first column.
 LCD.print("water level= ");       // Print water level= .
 LCD.setCursor(1,12);              // Set the cursor to begin writing from the second row and column 13.
 LCD.print( analogRead(A1));       // Print water level value .

 //------------------------------------------------------------------------------------------------------------

}

//------------------------------------------------------------------------------------------------------------
//                                               **ouside void loop**
//------------------------------------------------------------------------------------------------------------

void myFunction (char *commandSpoken)
{
 
  /* Print out the command spoken. */
  int num = atoi(commandSpoken);    // Converts string to int  and If no valid conversion could be performed, it returns zero.
  Terminal.println(num);
  
    Terminal.println(commandSpoken);
if( (num !=0) )                            
  {
    TextToSpeech.say("did you say  ");
    delay(1500);
    TextToSpeech.say(commandSpoken);
    delay(1000);
    TextToSpeech.say("liter of water ");
    delay(1500);
    number_of_liters=num;
  }
 
 else if( num==0 )                                                   /*num value equal zero in case of commandspoken is not a number  (int num = atoi(commandSpoken);
                                                                       i.e. voice recognizer save  the numbers as a words not as Numerals.
                                                                       i.e. commandSpoken = two  not (2)
                                                                                                                                                                */
 {
  
if(!strcmp(firstCommand,VoiceRecognition.getLastCommand()))          // Check if the voice command is the desired one.
     {
       TextToSpeech.say("hello sir ");                               // 1Sheeld responds using text-to-speech.
     }
else if(!strcmp(thirdCommand,VoiceRecognition.getLastCommand()))     
     {
       TextToSpeech.say("light turns on");
       digitalWrite(bulb_pin,HIGH);    //open the bulb 
       change_button_state_R=1;
     }
else if(!strcmp(fourthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("light turns off");
       digitalWrite(bulb_pin,LOW);    //close the bulb 
       change_button_state_R=0;
     }
else if(!strcmp(fifthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("filter turns on");
       digitalWrite(filter_pin,HIGH);     //open the filter
       change_button_state_O=1;
     }
else if(!strcmp(sixthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("filter turns off");
       digitalWrite(filter_pin,LOW);     //close the filter
       change_button_state_O=0;          
     }    
else if(!strcmp(oxygen_openCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("oxygen turns on");
       digitalWrite(oxygen_pin,HIGH);      //open the oxygen
       change_button_state_G=1;           
     }
else if(!strcmp(oxygen_closeCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("oxygen turns off");
       digitalWrite(oxygen_pin,LOW);      //close the oxygen
       change_button_state_G=0;             
     }
else if(!strcmp(seventhCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say(" start adding water ");
       digitalWrite(pump_add,HIGH);     //open  the pump                
       delay((number_of_liters/4)*60000);                              //my dc pump flow rate: 4L/MIN ,  so i used  num/4 to know how much time i need .
       digitalWrite(pump_add,LOW);     //close the filter
     }
else if(!strcmp(eighthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("start removing water");
       digitalWrite(pump_remove,HIGH);
       delay((number_of_liters/4)*60000);                             //my dc pump flow rate: 4L/MIN ,  so i used  num/4 to know how much time i need .
       digitalWrite(pump_remove,LOW);
     }
else if(!strcmp(ninthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("you want to add or remove water ");
     }
else if(!strcmp(tenthCommand,VoiceRecognition.getLastCommand()))
     {
       TextToSpeech.say("enter the number again");
     }
/*------------------------------------------------------------------------------------------------------------------
 sometimes voice recognizer spells the numbers as a words not as Numerals.
 i.e. one =1 ,two =2 ,.....,five=5.
  -------------------------------------------------------------------------------------------------------------------*/
else if(!strcmp("one",VoiceRecognition.getLastCommand()))
     {
    select_number(1);   //call select_number function and store 1 in (num) variable
     }
else if(!strcmp("two",VoiceRecognition.getLastCommand()))
     {
    select_number(2);   //call select_number function and store 2 in (num) variable
     }
else if(!strcmp("three",VoiceRecognition.getLastCommand()))
     {
    select_number(3);    //call select_number function and store 3 in (num) variable
     }
else if(!strcmp("four",VoiceRecognition.getLastCommand()))
     {
    select_number(4);   //call select_number function and store 4 in (num) variable
     }
else if(!strcmp("five",VoiceRecognition.getLastCommand()))
     {
    select_number(5);  //call select_number function and store 5 in (num) variable
     }

 //------------------------------------------------------------------------------------------------------------------   
else
     {
       TextToSpeech.say("please enter a valid command ");     
     }                                                   
  } 
                                       
}
 //------------------------------------------------------------------------------------------------------------------   
 //                                                   now we are outside the voide loop
 //------------------------------------------------------------------------------------------------------------------ 
void select_number(int num)  // any number the user say will be understand and stored in " number_of_liters " variable
{
    TextToSpeech.say("did you say  ");
    delay(1500);
    TextToSpeech.say(VoiceRecognition.getLastCommand());
    delay(1000);
    TextToSpeech.say("liter of water ");
    delay(1500);
    number_of_liters=num; 
}
void servo (byte sliderValue) 
{

              pos=sliderValue*90/255;           // scale convert from (0 to 255) to (0 to 90 degree) 
              myservo.write(pos);               // tell servo to go to position in variable 'pos' 
              delay(2);
}

Schematics

fishbwol_bb_8kiftsvhDv.jpg
Fishbwol bb 8kiftsvhdv

Comments

Similar projects you might like

Smart Access [Home/Office Automation]

Project in progress by Ajmal Muhammad P

  • 1,554 views
  • 5 comments
  • 6 respects

Internal Timers of Arduino

Project tutorial by Marcazzan_M

  • 5,050 views
  • 10 comments
  • 35 respects

SPCPM (Solar Powered City Pollution Monitor)

Project tutorial by 5 developers

  • 3,565 views
  • 0 comments
  • 18 respects

Mini CNC Laser Wood Engraver and Laser Paper Cutter

Project tutorial by Maggie Shah

  • 4,417 views
  • 0 comments
  • 27 respects

Smart Talking Humanoid Robot Just with Arduino!

Project tutorial by ashraf_minhaj

  • 738 views
  • 2 comments
  • 9 respects

Sigfox kWh Meter

Project tutorial by jassak

  • 4,817 views
  • 3 comments
  • 12 respects
Add projectSign up / Login