Як я зібрав smart-підставку для квітів і навіщо я це зробив

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Всім привіт, мене звуть Олександр Вітер і я працюю Senior Software Engineer у компанії SoftServe. За майже 10 років в ІТ я встиг попрацювати у різних напрямках й доменах, але у цій статті мова піде про мій пет-проєкт. Чи, точніше, плант-проект 🙂

Думаю, не існує такої людини в Україні, для якої війна не була б надвеликим стресом. Різні люди справляються з цим стресом по-різному, в залежності від того, у кого до чого лежить душа: хтось із головою пірнає в роботу, хтось заїдає стрес смачненьким, а хтось навіть стає а̶л̶к̶о шопоголіком.

Я почав вирощувати квіти, щоб на якомусь абстрактно-психологічному рівні компенсувати оточуючі смерть і руйнування. Як казав пан Зеленський: «Життя переможе смерть».

Звісно, коли айтішник за щось береться, воно не може бути «як у всіх нормальних людей» — треба обов’язково додати якусь автоматизацію і перетворити всю ідею у цирк на дроті зі скрам-покером й тестувальницями. З чого все почалося та до чого дійшло і піде мова у цій статті.

Проблема

Коли я тільки почав саджати перші кісточки від авокадо та спостерігати за тим, як йде ріст, то помітив, що ця рослина не така жвава, як, наприклад, соняшник, що обертається за сонцем протягом дня.

В результаті, для мене подальших варіантів було декілька:

  1. Найпростіший, явно не наш шлях, — змиритися з тим, що рослинка не повністю використовує сонячну енергію і дозволити їй рости у повільному темпі.
  2. Шлях, що потребував додаткових витрат — купити додаткове обладнання, щоб покращити рослині умови життя.
  3. Як казав Мандалорець: «This is the way» — зібрати все необхідне самостійно, з того, «що є під рукою у кожної, поважаючої себе домогосподарки».

Рішення

Враховуючи обраний варіант дій та той набір речей, які вже давно валялися на поличках від минулих незавершених проєктів, я вирішив, що цілком можна зібрати «smart підставку для квітів», яка буде вдень обертати горщик з рослиною оптимальним чином.

Прикладом подібної поведінки можуть слугувати розумні сонячні панелі, які не закріплені стаціонарно, а можуть обертатися таким чином, щоб максимально ефективно поглинати сонячне світло (зазвичай, займаючи положення, перпендикулярне падінню сонячних променів).

Переді мною стояла дуже схожа задача, тільки замість сонячних панелей були листя рослин, які треба було підставляти сонячним променям під найкращим кутом.

Цю велику задачу можна було розділити на декілька підзадач, умовно поділених на 2 групи:

Hardware:

  • власне, сама підставка, що може обертатися і при цьому витримувати вагу горщика з рослиною;
  • двигун, щоб обертати підставку на потрібний кут;
  • контролер, щоб керувати двигуном.

Software:

  • логіка для передачі команд від контролера до двигуна;
  • логіка для визначення потрібного часу для обертання (у різні дні сонце сходить та заходить у різний час, а вночі взагалі немає сенсу обертати рослинку);
  • математична логіка для визначення оптимальних кутів повороту підставки, враховуючи такі фактори як: час сходу та заходу сонця; частина світу, на яку виходить вікно, на підвіконні якого стоїть підставка з рослиною; оточуюча архітектура, будинки, що блокують сонячне світло у той чи інший час.

Хардверна частина була закрита наступним чином: у якості підставки я використав старий кулер від стаціонарного комп’ютера у поєднанні з деякими елементами конструктора Lego. За рух відповідав сервопривід MG996R, а у якості контролера використовувався міні-комп’ютер Raspberry Pi 4, на якому я колись запускав власних Telegram-ботів.

Щодо першого пункту з розділу Software, все було досить нескладно, бо і Raspberry Pi, і обрана модель сервоприводу є досить популярними у DIY (do it yourself) ком’юніті, так що знайти інструкцію з налаштування не склало проблем.

Єдиним не досить очевидним моментом тут була не зовсім продумана конструкція кабелів сервоприводу, через що довелося використовувати додаткові джампери, щоб з’єднати сервопривід і міні-комп’ютер. Проте це ніяк не вплинуло на якість їхньої роботи, лише трошки зіпсувало естетику виробу.

З двома іншими софтверними пунктами довелося трохи згадати геометрію та астрономію, бо ці знання не використовувалися практично зі шкільних років.

