Автоматическая дверца курятника по датчику освещённости: проект на ESP32 и сервоприводе
Зачем курятнику дверца на автомате
Куры встают с рассветом и сами выходят во двор, вечером возвращаются домой. Хозяину остаётся открывать дверцу утром и закрывать вечером — и не забывать: один пропущенный закат, и ночью в курятник приходит лиса или хорёк. Автоматика перекладывает это на железо, а датчик света тут удобнее таймера — время рассвета ползёт по календарю, и еженедельная подстройка часов надоедает.
Из чего собираем
Задача звучит просто, но требует точного измерения света, двух порогов, плавного хода створки и памяти о состоянии после сбоя питания. Это закрывается тремя модулями.
BH1750 — цифровой люксметр на I2C. Диапазон 1–65535 лк, погрешность ±20%, потребление 120 мкА. Он выдаёт люксы, а не «какое-то сопротивление», как фоторезистор, поэтому пороги выбираются один раз. Подробнее о разнице — в обзоре BH1750 против фоторезистора.
Сервопривод тянет створку. Для лёгкой дверцы 20×30 см из фанеры 4 мм хватает SG90: момент 1,8 кг·см при весе 9 г. Но зимой створку заклинивает льдом, а шестерни SG90 — пластик POM. Надёжнее сразу MG996R с шестернями из алюминия 6061-T6: 9,4 кг·см при 4,8 В, 11 кг·см при 6 В — с плечом 6 см это тяга почти в полтора килограмма, створка поедет даже с обмерзанием. Паспортные токи MG996R: 10 мА в покое, 170 мА без нагрузки, 1400 мА стопор (при 6 В — до 2,5 А). Цифры обеих серв — из обзора сервоприводов.
DS3231 — страховка по времени. Точность ±2 ppm при 0…+40 °C, живёт на батарейке годами. Если после 23:00 дверца почему-то открыта, контроллер закрывает её принудительно, что бы ни показывал датчик. Шина I2C у часов общая с BH1750.
Характеристики по паспортам
| Параметр | BH1750FVI (ROHM) | MG996R (TowerPro) | SG90 (TowerPro) |
|---|---|---|---|
| Диапазон / момент | 1–65535 лк | 9,4 кг·см @4,8 В | 1,8 кг·см @4,8 В |
| Питание | 2,4–3,6 В | 4,8–6,6 В | — |
| Потребление | 120 мкА | 10 мА покой / 170 мА без нагрузки / 1400 мА стопор | — |
| Точность / мёртвая зона | ±20% | 1 мкс | — |
| Разрешение / скорость | 0,5/1/4 лк за 120/120/16 мс | 0,19 с/60° @4,8 В | 0,1 с/60° |
| Шестерни | — | алюминий 6061-T6 | POM |
| Вес | — | 55 г | 9 г |
| Подключение | I2C, адрес 0x23/0x5C | ШИМ 50 Гц | ШИМ 50 Гц |
Механика и схема подключения
Механика несложная: на шкив сервы наматывается леска, перекинутая через блок; конец крепится к створке, возврат — резинкой. Оборот шкива радиусом 6 см даёт примерно 37 см хода лески — на створку с ходом 30–35 см. Момент расходуется только на трение и лёд, поэтому MG996R здесь с запасом.
Электрика: BH1750 и DS3231 вешаются на одну шину I2C ESP32 — SDA на GPIO21, SCL на GPIO22, ADDR датчика на землю — адрес 0x23. Датчик света питай от 3V3: логика ESP32 трёхвольтовая. Сервопривод: сигнальный провод — на GPIO13, питание — от отдельного блока 5–6 В на 2 А и больше, земля общая. От пина 5V платы серву кормить нельзя: стопорный ток 1,4 А просадит питание, и ESP32 уйдёт в перезагрузку посреди движения створки.
Код: два порога и плавный ход
Ключевая идея — гистерезис. Закрытие по «темнее 5 лк», открытие по «ярче 20 лк»: между порогами дверца ничего не делает, и пасмурный день не превращается в дёрганье створки.
// Дверца курятника: BH1750 (0x23) + сервопривод
// ESP32: I2C — SDA 21, SCL 22; серво — GPIO13.
// Для Arduino Uno: BH1750 на A4/A5, серво — D9.
#include <Wire.h>
#include <ESP32Servo.h> // на Arduino Uno — Servo.h
const uint8_t BH_ADDR = 0x23; // ножка ADDR на GND
const int SERVO_PIN = 13;
const int CLOSED = 90, OPEN = 0; // крайние положения створки
const float OPEN_LUX = 20.0; // ярче 20 лк — рассвет, открываем
const float CLOSE_LUX = 5.0; // темнее 5 лк — сумерки, закрываем
Servo hatch;
bool isOpen = false;
float readLux() { // режим 0x10: 1 лк, 120 мс
Wire.beginTransmission(BH_ADDR);
Wire.write(0x10);
Wire.endTransmission();
delay(130);
Wire.requestFrom((int)BH_ADDR, 2);
if (Wire.available() < 2) return -1;
uint16_t raw = (Wire.read() << 8) | Wire.read();
return raw / 1.2; // по datasheet ROHM: счёт / 1,2
}
void moveSmooth(int from, int to) {
int step = (to > from) ? 1 : -1;
for (int a = from; a != to; a += step) {
hatch.write(a);
delay(30); // 90° ≈ 3 с, створка не бьётся
}
hatch.write(to);
}
void setup() {
Serial.begin(115200);
Wire.begin(21, 22); // на Uno — Wire.begin();
hatch.attach(SERVO_PIN);
hatch.write(CLOSED); // после сбоя считаем створку закрытой
Serial.println("Готов");
}
void loop() {
float lux = readLux();
if (lux >= OPEN_LUX && !isOpen) {
moveSmooth(CLOSED, OPEN);
isOpen = true;
Serial.printf("%.1f лк — открыл\n", lux);
} else if (lux > 0 && lux <= CLOSE_LUX && isOpen) {
moveSmooth(OPEN, CLOSED);
isOpen = false;
Serial.printf("%.1f лк — закрыл\n", lux);
}
delay(10000); // опрос раз в 10 секунд
}
После сбоя питания код считает створку закрытой — ночью это безопаснее, чем «открыта». Состояние стоит держать в энергонезависимой памяти (на ESP32 — Preferences, у Arduino — EEPROM), а проверку по DS3231 «после 23:00 принудительно закрыть» добавить отдельной веткой в loop().
Частые ошибки
- Сервопривод питают от пина платы. Самая частая причина «ESP32 перезагружается при закрытии». Только отдельный блок питания 5–6 В от 2 А, земля общая.
- Один порог вместо двух. При пороге «10 лк в обе стороны» дверца дёргается весь пасмурный день: освещённость плавает вокруг значения. Гистерезис обязателен.
- Датчик видит фонарь или лампу курятника. BH1750 ставят снаружи, под козырёк, смотрящим в небо, — подальше от уличного фонаря и собственной подсветки. Иначе в полночь наступит «рассвет».
- SG90 зимой. Пластиковые шестерни и лёд на направляющей убивают серву за сезон: она жужжит, греется и не доезжает. Металлические шестерни и вычищенная направляющая решают проблему.
- Створку заклинило — а серв давит. Если ход остановился (лёд, паутина, перекос), привод продолжит давить и перегреется. Спасают паузы по 30 мс в плавном ходе и регулярная чистка направляющей.
Получившийся узел стоит копейки и живёт автономно месяцами: два датчика на одной шине, один привод, никаких реле. Нужна и автоматика полива — модули те же, отличается только исполнитель (см. готовый проект про теплицу).
Информация собрана из открытых источников и паспортов производителей и не является истиной в последней инстанции. Характеристики, распиновку и совместимость проверяйте по документации конкретной партии модуля перед покупкой и подключением.