Аквариум на Arduino: термометр и автокормушка без риска для рыб
Аквариум — тот случай, когда ошибка в первом проекте плавает живым существом: перегрели воду на три градуса, и у рыб начинаются неприятности; промахнулась кормушка — перекорм и мутная вода. Поэтому маршрут честного аквариумиста такой: сначала логика терморегулятора и кормушки в симуляторе, потом то же на макетке с ведром воды, и только потом — в банку с рыбами.
Ниже — что контролируем и чем, гистерезис с числами, скетч без delay() и таблица решений. DS18B20, реле и серво уже лежат в палитре «Макетка» нашего симулятора: двигаете ползунок температуры — реле щёлкает на нагрев, серво отрабатывает расписание.
Что контролируем: температура, корм и честность
Тропическому аквариуму нужна стабильность 24-26 °C: суточные качели больше чем на градус — стресс для рыб. Датчик — DS18B20 в герметичной гильзе: цифровой, точность ±0,5 °C, один пин по 1-Wire, и на ту же шину можно повесить второй датчик — у дна и у поверхности. Исполнитель — аквариумный нагреватель 50 Вт (расчёт: 1 Вт на литр, с запасом) через реле-модуль. Кормление — серво SG90: барабан с кормом поворачивается и высыпает порцию, дважды в день по 3-5 секунд работы. Рыбы сыты, вода не мутнеет от лишнего корма.
| Что контролируем | Датчик / исполнитель | Действие |
|---|---|---|
| Температура воды 24-26 °C | DS18B20 на пине D2 | ниже 24,0 — реле включает нагреватель |
| Зона гистерезиса 1 °C | реле-модуль на пине D7 | выше 25,0 — нагрев выключен |
| Кормление дважды в день | серво SG90 на пине D9 | поворот 180° и обратно по расписанию |
Гистерезис: почему нельзя просто «ниже 24 — включай»
Если включать нагрев при 24,0 и выключать при 24,1, реле будет щёлкать каждые полминуты: вода вокруг нагревателя прогревается быстрее, чем датчик успевает это увидеть, и регулятор играет в догонялки сам с собой. Решение — гистерезис: включение при 24,0, выключение при 25,0. Реле щёлкает раз в несколько минут, механика живёт годами, а рыбы разницы не замечают: 24-25 — их комфортная зона. Приём уже разобран в уроке про аквариумный термостат — там же история о том, как замерить реальный цикл секундомером.
Скетч: терморегулятор и кормушка без delay()
Оба механизма живут на millis(): терморегулятор опрашивает DS18B20 раз в секунду, кормушка хранит момент последнего кормления. В симуляторе всё видно сразу: ползунок температуры в карточке DS18B20 — единственный источник погоды, реле щёлкает в обе стороны, серво дёргается по расписанию.
#include <OneWire.h>#include <DallasTemperature.h>#include <Servo.h> OneWire oneWire(2); // DS18B20 на пин D2DallasTemperature voda(&oneWire);Servo kormushka; // сигнальный провод на D9 const byte PIN_RELE = 7; // реле нагревателяconst float T_ON = 24.0; // включаем нагрев нижеconst float T_OFF = 25.0; // выключаем выше — гистерезис 1 °C const unsigned long PERIOD_KORM = 6UL * 3600UL * 1000UL; // 6 часовunsigned long tKorm = 0, tPin = 0;bool nagrev = false; void setup() { voda.begin(); kormushka.attach(9); kormushka.write(0); pinMode(PIN_RELE, OUTPUT); Serial.begin(9600);} void loop() { if (millis() - tPin > 1000) { // опрос воды раз в секунду tPin = millis(); voda.requestTemperatures(); // конверсия честно занимает 750 мс float t = voda.getTempCByIndex(0); if (!nagrev && t < T_ON) { nagrev = true; digitalWrite(PIN_RELE, HIGH); } if ( nagrev && t > T_OFF) { nagrev = false; digitalWrite(PIN_RELE, LOW); } Serial.print("t="); Serial.print(t, 1); Serial.print("C "); Serial.println(nagrev ? "nagrev ON" : "nagrev OFF"); } if (millis() - tKorm > PERIOD_KORM) { // расписание кормушки tKorm = millis(); kormushka.write(180); // высыпать порцию delay(3000); // единственный delay: 3 с на корм kormushka.write(0); }}Про единственный delay() в скетче — честно: три секунды дважды в день тормозят loop() целиком, и для учебного стенда это не трагедия. Если хотите идеально чисто — выносите возврат серво на millis(), как сделано для нагревателя. Проверка в симуляторе: откройте стенд, добавьте «Термометр DS18B20», «Модуль реле» и «Сервопривод» из палитры «Макетка». Опустите ползунок ниже 24,0 — реле щёлкнет, лампа загорится; поднимите выше 25,0 — выключится. Кормушку не ждите шесть часов: временно поставьте PERIOD_KORM = 60000UL и смотрите порцию каждую минуту.
Что добавляют в аквариумные проекты следом
- Дневная лампа на втором реле: по часам DS3231 свет включается и гаснет сам — растения и рыбы живут по режиму даже в вашу командировку.
- Контроль уровня: тёплая вода испаряется заметно, и датчик уровня предупредит о доливе раньше, чем оголится нагреватель.
- Аварийный писк: зуммер срабатывает, если температура вышла из зоны 23-27 °C — реле могло залипнуть, и лучше узнать это сразу.
- Лог на SD-карту: температура за сутки графиком — видно, как часто щёлкает нагрев и хватает ли гистерезиса в 1 °C.
Расписание и часы: когда millis() перестаёт хватать
Кормить по millis() — значит мерять время с включения платы: мигнул свет, расписание уехало. Второй шаг эволюции аквариума — часы DS3231: кормление по времени суток, дневная лампа по закату, лог температуры на SD. Механика расписания на RTC уже разобрана в уроке про полив по расписанию — меняется исполнитель, логика остаётся. А уровень воды в банке (испарение — норма, но не в вашу пользу) подстрахует датчик уровня воды из палитры.