Фінальна версія проєкту працює приблизно ось так:

Я кажу саме «приблизно», бо на відео показаний загальний механізм роботи з іншим (демонстраційним) скриптом, а не з тим, з яким воно фактично працює.

Це зроблено для того, щоб у короткому відео продемонструвати, як все рухається на практиці і при цьому глядачеві не довелося чекати (а мені — знімати і робити таймлапс) реальних 10-15 годин роботи, коли підставка зміщується на невловимі оком долі міліметра кожні 5-10 хвилин.

Код рішення

А ось власне і код, який всім цим керує:

import time
import json
import pytz
import lgpio
import requests
from dateutil import tz
from datetime import datetime, tzinfo

PIN = 17  # RPi pin id where servo is connected
FREQ = 50  # default for our purpose
LAT, LNG = 46.4769954, 30.7302463  # where your device is located
endpoint = f'https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}&formatted=0'
h = lgpio.gpiochip_open(0)

while True:
    response = requests.get(endpoint)
    response = json.loads(response.text)
    sunrise = datetime.fromisoformat(response['results']['sunrise'])
    sunset = datetime.fromisoformat(response['results']['sunset'])
    sunrise = sunrise.astimezone(pytz.timezone("Europe/Kyiv"))
    sunset = sunset.astimezone(pytz.timezone("Europe/Kyiv"))
    now = datetime.now()
    
    if now.hour == sunrise.hour and now.minute == sunrise.minute:
        lgpio.tx_pwm(h, PIN, FREQ, 4.5)  # go to initial position
        delta = sunset - sunrise
        light_day = delta.total_seconds()
        time.sleep(int(light_day / 4))  # wait until sun will be in the right place
        
        for i in range(100):
            lgpio.tx_pwm(h, PIN, FREQ, 4.5+((i+1)*0.05))
            time.sleep(int(light_day / 200))
    else:
        time.sleep(60)

Деякі коментарі щодо коду, якщо ви захочете адаптувати його під свої потреби:

  1. Ви можете використовувати й інший пін, не обов’язково 17, але тоді треба буде точно знати його id і змінити це значення у коді, інакше сервопривід не буде реагувати на команди вашого коду.
  2. Для максимально точного результату треба буде ввести географічні координати того місця, де буде знаходитися пристрій — від цього залежатиме точний час сходу та заходу сонця, який поверне сервіс api.sunrise-sunset.org, а на цьому базуються всі подальші розрахунки.
  3. Якщо ви знаходитеся в іншому часовому поясі, значення Europe/Kyiv також треба буде змінити, бо сервіс повертає час сходу й заходу сонця виключно в UTC, тому його треба конвертувати у місцевий час.
  4. У мене пристрій стоїть біля вікна, яке виходить на південь, при чому оточуючі будинки закривають частину неба зліва і справа, так що перші та останні 45 градусів руху сонця випадають. На цьому базуються розрахунки стартової позиції й того, скільки поворотів треба буде зробити і як часто. В залежності від того, куди виходять ваші вікна та яка частина неба є відкритою, ці параметри можуть змінюватися. У мене підставка обертається від 45° до 135°, що відповідає передачі значень від 4,5 до 9,5 сервоприводу. Там трохи нелінійна залежність, бо параметр 2 відповідає куту 0°, а 12 — 180°. Всі інші значення між ними — це кути, на які може обертатися сервопривід, і для них треба підбирати відповідні значення.

Щодо рядка time.sleep(int(light_day / 200)), то логіка там така: ми пропускаємо першу чверть сонячного півкола, бо немає сенсу щось робити, доки промені не падають на рослину. Далі у нас є 90 робочих градусів, це половина від 180°, які сонце проходить протягом світлового дня. Отже, нас цікавить лише час light_day / 2.

Але позаяк у нас 100 ітерацій, то кожну ітерацію ми маємо обертати підставку через light_day / 2 / 100 секунд, тобто раз на light_day / 200, що ми й робимо у коді.

Вирощуючи декілька рослин та маючи лише одну подібну smart-підставку, можу сказати, що в цілому у проєкту є як плюси, так і мінуси.

Два плюси рішення

До плюсів можна віднести те, що хоча й не сильно, але все ж таки на підставці рослина росте трохи краще, ніж аналогічна, яка просто стоїть стаціонарно.

Також я б додав у позитивне те, що мені було досить цікаво працювати над хардверно-софтверним проєктом — це додало різноманіття у життя звичайного розробника, коли все, чим ти займаєшся, — пишеш код і спілкуєшся на мітингах, не маючи жодного матеріалістичного підтвердження власної роботи.

