ttanzil24
Published © GPL3+

Automatic Aquarium Management System (AAMS)

Never worry about your aquarium again! Regulate tank temperature, automate fish feeding, and set reminders for water changes.

IntermediateShowcase (no instructions)668
Automatic Aquarium Management System (AAMS)

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
IoT Relay Outlet
A powerstrip controlled using a relay (such as the SSR-25DA) would work as well. Used for heater control.
×1
Servo Module (Generic)
Used for automatic fish feeder mechanism.
×1
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
Used for temperature monitoring.
×1
Resistor 1k ohm
Resistor 1k ohm
×1
Resistor 220 ohm
Resistor 220 ohm
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1
Acrylic Sheet (.18 in thickness)
Used for the case, any stiff material works.
×1
Super Glue
Used to hold case together.
×1
Electrical Tape
Added support for case and wire management.
×1
LED (generic)
LED (generic)
Indicator light for water change.
×1
Hot Glue
Used to secure case and wires.
×1
Command Strips
Used to attach case & IoT Relay Outlet to the wall.
×1
Pill Bottle
Used for fish feeding mechanism. Any small container works.
×1
DS3231 RTC Module I2C
×1
Button
Used to indicate when a water change has been completed.
×1
OLED SSD1306 (128x64)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Laser cutter (generic)
Laser cutter (generic)
Only used for acrylic case.
Soldering iron (generic)
Soldering iron (generic)
Hot glue gun (generic)
Hot glue gun (generic)
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires
Wire Stripper & Cutter, 18-10 AWG / 0.75-4mm² Capacity Wires

Story

Read more

Custom parts and enclosures

Case Layout Sketch

Case CAD File (.dxf)

Schematics

Circuit Diagram

Code

AAMS_CODE

Arduino
Code for the AAMS.
Remember to change parameters to be specific to your sensors, servos, and pin layout.
Libraries needed:
RTClib
OneWire
DallasTemperature
Servo
Adafruit BusIO
Adafruit GFX Library
Adafruit SSD1306
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>
#include "RTClib.h"

#define pButton 2
#define pPowerStrip 8
#define pTemp 10
#define pStanServo 11
#define pLED 12

#define stanServoPos 0
#define stanServoPos2 180

#define daysToNext25Change 14

Servo stanServo;

//remove reset pin (my OLED has none)
Adafruit_SSD1306 display(-1);

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(pTemp);

// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

int buttonPresses;
int futureDay, futureMonth, futureYear;
int changePercent;

void setup() {

  Serial.begin(9600);

  stanServo.attach(pStanServo, 500, 2500);

  //start up library for temp sensor
  sensors.begin();

  //set pin modes
  pinMode(pButton, INPUT);
  pinMode(pPowerStrip, OUTPUT);
  pinMode(pTemp, INPUT);
  pinMode(pStanServo, OUTPUT);
  pinMode(pLED, OUTPUT);
  
  // initialize with the I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  

  // Clear the buffer.
  display.clearDisplay();

  delay(3000); // wait for console opening [for RTC module]

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  
    // Comment out below lines once you set the date & time.
    // Following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(2022, 10, 9, 7, 23, 10));
  
    // Following line sets the RTC with an explicit date & time
    // for example to set January 27 2017 at 12:56 you would call:
    // rtc.adjust(DateTime(2017, 1, 27, 12, 56, 0));

}

void loop() {

  if (sensors.getTempFByIndex(0) < 76) { //code to control heater activation

    digitalWrite(pPowerStrip, HIGH);
    
  }

  DateTime now = rtc.now();
  
  display.setTextColor(WHITE);
  display.clearDisplay();

  //Display current date MM/DD/YYYY
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print(daysOfTheWeek[now.dayOfTheWeek()]);
  char currentDate [16];
  uint8_t thisDay, thisMonth ;
  thisDay = now.day();
  thisMonth = now.month();
  sprintf (currentDate, "%02d/%02d/", thisMonth, thisDay); //add leading zeros to the day and month
  display.setTextSize(1);
  display.setCursor(62,0);
  display.print(currentDate);
  display.setTextSize(1);
  display.setCursor(102,0);
  display.print(now.year(), DEC);
  
  //Display current time 
  char buffer [16];
  uint8_t thisSec, thisMin, thisHour;
  thisSec = now.second();
  thisMin = now.minute();
  thisHour = now.hour();
  sprintf (buffer, "%02d:%02d:%02d", thisHour, thisMin, thisSec);
  display.setTextSize(2);
  display.setCursor(15,12);
  display.print(buffer);

  //display temperatures
  sensors.requestTemperatures(); // Call sensors.requestTemperatures() to issue a global temperature and Requests to all devices on the bus
  display.setCursor(7,30);
  display.setTextSize(1);
  display.print("Water Temp: ");
  display.print(sensors.getTempFByIndex(0));
  display.print((char)247);
  display.print("F");

  if (digitalRead(pButton) == HIGH) {

    DateTime future(now + TimeSpan(14,0,0,0));

    futureDay = future.day();
    futureMonth = future.month();
    futureYear = future.year();

    buttonPresses++;
    digitalWrite(pLED, LOW);
    
  }

  if (buttonPresses % 52 == 0 && buttonPresses != 0) {

    changePercent = 100;
    
  }

  else if (buttonPresses % 2 == 0 && buttonPresses != 0) {

    changePercent = 50;
    
  }

  else if (buttonPresses != 0) {

    changePercent = 25;
    
  }

  //display next water change
  display.setCursor(22, 40);
  display.print(changePercent);
  display.print("% change on:");
  char futureDate [16];
  sprintf (futureDate, "%02d/%02d/", futureMonth, futureDay); //add leading zeroes to date
  display.setCursor(35, 50);
  display.print(futureDate);
  display.print(futureYear);

  if (now.year() == futureYear && thisMonth == futureMonth && thisDay == futureDay) {

    digitalWrite(pLED, HIGH); //activate LED
    
  }

  if (sensors.getTempFByIndex(0) > 78) { //code to control heater activation

    digitalWrite(pPowerStrip, LOW);
    
  }

  if (thisHour == 12 && thisMin == 0 && thisSec < 5) { //code for auto fish feeder

    stanServo.write(stanServoPos);
    
  }

  else {

    stanServo.write(stanServoPos2);
    
  }

  display.display();

}

Credits

ttanzil24
0 projects • 1 follower

Comments