Как стать автором
Обновить

Автополив домашних растений с помощью кибернетики

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров2.1K

Добрый день, целью данного проекта было создания устройства для автополива комнатных растений из недорогих и доступных компонентов, которые можно заказать на AliExpress для реализации конечного изделия. Система построена на базе SoC CH32v003, на основе самой распространенной платы без кварцевого резонатора (на момент написания статьи она стоит 50 руб). Все исходники и чертежи в открытым доступе тут https://github.com/Levon24/ch32-auto-watering

Внешний вид поливатора
Внешний вид поливатора

Электрическая схема устройства использует готовые блоки, из навесного оборудования ключ для управления насосом автополива, его лучше построить на современной элементной базе полевых транзисторов, однако у меня завалялось много советских транзисторов по типу КТ601, КТ602, КТ815 на которых я и собрал ключ для управления помпой.

Схема принципиальная
Схема принципиальная

Чертежи блока управления находятся в каталоге Docs, там же 3D модель и схема устройства. Как видно на картинке ниже, большая часть прототипа устройства выполнена навесным монтажом и пока не закончена, так как проект все еще находится в процессе доработок.

Устройство блока управления
Устройство блока управления

Также стоит оговориться, что измерять влажность мы будем в "условных" процентных. Я не закончил институт на агронома и у меня нету точных приборов для измерения влажности почвы и сравнению показателей. Подробнее про влажность почвы, можно прочитать, например, тут или в ГОСТ 28268-89. На сколько я понял, для получения показателей сухой почвы, её выпаривают в сушильном шкафу и эту цифру берут за 0%. Для получения максимально влажной почвы, её обильно поливают, лишняя вода уходит и сколько воды может задержать почва - это и есть 100%. Меняется почва, меняется и объем воды, который почва может задерживать. Для калибровки прибора я использовал стакан воды, в стакане нет воды - это 0%, в стакане вода - это 100%. Даже при таком простом подходе я получал немного разные показатели, однако это точнее чем измерять влажность пальцем и для определения момента начала полива воды как мне показалось достаточным.

Изначально я взял для устройства распространенный резистивный датчик для измерения влажности почвы и, как видно из схемы выше, подал сигнал на вход АЦП. Измерять данные им было удобно, от 0в до напряжения питания 3.3в. В контроллере 10битный АЦП, так что значения получались от 0 до 1023 и их удобно было преобразовывать в проценты влажности. Однако потом что-то пошло не так и датчик ушел в обрыв.

Шуп окислился и перестал проводить электричество
Шуп окислился и перестал проводить электричество

Собственно процесс окисления электродов датчика как оказалось известный. Оригинальное решение проблема можно посмотреть тут. Однако, чтобы не бороться с ветряными мельницами, лучше использовать емкостные датчики. С ними тоже есть проблема, находчивые китайцы ставят перемычку вместо стабилизатора U2, у таких датчиков показания будут плавать, если их не запитывать от стабильных 3.3в. Я же планировал использовать lion аккумулятор и в идеале использовать только солнечную батарею для работы устройства.

Емкостной датчик
Емкостной датчик

На маркете существует 2 версии датчика, v1.2 и v2.0.0, результаты измерений влажности методом стакана воды показали незначительные отклонения результатов измерения, но их можно прописать в исходниках, либо вынести в настраиваемый параметр в меню для калибровки (планируется в следующих версиях).

Для отображения данных был выбрал oled display с разрешением 128х32. На нем отображаются текущие показания, а так же график влажности по времени. В настройках можно указать целевое значение для влажности почвы. На дисплее отображаются 2 параметра, M - влажность почвы и F - значение потопа. Сам дисплей подключается по 2 проводам и работает по протоколу i2c. Стоимость дисплея в районе 100руб.

Отображение информации
Отображение информации

Итак, если влажность почвы недостаточная, то прибор начинает непрерывно подавать воду до порога отсечки по времени, либо до набора почвы необходимой влажности. Порог по времени настраивается в исходниках, я использовал самый маленький насос CJWP08 стоимостью порядка 50 рублей, поэтому поставил порог на 30 секунд непрерывного полива. Далее помпа переходит в капельный режим работы и раз в определенное время выдавливает каплю воды, пока не достигнет необходимой влажности.

