Comments 97
const int MYHIGH = LOW;
Нейминг суровое ;)
Не то чтобы это сильно мешало.. но специальная константа для ровно одного места, да с таким странным именем..
Логику и реализацию лучше бы разделить. Вдруг кому то на Raspberry pi захочеться портировать ;)
Воще выделение памяти в контроллерах дурной тон. Что произойдет, если памяти для add Pump не хватит?
Нейминг да) у меня ардуино выключает релюхи в режиме HIGH, а хотелось бы включение с таким названием.
Над разделением логики и реализации надо ещё соображать что и где разделять. А какие будут предложения?
А вот как проверять оставшуюся свободную память на ардуино пока не знаю. Но я специально так сделал чтобы было удобнее добавлять насосы.
Как альтернатива можно использовать вместо HIGH/LOW - ON/OFF.
совсем решил избавиться от этих костант( и еще добавил проверку памяти): https://github.com/Akullaaa/pumpController/blob/main/pumpController.ino
проверил использование памяти: при создании 10 насосов будет использована половина памяти ардумино уно, т.е. из 2К остаётся только 1К.
Памяти может не хватить в любой момент. Добавите какие то улучшения, поменяете проц - и оно вдруг ребутнется.
В новой версии будет отображаться оставшаяся память RAM.
Тогда надо лог писать. Чтобы если ребутнулось, можно было взять флешку и прочитать.
Это надо новое железо добавлять как я понимаю. Хотя мне канешна хорошо бы вести логи, а то каждый раз когда включаю монитор порта в ARDUINO IDE программа заново перезапускается. Какой модуль добавить для флешки? Что порекомендуете?
Я рекомендую аллоцировать все обьекты статически. Если что то не влезет в память - прошивка не соберется.
Если поменять МК на более современный, то памяти будет намного больше. Например, RP2040-Zero сейчас можно купить дешевле, чем Arduino UNO. А там SRAM на два порядка больше, чем в ATMega328.
Если нужно динамическое распределение памяти, то выделять её надо ещё при инициализации, а в тех случаях, когда это невозможно - обрабатывать ошибку нехватки памяти с индикацией этого события каким-то способом. Хоть светодиодом.
Если поменять МК на более современный
Тут stc8 нормально подойдет ;)
Я про сам принцип. Какой смысл в динамическом выделении памяти, когда мы заранее знаем, что подключено к контроллеру?
обрабатывать ошибку нехватки памяти с индикацией этого события каким-то способом
Возвращаешься из отпуска- соседи залиты, цветы засохли, на контроллере бодро мигает лампочка ;)
Тут stc8 нормально подойдет
Если насосов всего пара, то даже PMS171B-S08 за 10 рублей подойдет. Вот только Arduino IDE Padauk не поддерживает и через USB его без дополнительного оборудования, причем совсем не дешевого, не прошить. Я всё же пытаюсь держаться рамок DIY уровня Arduino )
Какой смысл в динамическом выделении памяти, когда мы заранее знаем, что подключено к контроллеру?
А если не знаем на момент прошивки, позволяя пользователю задавать всё в динамике, сохраняя конфигурацию в EEPROM или флеш? Не предлагать же своей жене или бабушке перепрошивать МК, если захотелось добавить цветок или датчик из фиалок переставить в алоэ?
Возвращаешься из отпуска- соседи залиты, цветы засохли, на контроллере бодро мигает лампочка ;)
Или МК уже обругался электронными письмами или сообщениями в Telegram через HA. В любом случае, ошибку надо обрабатывать так, чтобы последствия были минимальны. Это как раз при уходе в перезагрузку можно соседей залить, а не при аварийном завершении работы с отключением всех насосов.
задавать всё в динамике,
Ну и задавайте. Контроллеры насосов и датчиков аллоцированы сразу, а конфигурируются значениями из eeprom.
Так то если памяти много можно писать на питоне и не заморачиваться с плюсами.
Ну и задавайте. Контроллеры насосов и датчиков аллоцированы сразу
Вы вообще читаете на что отвечаете? Я же писал: "Если нужно динамическое распределение памяти, то выделять её надо ещё при инициализации".
Другая проблема, как тоже я писал, "в тех случаях, когда это невозможно".
Если хватает памяти на одновременную работу интерфейса конфигурации и на обслуживание датчиков и насосов - хорошо. Но это совсем не всегда так.
Даже во время работы, если параметры регулирования подбираются автоматически, то памяти может не хватать на одновременную калибровку всех датчиков и насосов.
Так то если памяти много можно писать на питоне и не заморачиваться с плюсами.
Можно. Но можно упереться в производительность. Например, ПИД регулирование с автоподстройкой методом многомерного сканирования Вишняковой нескольких одновременно включенных насосов, на Python может оказаться слишком ресурсоемкой задачей для МК из-за издержек динамической типизации. Впрочем, ТС обошелся вообще без ПИД регулирования, опытным путем подбирая параметры, исходя из размера горшков и мощности насосов, на удивление обеспечивающих одинаковый расход воды при разном его уровне в накопительном баке )))
Если нужно динамическое распределение памяти
Если. Как правило, нет в нем необходимости. В данном проекте точно нет
ТС обошелся вообще без ПИД регулирования
Сложно было бы его сюда прикрутить ;)
Как правило, нет в нем необходимости
И где ссылка на это правило? У меня почему-то намного чаще динамическое распределение памяти требуется.
Сложно было бы его сюда прикрутить
Для Вас? )))
Разные задачи по разному решаются. Здесь ни pid регулятор ни динамическое распределение памяти нафиг не нужны. Но если хочется, то конечно же можно.
Аргументация потрясающая. Ну вперед, докажите для начала ложность моего утверждения: "Если хватает памяти на одновременную работу интерфейса конфигурации и на обслуживание датчиков и насосов - хорошо. Но это совсем не всегда так."
А потом уже вернемся к тому, насколько инертно изменение влажности земли.
Неплохо было бы, если бы ктото доказал, что динамическое выделение памяти - всегда правильное решение.
А гдеб почитать про пид регулирование с подстройкой постоянной? Может есть какие готовые библиотеки ? Хочется для печи сделать, у нее все время разная загрузка + нужны разные коэффициенты для разной температуры.
Если на маленьком МК динамическая память используется только при инициализации, то значит динамическая память не нужна.
Если в маленьком МК используется динамическая память в процессе работы, и это устройство должно наботать автономно, то это ошибка проектирования. Динамического распределения памяти там быть не должно (в общепринятом понимании).
Если на маленьком МК динамическая память используется только при инициализации, то значит динамическая память не нужна.
Докажите, что не нужны МК с конфигурацией задаваемой пользователем и от которой может зависеть потребность в оперативной памяти.
Динамического распределения памяти там быть не должно
Докажите, для примера, что буфер размером в страницу флеш-памяти, необходимый исключительно в момент сохранения изменений конфигурации, должен быть выделен статически. Даже если он занимает до четверти всей RAM.
А потому уже перейдем к обсуждению того, можно ли вообще, например, в ESP32 c RTOS обойтись без динамического распределения памяти. И насколько разумно для встроенного веб-сервера статически выделять память.
Я упоминаю конкретные случаи, в которых использование динамического выделения памяти не оправдано.
Если у меня две не пересекающиеся задачи, например, показать меню и сохранить настройки, которые требуют по 1Кб памяти, то разумно размещать их временные данные в структурах размещенных по одному и тому же адресу в статически выделенном буфере. Зато я точно знаю, что на эту память больше никто не претендует. И сюрпризов не возникнет, что в очередной запрос у меня почему-то окажется свободными только 900 байт.
Ну и я рассуждаю про себя, а не про пользователя. Для удобства пользователя пусть выделяет себе память динамически, это его задачи.
Конкретно, если рассматривать поливалку, если ей не хватит памяти при статической инициализации, то никакая динамика ее не спасет.
Встречал интересные случаи, когда вроде бы человек оперировал только строками (с динамическим выделением), но из-за интересного расположения переменных в стеке вызова и перекрывающемся времени жизни и немного гуляющего размера МК приходил к ситуации сегментирования кучи. И привет.
Неприятность динамического выделения в двух местах. Первое - это сегментирование. Второе - это привычка им пользоваться забывая про первое.
Если у меня две не пересекающиеся задачи, например, показать меню и сохранить настройки, которые требуют по 1Кб памяти, то разумно размещать их временные данные в структурах размещенных по одному и тому же адресу в статически выделенном буфере.
С точки зрения безопасности при работе с памятью - это совершенно не разумно. Намного надежней выделять динамически память для буферов страницы флеша, сектора FAT на SD-карте или MQTT сообщения, корректно обрабатывая ошибки выделения памяти, чем писать свою реализацию динамической работы с памятью в пуле.
И сюрпризов не возникнет, что в очередной запрос у меня почему-то окажется свободными только 900 байт.
Откуда уверенность в безошибочности своего кода? )))
Просто проверяйте успешность выделения памяти, а память, необходимую для аварийного завершения, выделяйте заранее. Зато сможете адекватно сообщить пользователю, что, для примера, либо ему надо уменьшить количество насосов, либо сократить глубину хранения истории температур и влажности с датчиков.
А вот если Вы напишете работоспособный аналог lwip без динамического выделения памяти - я сильно удивлюсь. И да, поливалка тоже вполне может работать с использованием MQTT. А в случае интеграции этой поливалки в HA, MQTT становится обязательным требованием.
Конкретно, если рассматривать поливалку, если ей не хватит памяти при статической инициализации, то никакая динамика ее не спасет.
Почему не спасёт? Например, если не хватает памяти для 10 датчиков и 512-байтного буфера для SD-карты, она просто об этом сообщит и пользователь будет вынужден или ограничиться 9 датчиками, или отказаться от протоколирования на SD-карту.
Неприятность динамического выделения в двух местах. Первое - это сегментирование. Второе - это привычка им пользоваться забывая про первое.
С этим никто не спорит. Но для решения этой проблемы известны пути решения.
Например, если не хватает памяти для 10 датчиков и 512-байтного буфера для SD-карты, она просто об этом сообщит
Где то в в давно забытом шкафчике есть давно забытая коробочка. На ней засветилась красная лампочка.
Потому что пользователь добавил датчик или включил протоколирование на SD-карту и ушел не посмотрев на результат? )))
Вся надежда на программиста. Он всегда обрабатывает исключительные ситуации. Правда?
Тут чего-то разделили пользователя и программиста. В данном примере есть только программист. Он сконфигурировал поливайку, она либо при компиляции не влезла в память, либо при первом запуске завалилась.
У пользователя никаких вариантов нет, кроме того, что уже умеет устройство. Поддерживает 10 датчиков, значит в нем уже есть память под них. Даже если сейчас только 2 подключено. Было бы странно докупив еще комплект датчик+насос и выбрав в меню большее количество получить красную лампочку.
Тут чего-то разделили пользователя и программиста.
Не предлагать же своей жене или тёще перепрошивать МК, если захотелось добавить цветок или датчик из фиалок переставить в алоэ?
Поддерживает 10 датчиков, значит в нем уже есть память под них.
А то, что количество поддерживаемых датчиков может зависеть от параметров задаваемых пользователем Вы так и не смогли представить?
А то, что количество поддерживаемых датчиков может зависеть от параметров задаваемых пользователем Вы так и не смогли представить?
Пользователь: меняет настройки. Программа: падает, настройки несовместимы с количеством памяти. Представить могу, конечно. Но такие шедевры , слава Б-у, не попадались.
Пользователь: меняет настройки. Программа: падает, настройки несовместимы с количеством памяти.
Вы просто не умеете программировать, поэтому и не можете представить, что программа при ошибке выделения памяти может не падать, а внятно информировать пользователя, какие из заданных им параметров можно изменить и в какую сторону, чтобы программа могла продолжить работу.
На ESP32 я прямо в веб-интерфейсе такие параметры подсвечивал, что даже домохозяйке должно быть понятно.
такие шедевры , слава Б-у, не попадались
Если Вы ни разу не сталкивались с нехваткой памяти на принтерах, коммутаторах, роутерах и т.п., то это говорит лишь о недостатке Вашего опыта.
Если Вы ни разу не сталкивались с нехваткой памяти на принтерах, коммутаторах, роутерах и т.п., то это говорит лишь о недостатке Вашего опыта
Или я просто везучий ;) Чтобы словить баг в кофеварке, и уверенно продиагностировать именно нехватку памяти - нужно быть очень талантливым и везучим тестировщиком. Ну, и я надеюсь, что прошивки для кофеварок таки тестируются, и когда там обнаруживают такое поведение - программистов лишают смузи, а каждого 10-го бьют палкой.
Не нужно увеличивать количество говнокода. Отличный пример как не надо делать.
То есть, кофемашина знающая только восемь рецептов приготовления кофе, заложенных производителем - это хорошо. А кофемашина, поддерживающая множество задаваемых пользователем рецептов, количество которых ограничено лишь доступной памятью - уже говнокод? )))
Кофемашина с записью рецептов - хорошо. Говнокод, который никто не тестировал, навайбкодили и в прод - плохо. Ложная дихотомия - один из приемов демагогии, плохо.
Множество пользовательских рецептов - хорошо.
"Пользовательских рецептов 3 из 10 возможных. 7 свободно.
[ДОБАВИТЬ][УДАЛИТЬ]"
- допустимая картинка на экране.
Ваше предложение выглядит как сообщение на смартфоне: Можете включить запись видео, 7 видеозаписей осталось )))
Рецепты могут занимать разный объем памяти. Теоретически, можно такой рецепт наворотить из смеси зерен разного помола и жарки, что он вообще всю память займёт.
Память, в которую влезут абсолютно все рецепты в мире, стоит как несколько чашек кофе.
Только если найдется идиот, который в кофемашину установит SSD. Это даже не считая усложнения схемотехники и снижения надёжности устройства при использовании внешней памяти для МК.
Можно на Ваш github взглянуть? На мой то я не раз уже ссылки давал. И насколько сложно использовать внешнюю память, там хорошо видно.
Сколько стоит микро sd карта на 16 Гб? Сколько места занимает 1 рецепт? Если в виде циклограммы - в какой момент какой релюшкой щелкать - наверное, 1К. Пожалуй, все существующие рецепты кофе влезут в вашу esp32 ;)
микро sd карта
Вот это я и называю идиотизмом. Вы бы еще программы лифта предложили на SD-карте держать )))
Сколько места занимает 1 рецепт?
Сначала дайте ссылку на Ваш github, а потом я буду отвечать на подобные вопросы.
Сколько стоит emmc память? На каком волшебном принципе работает память в вашем esp32?
Упсь, я дверью ошибся. Тут экзамен идет. Ухожу, ухожу..
:D
Точно ошиблись. Коллеги как то делали на ПЛК110 Овен только обжарку кофе. Ну так не хватило 6МБ энергонезависимой памяти на борту для всех рецептур, которые хотел заказчик. Пришлось делать загрузку рецептур из CODESYS по Ethernet.
не хватило 6МБ
Ну, не хватило и не хватило. Нет такой памяти, которую невозможно занять всю. Просто интересно, что такое рецепт. Если текстовое описание - пару килобайт. Если программа на lua - то же в принципе. Если видеоинструкция - ну, тут никакого ssd не хватит.
Для недорогих ростеров стоимостью до миллиона рублей обычно используются opensource Artisan. Там репозиторий не больше гигабайта, так что вполне можете склонировать и изучить.
Для чего-то более серьёзного используется уже проприетарный софт и ПЛК.
программа на lua
Lua плохо подходит даже для ПИД-регулирования, не говоря уже о более сложных моделях прогнозирования. Из простого, тут скорее Python с numpy и прочими библиотеками на C/C++.
Вам не хватило памяти для рецептов. Вот я и интересуюсь, что такое рецепт. Если это та кривая с readme - если ее тупо задать по точкам - 16 байт на точку. 16 К на 1000 точек. Если использовать сжатие - меньше.
Но раз вам не хватило 6 Мб, значит вы хранили что то другое.
Я же дал ссылку на репозиторий! Изучите код. Откуда я знаю о какой кривой Вы речь ведете: температуры воздуха, зёрен, нагревателей или влажности, кислотности, насыщенности одного из контрольных цветов, скорости одного из приводов или вентиляторов?
В src/test/data/profile1.json лежит пример простого тестового профиля. Вот и изучите его для начала.
Но раз вам не хватило 6 Мб, значит вы хранили что то другое.
Даже в пределах одной партии зерен технологу нужно больше десятка программ. Не говоря уже о разных программах для разных сортов, разного географического происхождения и разных годов урожая кофе.
Коллеги как то делали на ПЛК110 Овен только обжарку кофе. Ну так не хватило 6МБ
Это промышленное. Если сравнивать с этим, то тогда и по теме - управление теплицами на ферме. Здесь же - домашняя поливалка цветов и пользователь не видевший ничего сложнее лейки.
Память, в которую влезут абсолютно все рецепты в мире, стоит как несколько чашек кофе.
Пользователю дома не нужны все рецепты мира. После того как он наиграется, в работе остаются 2-3 ежедневных рецепта. Можно использовать как маркетинговую фишку, но, сомневаюсь, что всей емкостью будут активно пользоваться.
Неужели это не диагностический режим? Это допустимо на этапе конфигурирования. Но это не для "пользователя".
Пользователь: меняет настройки. Программа: падает, настройки несовместимы с количеством памяти. Представить могу, конечно. Но такие шедевры , слава Б-у, не попадались.
Программы попадались, это еще меньшее из зол.
А вот когда так начинает вести себя устройство с 5 кнопками... Хорошо, если есть кнопка (или способ) сброса к заводским настройкам.
А то, что количество поддерживаемых датчиков может зависеть от параметров задаваемых пользователем Вы так и не смогли представить?
Для устройства, которое используется еще кем-то кроме его создателя, это плохой дизайн.
Не предлагать же своей жене или тёще перепрошивать МК, если захотелось добавить цветок или датчик из фиалок переставить в алоэ?
Не предлагать. Придумайте интерфейс пользователя заново.
Для устройства, которое используется еще кем-то кроме его создателя, это плохой дизайн.
Ну так отберите у жены и тёщи смартфоны, ведь там тоже памяти может не хватить )))
А то ведь такой ужас! Снимает пользователь видео, а ему вдруг смартфон заявляет, что память закончилась. Очень интересно, какой же дизайн собрались предложить для этого Вы? )))
А то ведь такой ужас! Снимает пользователь видео, а ему вдруг смартфон заявляет, что память закончилась. Очень интересно, какой же дизайн собрались предложить для этого Вы? )))
О, как это знакомо. Контролировать объемы, не допускать переполнения, предупреждать о нехватке ресурсов - все правильно. Сложно - придумать как это сделать на языке пользователя, чтобы было понятно, не мешало работать и не приводило к неожиданным проблемам.
Было у меня на каком-то предыдущем смартфоне. Программы просто наедались, рос кэш, росли данные. И какая-то мелкая но очень нужная, хоть и редкоиспользуемая программка в одном из своих экранов просто выдавала пустой список вместо моих данных. Через аккаунт на сайте я все вижу, а клиент не показывает. Хорошо, я интуитивно глюки чую (работа такая), память подосвободил, к жизни вернул.
Сумеете предложить грамотный дизайн поливалки с наращиваемым количеством горшков, чтобы любая домохозаяйка справилась - отлично. Требования - любое (пока памяти хватит) количество горшков и любое расписание на каждый (элемент расписания, будильник, тоже отъедает память). Управление - только через меню. Уровень подготовки - нулевой, т.е. не сложнее бытовой техники на кухне.
Я с такими случаями сталкивался. Проще - сразу сказать что 10 горшков, в каждом по 3 расписания. Хочешь больше - бери второе устройство. Хотя как программист я знаю, что можно 15 горшков втолкать с 1 расписанием. Или 5 горшков, но где-то 10 расписаний, где-то 1...
Сложно - придумать как это сделать на языке пользователя, чтобы было понятно, не мешало работать и не приводило к неожиданным проблемам.
Ничего сложного. Я же уже давно писал решение:
"внятно информировать пользователя, какие из заданных им параметров можно изменить и в какую сторону, чтобы программа могла продолжить работу.
На ESP32 я прямо в веб-интерфейсе такие параметры подсвечивал, что даже домохозяйке должно быть понятно."
Вы правда планируете использовать сенсор так, как изображено на предпоследнем фото? Насколько его хватит, как думаете ?
В таких проектах основная сложность монтаж и обработка аварий...
Вы правда планируете использовать сенсор так, как изображено на предпоследнем фото?
Если он не ёмкостный, то питание подавать только на время опроса. Это конечно должно быть предусмотрено в схеме.
Capacitive Soil Moisture Sensor v2
Судя по слову Capacitive, он емкостный
Согласен. Какой-нибудь MOSFET использовать. В следующей версии скорректирую.
А если датчик немного более чем ёмкостный то питание не стоит отключать? Или все таки добавить эту фичу?
За статью и старания большое спасибо! Надо дальше расти, прикручивать взрослые вещи на контроль ошибок (как мы мониторим наличие/отсутствие/неисправность датчика, как мы отслеживаем исправность насоса, наличие воды. Вотчдог не повредит)
Электронику платы датчика не помешает в специальный лак закатать. Датчики можно по питанию включать и выключать, выдерживая время готовности для замера
В лак закатал края платы сенсора. Планирую добавить управление питанием датчиков. А вот как мониторить неисправности(датчика\насоса) пока сложно представляю. Долив воды планирую сделать с поплавковым клапаном.
Аналоговые значения выхода датчика обычно никогда не бывают 0 и 1023, можно отслеживать выход за диапазон. Цифровые датчики обычно имеют библиотеки, там часто есть функционал контроля наличия датчика, даже у простейшего ds18b20 это есть. Наличие воды и исправность насоса можно контролировать косвенно (полили X секунд, через Y минут должна вырасти влажность почвы), напрямую либо датчики уровня (если это ёмкость), либо датчики давления, если это водопровод. Датчики давления бывают вечные промышленные 4-20мА и все остальное дендрофекалити. Насосы можно мониторить датчиками тока или датчиками давления
Классная статья!
А можете расписать список покупок? Что входит помимо сенсора и ардуины?
Я покупал набор с Али. Там ещё насосы и блок реле: https://a.aliexpress.com/_oDFKljH

