ESP32 DevKit v1 · pinport
готово
⋮

Тепловой насос вода–вода на ESP32, версия 2: таблица ЭРВ по скважине, защита по току и MQTT

Вторая версия контроллера теплового насоса вода–вода по замечаниям пользователей: стартовая позиция ЭРВ из таблицы «вода из скважины → шаги» с поправкой на обратку и самообучением, ПИ с шагом по открытию вентиля, счётчик пусков, вход аппаратной защиты с причиной в журнале, защита по току компрессора, необязательная погодная поправка и MQTT по темам. Первая версия остаётся в галерее.

Что на схеме

Плата ESP32 DevKit v1, к ней подключены:

  • DS18B20 (термометр 1-Wire) «Всасывание» — tf1, температура 8 °C
  • DS18B20 (термометр 1-Wire) «Нагнетание» — tf2, температура 80 °C
  • DS18B20 (термометр 1-Wire) «Жидкость» — tf3, температура 30 °C
  • DS18B20 (термометр 1-Wire) «После ЭРВ» — tf4, температура 3 °C
  • DS18B20 (термометр 1-Wire) «Скв. вход» — tc1, температура 12 °C
  • DS18B20 (термометр 1-Wire) «Скв. выход» — tc2, температура 7 °C
  • DS18B20 (термометр 1-Wire) «Улица» — tc3, температура 9 °C
  • DS18B20 (термометр 1-Wire) «Пол обратка» — th1, температура 30 °C
  • DS18B20 (термометр 1-Wire) «Пол подача» — th2, температура 34 °C
  • DS18B20 (термометр 1-Wire) «Помещение» — th3, температура 22 °C
  • DS18B20 (термометр 1-Wire) «Корпус» — th4, температура 45 °C
  • Шаговый двигатель «ЭРВ» — eev
  • Потенциометр «Давл. высокое» — ph
  • Потенциометр «Давл. низкое» — pl
  • Потенциометр «Ток компрессора» — pa
  • Переключатель «Проток скважины» — fc
  • Переключатель «Проток пола» — fh
  • Переключатель «Цепь защит» — ch
  • Кнопка «Пуск / сброс» — btn
  • Реле «Компрессор» — k1
  • Реле «Насос скважины» — k2
  • Реле «Насос пола» — k3
  • Реле «Авария» — k4
  • Ввод 230 В «Ввод 230 В» — in
  • Автоматический выключатель «Цепи упр.» — qf1
  • Автоматический выключатель «Компрессор» — qf2
  • Контактор «Контактор» — km1
  • Двигатель однофазный «Компрессор» — mc
  • Двигатель однофазный «Насос скважины» — mw
  • Двигатель однофазный «Насос пола» — mf
  • Светильник 230 В «Лампа аварии» — la1

Задействованы выводы платы: 3V3, GND, D4, D5, D23, D18, D19, D21, D22, D34, D35, VN, D14, D27, D16, D13, D25, D26, D32, D33. Всего соединений на схеме: 83.

Что это и чем отличается от первой версии

Второй вариант установки вода–вода на базе наружного блока кондиционера «старт–стоп»: вода из скважины кипятит фреон в испарителе, компрессор его сжимает, в конденсаторе фреон отдаёт тепло воде тёплого пола, а электронный расширительный вентиль (ЭРВ) на шаговом двигателе дросселирует жидкость обратно к испарителю. Первую версию мы оставили в галерее («Тепловой насос вода–вода на ESP32: 11 датчиков DS18B20, ЭРВ и панель Settings»); эта собрана по замечаниям тех, кто её повторял. Что изменилось:

  1. Стартовая позиция ЭРВ — из таблицы «температура воды из скважины на входе (tc1) → шагов», с поправкой на обратку пола (th1), а не константа 220.
  2. Шаг ПИ зависит от открытия вентиля (флаг в панели).
  3. Счётчик пусков за час и за всё время, длительность последнего цикла — оценка буфера.
  4. Вход «цепь аппаратной защиты»: если цепь разомкнулась, в журнале — что видели датчики в этот момент.
  5. Защита по току компрессора: слишком малый (обрыв, сухой ход) и слишком большой.
  6. MQTT отдельными темами, по значению на тему.
  7. Погодозависимость — по желанию, наклоном или кривой по четырём точкам; по умолчанию выключена.
  8. Один фреон для сборки на железе и обновление по воздуху — константами в начале скетча.
  9. Исправлена ошибка первой версии: если сбросить аварию, пока насосы ещё в выбеге, они оставались включёнными до следующего пуска. Теперь в покое насосы выключаются всегда.

