Tanker - A IoT Aquarium


#1

About This Project

This is my final project entry and it is my favorite. I call it tanker. It is a aquarium controller that manages many aspects of the aquarium such as lighting, temperature, water flow, energy consumption, feeding and soon CO2 control. It uses a waterproof temperature probe (DS18B20) as its basis for regulating the temp at 77.0F, a ACS712 to monitor energy consumption, and several relays to control the outlets devices such as the filter, heater and lights are plugged into. I added a small OLED screen via I2C on the case of the Mega to see real time temperature and connection status to Cayenne without a computer or smartphone. The filter relay is setup so if the internet is down, it defaults to “on.” I also hacked a inexpensive fish food feeder for controlled automated feeding by adding a relay and repurposing the micro switch inside so the Arduino knows when to stop the rotation of the food drum. I did have a AC solenoid setup for the CO2 control but I decided to remove it due to safety concerns. It was getting too hot in my opinion so I’m looking into other means for that aspect. I also plan to upgrade the power supply to a 2A instead of the 700ma currently. 700 should be enough to run it but I’m having power dropouts when the relays flip and it occasionally makes the ESP8266 drop the connection momentarily. I also may add a dosing pump for the plant food and a real time clock for calculating kWH. The cover and CO2 holders I designed and printed with my Ultimaker 2 clone. Overall I’m very happy with the project. This is my second version of the aquarium controller.

When feeding the fish, one presses “feed fish…” and that turns on the “Fish Eating” indicator. That triggers the pump to turn off so the fish can eat in peace and prevent food from wasting by getting into the filter. Code side as follows:

#include <CayenneESP8266Shield.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SimpleTimer.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


#define ONE_WIRE_BUS 10

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

SimpleTimer timer;

char token[] = "token";
char ssid[] = "wifi ssid";
char password[] = "password here";


#define EspSerial Serial
ESP8266 wifi(EspSerial);

#define OLED_RESET 12
Adafruit_SSD1306 display(OLED_RESET);


#define LOGO16_GLCD_HEIGHT 64
#define LOGO16_GLCD_WIDTH  128


#define foodTrig 9
#define foodThrow 8
#define currentPin A2
#define filterPin 7

const unsigned long sampleTime = 100000UL;
const unsigned long numSamples = 500UL;
const unsigned long sampleInterval = sampleTime / numSamples;
const int adc_zero = 510;

int feedButton;
int filterButton;
int trigger;
float temp;
int feedingTimer;
int currentTimer;

int displayTimer;
bool online = false;



void setup()
{

	display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
	display.clearDisplay();

	for (int16_t i = 0; i<display.height(); i += 2) {
			display.drawCircle(display.width() / 2, display.height() / 2, i, WHITE);
			display.display();
			delay(1);
		}


	display.setTextSize(2);
	display.setTextColor(WHITE);
	display.setCursor(5,25);
	display.println("tanker 2.1");
	display.display();

	for (int16_t i = 0; i<display.height(); i += 2) {
			display.drawCircle(display.width() / 2, display.height() / 2, i, BLACK);
			display.display();
			delay(1);
		}

	display.clearDisplay();
	display.setTextSize(2);
	display.setTextColor(WHITE);
	display.setCursor(5,25);
	display.println("tanker 2.1");
	display.display();





	EspSerial.begin(9600);
	delay(10);

	sensors.begin();



	Cayenne.begin(token, wifi, ssid, password);

	feedingTimer = timer.setInterval(600000, feedingDone);
	currentTimer = timer.setInterval(5000, getCurrent);

	displayTimer = timer.setInterval(10000, displayUpdate);
	timer.disable(feedingTimer);

	pinMode(foodTrig, INPUT_PULLUP);
	pinMode(currentPin, INPUT);
	pinMode(filterPin, OUTPUT);
	pinMode(foodThrow, OUTPUT);

	Cayenne.virtualWrite(V3, LOW);
}

void loop()
{
	timer.run();
	Cayenne.run();


	if (filterButton == 1)
		{
			digitalWrite(filterPin, 1);
		}
	else
		{
			digitalWrite(filterPin, 0);
		}



	if (feedButton == 1)
		{

			Cayenne.virtualWrite(V3, HIGH);

			timer.enable(feedingTimer);
			digitalWrite(foodThrow, HIGH);
			delay(500);

			trigger = digitalRead(foodTrig);
			while (trigger == HIGH)
				{
					trigger = digitalRead(foodTrig);
					delay(100);
				}
			digitalWrite(foodThrow, LOW);
			feedButton = 0;

			Cayenne.virtualWrite(V1, LOW);
		}
}


void feedingDone()
{
	Cayenne.virtualWrite(V3, LOW);
	timer.disable(feedingTimer);
}


