Если ты, читатель, тоже страдаешь понятием "Не баг, а фича" и желанием покапаться в железках, то этот пост для твоих "кривых ручек", как у меня.
1. Обзор и сборка проекта
На днях, я искал интересный корпус для Raspberry Pi 4, мне очень уж понравился набор
Mini Tower Kit от https://github.com/geeekpi/minitowercase, но вот незадачка, проект, изначально, предназначен для RPi 5, а у меня RPi 4, но хотелка меня переосилила и я решился купить его за 2300 денег.
Корпус Mini Tower Kit это интересный и прикольный проект, напечатанный на 3Д принтере, состоящий из 3х частей корпуса, кулера (Ice Tower), OLED-экрана и RGB-подсветки, на кулере (не управляемая) и на обратной стороне экрана, выглядит это чудо как уменьшенная копия геймерского ПК. Так же в комплекте блок расширения GPIO контактов.

Все бы хорошо, но вот незадачка, кулер подключается через fan-интерфейс на RPi 5, а на RPi 4 такого нет.
- Чож делать, Чож делать?
- Кустарить!
Мое приключение началось с разбора распиновки, в прочем ничего особенного, вот она:
Ну, в целом, разницы особо никакой, поэтому проблем с OLED и I2C не будет, значит надо разбираться с кулером.
Распиновка кулера представляет из себя JST-PH 2.0 мм (4 pin), у которого:
|
Цвет провода |
Назначение |
Что с ним делать |
|---|---|---|
|
🔴 Красный |
+5V питание |
5V (Pin 2 или Pin 4) |
|
⚫ Чёрный |
GND |
GND (Pin 6 / 9 / 14 и т.д.) |
|
🟡 Жёлтый |
TACH / Sense (датчик оборотов) |
Опционально, можно не подключать |
|
🔵 Синий |
PWM control (управление скоростью) |
GPIO (GPIO 13 / Pin 33) |
Ну, красный и черный - понятно и валенку, а желтый и синий - нужно разбираться.
ЖЁЛТЫЙ (RPM) - тахометр (мы его НЕ используем) - это это выход вентилятора
Что он делает:
-
вентилятор шлёт импульсы
-
обычно 2 импульса на один оборот
-
это open-collector выход (нужна подтяжка к 3.3V)
Используется для:
-
подсчёта RPM (оборотов)
-
мониторинга: «крутится / заклинил»
В нашей переделке нам не нужен RPM, потому что мы его регулируем по температуре CPU, которая прекрасно вычисляется самим RPi 4. Таким образом в этом корпусе малинки нет смысла использовать его, потому что придется проводить рассчеты напряжения, ставить сопротивление, потому что GPIO не любит получать чистый 3.3v на вход - ну его нафиг.
А вот СИНИЙ (PWM) - это провод на вход к кулеру, т.е. он управляет самим кулером.
Как это работает:
-
Вентилятор питается постоянно от 5V
-
Синий провод принимает логический сигнал
-
Частота обычно ~25 кГц (PC стандарт) (по крайней мере так пишут про подобные на просторах тырнета)
-
Но 5V вентиляторы терпят и 100–1000 Гц
Получается такие вертушки работают по принципу:
|
Duty Cycle |
Что происходит с сигналом |
Как крутится вентилятор |
|---|---|---|
|
0% |
всегда LOW |
не крутится |
|
10% |
1 короткий «пшик» |
еле живой |
|
25% |
четверть времени ON |
медленно |
|
50% |
половина ON / половина OFF |
средне |
|
75% |
почти всегда ON |
быстро |
|
100% |
всегда HIGH |
максимум |
Таким образом, мы подаём PWM с GPIO, и вентилятор сам регулирует обороты.
Теперь, когда мы разобрались во всех причинно-следственных связях, переделаем контактики на виртушке, под нашу архитектуру.
Я особо не запаривался, отрезал покороче JST, взял коннекторы типа "мама" с ардуиновских проводов и просто перепаял провода и насадил коннекторы
Синий, в общем-то, я не захотел изолировать или удалять, поэтому просто тоже насадил на него коннектор, а вось когда-нибудь и пригодится :D
Затем приступил к сборке, согласно распиновки из комплекта, но столкнулся с небольшой накладкой, т.к. пины OLED дисплея и кулера пересекались. Эта задачка была решена достаточно тривиально - использованием блока расширения для GPIO и простой сменой ШИМ-порта с GPIO 18 на GPIO 13 - код все поправит
Прекрасно, железо запустилось, кулер крутится, диоды на нем горят, но дисплей не воркает, потому что I2C еще не инициализирована в системе.
Так, с железом разобрались, переходим к программной части.
У меня RPi 4 с Ubuntu Server на борту, а родное ПО предполагает RPi 5 с RPi OS.
Выкачиваем репозиторий, смотрим какие библиотеки использует код. Для работы с OLED и I2C используется rpi_ws281x - не проблема, питон переварит. Для кулера же, все гораздо проще, на уровне драйверов ОС (kernel / firmware).
Ну, с дисплеем все понятно, а по поводу вентилятора придется вернуться к истокам ардуино, в принципе, тоже ничего сложного, в тырнете полно информации. Питон спасет мир, поэтому вот, я реализовал это у себя:
GPIO.setup(FAN_PIN, GPIO.OUT)
pwm = GPIO.PWM(FAN_PIN, 250) # частота
pwm.start(0)
while True:
temp = get_cpu_temp()
if temp < 45:
pwm.ChangeDutyCycle(20)
elif temp < 60:
pwm.ChangeDutyCycle(50)
else:
pwm.ChangeDutyCycle(100)
На этом моменте основной функционал отработан, тесты положительные, все воркает.
Теперь можно экспериментировать.
2. Архитектура ПО
Оригинальный софт представлял собой один бесконечный цикл на Python, который пытался делать всё сразу. Я пошел по пути Unix-way: одна задача - один процесс.
Вся экосистема проекта была разбита на независимые демоны (Systemd Services), которые общаются друг с другом через файлы состояний и конфигурационный JSON-файл.
Структура проекта
Файловая система организована так, чтобы отделить исполняемый код от конфигурации, доступной пользователю.
/
├── etc/
│ └── minitower/
│ └── config.json # Глобальный конфиг (пользовательские настройки)
├── usr/
│ └── local/
│ ├── minitower/
│ │ ├── fan_control.py # Логика охлаждения
│ │ ├── led_service.py # Драйвер подсветки (запущен от root)
│ │ ├── sysinfo.py # Драйвер OLED дисплея
│ │ └── led_control.py # CLI-утилита для пользователя
│ └── bin/
│ ├── led # Симлинк для удобного вызова
│ └── minitower_wrapper # Перехватчик команд reboot/shutdown
└── tmp/
└── led_status # IPC-канал для приоритетных сигналов
Такая структура позволяет обновлять скрипты, не затирая настройки пользователя, и дает возможность управлять подсветкой без прав суперпользователя.
Логика работы сервисов
1. Сервис охлаждения (Fan Control)
Максимально простой и надежный скрипт. Он читает /sys/class/thermal/thermal_zone0/temp и управляет скважностью ШИМ на GPIO 13.
-
Тихий режим: До 45°C вентилятор полностью остановлен.
-
Линейный рост: С 45°C до 65°C обороты плавно растут.
-
Турбо: Выше 65°C вентилятор включается на 100%.
2. Сервис подсветки (Moodlight Service)
Это не просто «гирлянда», а конечный автомат (State Machine). Сервис работает с библиотекой rpi_ws281x и имеет систему приоритетов.
Приоритет 1 (Высокий): Системные события.
Скрипт мониторит наличие файла-флага в /tmp/led_status.
-
Если файл содержит
BLINK_RED- пропал интернет, мигаем красным. -
Если
BLINK_ALARM- обнаружена попытка взлома, агрессивный стробоскоп (в моем случае реализовано при неправильном вводе пароля по SSH. -
Если
REBOOT- плавное угасание.
Приоритет 2 (Низкий): Пользовательские настройки.
Если системных событий нет, сервис читает /etc/minitower/config.json. Пользователь может выбрать статический цвет, режим «радуги», «матрицы», «дыхания» и т.п.
Хак с правами доступа: Чтобы менять цвет мог обычный пользователь командой
led greenбезsudo, файл конфигурации и папка/etc/minitowerимеют права 666/777. Демон подсветки (работающий от root) просто перечитывает файл при изменении его времени модификации.
3. Сервис OLED-дисплея (Sysinfo)
Экран 128x64 используется на 100%. Вместо стандартных логотипов, я сделал полноценный дашборд.
-
Верхняя панель: Hostname и часы.
-
Метрики: CPU Temp, RAM Usage, Disk Usage. Если значение превышает критический порог (например, RAM > 80%), строка инвертируется (черный текст на белом фоне), привлекая внимание.
-
Сетевой монитор:
-
Скрипт пингует
8.8.8.8. Если пинга нет - на экран выводится крупное предупреждение CONNECTION LOST, и отправляется сигнал подсветке стать красной. -
Если сеть есть, отображается локальный IP.
-
-
Детектор SSH: Через библиотеку
psutilсканируются активные TCP-соединения на 22 порту. Если вы подключились к серверу, на дисплее появится надписьssh connectedи IP-адрес вашего клиента.
4. Intruder Alert (Система безопасности)
В отдельном потоке дисплейного сервиса запущен мониторинг логов journalctl.
Если скрипт видит строки Failed password или Invalid user от sshd:
-
Создается файл-флаг тревоги для подсветки.
-
OLED-экран начинает быстро мигать белым фоном.
-
На дисплее крупно выводится надпись INTRUDER ALERT и IP-адрес атакующего.
Это превращает сервер в наглядный индикатор того, что вас пытаются брутфорсить.
Магия выключения (Shutdown Wrappers)
Самая интересная техническая задача - сделать красивое выключение. Если просто написать systemd-юнит с Before=shutdown.target, система может убить процессы экрана и подсветки раньше, чем они успеют отрисовать анимацию прощания.
Я пошел радикальным путем: Shell Wrappers.
Системные команды /usr/sbin/reboot, shutdown, poweroff и halt подменяются симлинками на мой скрипт-обертку.
Алгоритм работы обертки:
-
Пользователь вводит
sudo reboot. -
Запускается мой скрипт.
-
Он вызывает скрипт дисплея с аргументом
reboot. -
Рисуется Progress Bar остановки сервисов, подсветка плавно гаснет.
-
Только после завершения анимации скрипт вызывает системный бинарник перезагрузки.
CLI-интерфейс
Чтобы не править JSON вручную, написана утилита led. Она написана на Python, но скомпилирована в исполняемый файл (или вызвана через shebang) и доступна в $PATH.
Примеры команд:
root@AnDyPi:~$ led
Minitower LED Control v2.6
Использование:
led on / off - Включить (белый статический) или выключить
led [название_цвета] - Статичный цвет (red, orange, yellow, green, blue, indigo, violet...)
led mode [название] - Эффект (rainbow, pulse, breath, knight, strobe, sparkle, fire, matrix, party, ycle)
led auto [on/off] - Автоматическая смена режимов (гирлянда)
led brightness [0-255] - Установка яркости
led speed [1-100] - Скорость анимации (чем меньше, тем быстрее)
led set [r] [g] [b] - Установка своего RGB цвета
Установка и деплой
Весь проект упакован в Git-репозиторий - https://github.com/Reider0/PC_Pi_pack.git
install.sh делает всю грязную работу по установке:
-
Проверяет root-права.
-
Ставит зависимости (
python3-pip,i2c-tools,rpi.gpio). -
Разносит файлы по папкам
/usr/local/minitower/и/etc/minitower/. -
Создает Systemd юниты и активирует их.
-
Создает симлинки для перехвата команд выключения.
Итог
Вместо китайской игрушки для Raspberry Pi 5 получился полноценный, информативный домашний кампуктер на Raspberry Pi 4 с Ubuntu Server на борту.
Этот проект - отличный пример того, как с помощью Python и понимания устройства Linux можно значительно прокачать опыт даже на таком простом наборе для для Raspberry Pi, а самое главное его преимущество, что возможности ограничиваются только фантазией и количеством токенов в ChatGPT :D
Автор: Reider0