Одиннадцать датчиков на трёх линиях 1-Wire, давления, перегрев и переохлаждение, защиты, панель Settings остались как в первой версии — подробности в её статье.

Стартовая позиция ЭРВ: ключ — вода из скважины

У воды из скважины температура почти постоянна, но в разных местах и в разные сезоны она разная — от 4 до 14 °C. От неё зависит давление кипения, а значит, и то, сколько фреона вентиль должен пропустить в первые минуты. Поэтому ключ таблицы — температура воды на входе испарителя (датчик tc1), а не уличная, как в варианте воздух–вода. Таблица из пяти точек (2, 5, 8, 11, 14 °C), между точками — линейная интерполяция, за краями — значение крайней точки. Сверху добавляется поправка на обратку пола: чем она горячее, тем выше давление конденсации и тем больше нужно прикрыть вентиль (шагов на градус выше опорной обратки 30 °C).

Откуда берутся числа по умолчанию. Из формулы расхода: вентиль пропускает тем больше, чем больше перепад давления, а нужен ему расход компрессора, который растёт с давлением кипения:

шагов = eevStart · (Pкип / Pкип0) · √((Pконд0 − Pкип0) / (Pконд − Pкип))

Опора — кипение 0 °C, конденсация 40 °C, 220 шагов. Кипение принимается на 6 К ниже воды из скважины, конденсация — на 8 К выше обратки. Это первое приближение, а не паспорт вентиля: настоящая характеристика ЭРВ нелинейна, поэтому таблицу подстраивают руками (панель → «Стартовая позиция ЭРВ») или оставляют самообучению. При смене фреона кнопка «Заполнить по формуле» пересчитывает таблицу для нового.

Самообучение. Если перегрев держался у цели (в пределах ±1 К) дольше заданного времени (30 с в симуляторе, 10 минут на железе), текущее открытие считается подходящим для этой температуры скважины, и два соседних узла таблицы сдвигаются к нему на 20 % расхождения — пропорционально весам. Запись во флеш происходит только при остановке компрессора, а не по ходу работы: NVS рассчитана на ограниченное число записей. В журнале строка «самообучение: …» показывает, что и куда сдвинулось. Выключается переключателем.

ПИ с шагом, зависящим от открытия

Скоростной ПИ-регулятор считает приращение Kp·(ошибка − прошлая) + Ki·ошибка·5 с. При малом открытии вентиля шаг в несколько шагов двигателя меняет расход сильнее, чем при большом, и один и тот же коэффициент то раскачивает контур, то вяло его ведёт. Теперь Kp и Ki умножаются на (открытие / piRef)^piPow: piRef — 250 шагов, степень 1 по умолчанию, множитель ограничен 0,25–3. В панели («ЭРВ») это переключатель «Масштабировать Kp и Ki по открытию»; выключите его — и увидите поведение первой версии.

Пуски, цикличность и буфер

Компрессор «старт–стоп» не любит частых пусков. Плата считает пуски за последний час (по меткам времени последних 24), всего (в NVS, пишется при остановке) и запоминает длительность последней работы и паузы перед ней. Если пусков за час больше предела (по умолчанию 6), в журнал идёт предупреждение: объёма воды в контуре не хватает, и установка тактует. Это и есть оценка буфера: короткая работа и частые пуски — буфер мал. Лекарство — буферная ёмкость на подаче или шире гистерезис при большей паузе между пусками; цифры в панели («Последний цикл») показывают, помогло ли. Если все зоны пола закрываются сервоприводами, оставьте байпас между подачей и обраткой — иначе насос будет гнать воду в тупик, а проток пропадёт.