Мінусів я б виділив 2+1

1. Не у кожного є «непотрібний» міні-комп’ютер, сервопривід та решта деталей, які потрібні для збірки цього диводевайсу. А купляти все спеціально для цього проєкту не дуже раціонально, особливо, враховуючи ціни на електроніку останніх пари років.

2. RaspberryPi хоча й споживає досить мало енергії, але все ж таки це енергозалежний прилад. Тобто кожен раз, коли у вас вдома немає світла, вся ця конструкція втрачає сенс і рослина продовжує рости у звичайному режимі. Це можна було б вирішити за допомогою павербанку, але тоді вся конструкція починає перетворюватися на якогось монстра, якого просто не хочеться використовувати для такої дрібної задачі, бо це як стріляти артилерією по горобцях.

3. (Опціональний мінус) У нас вдома живе киценька, яка дуже полюбляє гризти рослини та дроти. Так що така конструкція, як рослина в оточенні дротів, привертає її увагу з подвійною силю і вимагає додаткового захисту «від нападу хижаків». І якщо раптом одного дня цей захист не впорається — я залишусь і без проєкту, і без рослини.

UPD: вже під час роботи над статтею киценька таки дірвалася до рослин, тому вони, на жаль, мають не дуже презентабельний вигляд, але, наче, живі і продовжують рости.

Якщо цей проєкт надихнув вас на власні ідеї або ви раніше вже робили щось цікаве з Raspberry Pi — діліться у коментарях.

👍ПодобаєтьсяСподобалось14
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Привіт! Вау. Прикольна ідея, зберегла собі у список того, чим буду займатися на пенсії (якщо все буде добре)

Девайс прикольний, але

листя рослин, які треба було підставляти сонячним променям під найкращим кутом

це трохи сумнівна теза, надлишок сонячного світла може привести до опіків на листках. Та й загалом, більшості кімнатних рослин краще саме розсіяне світло, а не прямі сонячні промені. Ну і питання наскільки ок рослині буде постійне смикання під час поворотів підставки

Я сподіваюся там не ваша локація захардкожена у коді?

LAT, LNG = 46.4769954, 30.7302463 # where your device is located

Схоже що його. Принайні по стріт вью із його вікон цілком можливий саме такий вид. По фото із вікна цілком можна визначити квартиру. Буду в Одесі може загляну — поговоримо про інформаційну безпеку :-) (жарт, не хочу поки що в Одесу)

Насправді я думав координати винести в окремий конфіг і не світити публічно, але потім вирішив, що всім мабуть буде всеодно до того, де я живу :)
Ну може окрім ТЦК та СП))

Олександре, дякую за точні координати, виїзжаємо...

Ви мені нагадали анекдот :)

Містечко у західноамериканському степу. Салун. За столом сидять два ковбої, місцевий та приїжджий, і п’ють віскі. Раптом по вулиці хтось проноситься на величезній швидкості, палячи на всі боки з пістолетів. У салуні ніхто й вухом не веде. Приїжджий місцевому:
— Білл?
— Так, Гаррі?
— Що це було?
— Це був Невловимий Джо.
— А чому його звати Невловимим Джо?
— Бо його ще ніхто не впіймав.
— А чому його ніхто ще не впіймав?
— Бо він нікому нафіг не потрібен.

Хоча от буквально на наступний день після публікації цієї статті по Одесі шмальнули купою ракет і БПЛА (які слава богу збили), але все падало в тому районі, де я живу. Співпадіння?

Круто 👍 для розвитку особистого. Щодо рослини , то я б купила додаткову підсвідку. Це з власного досвіду кажу, так як маю досить велику колекцію рослин. Теж для мене як антистрес.

бо і Raspberry Pi

Хех. Цілий ПК з інтернетом щоб крутити серву за сонцем :) Пара ІЧ фотодіодів і attiny13 з головою, хоча і на багатоканальному ОУ можна наляпати. Та і ESP12 за 1$ то є, як інтернет дуже треба.
Взагалі без логіки, але гарне освітлення треба — youtu.be/7AuBC-hoP1w

attiny13

то вже інший рівень на якому треба вміти в програмування мікроконтролерів. А так да, безумовно буде дешево сердито і просто)

треба вміти в програмування мікроконтролерів.

Для таких придумали ардуїно, чи ще краще nodemcu з тим же пітоном, js, луа чи С за <2$ з доставкою.

