Plug and Play Aquarium Maintenance

Ashwin Vadivel and Niko Maheras

Background and Purpose

Fish waste decays into ammonia and further into nitrites and nitrate. This is a flow-through water change method to maintain certain water parameters constant. The goal is to reduce human intervention for tank maintenance and provide data about the whole system.

Required Hardware

  • List Wires
  • List Protoboard
  • List Mbed lpc1768
  • List 5 peristaltic pumps
  • List Tubing
  • List 3 Tpc6612 motor driver
  • List Pushbutton
  • List SD file breakout board

Pins

/media/uploads/avadivel3/pic.png

High Level Architecture

/media/uploads/avadivel3/snip.png

Software

The software can be thought of as two threads: Thread A and Thread B. Thread A’s top priority is to ensure that the fresh water reservoir remains full at all times. Once that condition is met, it will control freshwater top off from the fresh water reservoir to the display tank and saltwater reservoir. Thread B is responsible for the water exchange between the display tank and waste water reservoir. Flow rate sensors are used to ensure that the exchange is not bias one way or the other.

Project Idea

/media/uploads/avadivel3/agua.png

Prototype

/media/uploads/avadivel3/wx1.png /media/uploads/avadivel3/aqua.png /media/uploads/avadivel3/aqua1.png

Future Work

  • List Create saltwater with saline solution and commence water change procedure.
  • List Provide user-friendly LCD screen and web GUI.

Code

4180_final_project

#include "mbed.h"
#include "TB6612FNG.h"
//#include "SDFileSystem.h"
#include "rtos.h"
 
//SDFileSystem sd(p5, p6, p7, p8, "sd"); // the pinout on the mbed Cool Components workshop board
Thread thread;
Thread test_thread;
// -------------------available pins--------------------------------
//__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __ ,__,__,__,__
// -------------------------------------------------------------

//direction pins
DigitalOut idir1(p9);
DigitalOut idir2(p10);
DigitalOut i2_dir1(p27);
DigitalOut i2_dir2(p28);
DigitalOut i3_dir1(p30);
DigitalOut i3_dir2(p17);

//in Thread thread;
DigitalOut wc2_dir1(p19); //SOLDER
DigitalOut wc2_dir2(p20); //SOLDER

DigitalOut wc1_dir1(p12); //SOLDER
DigitalOut wc1_dir2(p13); //SOLDER

//pushbutton to stop program execution
DigitalIn pb(p29);

//pwm out to motors
PwmOut ipwm(p21);
PwmOut i2_pwm(p22);
PwmOut i3_pwm(p23);

//in Thread thread;
PwmOut wc_in_pwm(p24);
PwmOut wc_out_pwm(p25);

//standby pins
DigitalOut istdby(p11);
//DigitalOut set2_istdby(p18);
DigitalOut i2stdby(p14);
DigitalOut i3stdby(p18);

//water level sensors
DigitalIn water_level_fw_reservoir(p15);
DigitalIn water_level_display_tank(p16);
DigitalIn salt_mix_reservoir(p26);

//flow rate (L/ # of days)
float flow_rate_L_num_days = 50;

//timespan (# of days)
int days = 1;
int sec_days = days * 86400;

//vol of 2s pump (L)
float two_s_pump_volume_L = 0.002;

//pc serial connection
Serial pc(USBTX, USBRX); // tx, rx

//motors in main thread
TB6612FNG fw_reservoir_to_display_tank(p27, p28, p22, p11);
TB6612FNG source_to_fw_reservoir(p9, p10, p21, p11);
TB6612FNG reservoir_to_mix(p30, p17, p23, p18);

//motors in Thread thread;
TB6612FNG water_change_in(p29, p20, p24, p14);
TB6612FNG water_change_out(p12, p13, p25, p14);

//Motor Pins
//TB6612FNG motor(PinName idir1, PinName idir2, PinName ipwm, PinName istby);