Аппаратная защита и вход «цепь цела»

Предупреждение о нехватке фреона. Если ЭРВ открыт на максимум, а перегрев всё равно больше цели на 4 К и дольше 5 минут (в симуляторе — 20 секунд), плата не останавливает установку, но пишет в журнал «возможна нехватка фреона или засор фильтра», показывает «Предупреждение» на панели и публикует тему warning в MQTT. Без него такое состояние выглядит штатным: регулятор просто упёрся в предел. Порог и время — в панели (0 секунд — не следить); сообщение снимается, когда перегрев вернулся к цели. Что именно — фреон или фильтр, скетч не знает: смотрите на переохлаждение — оно есть в сообщении: около нуля значит нехватку фреона, нормальное — подозрение на фильтр.

Контроллер — не единственная защита. Для настоящего компрессора часть защит ставят аппаратно, в цепь катушки контактора — чтобы они работали, даже если плата зависла или пропало питание датчика:

  • реле высокого давления (HP) — нормально замкнутый контакт последовательно в цепь катушки, без обходов. Разомкнулось — контактор отпал; многие реле HP с ручным сбросом, и пуск невозможен, пока кто-то не придёт и не разберётся;
  • реле низкого давления (LP) — тоже в цепь катушки, но с обходом на время пуска. В момент пуска давление всасывания ещё не поднялось, и «голое» LP в цепи либо не даст компрессору стартовать, либо выбьет его тут же. Обход делают реле времени на 30–120 с или контактом пускового реле: он шунтирует LP только на время пуска, потом LP работает как обычно;
  • термостаты (нагнетание, корпус, выход воды из испарителя против замерзания) и реле протока обоих контуров — последовательно в ту же цепь.

Вход D16 этим не управляет. Это оптрон (PC817 или модуль на 230 В), вход которого стоит после последнего контакта цепи, перед катушкой: он сообщает контроллеру «напряжение на катушке есть». На схеме его заменяет переключатель ch: замкнут на землю (движок справа) — цепь цела. Если цепь разомкнулась при работе, плата останавливает всё, поднимает аварию «сработала аппаратная защита» и пишет в журнал, что видели датчики в этот момент — высокое или низкое давление, нагнетание, потерю протока скважины или пола, близкий к замерзанию выход испарителя. Если ничего из этого не видно, так и написано: смотрите реле HP и LP, термостаты, контактор. Если цепь разомкнута до пуска, установка не стартует и через 3 с объясняет, почему. Авария по цепи сама не повторяется: кто-то должен прийти к реле.

Защита по току

Ток компрессора — потенциометр pa на входе D39 (VN), шкала 0…10 А. На железе вместо него — трансформатор тока с выпрямителем и делителем или счётчик PZEM-004T по UART: для PZEM достаточно заменить тело функции readCurrent(), остальная часть скетча берёт ток только из переменной amps. PZEM в симуляторе не эмулируется, и с настоящим датчиком эта часть не проверялась.

Через несколько секунд после пуска (пусковой бросок не считается) ток должен быть между «не ниже» (1,5 А: обрыв, сухой ход, не включился контактор) и «не выше» (8,5 А). Выход за предел — авария, которая сама не повторяется. Все три числа — в панели.

Погодозависимость: по желанию

У скважины тепло не зависит от погоды, а вот нужная температура подачи — зависит: чем холоднее на улице, тем горячее нужна вода в полу. Поэтому цель с поправкой можно включить, но по умолчанию она выключена. В панели («Управление») — «Прибавка на градус мороза» (цель задана для 0 °C на улице; 0 — выключено) или переключатель «Кривая по точкам вместо наклона» с четырьмя точками «улица → подача». Поправка применяется только в режимах «по подаче» и «по обратке»: в режиме «по помещению» цель — температура комнаты, и погода её не меняет.

Протоки, промерзание, реле аварии

