-
-
Save b4tman/8903893c3d8edc6b43fd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
# coding: utf8 | |
# скрипт мониторит температуру, и с помощью ШИМ управляет | |
# GPIO пином (0-3В), который должен быть подключен на базу транзистора, | |
# который является ключем в цепи питания вентилятора (5В). | |
# пример подключения вентилятора через ключ: | |
# https://easyeda.com/b4tman.p2p/rpi-fan-01 | |
# параметры: | |
T_MIN=50000 # минимальная температура включения (в градусах С * 1000) | |
T_FULL=60000 # температура для включения на полную скорость | |
S_MIN=15 # минимальная скорость, при включении вентилятора (процент) | |
S_MAX=100 # максимальная скорость вентилятора | |
GPIO_pin=4 # номер управляющей GPIO ноги | |
DELAY=5 # интервал между проверками (секунд) | |
# --- | |
import time | |
import logging | |
from gpiozero import PWMOutputDevice | |
from gpiozero.pins.rpigpio import RPiGPIOPin | |
import gpiozero.devices | |
# генератор, бесконечно получает температуру | |
def get_temp(): | |
with open('/sys/class/thermal/thermal_zone0/temp', mode='r') as f: | |
while(True): | |
f.seek(0,0) | |
txt = f.read() | |
yield int(txt.strip()) | |
# аналог Arduino-функции map | |
def val_map(src_x, src_a, src_b, dst_a, dst_b): | |
if dst_a == dst_b: | |
return dst_a | |
src_plus = 1 if src_b >= src_a else 0 | |
dst_plus = 1 if dst_b >= dst_a else 0 | |
src_len = (src_b - src_a) if src_plus else (src_a - src_b) | |
dst_len = (dst_b - dst_a) if dst_plus else (dst_a - dst_b) | |
val = (float(src_x) - (src_a if src_plus else src_b))/(float(src_len) if src_len > 0 else 1) | |
return int((dst_a if dst_plus else dst_b) + ((1 if dst_plus else -1)* val * dst_len)) | |
# аналог Arduino-функции constrain | |
def val_constrain(x, start, end): | |
return min(max(x, start), end) | |
# настройка ШИМ | |
gpiozero.devices.pin_factory = RPiGPIOPin | |
fan = PWMOutputDevice(GPIO_pin) | |
logging.basicConfig(format = '[%(asctime)s] %(message)s', datefmt='%H:%M:%S', level = logging.DEBUG) | |
t = 0 | |
try: | |
for t in get_temp(): | |
if t < T_MIN: | |
fan.off() | |
time.sleep(DELAY) | |
continue | |
t = val_constrain(t, T_MIN, T_FULL) | |
speed = val_map(t, T_MIN, T_FULL, S_MIN*10, S_MAX*10) | |
logging.debug('temp: %.3f °С, speed: %d %%', float(t)/1000, int(speed/10)) | |
fan.value = float(speed)/1000. | |
time.sleep(DELAY) | |
except KeyboardInterrupt: | |
pass | |
finally: | |
fan.close() |
#!/bin/sh | |
docker run -d \ | |
--device /dev/gpiomem:/dev/gpiomem \ | |
-v /sys/class/thermal/thermal_zone0/temp:/sys/class/thermal/thermal_zone0/temp:ro \ | |
--restart=unless-stopped \ | |
--name=rpi-fan \ | |
b4tman/rpi-fan |
FROM arm32v6/python:alpine3.7 | |
WORKDIR /usr/src | |
ENV TZ=Europe/Moscow | |
RUN set -ex \ | |
&& apk add --no-cache --virtual .build-deps \ | |
gcc \ | |
libc-dev \ | |
alpine-conf \ | |
tzdata \ | |
&& /sbin/setup-timezone -z $TZ \ | |
&& pip install --upgrade --no-cache-dir pip \ | |
&& pip install --no-cache-dir \ | |
RPi.GPIO \ | |
gpiozero \ | |
&& apk del .build-deps | |
COPY fan_ctrl.py /usr/src | |
CMD ["python", "/usr/src/fan_ctrl.py"] |
Если не сложно расскажите пожалуйста куда (по каким директориям) разложить эти файлы и что надо выполнить запустить что бы начал работать вентилятор.
Заранее спасибо
Привет! а не скажешь куда сохранять скрипты и какие запускать, например через rc.local речь о RPi3. Не очень я силен в скриптах, что то понимаю. Но тут понять не могу.... было бы классно иметь инструкцию для чайников)))
@blackangel666 Привет
- Предлагаю запускать через докер (по установке можно прочитать например здесь: https://docs.docker.com/install/linux/docker-ce/debian/ ).
-
Можно взять уже готовый образ:
docker pull b4tman/rpi-fan
Или собрать самостоятельно:
docker build -t b4tman/rpi-fan -f rpi-fan.Dockerfile .
-
Установить и запустить можно с помощью
install.sh
- Но можно и без докера запускать.
-
Нужно просто установить
python
и зависимости:
pip install RPi.GPIO gpiozero
-
А потом запускать например через rc.local:
python /path/to/script/fan_ctrl.py
где/path/to/script/
- папка со скриптом
Не подскажешь какой транзистор можно использовать?)
@MrPhelko я использовал BC337 по такой схеме: https://disk.yandex.ru/d/f2PAsS5Q3GHYGh/rpi-fan_circuit.png
подойдет почти любой NPN транзистор, но нужно проверить по даташиту, чтобы выдержал ток нужный вентилятору, и соответственно подобрать резистор на базу
SyntaxError: 'utf8' codec can't decode byte 0xef in position 0: invalid continuation byte
видимо файл сохранился в кодировке UTF8 с BOM (EF BB BF
в начале файла), попробуйте скачать файл целиком нажав "Сохранить ссылку как" в контекстном меню (ПКМ) на кнопке Raw или просто пересохранить без BOM.
или так:
git clone https://gist.github.com/b4tman/8903893c3d8edc6b43fd
Если не помогло, то напишите версию python и полный текст ошибки.
Установил по ссылке(или команде). все заработало. Спасибо
Не подскажите почему выдаёт ошибку?
root@raspberrypi:/opt/FanControl# python3 /opt/FanControl/fan_ctrl.py
Traceback (most recent call last):
File "/opt/FanControl/fan_ctrl.py", line 21, in
from gpiozero import PWMOutputDevice
ModuleNotFoundError: No module named 'gpiozero'
Не подскажите почему выдаёт ошибку?
root@raspberrypi:/opt/FanControl# python3 /opt/FanControl/fan_ctrl.py Traceback (most recent call last): File "/opt/FanControl/fan_ctrl.py", line 21, in from gpiozero import PWMOutputDevice ModuleNotFoundError: No module named 'gpiozero'
нужно установить зависимости, например так:
pip3 install RPi.GPIO gpiozero
должен быть установлен pip3, если нет тогда:
apt install python3-pip
демо