Article
Build an Automated Aquarium Controller with ESP32
🐠
Keeping an aquarium means feeding on a consistent schedule and keeping water temperature stable — both easy to miss when you’re traveling or away for a few days. An automated aquarium controller built around an ESP32 handles both: scheduled feeding via a servo, continuous water temperature monitoring with a waterproof sensor, and a Telegram alert the moment temperature crosses a safe threshold — all trackable remotely from your phone.
How it works
- The ESP32 keeps real-time sync via NTP (pulling accurate time from the internet) and compares it against pre-set feeding times (e.g., 8:00 and 18:00 daily).
- At the scheduled time, a servo mounted on the food hopper rotates a small angle to release a pre-measured amount of pellet food, then rotates back to the closed position.
- A waterproof DS18B20 temperature sensor continuously measures water temperature; if it drifts outside a safe range (say, below 22°C or above 30°C depending on the fish species), the ESP32 sends an alert via the Telegram Bot API.
- All state (current temperature, last feeding time) can be published over MQTT for display on a dashboard or in Home Assistant.
Parts list
- An ESP32 (with WiFi, for NTP sync and sending Telegram messages)
- An SG90 servo mounted on the pellet food hopper
- A waterproof DS18B20 temperature sensor (1-Wire interface)
- A 4.7kΩ resistor (pull-up for the DS18B20)
- A food hopper, DIY or store-bought, with a rotating gate matching the servo shaft
- A stable 5V power supply; keep the controller itself somewhere dry, away from tank moisture
Sample code
#include <WiFi.h>
#include <time.h>
#include <ESP32Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <UniversalTelegramBot.h>
#include <WiFiClientSecure.h>
const char* WIFI_SSID = "your-wifi";
const char* WIFI_PASS = "your-wifi-password";
const char* BOT_TOKEN = "TELEGRAM_BOT_TOKEN";
const char* CHAT_ID = "TELEGRAM_CHAT_ID";
Servo feederServo;
OneWire oneWire(4);
DallasTemperature tempSensor(&oneWire);
WiFiClientSecure secureClient;
UniversalTelegramBot bot(BOT_TOKEN, secureClient);
const int FEED_HOURS[] = {8, 18}; // feed at 8am and 6pm daily
int lastFedHour = -1;
const float TEMP_MIN = 22.0;
const float TEMP_MAX = 30.0;
bool alertSent = false;
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
configTime(0, 0, "pool.ntp.org"); // set to your local UTC offset
feederServo.attach(13);
feederServo.write(0); // closed position
tempSensor.begin();
secureClient.setInsecure();
}
void feedFish() {
feederServo.write(90); // open the gate, release food
delay(500);
feederServo.write(0); // close it again
bot.sendMessage(CHAT_ID, "Fed the fish at " + String(millis() / 1000), "");
}
void checkTemperature() {
tempSensor.requestTemperatures();
float tempC = tempSensor.getTempCByIndex(0);
if ((tempC < TEMP_MIN || tempC > TEMP_MAX) && !alertSent) {
bot.sendMessage(CHAT_ID, "ALERT: aquarium temperature is " + String(tempC) + " C", "");
alertSent = true;
} else if (tempC >= TEMP_MIN && tempC <= TEMP_MAX) {
alertSent = false; // reset so a new alert fires if it drifts out again
}
}
void loop() {
struct tm timeInfo;
if (getLocalTime(&timeInfo)) {
for (int h : FEED_HOURS) {
if (timeInfo.tm_hour == h && timeInfo.tm_min == 0 && lastFedHour != h) {
feedFish();
lastFedHour = h;
}
}
}
checkTemperature();
delay(30000); // check every 30 seconds
}
Common pitfalls
- The servo jamming on pellets caught in the mechanism — design the hopper’s outlet so it’s only wide enough for a small amount of food per rotation, keeping pellets out of the servo’s gears.
- No debounce on alerts floods Telegram with repeated messages when temperature hovers right at the threshold — use the
alertSentflag to only send one alert until the reading returns to normal. - Mounting the ESP32 too close to the water surface risks damage from humidity or splashes — only the waterproof DS18B20 sensor should sit in the tank; keep the ESP32 board mounted higher up, somewhere dry.
- Losing WiFi while traveling prevents NTP sync and breaks the feeding schedule — consider adding an RTC module (DS3231) to keep accurate time even through brief network outages.
Extensions
Add a water level sensor to alert when topping off is needed, attach a small pump for scheduled partial water changes, or add an ESP32-CAM like the one in the ESP32-CAM smart doorbell post to check on your fish remotely from your phone.
Tags:#esp32#sensors#automation
Comments