Установка не запустится, пока нет протока и в скважине, и в полу; пропал проток при пуске или работе — авария (повтор через tRetry, до трёх попыток), в журнале — какой контур и сколько компрессор успел проработать. Вода на выходе испарителя холоднее порога (2 °C) дольше 5 с — авария «промерзание испарителя»: лёд в испарителе рвёт пластины. Реле 4 включено, пока идёт авария: к нему подключают лампу, сирену или вход котла.

MQTT: по значению на тему

Каждое значение публикуется в свою тему pinport/heatpump/water/<имя> с флагом retain: state, fault, fault_text, compressor, pump_well, pump_floor, alarm, superheat, subcool, t_evap, t_cond, p_low, p_high, eev_steps, starts_hour, starts_total, current, protection_chain, flow_well, flow_floor, а температуры — в temp/suction, temp/discharge, temp/liquid, temp/evap_in, temp/well_in, temp/well_out, temp/outdoor, temp/return, temp/supply, temp/room, temp/compressor. Так Home Assistant получает готовые датчики без разбора JSON. Тема меняется не чаще раза в секунду (5 секунд на железе) и раз в 20 секунд (5 минут) обновляется, даже если не менялась; статус …/status — online или offline (последняя воля). Контроллер только публикует и команд из сети не принимает. Брокер недоступен — плата работает без него и пробует подключиться не чаще раза в 30 секунд (пока компрессор идёт — в две минуты), чтобы блокировка подключения не останавливала ЭРВ и защиты.

В симуляторе любой адрес ведёт на встроенный брокер PinPort (вкладка «MQTT»); на железе пропишите свой брокер, логин и пароль в начале скетча.

Сборка на железо: константы в начале

  • SIM_DEMO — 0: вернутся реальные задержки (пауза 5 минут, выбег минута).
  • REAL_BUILD — 1: в прошивке остаётся один фреон, а лишние таблицы и выбор в панели убираются.
  • REFRIGERANT_DEFAULT — номер фреона (0 R22, 1 R410A, 2 R134a, 3 R407C, 4 R404A, 5 R290, 6 R600a).
  • USE_OTA — 1: обновление по воздуху через ArduinoOTA; на время обновления установка останавливается. В симуляторе не проверяется.
  • Датчики давления через делитель, драйвер ЭРВ (ULN2003/ULN2803 или L298N/DRV8833), реле — модуль AC-DC-ESP32-Relay-x4 с выводами 25, 26, 32, 33.

Что проверено и что нет

Логика скетча — таблица и интерполяция, самообучение, запись во флеш только при остановке, масштаб ПИ, счётчик пусков, цепь защит, ток, протоки, промерзание, погодная поправка и кривая, темы MQTT, поведение без брокера, переход millis() через 2³² — прогнана на хосте с подставными библиотеками и виртуальным временем; сценарий этой страницы — тоже. Прошивка под ESP32 и сам PinPort в этих прогонах не участвовали: если что-то на вашей схеме ведёт себя иначе, пришлите журнал из порта. На железе не проверялись ни OTA, ни PZEM.

Что не так в симуляторе

Пока галочка «запускать со сценарием» снята, датчики и ток вам не принадлежат: ими управляет модель фреонового контура (вкладка «Контур»). Реле платы включают компрессор и оба насоса, шаги ЭРВ открывают клапан, а давления, температуры воды и ток компрессора возвращаются в датчики. Поэтому ПИ в симуляторе сходится: перегрев откликается на положение вентиля, а не задан рукой. Реле протоков следуют за насосами; щёлкните выключатель протока — и «оборвёте» проток, как в жизни.

Рычагов на вкладке три: температура воды из скважины, заправка и засор фильтра. Утечка заставит ЭРВ уйти на максимум и даст предупреждение о фреоне, холодная скважина (в проверке — 3 °C) — защиту от промерзания. Ручки потенциометров давления и тока и температуры датчиков при включённой модели ничего не решают: их перезаписывает модель. Со сценарием она молчит: сценарий задаёт те же датчики по своим строкам.

Модель учебная: сосредоточенные параметры, температурный глайд смесей не считается, размер установки подогнан под компрессор 1,1 кВт из этого примера. Насосы и аккумулятор на схеме нарисованы, но их динамика не считается.

