Август, полдень, теплица три на шесть — тридцать два градуса по датчику, а я на работе. Вечером помидоры выглядели как сваренные. На следующий год я поставил механический термопривод: цилиндр сам распахивал форточку при нагреве, и это честно работало — пока я не столкнулся с обратной стороной: уставка зашита в конструкции, около двадцати пяти градусов, ход медленный, а «закройся сейчас» — перед градом или обработкой медьсодержащим препаратом — цилиндр не умеет вовсе. Автоматика, у которой нет слова «немедленно закрыть», — полуавтоматика. Вторая задача проветривания — движение воздуха: застоявшийся влажный угол за стеклом заселяется серой гнилью быстрее, чем жара сушит ботву, поэтому створка нужна не только в тридцать два градуса, но и в двадцать шесть после полива.
Форумы самодельщиков решают это приводом с логикой: серво на форточку или редукторный мотор на дверь, датчик, скетч. Полив по влажности в моей теплице уже вёл отдельный скетч из урока про контроль теплицы, и там прямо сказано: автоматика форточки — следующий этап, приводу нужна своя логика. Вот она, в трёх частях: полоса пропорциональности вместо тумблера, темп решений с гистерезисом закрытия и привод с честным питанием.
Полоса пропорциональности: угол вместо тумблера
Лобовое решение — включать проветривание порогом «открыть при двадцати пяти» — даёт форточку-хлопушку: утром у границы показание прыгает туда-сюда на шуме датчика, и створка по пять раз за час проходит путь от закрытой до распахнутой. Пропорциональная полоса убирает хлопанье: между нижней границей открытия и уставкой полного хода угол растёт линейно с перегревом. При двадцати четырёх — приоткрыто на щель, при двадцати шести — на треть, при уставке тридцать — полный приток. Климат меняется плавно, и створка следует за ним без единого рывка.
Посчитайте на пальцах, как полоса ощущается створке: при двадцати пяти расчёт отдаёт двадцать один градус — узкая щель, при двадцати семи — сорок пять, при двадцати девяти — шестьдесят восемь, и до полного хода остаётся один градус жары. Ширина полосы — вопрос не вкуса. Уже два градуса: дрожь у границ на шуме DHT22 в две-четыре десятых не успевает успокоиться. Восемь и больше: солнечный пик прожаривает теплицу быстрее, чем угол доползает до полного хода. Мои четыре-шесть градусов — оптимум, проверенный на двух сезонах: за утро створка проходит полосу один раз, без возвратов. Уставку полного хода выношу на ползунок: огурцам душно к тридцати, рассаде страшно сквозняка — одно движение ручки, без перепрошивки.
Упоры ставлю на десять и восемьдесят градусов, а не на паспортные ноль и сто восемьдесят: рычаг на качалке форточки должен иметь запас хода в обе стороны, иначе каждое включение бьёт мехом в упор и жжёт мотор током удержания. Разметка углов делается по факту — как и границы хода на упорах, которые подробно разобраны в уроке про упоры и constrain. И не забывайте, что map() не ограничивает выход: температура за уставкой даст угол за упором, поэтому constrain стоит рядом с map всегда.
| Температура в теплице (уставка 30) | Угол (упоры 10-80) | Что происходит |
|---|---|---|
| ниже 23 °C | 10 — закрыто | ночь и прохлада, форточка на упоре, серво можно отпустить |
| 24-26 °C | 20-40 — щель | утренний подъём, полоса пропорциональности начала работу |
| 26-28 °C | 40-60 — треть хода | день, солнце работает, приток дозируется |
| выше 29 °C | 80 — полный ход | пик жары, створка на упоре полного открытия |
Темп решений и гистерезис на закрытие
Серво нельзя дёргать каждые две секунды новым углом: каждая команда — это ход редуктора, ток и износ, а климат за две секунды всё равно не меняется. Мой темп: решение об угле раз в десять-пятнадцать секунд, и это среднее из трёх проб с паузой в две секунды — интервал задаёт сам сенсор, урок про интервал опроса объясняет, почему быстрее физически нельзя. Второй ограничитель — шаг: за одно решение угол меняется не больше чем на десять градусов. Солнце вышло из-за туч, показание подскочило на четыре градуса — створка дожимается за два цикла, а не хлопает за один.
Гистерезис на закрытие — вторая половина темпа. Открытие начинается от двадцати четырёх, а полное закрытие разрешается только при остывании ниже двадцати трёх: между этими границами створка сохраняет текущий угол, сколько бы ни шумело показание. Без этого окна утренняя температура двадцать три и восемь превратила бы каждое решение в ход рычага. Механику двух порогов на одном параметре я раскладывал в уроке про гистерезис реле — здесь она та же, только вместо щелчка реле ход качалки.
Шторм-кнопка — то, чего термопривод не умеет в принципе. Удержание кнопки перекрывает всю автоматику и ведёт створку на упор закрытия: град, обработка, залетевшая птица — причина неважна, приоритет у человека. Отпустили — автоматика вернулась к полосе, и угол доехал до расчётного своим шагом. Для ветреного участка это ещё и штатный режим на ночь: закрытая створка на упоре не парусит, а серво на упоре спит без тока. Все тайминги держатся на millis без блокировки цикла, кнопка читается каждые два прохода, поэтому отдельная логика фронтов не нужна.
Привод: питание, отпускание и честный спор с термоприводом
В теплице серво живёт жёстче, чем на столе. Старт под створкой — сто-двести пятьдесят миллиампер, а если створку заклинит или ледяная рама сядет на упор, серво упирается и ест свои максимальные шестьсот-семьсот миллиампер, пока не перегреется. Пятнадцатый пин Uno такой ток не отдаст: просадка уронит питание платы, и автоматика перезагрузится посреди дня. Питание приводу — отдельный блок на пять вольт с запасом вдвое-втрое, общий минус с платой, электролит у серво; вся арифметика просадок собрана в уроке про пик тока и сброс платы. Второй приём — отпускание: пока форточка лежит на упоре закрытия, серво detachment и молчит, приём из урока про переключатель с двумя положениями.
Теперь спор, который у вас уже зреет. Термопривод дешевле, не требует ни провода, ни электричества, открывает и закрывает сам — против него у серво всего три аргумента: произвольная уставка, произвольный угол в полосе и команда «закройся сейчас». У меня они перевешивают, потому что теплица под проводом и обработка по расписанию. На дальнем участке без розетки я бы честно поставил цилиндр и не мучился: ход штока у ходовых моделей — четыре-семь сантиметров, для форточки хватает, а его медленность в остывании скорее полезна. Граница применимости у обоих приводов честная, и выбор зависит от того, есть ли рядом источник пяти вольт.
Последнее — место датчика. Не у самой форточки: открытая створка тянет уличный воздух прямо по сенсору, и автоматика закрывает то, что только что открыла. Центр теплицы, высота кроны, капельник над корпусом — те же правила, что и для любой комнаты, собранные в уроке про микроклимат и место датчика. Датчик в потоке притока — самый частый способ получить систему, которая хлопает форточкой без остановки.
#include "DHT.h"#include <Servo.h> DHT dht(2, DHT22);Servo vent; const int POT_MAX = A0; // уставка полного хода: 28..34 градусаconst int BTN_STORM = 3; // удержание - форс-закрытиеconst int LED_OPEN = 12; // горит, когда форточка отошла от упора const int UGOL_ZAKR = 10; // механический упор "закрыто"const int UGOL_POLN = 80; // механический упор "полный приток"const float T_OPEN = 24.0; // нижняя граница полосыconst float T_CLOSE = 23.0;// гистерезис закрытияconst int SHAG = 10; // максимум градусов за одно решениеconst unsigned long TICK_MS = 12000; // решение раз в 12 секунд unsigned long lastTick = 0;unsigned long calmSince = 0;bool detached = true;int ugol = UGOL_ZAKR; void setup() { Serial.begin(9600); pinMode(BTN_STORM, INPUT_PULLUP); pinMode(LED_OPEN, OUTPUT); dht.begin(); Serial.println("fortochka: polosa 24..ustavka, upory 10-80, shag 10");} void servoGoto(int target) { if (target != ugol) { if (detached) { vent.attach(11); detached = false; } vent.write(target); ugol = target; calmSince = millis(); }} void loop() { if (millis() - lastTick < TICK_MS) return; lastTick = millis(); // среднее из трёх проб: DHT22 отвечает раз в две секунды float sum = 0.0; for (int i = 0; i < 3; i++) { sum += dht.readTemperature(); delay(2100); } float t = sum / 3.0; float tmax = map(analogRead(POT_MAX), 0, 1023, 280, 340) / 10.0; if (tmax < T_OPEN + 2.0) tmax = T_OPEN + 2.0; // полоса не бывает нулевой int target; if (digitalRead(BTN_STORM) == LOW) { target = UGOL_ZAKR; // шторм сильнее автоматики } else if (t < T_CLOSE) { target = UGOL_ZAKR; // гистерезис: закрылись ниже 23 } else if (t < T_OPEN) { target = ugol; // между границами - держим угол } else { long t10 = t * 10; // десятые градуса для map long hi10 = tmax * 10; target = map(t10, 240, hi10, UGOL_ZAKR, UGOL_POLN); // 240 = T_OPEN 24.0 target = constrain(target, UGOL_ZAKR, UGOL_POLN); } if (target > ugol + SHAG) target = ugol + SHAG; // темп: не быстрее шага if (target < ugol - SHAG) target = ugol - SHAG; servoGoto(target); digitalWrite(LED_OPEN, ugol > UGOL_ZAKR + 2 ? HIGH : LOW); // на упоре закрытия серво можно отпустить - упор держит створку сам if (ugol == UGOL_ZAKR && !detached && millis() - calmSince > 30000) { vent.detach(); detached = true; Serial.println("upor: servo otpushchena"); } Serial.print("t="); Serial.print(t, 1); Serial.print(" ustanovka="); Serial.print(tmax, 1); Serial.print(" ugol="); Serial.println(ugol);}- 1. Что даёт полоса пропорциональности вместо порога «открыть при 25»?
- 2. Почему упоры ставят на 10 и 80 градусов, а не на паспортные 0 и 180?
- 3. Утро, температура 23,4 °C, полоса начинается с 24, закрытие разрешено ниже 23. Что делает форточка?
- 4. Почему серво форточки питают отдельным блоком на пять вольт?
- 5. В чём серво честно проигрывает механическому термоприводу?
- Полоса пропорциональности четыре-шесть градусов вместо порога: угол следует за климатом, хлопанье у границы исчезает.
- Решение об угле раз в десять-пятнадцать секунд по среднему из трёх проб, шаг не больше десяти градусов за цикл.
- Гистерезис закрытия: открытие от 24, закрытие только ниже 23 — утро без хлопков.
- Шторм-кнопка перекрывает автоматику и ведёт створку в упор: то, чего термопривод не умеет в принципе.
- Питание — отдельный БП пять вольт с запасом и отпускание серво на упоре; ограничители map — constrain и минимальная ширина полосы.
Частые вопросы по теме урока
- Что даёт полоса пропорциональности вместо порога «открыть при 25»?
- Один порог превращает утро в череду хлопков: показание прыгает через границу, створка ходит от закрытой до распахнутой. В полосе угол следует за климатом, а дрожь показаний внутри полосы вообще ничего не меняет. Угол растёт с перегревом плавно, и створка не хлопает у границы на шуме датчика
- Почему упоры ставят на 10 и 80 градусов, а не на паспортные 0 и 180?
- Калиброванные упоры с запасом — приём из серво-уроков: на краях паспортного хода привод давит в механический упор и ест максимальный ток. Реальные границы размечают по факту на качалке. Рычагу нужен запас хода в обе стороны, иначе каждое движение бьёт в упор током удержания
- Утро, температура 23,4 °C, полоса начинается с 24, закрытие разрешено ниже 23. Что делает форточка?
- Между границей закрытия и началом полосы створка сохраняет угол — ровно то, что убирает утренние хлопки. Первое открытие случится от 24, полное закрытие — только ниже 23. Держит текущий угол: между 23 и 24 лежит зона гистерезиса, решений нет
- Почему серво форточки питают отдельным блоком на пять вольт?
- Пуск под створкой и упор — те самые цифры, из-за которых SG90 сбрасывает плату с USB: полампера на линии пять вольт не хватает. Отдельный БП с запасом и общий минус — стандарт серво-уроков. Пин Uno не отдаёт пусковые двести пятьдесят миллиампер и упорные семьсот: просадка перезагружает плату
- В чём серво честно проигрывает механическому термоприводу?
- Термопривод выигрывает автономностью: уставка зашита, питания не нужно, ход штока четыре-семь сантиметров. Серво платит проводом и питанием за уставку на выбор, произвольный угол и шторм-закрытие. Требует провода, питания и скетча, тогда как цилиндр работает без электричества