Так же для работы прибора потребуются 4 кнопки и прототипная плата 2x8 см. В итоге цена изделия, получается в районе 300 руб, а сколько радости оно подарит, тут каждому самому решать.

Как видно на картинке выше, устройство содержит опционально аккумулятор для резервного питания. На плате устройства в цепи питания находится диод, он выпаивается и проводами подсоединяется любой контроллер заряда АКБ, можно использовать линейный на базе TP4056 или более современный MPPT. У меня более современный начинал тихо свистеть, когда питался от солнечной панели, т.к. она не обеспечивала достаточного тока. Если все же будет выбрана опция с солнечной батарей - то нужно следить за напряжением питания, если оно снизится ниже 3.3в то показания датчика влажности поплывут. Я планировал сделать защиту от этой проблемы, но пока у меня лапки не дошли до реализации.

От схемы устройства переходим к исходникам, драйвер дисплея тут самописный, находится тут display.c и в основе своей реализует минимальный функционал для работы. Самое мне непонятное оказалось - это управление контрастностью дисплея, такое чувство, что дисплей игнорирует этот параметр, а регулировки яркости я не нашел. Может кто подскажет?

void displaySetContrast(uint8_t value) {
  displaySendCommand(SSD1306_SET_CONTRAST);
  displaySendCommand(value);
}

Для отображения шрифтов используется базовой шрифт 8х8, находится в файле fonts.c и кроме него я больше шрифтов не стал добавлять. Особенностью шрифтов для дисплеев SSD1306 является их поворот на 90 градусов. Была идея подергать шрифты из ZX Spectrum машин, но в конечном счете дисплей очень маленький, плохо видно.

Для хранения истории используется массив из показателей, который сдвигается по таймеру влево. Были планы на основе статистики показаний высчитывать оптимальный полив, но на практике эти данных имеют смысл только на графике. Возможно в следующей версии данные будут отправляться в брокер MQTT с последующим отображением в grafana.

uint8_t chartValues[128];

/**
 * @brief IRQ Timer 2
 */
void TIM2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM2_IRQHandler(void) {
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
    if (seconds < CHART_SECONDS) {
      seconds++;
    } else {
      seconds = 0;
      
      for (uint8_t p = 127; p > 0; p--) {
        chartValues[p] = chartValues[p - 1];
      }
      chartValues[0] = moisture;
    }
    
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 
  }
}

А вот с отображение графика возникли вопросы, изначально в оставшуюся высоту в 3 линии по 8 бит я хотел отобразить от 0 до 100% значения, но тогда график становился линией и не нес смысловой нагрузки. В итоге график показывает отклонения от целевой влажности в единицах процентов +10 и -14, если целевое значение влажности 80% то график будет отображать часть от 66% до 90%, что оказалось удобнее.

  for (uint8_t position = 0; position < 3; position++) {
    for (uint8_t p = 0; p < 128; p++) {
      uint8_t value = chartValues[p];

      uint8_t maxValue = minMoisture + CHART_MAX;
      if (value > maxValue) {
        value = maxValue;
      }

      uint8_t minValue = maxValue - CHART_SIZE;
      if (value < minValue) {
        value = minValue;
      }

      value = value - minValue;

      if (value > (2 - position) * 8) {
        uint8_t level = value - (2 - position) * 8;
        if (level > 8) {
          level = 8;
        }
        displayLine[p] = levels[level];
      } else {
        displayLine[p] = 0;
      }
    }
    displaySendData(position, displayLine, sizeof(displayLine));
  }

При работе с дисплеем всплыла интересная особенность, если аккумулятор дохлый, у меня такие и есть в наличие. Тогда может не хватить энергии в пике для запуска дисплея, тогда следует подсоединить по питанию дисплея электролитический конденсатор на 470-1000 мкф (на фотографии он есть).

В целом на этом, наверное, пока все. Если идея понравилась, могу позже дописать расчеты по солнечной батареи и расходу электричества устройством. Так же можно, наверное, использовать 8 каналов АЦП для контроля и 8 портов для управления помпами, однако я пока такой цели на ставил.

Всем спасибо, мира и добра!

Теги:
Хабы:
+8
Комментарии10

Публикации

Ближайшие события