void test(){
              while(1){
              ///////////////////////////////////////////////////////
   int val3 = salt_mix_reservoir.read(); //read display tank water level
        pc.printf("salt mix sensor = %d\n",val3);
        
        
        reservoir_to_mix.start(); //pump start
        
        
        if(val3 == 1) { //air detected (needs water)
        //fprintf(fp, "FWR TO SLT MX RVR #%d\n", count3);
        //time_t program_seconds = time(NULL);
        //fprintf(fp, "Latest measurement time: %d\n", program_seconds);
        reservoir_to_mix.fwd(1); //power pump forward
       // count3++;
        wait(5);
            pc.printf("entered salt mix loop\n");

            }
        
        reservoir_to_mix.stop(); 
        }
        }
        /*
   ///////////////////////////////////////////////////////
    
    }


void water_change(){
    
    time_t start = time(NULL);
    
  //  float flow_rate_L_num_days = 40;
   // float two_s_pump_volume_L = 0.05;
    int pumps_per_num_days = flow_rate_L_num_days / two_s_pump_volume_L;
    int total_wait_time = sec_days - (pumps_per_num_days * 2); 
    int wait_bw_pump = total_wait_time / pumps_per_num_days;
    
    pc.printf("delay bw pumps in seconds: %d\n", wait_bw_pump);
    

    
    while((time(NULL) - start) < sec_days) {
        
    water_change_in.start(); 
    water_change_out.start(); 
        
        water_change_in.fwd(1); 
        water_change_out.fwd(1);
        
        wait(2);
        
        water_change_in.stop(); 
        water_change_out.stop();
        
        wait(wait_bw_pump);
    
        }
 
    water_change_in.stop(); 
    water_change_out.stop();
 
    }
  */  

int main() {
        
      //  pc.printf("start program\n");
        
    //thread.start(water_change);
    
    
        pb.mode(PullUp);
        int count = 0;
        int count2 = 0;
        int count3 = 0;
      /*   
         mkdir("/sd/mydir", 0777);
    
    FILE *fp = fopen("/sd/mydir/sdtest.txt", "a");
    if(fp == NULL) {
        error("Could not open file for write\n");
    } 
    
    time_t start = time(NULL);
    fprintf(fp, "Start Time: %d\n", start);
*/
  //  test_thread.start(test);
    while(/*pb != 0*/1) { //push button not pressed.  pb != 0
    
   // pc.printf("entered while loop\n");
        //pc.printf("%d \n", test);
      //////////////////////////////////////////////
        int val = water_level_fw_reservoir.read();
        
        source_to_fw_reservoir.start(); 
                
        
        while(val == 1) { //air detected
        val = water_level_fw_reservoir.read(); 
        source_to_fw_reservoir.rev(1); 
        //fprintf(fp, "SOURCE TO FWR #%d\n", count);
          //      time_t program_seconds = time(NULL);
            //    fprintf(fp, "Latest measurement time: %d\n", program_seconds);
        wait(2);
        count++;
        
            pc.printf("entered FW reservoir loop\n");


            }
            
        source_to_fw_reservoir.stop();
        
             ///////////////////////////////////////////////////////
             
   int val3 = salt_mix_reservoir.read(); //read display tank water level
        pc.printf("salt mix sensor = %d\n",val3);
        
        
        reservoir_to_mix.start(); //pump start
        
        
        if(val3 == 1) { //air detected (needs water)
        //fprintf(fp, "FWR TO SLT MX RVR #%d\n", count3);
        //time_t program_seconds = time(NULL);
        //fprintf(fp, "Latest measurement time: %d\n", program_seconds);
        reservoir_to_mix.rev(1); //power pump forward
        count3++;
        wait(5);
            pc.printf("entered salt mix loop\n");

            }
        
        reservoir_to_mix.stop(); 
        
        
        
   ///////////////////////////////////////////////////////
   int val2 = water_level_display_tank.read(); //read display tank water level
        
        
        
        fw_reservoir_to_display_tank.start(); //pump start
        
        
        if(val2 == 1) { //air detected (needs water)
        //fprintf(fp, "FWR TO DSPLY TANK #%d\n", count2);
        //time_t program_seconds = time(NULL);
        //fprintf(fp, "Latest measurement time: %d\n", program_seconds);
        fw_reservoir_to_display_tank.fwd(1); //power pump forward
        count2++;
        wait(2);
            pc.printf("entered display tank loop\n");

            }
        
        fw_reservoir_to_display_tank.stop(); 
        
   
         
    
    }
    
  //fclose(fp); //close sd filesystem
}


Please log in to post comments.