А где диоды параллельно каждой помпе?
также раз у вас реле ими щёлкает (хотя я бы поставил по транзистору с контролем тока (шунт... можно один для всех на общий и если насосов много - то возможно ещё один общий ключ на случай отключения всей цепи), но параллельно контактам нужна RC цепочка... тут достаточно 0.1 мкф плёнка/керамика + 1...10 Ом
Но такой подход аппаратной избыточности возможно не всем подходит, речь про доп коммутацию питания и измерения (диоды и RC тут обязательны!)
Можно глянуть на промку как это сделано.
Поставил диод 1N4007, однако в моем случае это вряд ли поможет - у меня отдельный аккумулятор для насосов.


Паранойи много не бывает ;) чуть меньше износ контактов; протянут не 10 лет а все 20 ;)
однако в моем случае это вряд ли поможет
и для @randomsimplenumber что бы два раза не писать:)
Паранойи много не бывает ;) чуть меньше износ контактов; протянут не 10 лет а все 20 ;)
Так это для того что бы из за обратной ЭДС не было высоковольтной искры которая для такого монтажа словно РЭБ девайс :) На катушку реле также ставят - на плате блока реле видно стеклянный красный 1N4148 около каждого реле.
Расскажите о механической части - конструкция насоса с поплавком, зачем так, какая проблема решалась?
Как решается проблема медленного смачивания почвы? До момента попадания влаги на датчик насос может накачать достаточно много воды в горшок.
Насос с поплавком потому что насосы пришли с концами проводов только 20см. Я удлинил канешна же провод и соединения сделал с термоусадкой, но мне всё равно не нравится что соединение находится в воде. А с поправком уже лучше.
А вот проблема медленного смачивания почвы думаю решать увеличением интервала опроса датчика, за один опрос - один полив, до того момента пока налившаяся вода не впитается(методом проб и ошибок канешна же).
А теперь давайте ближе к реальности. Я вижу, у вас автономное питание. Рассказывайте, сколько система живет по времени без участия человека. Надолго ли можно уехать в отпуск оставив цветы под присмотром этого устройства.
Я тоже такую штучку собираю. Только не на датчиках влажности, а на расписании со счетчиком воды.
За четыре дня работы берите показатели