Пара ІЧ фотодіодів
хоча і на багатоканальному ОУ можна наляпати.

...і вийде головка самонаведення ракет від ПЗРК :)

ПЗРК «Авокадо» чудово доповнить інші рослинні назви наявної радянської техніки :D

ПЗРК «Авокадо» чудово доповнить інші рослинні назви наявної радянської техніки :D
LAT, LNG = 46.4769954, 30.7302463 # where your device is located

Тсс, а то зараз на болотах почнуть обдаровані перекладачі працювати і знайдуть ще де розробляють головку самонаведення на сонцеликого :)

Коти — зло. Але ж вони такі милі. Моя добряче пожувала авокадо, після того воно чомусь взагалі не хоче рости. Що вже тільки не робив...і пересаджував. Листя засохло і опало, потім стовбур почав сохнути, далі на стовбурі зʼявились маленькі молоді листочки, і в районі кісточки і знов сохне і відпадає...фігня якась.

Питання до ТС, у вас що авокадо взагалі в воді росте?

В ході довготривалих експериментів Добре Росте в горщику з самополивом. Вирощує вже не в перше . Вони дуже капризні -легко перелити або не долити.

Так, досить довго вже стоїть у воді (з весни так точно), я лише підливаю нову кожні декілька днів, а воно саме регулює, скільки в себе увібрати)
Хоча мабуть треба буде вже саджати у землю, щоб воно нормально пережило осінь та зиму.

Круто. Тема скрампокера з тестувальницями не розкрито)

Колись про це точно буде окрема стаття, але мабуть коли я вже буду на пенсії і не буду переживати щодо своєї репутації та що після подібних статтей мене більше ніхто ніколи на роботу не візьме :D

Raspberry Pi для такого — явно перебір (ну та ви й самі про це пишете), хіба що під рукою лише він.
Якщо мислити як усі люди, то варто було б вирощувати не авокадо, а умовний фікус, якому і так буде нормально, і розвертати його раз на місяць, йому цього достатньо. З іншого боку, відчуття того, що за допомогою програмування вирішив прикладну задачу — безцінне, хай би яким те рішення не було 🙂
До речі, із заголовка подумав, що мова буде про чергову поливалку, яких повно. Іще не бачив, щоб хтось автоматизував саме аспект обертання рослин, це... змушує задуматися. Можливо, професійне виконання у вигляді дуже плоскої підставки, де б в одному сантиметрі висоти було вміщено акумулятор, сервомотори підшипники і всю електроніку, вирішило б проблему того, що рослини на підвіконні тягнуться до сонця і, як результат, краще виглядають ззовні, ніж зсередини.

Прикольно, конечно, но поворотное устройство действительно выглядит как хардкорный DIY))
В качестве развития на будущее я предложил бы взять шаговый двигатель — он проще и надежнее в сравнении с сервой. Выдерживает бОльшие нагрузки. Из самого дешманского — обычные ардуиновские шаговики. Если хочется покрасивше\подороже\понадежнее — шаговик из серии NEMA.
В качестве управления можно прикрепить драйвер а-ля A4988 или TMC21ХХ, и там и там управление осуществляется по двум пинам:
STEP — шаг двигателя, импульс подал — двигатель повернулся на х градусов (дефолт 1.8 градуса на шаг, но драйвера умеют в деление от 1\4 до 1\32;
DIR — направление, единичка — в вал поворачивается в одну сторону, нолик — в другую.
А4988 очень дешевый, но шумный в процессе поворота двигателя. Шум будет соизмерим с шумом сервы. Драйвера серии ТМС в сравнении с А4988 бесшумные.
Остается только проблема обратной связи. В серве-то это решено, а в шаговиках придется решать самому. Тут тоже могу предложить 2 варианта:
1. На вал шаговика поцепить магнит, напротив соосно — магнитный энкодер что-то вроде AS5030, например. Тут 360 градусов, программируемый ноль, дрова на гитхабе есть, правда хз есть ли под малинку) Но и самому написать не сложно, там просто все.
2. Поступить как 3д принтерасты — придумать где-то на платформе\возле вала двигателя\под платформой\etc. что-то вроде нулевой точки с каким-нибудь концевиком. При подаче питания нужно пройти до этой самой нулевой точки, и уже от неё с учетом деления шагов считать угол поворота и поворачивать. Так будет ощутимо дешевле)

Было приятно почитать. Спасибо. Люблю железяки <3

Підписатись на коментарі