В вводной части повествования речь вкратце пошла об общем развитии системы. В этой части, более подробный рассказ об измерительной технике, с которой довелось познакомиться по ходу развития проекта, электронике и, конечно же, о падениях в грязь лицом.
Уровень воды
Сначала был дискретный сенсор, сделанный из двух пластин нержавейки.
Через некую (давно было, не сыскать уже исходников) схему сигнал поступал на контроллер. Дискретность его заключалась в том, что он показывал лишь наличие или отсутствие погружения сенсора в воду. Планировалось также мониторить уровень линейно – в зависимости от степени погружения пластин в раствор, меняется сопротивление на таком сенсоре. Но данный метод был быстро забракован ввиду накопления осадка на пластинах (даже если не брать в расчёт налёт возникающий на пластинах вследствие электрического осаждения элементов раствора, оставался налёт, возникающий из-за высыхания раствора на воздухе) и, со временем, изменяющегося оттого сопротивления. Калибровка сбивалась.
Далее были опробованы различные ультразвуковые датчики: HY-SRF05, HC-SR04, JSN-SR04T, US-025. Наиболее приемлемыми (по измеряемому диапазону) и стабильными (с точки зрения показаний и выносливости) были были выбраны HC-SR04.
Ультразвуковой датчик справлялся достаточно хорошо, тем более, что контроллер поддерживает два таких датчика. На случай аварий, приводящих к потопу, вся система проектировалась таким образом, чтобы перелив происходил в аварийный слив, который прорабатывался таким образом, дабы справляться с потоком воды, переливающимся через край. То есть, в баке, чуть ниже уровня установки ультразвукового датчика ставился дополнительный слив в дренаж. Учитывая, что вода в бак часто поступает под давлением, а через аварийный дренаж сливается самотёком, сечение аварийного дренажа выбирается покрупней, с диаметром, определяемым опытным путём. Такой аварийный дренаж периодически проверяется тестовым переливом через край, на предмет засорения. Тем не менее, опция установки поплавка с аварийным клапаном (аварийная отсечка), остаётся.
Этот поплавок ставится вместе с дополнительным клапаном, как отдельная система, перекрывающая подачу воды в систему вообще. Но эта опция, в ряде случаев, помогает только тогда, когда есть пассивный аварийный дренаж, упомянутый выше. И вот кейс, который наглядно демонстрирует необходимость аварийного дренажа, даже в случае с опцией перекрытия ввода воды по переполнению бака: представим реверсивную систему, в которой, скажем, маты из минеральной ваты насыщаются раствором. Поскольку система реверсивная, то слив из матов происходит обратно в бак. Из матов вода сливается достаточно продолжительное время и уровень раствора в баке постепенно нарастает. Если в течение времени, пока раствор возвращается в бак, произойдёт долив воды (чего не запретишь пользователю сделать в ручном режиме) со срабатыванием аварийной отсечки, то уже и без того заполненный бак продолжит наполняться раствором из матов. Это зачастую означает перелив. Поэтому пассивный аварийный дренаж должен присутствовать в любом случае.
Слышал про использование лазерного датчика уровня. В комментариях подсказывают – ставится в бак трубка с поплавком и на поплавок наводим лазер. С ним я пока не имел дел. Будет датчик – попробую.
С трубкой есть ещё один способ, подобный лазерному поплавку – та же самая трубка, без поплавка и лазера, верхний конец герметично закрывается и в этот же конец ставится достаточно чувствительный датчик давления воздуха. Чем больше уровень, тем выше давление. В трубке.
Какие проблемы возникали при использовании ультразвуковых сенсоров? Первое, самое очевидное – это колебания воды, при заполнении бака. Решается такое усреднением показаний, считываемых с датчика, в прошивке контроллера. Второе – иногда бывают показания вообще за пределами диапазона пустой-полный бак. Подозреваю, что такое случается вследствие помех, наведённых на провод от датчика к контроллеру. Решается использованием провода не более двух-трёх метров и опять же программным способом – если значение, уже усреднённое, достаточно долго находится выше верхней границы бака (а это значение мы задаём в момент настройки, калибровкой датчика по баку), то программа долива приостанавливается, закрывая клапан забора воды. Если же значение, читаемое с датчика, выше уровня в течение времени больше некоторого таймаута (назовём его TO1), то останавливаем забор воды, поднимая флаг соответствующей ошибки.
Третья проблема – датчик залип на некотором значении внутри диапазона верх-низ бака. Такое, как правило, происходит по причине попадания воды на сенсор уровня. Для подобного рода ситуаций предусмотрен ещё один таймаут – TO2. Это время, подбираемое опытным путём, устанавливает пользователь во время первичной настройки. Подбирается обычно так, чтобы быть чуть больше времени, затрачиваемого системой на заполнение бака с нуля до самого верха. Если этот таймаут превышен, то отключам автоматику долива, поднимая флаг ошибки. Вернуться к работоспособности автоматики можно после сброса пользователем данной ошибки.
Кто-то может удивиться, мол, зачем такие сложности? Если у вас теплица на земле, действительно, может статься так, что часть мер излишняя. Но если под вами есть соседи, то я бы порекомендовал проверить в тестовом прогоне все варианты аварий, приводящих к потопу.
Температура
Тут можно измерять температуры воды, воздуха. Изначально опыты проводились на обычных резистивных датчиках, типа, PT100. Далее были освоены датчики DHT11/22. И ещё позже DS18B20. Резистивным датчикам необходим аналоговый вход на контроллере. По входу на каждый датчик. DHT тоже хотят по входу на каждый, но уже можно использовать цифровые входы (коих, обычно, больше). В DHT плюсом идёт измерение влажности. DS18B20 хорош тем, что на один пин контроллера можно подключить несколько датчиков разом. По-итогу, на сегодня, в самом устройстве ставится один DS18B20, измеряющий температуру воды в районе магистрали смешивания удобрений. Это становится излишним, когда в сенсор EC уже встроен резистивный термодатчик, измерения с которого снимаются AD5934, входящим в состав блока для измерения EC.
DS18B20 подключается с резистором 10к между питанием и линией данных.
EC (ака TDS, ака солемер)
Для измерения количества солей были также перепробованы несколько способов:
1. По этой ссылке была найдена следующая схема
Далее была разведена плата и фоторезистивным методом собственноручно (то было во времена, когда JLCPCB был мне неизвестен, если существовал вообще) изготовлена, с применением хлорного железа и прочими шаманствами. Подозреваю, что руки мои на тот момент росли значительно ниже плеч, что попрепятствовало успеху с данной схемой. На самом деле, один модуль даже работал и весьма неплохо. А вот ещё парочка-другая, почему-то заводиться отказалась.
2. Была ещё одна схема на TL074, но сейчас, к сожалению, не вспомню откуда и какая. Учитывая только память о том, что была пробная сборка на макетке, видимо она не заработала.
3. Самой простой и очевидной оказалась схема измерения влажности на таймере 555.
Это натолкнуло меня на изучение данного таймера и в итоге я собрал нечто похожее, что даже заработало. Погрешность была, мягко говоря, так себе. Однако воспроизводимость была 100%. Достаточно долго этот вариант меня вполне устраивал, пока не появилась необходимость сделать более точный. Так появился следующий вариант с применением...
4. AD5934 который входит в состав демонстрационной платы EVAL-0349, от Analog.
Тут уже всё стало более чем серьёзно (на самом деле есть варианты ещё более точные, с более широким диапазоном измерений и более кусачей ценой, но наврядли они пригодятся в растениеводстве). Шутка ли – два диапазона измерений (первый: от 25μS до 2500μS, второй: от 0.2mS до 200mS) с относительной погрешностью измерений 0.5% для первого диапазона и 1% (после программной коррекции. Если без неё, то 3%) для второго. Вообще, AD5934, насколько я сегодня понимаю, был придуман больше для измерения качества проводной сети (типа, проверять затухание сигнала в витой паре). Но CN0349 рассказывает удивительные вещи и про растворы солей. Рекомендую изучить сей circuit note, для общего образования.
Если вкратце, то работает эта штука следующим образом: есть микросема ADG715, которая делает выбор между одним из двух пределов измерений EC или термодатчиком. Есть сам AD5934, который измеряет сопротивление с сенсора EC или резистивного термодатчика через операционный усилитель AD8606. Всё это дело заведено через изолятор питания ADuM5000 и изолятор данных ADuM1250. Чтобы всё это собрать и запустить на своей плате, пришлось изрядно покурить даташиты по всем этим компонентам. В итоге, когда всё заработало, измерения электропроводности воды стали максимально достоверными за всю историю проекта. Сами сенсоры, после самодельных, были взяты с aliexpress, с сантехнической резьбой пол-дюйма, со встроенным резистивным термодатчиком. Константа сенсора 1.0.
Для внедрения этого, достаточно длинного сенсора, в уже имеющуюся гидросистему, пришлось сделать небольшой удлинитель.
Сенсоры давления воды
Были опробованы стальные из нержавейки, потом из некого иного металла, покрытого хромом и уже потом нашлись пластиковые. Первый был с метрической резьбой и найти готовый переходник на сантехническую резьбу оказалось проблемой. Второй и третий уже были с резьбой BSP на четверть дюйма. Перейти на требуемые пол-дюйма уже не составило труда (с помощью найденного в продаже полипропиленового переходника). Во времена попыток с первым сенсором из нержавейки, мне даже не пришло в голову, что можно взять метчик и нарезать метрическую резьбу нужного размера в любой подходящей заглушке на пол-дюйма, предварительно лишь засверлив её.
Все эти сенсоры расчитаны на 5В питание. Выдают, соответственно, напряжение, линейно зависящее от давления, в диапазоне от 0.5В до 4.5В. АЦП контроллера STM32 запитан от 3.3В, следовательно в схему подключения привносится самый простой делитель напряжения – резистивный.
Измерение кислотности раствора
Измерение кислотности раствора происходит обычным сенсором pH, которые также продают на aliexpress.
Как уже упоминалось, первый, достаточно добротный вариант удалось собрать на операционном усилителе CA3240. Схема была взята тут.
Первая версия, собранная своими руками выглядела как-то так
Следующим стал модуль на специализированном решении (LMP91200 от Texas Instruments), заточенном под измерение кислотности стандартными сенсорами pH.
Типичная схема из даташита незамысловата, её и взял.
там же в даташите нарисовано как надо разводить плату.
По схеме из даташита, как видим, выход с LMP91200 подаётся на вход АЦП контроллера, я же направил этот выход на вход отдельного АЦП – ADS1110. Этот АЦП уже передаёт данные на STM32 по I2C, через гальваническую развязку в лице ADuM1250 (данные) и дешевого изолятора питания на 1 ватт – B0505S-1W (питание).
Можно, конечно, как в EVAL-0349 использовать ADuM5000, но этот товарищ имеет одно неприятное свойство – достаточно сильные помехи (про это можно почитать в даташите на данный изолятор и сопутствующие аппноты про EMI considerations), требующие разводить плату соответствующим образом.
RTC
Хоть это и не сенсор, но тоже важная периферия, поскольку в системе активно используются различные таймеры. Дело в том, что многочисленные проблемы с RTC, идущим вместе с STM32 прилично утомили. Среди этих проблем были некачественные blue-pill (да, именно на них была разведена основная масса версий плат), криво припаянные кварцы, невидимые сопли на контактах кварца или пинах (PC14, PC15), самого чипа контроллера, куда подключаются кварцы. Однажды я заметил, что часы идут, пока blue-pill не вставлена в разъёмы платы контроллера. Как только вставляешь – не идут. Достаёшь – опять идут. Отрезал от пилюли пины (PC14, PC15), которые вонзались в разъёмы – часы пошли в любом положении. Не любят эти выводы лишних емкостей. Можно было бы как следует чистить платы, разъёмы, отрезать пины, покрывать лаком... да вот один случай совсем расстроил – в один из аппаратов забрался таракан и прилёг погреться на чип STM32. Что за дискотеку он там устроил не очень понятно, да вот только напачкал прилично, прям на чипе и вокруг. Встроенный RTC встал. Чистка помогла, но было принято решение – дублировать часы при помощи DS3221.
Что было опробовано, но пока не вошло в обиход в силу тех или иных причин
Счётчик воды
В числе прочих тестированию подверглись две модели счётчиков воды. Однако, эти измерительные приборы для выдачи верных показаний требуют полное отсутствие пузырей в жидкости. Любые изгибы, смены диаметров водонесущих трубок и прочие мелочи вызывают появление пузырей в воде. Когда пузырь проходит по счётчику, последний норовит посчитать воздух за воду, да ещё и в бОльшем объёме.
На практике достичь такой однородности, чтобы не было существенных отклонений показаний от действительности у меня не получилось, поэтому развёрнуто говорить на эту тему у меня пока не получается.
СО2
Эксперимента ради был также испробован сенсор концентрации углекислого газа MG811. Сенсор представляет из себя устройство, типа батарейки, с электролитом внутри. Судя по даташиту, ЭДС такой батарейки связан через уравнение Нернста с концентрацией углекислого газа в измеряемой атмосфере. Генерируемые токи такого элемента в районе единиц пикоампер, поэтому часто можно в продаже встретить MG811 в составе шилда, на котором расположен операционный усилитель для поднятия столь мизерных токов. Испольуется такой сенсор не сразу, типа, включил и измеряешь, а в условиях прогретого сенсора. Для этого в MG811 встроен нагревательный элемент, который запитывается по двум (из шести всего) отдельным пинам и потребляет пару сотен миллиампер. И эти миллиамперы, зачастую, несмотря на шилды со встроенными усилителями, требуется подавать с напряжением 6В. Не сказать, чтобы большая проблема – поставить дополнительный повышающий преобразователь с 3.3 или 5 вольт, но учитывать этот момент всё же приходится. Вероятно, есть в природе шилды со встроенным повышающим преобразователем напряжения, но мне попадались без него. Времени на разогрев требуется около минуты, отзывчивость тоже не такая резкая, что подышал и увидел броски показаний. За неимением газового обрудования и возможности его применять в полной мере, отложил сей сенсор пока на полку. Кстати, для полноценной работы с ним будет нелишним обзавестись смесями калибровочных газов, что иногда затруднительно и доставляет хлопот поболее, чем с теми же калибровочными жидкостями для pH сенсоров.
Из известных мне, есть ещё инфракрасные сенсоры углекислоты, так называемые NDIR. Их есть несколько моделей. Отличаются скоростью отклика, диапазонами измерений, погрешностью и, разумеется, ценой. В качестве примера, на который в своё время посматривал, могу назвать MH-Z14A. Рекомендовать или отговаривать не могу, ибо не имею в наличии и не проверял. На Хабре есть те, кто держал подобные в руках (раз и два).
Датчик освещённости
Хороший пример описан тут
Системы, способы контроля и предотвращения нештатных ситуаций. Электроника
Различные нежелательные эффекты, возникающие при эксплуатации устройства привели к разработке ряда ухищрений, среди которых следует отметить следующие.
Watchdog
В контроллерах STM32 имеется встроенный независимый вочдог таймер именуемый IWDG (Independent WatchDoG). Он хорошо справляется с подавляющим числом зависаний контроллера, на большинстве контроллеров позволяет даже просыпаться из глубокого сна. Однако, как показала практика (особенно на сырых версиях электроники, да простят меня олдовые), в реальных условиях, даже он не всегда справляется. Поэтому был установлен дополнительный, аппаратный сторожевой таймер. С усовершенствованием схемотехники и прошивок, толку от него становится меньше. Тем не менее, для страховки он остался по сей день. Я использовал MAX6369. Для тех кто не в курсе, поясню вкратце – у аппаратного сторожевого таймера выход WDO подключается на вход RESET контроллера, а вход WDI заводится на одну из ног контроллера. Когда всё работает, прошивка периодически генерирует импульс на WDI, чтобы дать понять сторожевому таймеру, что всё впорядке. Если в течение продолжительного времени на WDI такого импульса не приходит, сторожевой таймер даёт импульс на WDO, что приводит к аппаратному (как от кнопки) перезапуску контроллера. Можно такой сторожевик собрать и на таймере 555 (чем я тоже баловался в качестве эксперимента), но он занимает прилично места, по сравнению со специализированными решениями.
Неопредённые состояния во время старта
Неопредённые состояния во время старта больше всего досаждают на исполнительных устройствах. Пока контроллер не загрузился, на выходах творится непонятное, что приводит к нежелательным срабатываниям всего, что управляется этими выводами (управление питанием измерительной техники, клапана, дозаторы...). Чтобы устранить эти явления, на контроллере можно железно подтянуть управляющие выходы к земле (или питанию. В зависимости от полярности управляющего сигнала) резистором. В данном случае так сделано, например, для полевых транзисторов, которые управляют питанием измерительных модулей и Raspberry Pi.
Поскольку у меня исполнительными устройствами усправляет отдельный драйвер, где управляющие сигналы создаёт экспандер MCP23017, то подтянуть все 16 линий, вероятно (следует заглянуть в даташит на L6205 и/или протестировать в железе, чтобы уточнить однозначно), можно на нём. Однако, чтобы получить результат наверняка и с меньшим числом точек запайки я выбрал установку достаточно мощного полевого P-канального транзистора на питание всех L6205. В результате, этим полевиком управляет основной контроллер STM32 через оптопару. Логика прошивки сначала инициализирует все входы/выходы на выход, пишет в регистры выходов нули (всё выключено), зачитывает обратно содержимое этих регистров, сверяет с тем, что только что было записано и, если все биты совпадают, то старт считается успешным. Если старт определился как неуспешный, поднимается соответствующий флаг ошибки и работа всей силовой части блокируется (основной контроллер не станет открывать полевик до устранения проблемы). Если же старт засчитан успешным, то полевик всё ещё будет закрыт. До тех пор, пока не будет выдана команда на запуск одной из нагрузок, которая (команда) отправит на экспандер драйвера последовательность бит (где как минимум один из битов будет отличаться от нуля) и не прочитает обратно такую же последовательность. Когда все эти условия выполнятся, основной контроллер открывает MOSFET и только тогда драйвер начинает питать нагрузку. По завершении работы нагрузки/нагрузок, основной контроллер вновь отключает питание силовой части драйвера, закрывая полевик до следующих мероприятий. Если происходит физический обрыв проводов (скажем, отгрызла внезапная мышь), то линия управления полевым транзистором ложится в ноль (для P-канального, на самом деле, в 1) и нагрузки не сдвинутся с места (как минимум, до тех пор, пока не будет отгрызен подтягивающий резистор).
Кстати, о силовом драйвере. Однажды, пришёл ко мне один молодой человек и попросил дать ему попрактиковаться в сборке. Было ему выделено место, даны компоненты, паяльник, платы, схемы, тестовый аппарат. Собрал он пару таких драйверов и стал их тестировать. Не получается. Звонит мне, рассказывает невероятные вещи. Приехать на место и проверить лично в чём там дело непросто - я в другой стране. В драйвере этом, в роли экспандера, использовалась 74HC595. Он тычет в неё и говорит, мол, то ли микросема отстой, то ли прошивка твоя не важнецкая. Дело дрянь, вобщем. Я проверяю прошивку на своём девайсе, перепроверяю все подключения у себя, шлю ему видео. И у него всё-равно не работает. Ну, думаю, что с микросхемами-то может быть. Я же не DI HALT, который всё-всё видывал в силу огроменного опыта и может писать про подделки, в которых нет кристаллов или ещё что похуже. Мне чисто по теории вероятности левак достанется крайне наврядли - думал я. А вариант с прошивкой не подтверждался в моих тестах.
Микрухи, действительно, оказались леваком. Об этом я узнал, когда прибыл на место событий. Чувак к тому моменту пропал за горизонтом. Так что, если ты вдруг это читаешь, дядька, знай - ты был прав, микрухи оказались шляпой. А я ошибся.
Малина
Иногда Raspberry Pi может перестать подавать признаки жизни. Как сказано выше, основной контроллер может управлять её питанием. И в таких случаях тишины он именно это и делает. Причин тишины от малины может быть несколько. Наиболее частые из них: перегрев малины или износ карты памяти. Для нивелирования зависаний по перегреву основной контроллер выжидает заданный промежуток времени, после чего перезапускает питание Raspberry Pi. То же самое происходит и в случае с износом карты памяти, только здесь, как несложно догадаться, рестарт уже не помогает. Специальный счётчик даёт несколько попыток рестарта. Если они не помогли, то, как это уже стало традицией, поднимается соответствующий флаг ошибки и малина оставляется в покое.
Чтобы износ карт памяти происходил как можно реже, используется как минимум две карты. Одна из них монтируется в режиме только для чтения. С неё происходит загрузка системы. Логи, данные, графики пишутся на отдельную карту, смонтированную для чтения/записи. Кроме этого, в ходе испытаний были испробованы различные карты памяти и из них выбраны наиболее долговечные. Разница в жизнеспособности разных представителей карт памяти измеряется порядками. Некоторые карты перестают записываться, а некоторые даже читаться. Чтобы не просрать все полимеры логи, написана функция, запускающая телеграм-бота, который периодически шлёт пользователю графики логов.
Питание
Питание системы также отметилось в статистике отказов. Наиболее частой проблемой стали излом проводов и раскручивания клемм на блоках питания. Это нормальная ситуация на аппаратах, нагруженных вибрацией. Чтобы хоть как-то минимизировать этот эффект, было решено закручивать в клеммы не просто концы проводов, а делать на концах колечки. Это улучшает зажим. Плюс к этому, закручивать следует изо всех сил. Несмотря на силу закручивания, пользователю рекомендуется иногда приносить аппарат на профилактику, в ходе которой, среди прочего, делается протяжка клемм.
Кстати, о клеммах
Есть такие клеммы, очень популярные, вы, скорей всего, их видели, зажимные с винтами.
Они были использованы в первых версиях аппаратов на проводах основного насоса. Сначала ставились рядом с мотором, чтобы удобно было поставить обратный диод. Когда принесли аппарат с погоревшими клеммами, диод я стал запаивать, а клеммы вынес подальше, сантиметров на 10-15. Это не изменило ровным счётом ничего. Больше я их там не использую вообще, только запайка. А вот разём GX16 справляется и не чернеет даже (хотя, лет через 10, кто его знает).
Пара историй про химические фэйлы
Один раз банку с органическими удобрениями разорвало давлением изнутри (загадочные процессы в самом удобрении, происходящие, скорей всего, из-за несоблюдения чистоты на обратной стороне крышки банки) и содержимое оказалось на мраморном полу. Взял бы да вытер, но нет. Не было меня на месте этого происшествия несколько недель. Удобрению понравился мрамор и оно проело в нём пару миллиметров верхнего слоя.
Второй аналогичный случай произошёл на бетонном полу. Бетон тоже пришёлся органике по вкусу. Никакая перекись не смогла справится со следами после уборки. Спустя время, в этом месте, на бетоне продолжилась жизнь в лице зелёной плесени.
Ещё один случай связан с кислотой. Там была азотная кислота, около 35% концентрации, подключенная в дозатор. На КДПВ из первой части видно, как штатные светло-кремовые шланги дозаторов переходят через черные соединители в коричневые (бывают черные) ПВХ. Это был тот самый случай. Как выяснилось (да простят меня химики), так делать категорически не следует. ПВХ за считанные дни задубел, соединители превратились в сопли-порошок, система потекла (хорошо, что аварийный дренаж был в наличии). Теперь только шланги, рекомендованные производителем под эти кислоты, с регламентом снятия/замены. И кислоты разводить в воде.