void getCurrent()
{
	unsigned long currentAcc = 0;
	unsigned int count = 0;
	unsigned long prevMicros = micros() - sampleInterval;
	while (count < numSamples)
		{
			if (micros() - prevMicros >= sampleInterval)
				{
					int adc_raw = analogRead(currentPin) - adc_zero;
					currentAcc += (unsigned long)(adc_raw * adc_raw);
					++count;
					prevMicros += sampleInterval;
				}
		}

	float rms = sqrt((float)currentAcc / (float)numSamples) * (75.7576 / 1024.0);
	int watts = rms * 120;
	Cayenne.virtualWrite(V4, rms);
	Cayenne.virtualWrite(V11, rms);
	Cayenne.virtualWrite(V15, watts);

}


void displayUpdate()
{
	display.clearDisplay();
	display.setTextSize(2);
	display.setTextColor(WHITE);
	display.setCursor(0,0);
	display.print("Temp:");
	display.print(temp);
	display.setCursor(25,30);
	display.print("Cayenne");
	display.setCursor(30,50);
	if (online == true)
		{
			display.print("Online");
		}
	else
		{
			display.print("OFFLINE!");
		}

	display.display();
}



CAYENNE_CONNECTED()
{
	online = true;
}

CAYENNE_DISCONNECTED()
{
	online = false;
	digitalWrite(filterPin, 0);
}







CAYENNE_OUT(V0)
{
	sensors.requestTemperatures();
	temp = sensors.getTempFByIndex(0);
	Cayenne.virtualWrite(V0, temp);
	Cayenne.virtualWrite(V10, temp);
}
CAYENNE_IN(V1)
{
	feedButton = getValue.asInt();
}
CAYENNE_IN(V5)
{
	filterButton = getValue.asInt();
}

What’s Connected

Arduino Mega
ESP8266-01S
Mega Protoboard
AC/DC 5V 700ma power supply
Dallas 18B20 waterproof temp probe
.96" Bi Color OLED Display
ACS712 Current sensor
hacked generic fish food auto feeder (added 5v relay inside)
4x 5v Relay board
Cascade Canister Filter
100W Aquarium heater
2x Compact Fluorescent Lights
Coming soon: CO2 valve

Connected via Cayenne dashboard:
Arduino Mega (for ambient temp & humidity)

Triggers & Alerts

I use several triggers for this project. I use two triggers to control the aquarium heater based on the temp sensor, two triggers to control the filter when the fish are eating, and a notification/alarm if the temp gets out of range.

Scheduling

The scheduler turn on and off the light everyday and also feeds the fish once a day in the evening.

Dashboard Screenshots


Photos of the Project


Video



The Judges Have Spoken! ~CONTEST RESULTS~
WifiShield with arduino uno compiling error
#2

Wow it looks awesome and soo profesional!!


#3

Very nice project!


#4

nice… i have 3 display tanks 75 saltwater 55 reef 30gal QT tank and a 10 freshwater tank…
i have apex jr on the 75 and reefkeeperlite on the 55…

i would like to build something for my 55 so i could have iot access also for the qt and 10gal


#5

nice, i used to have 75G reef with a 30G sump setup. had to take it down when i moved


#6

Would you mind posting the .stl file for the enclosure that you printed?


#7

Also, I am new to Cayenne. Is there a way to import this project into my account?


#8

let’s hope @vapor83 comes online and you get the .stl file.

[this project code is based on old cayenne library so you need to use the new MQTT library. Rest all other code for sensor will remain same.
Which device are you using?


#9

Yea that’s no problem! I’ll post it this evening when I get home from work.


#10

Right now I only have a Pi 3B+. As this is an Arduino project, I’ll have to go ahead and get one of those. I need to put together a parts list and see how much the whole project will run and see what kind of budget I have for this.


#11

Let me know if you need a hand switching the code to the new format when your ready. I’ve been away from the forums for a bit but getting back into the game :slight_smile:


#12

Thanks, @vapor83. looking forward to seeing you more into the forum :slightly_smiling_face:.


#13

[quote=“vapor83, post:1, topic:2734”]

Any chance that you have the part numbers for the build list?


#14

Hey Vapor83,
Any chance you would be game for selling me a pre-built unit?


#15

This is irishjd, I just have a new account name :wink:


#16

Same here @vapor83. i also need one for my aquarium.


#17

I hate to nag, but @vapor83, would you be willing to sell any pre-built units? I just started a new job, and I really don’t have the time to build one myself.


#18

Yea I can build some. I apologize for not getting back to you sooner. I’ve sold my condo, moved everything to storage, got my house, moved from storage all in the last week and just got internet today. Fun lol. I’ll message you and we can chat about it.


#19

No worries, and no hurry. Actually, this would be for my son. He just got his first real aquarium and is also a big time tinker ;-). When you have time, let me get him in touch with you and he has tell you what he is looking for. Thanks for taking the time to do this for us!

Jon


#20

Hello I am starting doing a project almost equal. I am new on arduino & cayenne but I have the same temperature sensor and arduino UNO & an ESP 01. Also I have a Jagger heater and I already order an automatic feeder. I won’t implement C02 in my aquarium. But I want to install a PH sensor do you know if I need to do something special with this sensor? Also are planning to do a video of what you did on cayenne? It would be really helpfull I am really new on this I discovered cayenne 2 days ago and some people told me that sometimes there are trouble connecting Arduino Uno & ESP 01 to Cayenne.