Библиотеки

Пример собирается с библиотеками:

  • WiFi
  • Preferences
  • LittleFS
  • OneWire
  • DallasTemperature
  • AccelStepper
  • PubSubClient
  • Settings

Они уже установлены на сервере сборки — отмечать их в проекте вручную не нужно, список приезжает вместе с примером.

Как это устроено в коде

Основное, чем пользуется скетч:

  • Preferences — хранение настроек во flash, переживает перезапуск
  • Stepper — шаги двигателя по фазам
  • constrain() — зажимает значение в границах
  • millis() — миллисекунды с запуска: на них строят работу без остановки
  • Serial.println() — печатает строку в монитор порта
  • digitalWrite() — выставляет на выводе высокий или низкий уровень
  • Serial.printf() — печатает в монитор порта с форматированием
  • analogRead() — измеряет напряжение на выводе через АЦП
  • digitalRead() — читает уровень на выводе
  • WiFiClient — TCP-соединение с сервером
  • WiFi.begin() — подключается к точке доступа виртуального Wi-Fi
  • delay() — пауза, на время которой ядро занято ожиданием

В скетче 1617 строк; свои функции: satTemp(), satPress(), formulaPos(), fillTable(), setDefaults(), sortTables(), saveSettings(), loadSettings(); подключено заголовков: 9. Сам скетч открыт на соседней вкладке — его можно менять и запускать заново.

Что попробовать изменить

  1. Нажмите «Запустить». Плата найдёт датчики на трёх линиях (4, 3 и 4), найдёт ноль ЭРВ и поднимет страницу. Сценарий сам переведёт вправо ползунки протоков fc и fh и переключатель цепи защит ch; без сценария сделайте это мышью, иначе установка не запустится.
  2. Нажмите кнопку на схеме: насос скважины, через 2 секунды насос тёплого пола, затем компрессор. В журнале будет «ЭРВ N шагов (по таблице)» — стартовая позиция из таблицы по температуре воды из скважины (датчик tc1) и обратке пола (th1), а не константа 220.
  3. Откройте «Веб-интерфейс» → «Стартовая позиция ЭРВ»: таблица из пяти точек, поправка на обратку и строка «Для текущих условий». Задайте для tc1 другую температуру — число изменится. Смените фреон и нажмите «Заполнить по формуле» — таблица пересчитается.
  4. Откройте вкладку MQTT симулятора: плата публикует pinport/heatpump/water/state, compressor, pump_well, superheat, subcool, starts_total, protection_chain, current и температуры в temp/… — по значению на тему, с retain.
  5. Нажмите на деталь tf1 («Всасывание») и поднимите температуру: перегрев вырастет, ЭРВ начнёт открываться. Шаг ПИ зависит от открытия вентиля — выключите «Масштабировать Kp и Ki по открытию» и сравните.
  6. Переведите ползунок fc влево: через 3 секунды компрессор остановится, в журнале — «проток скважины пропал (… компрессор работал N с)». Верните ползунок и долгим нажатием кнопки сбросьте аварию. Задайте tc1 +4 °C — следующий пуск пойдёт с другой стартовой позицией.
  7. Крутите ручку pa («Ток компрессора») выше 85 %: через секунду авария по току, реле аварии замкнётся. Ток ниже 15 % после пуска — тоже авария (обрыв, сухой ход).
  8. Переведите ch влево во время работы: сработала аппаратная защита, в журнале — что видели датчики в этот момент (например, «нет протока скважины»). В «Управление» включите «Прибавка на градус мороза» и задайте tc3 («Улица») −10 °C — цель подачи вырастет.

Смотрите также

← Все примеры галереи

Схема
Проект из галереи — запускать можно, менять нельзя.

      
Сборка ещё не запускалась.

    Печатайте в Serial числа — они станут графиком. Serial.println(t); — один ряд, Serial.printf("t:%.1f h:%.1f\n", t, h); — два с подписями. Формат тот же, что понимает плоттер Arduino IDE.