По МК более интересно. Переведите в дни живучести. Разряд линейный? Начальное значение какое? Минимальное при котором еще работает какое?
И показательнее токи померить. В режиме контроля и в режиме активного реле. Ну я больше вас спрашиваю, потому что по спецификации я знаю потребление МК и релюшек.
Дополню. Посмотрел графики разряда аккумуляторов. Если две банки дают 5.35, то одна, скорее всего дает половину - 2.675, а на графиках это уже за пределами линейного участка разряда, и дальше крутое пике в ноль. И это уже не рекомендованное состояние по разряду - сильно влияет на износ.
Вот как я поменял значения:
https://github.com/Akullaaa/pumpController/commit/46d272f37a00d0e030d79d9649b524239755292f

Добрый день!
Делал я нечто подобное на той же Ардуинке, с тем же датчиком, но с другой помпой. Мои заметки:
1. Датчики нужно обязательно покрывать лаком со всех сторон (и торцов тоже). Штатное исполнение не защищает от влаги, она скоро проникнет к электродам, и начнутся глюки с показаниями.
2. Датчики нужно запитывать от образцового напряжения, иначе показания так же "плывут".
3. Для стабильности измерений я брал среднее из нескольких измерений.
4. Каждый датчик нужно калибровать индивидуально.
5. Крайне нежелательно проводить замеры при работающем насосе. Как бы ни фильтровал -- будут погрешности.
Можно использовать BlueTooth/ZigBee влагозащищенные датчики, что автоматически решает первые две проблемы и последнюю.
Для стабильности измерений лучше медиана, чем среднее.
При большом количестве датчиков я бы предпочёл насосам гидроаккумулятор и электромагнитные клапаны, что позволило бы подключать цепочкой, а не звездой. Но это уже дело вкуса.
При большом количестве датчиков я бы предпочёл насосам гидроаккумулятор и электромагнитные клапаны, что позволило бы подключать цепочкой, а не звездой. Но это уже дело вкуса.
Думаю, тут достаточно будет резервуара приподнятого на пару метров и самотека. Качать в резервуар по поплавку. В общую магистраль импульсный счетчик воды. Лить в каждый горшок по количеству. Повторная поливка по высыханию, но опять по количеству - этим избегаем проблему перелива из-за медленного смачивания. Аварийные ситуации типа "всегда сухо" или "всегда мокро" переводит горшок в поливку строго определенным минимальным количеством, чтобы только цветок не сдох.
достаточно будет резервуара приподнятого на пару метров и самотека
Так это и есть один из видов гидроаккумуляции. Причем весьма популярный до сих пор в странах с мягким климатом. И, насколько я знаю, единственный используемый в гидроаккумулирующих электростанциях.
В общую магистраль импульсный счетчик воды.
Я бы не усложнял аппаратную часть, так как ПИД регулирование даст куда более точный результат, позволяя поддерживать влажность в заданных пределах. Да это и проще, чем анализировать дебет воды и испарение, в зависимости от температуры, влажности воздуха и попадания солнечных лучей на почву.
Аварийные ситуации
Тут огромный простор для деятельности. Например, в Невинномысске у нас почти везде тройное резервирование плюс автоматические чисто аппаратные аварийные системы. Так что всё зависит от паранойи создателя системы )
Для дома я бы в аварийной ситуации просто обесточивал систему. Слишком мокро - возможно будет выливаться из горшка. Слишком сухо - возможно трубка полива вывалилась из горшка и льет на пол. Лучше цветочки засохнут, чем залить соседей. Но это моё субъективное мнение.
Для дома я бы в аварийной ситуации просто обесточивал систему. Слишком мокро - возможно будет выливаться из горшка. Слишком сухо - возможно трубка полива вывалилась из горшка и льет на пол. Лучше цветочки засохнут, чем залить соседей. Но это моё субъективное мнение.
Для себя - все цветы в поддоне, объем заведомо больше резервуара. Объем резервуара достаточен для всего срока отсутствия. Датчик протечки в поддоне, контроль уровня в резервуаре, мониторинг питания, контроль объема налива - при выходе за допустимые значения СМС на телефон "я сделал все что мог", переход в аварийный режим (смотря какой отказ) и попытка дотянуть пока едет помощь.
Понимаю, что тут перебор по функциональности и паранойя зашкаливает, но у меня это игрушка, я так пар после работы спускаю.
попытка дотянуть пока едет помощь
Мои заказчики почти всегда такое исключают, так как всё предусмотреть невозможно. Но при 500 градусах и 350 атмосферах последствия могут быть куда хуже, чем при заливе соседей водой )
паранойя зашкаливает
Так у меня тоже самое. С "Невинномысским азотом" проект закончили, так теперь бразильские заводы начались )
Приветствую ! Спасибо за статью. Тоже недавно приобрел такой сенсор. Буду смотреть. А пока:
Динамическое добавление насосов в класс контроллера. Для добавления насоса в контроллер надо добавить строку:
С одной стороны динамическое. С другой --- нужно модифицировать прошивку и перешивать.
с классами
SoilSensor,
PumpController, ProcessStats иPump,
NIT. Форматирование не везде.
на микроконтроллерах Arduino
NIT. ИМХО здесь лучше использовать слово платформа (которое вы как раз далее используете).
// Буфер для форматированной строки
char buffer[100];
Захардкоженное значение. Я бы использовал:
constexpr uint8_t gBufferSize = 100;
char buffer[gBufferSize];
Но вообще я предпочитаю конфигурацию хранить в отдельном файле. Типа config.h
. Так скетч не захламляется.
// Инвертированные значения HIGH и LOW
const int MYHIGH = LOW;
const int MYLOW = HIGH;
Тут уже сказали про это. Имя плохое. Более того, int
здесь избыточен может быть. Достаточно uint8_t
, хотя надо смотреть, что там по памяти будет. В любом случае, всякие digitalWrite
uint8_t
ожидают, ЕМНИП.
unsigned long minTime = 0xFFFFFFFF; // Максимальное значение unsigned long
Я бы поглядел в limits.h
: тут . Т.е.
#include <limits.h>
...
unsigned long minTime = ULONG_MAX;
// А ещё лучше
typedef unsigned long ms_t; // Или time_t
...
ms_t minTime = ULONG_MAX;
// Метод для добавления насоса
bool addPump(SoilSensor sensor, int pumpPin, unsigned long pumpDuration) {
Я бы ещё добавил проверку на пересечение. Т.е. что будет, если я пытаюсь добавить насос на занятый пин ? С другой стороны, ниже в setup
я не вижу проверки статуса добавления.
// Класс контроллера насосов
class PumpController {
private:
Pump** pumps; // Массив указателей на насосы
Как альтернатива, можно использовать шаблоны, и сделать класс
template <uint8_t N = 10>
class PumpController {
private:
Pump*[N] = {}; // ЕМНИП тут уже нулевые указатели, но проверьте
public:
static constexpr MaxN = N; // если надо
}
// Инициализация последовательного порта
Serial.begin(9600);
Зачем такая низкая скорость ? Не, я понимаю, что тут, наверное, не бутылочное горлышко, но подозреваю, что это сделано, потому что в тутриалах так.
// Добавление насосов в контроллер
pumpController.addPump(SoilSensor(A0, 800, 100000), 2, 2000); // Насос 1
pumpController.addPump(SoilSensor(A1, 275, 16000), 3, 2000); // Насос 2
pumpController.addPump(SoilSensor(A2, 600, 700000), 4, 2000); // Насос 3
pumpController.addPump(SoilSensor(A3, 700, 7000000), 5, 2000); // Насос 4
Как я уже сказал выше: не вижу проверку статуса добавления. И так, просто мысли вслух: я вижу тут проблему, что сенсоры приколочены к контроллеру. Т.е., если мне надо сенсор, ещё как-то использовать, то я этого сделать не могу, потому что он только внутри контроллера существует. Может быть, лучше было сделать так:
Pump::Pump(const SoilSensor* sensor);
// и
bool PumpController::addPump(const Pump* pump);
И тупо в скетче (скорее всего где-то вру, но набросок) :
SoilSensor(A0, 800, 100000) sAloe;
SoilSensor(A1, 275, 16000) sLemon;
SoilSensor(A2, 600, 700000) sCactus;
Pump pAloe(&sAloe);
Pump pLemon(&sLemon);
Pump pCactus(&sCactus);
PumpController p;
p.addPump(&pAloe);
p.addPump(&sLemon);
p.addCactus(&pCactus);
На мой взгляд так выглядит нагляднее. И возникает возможность использовать один насос на несколько датчиков, если нужно.
P.S. Вот такой тред есть:
https://www.reddit.com/r/arduino/comments/q1anwt/beware_of_faulty_capacitive_soil_moisture_sensors/
P.P.S. А почему >
для цитирования не работает ?
Контроллер управления насосами полива на Arduino Uno с сенсорами Capacitive Soil Moisture Sensor v2