Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@b4tman
Last active March 28, 2023 09:57
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save b4tman/8903893c3d8edc6b43fd to your computer and use it in GitHub Desktop.
Save b4tman/8903893c3d8edc6b43fd to your computer and use it in GitHub Desktop.
Включение и регулировка скорости вращения вентилятора в зависимости от температуры для Raspberry Pi с помощью программной реализации ШИМ
#!/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"]
@b4tman
Copy link
Author

b4tman commented Mar 23, 2017

@harrysmith63
Copy link

Если не сложно расскажите пожалуйста куда (по каким директориям) разложить эти файлы и что надо выполнить запустить что бы начал работать вентилятор.
Заранее спасибо

@blackangel666
Copy link

Привет! а не скажешь куда сохранять скрипты и какие запускать, например через rc.local речь о RPi3. Не очень я силен в скриптах, что то понимаю. Но тут понять не могу.... было бы классно иметь инструкцию для чайников)))

@b4tman
Copy link
Author

b4tman commented Mar 21, 2018

@blackangel666 Привет

  1. Можно взять уже готовый образ:
    docker pull b4tman/rpi-fan
    Или собрать самостоятельно:
    docker build -t b4tman/rpi-fan -f rpi-fan.Dockerfile .

  2. Установить и запустить можно с помощью install.sh

  • Но можно и без докера запускать.
  1. Нужно просто установить python и зависимости:
    pip install RPi.GPIO gpiozero

  2. А потом запускать например через rc.local:
    python /path/to/script/fan_ctrl.py
    где /path/to/script/ - папка со скриптом

@MrPhelko
Copy link

Не подскажешь какой транзистор можно использовать?)

@b4tman
Copy link
Author

b4tman commented Dec 1, 2021

@MrPhelko я использовал BC337 по такой схеме: https://disk.yandex.ru/d/f2PAsS5Q3GHYGh/rpi-fan_circuit.png

подойдет почти любой NPN транзистор, но нужно проверить по даташиту, чтобы выдержал ток нужный вентилятору, и соответственно подобрать резистор на базу

@b4tman
Copy link
Author

b4tman commented Feb 17, 2023

@mgritsan

SyntaxError: 'utf8' codec can't decode byte 0xef in position 0: invalid continuation byte

видимо файл сохранился в кодировке UTF8 с BOM (EF BB BF в начале файла), попробуйте скачать файл целиком нажав "Сохранить ссылку как" в контекстном меню (ПКМ) на кнопке Raw или просто пересохранить без BOM.

image

или так:

git clone https://gist.github.com/b4tman/8903893c3d8edc6b43fd

Если не помогло, то напишите версию python и полный текст ошибки.

@mgritsan
Copy link

mgritsan commented Feb 17, 2023

Установил по ссылке(или команде). все заработало. Спасибо

@AleksandrGromov
Copy link

Не подскажите почему выдаёт ошибку?

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'

@b4tman
Copy link
Author

b4tman commented Mar 28, 2023

@AleksandrGromov

Не подскажите почему выдаёт ошибку?

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment