-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathfan_control.py
executable file
·57 lines (45 loc) · 1.8 KB
/
fan_control.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#! /usr/bin/env python3
import RPi.GPIO as GPIO
import time
import signal
import sys
# The Noctua PWM control actually wants 25 kHz (kilo!), see page 6 on:
# https://noctua.at/pub/media/wysiwyg/Noctua_PWM_specifications_white_paper.pdf
# However, the RPi.GPIO library causes high CPU usage when using high
# frequencies - probably because it can currently only do software PWM.
# So we set a lower frequency in the 10s of Hz here. You should expect that
# this value doesn't work very well and adapt it to what works in your setup.
# We will work on the issue and try to use hardware PWM in the future:
PWM_FREQ = 25 # [Hz] PWM frequency
FAN_PIN = 18 # BCM pin used to drive PWM fan
WAIT_TIME = 1 # [s] Time to wait between each refresh
OFF_TEMP = 40 # [°C] temperature below which to stop the fan
MIN_TEMP = 45 # [°C] temperature above which to start the fan
MAX_TEMP = 70 # [°C] temperature at which to operate at max fan speed
FAN_LOW = 1
FAN_HIGH = 100
FAN_OFF = 0
FAN_MAX = 100
FAN_GAIN = float(FAN_HIGH - FAN_LOW) / float(MAX_TEMP - MIN_TEMP)
def getCpuTemperature():
with open('/sys/class/thermal/thermal_zone0/temp') as f:
return float(f.read()) / 1000
def handleFanSpeed(fan, temperature):
if temperature > MIN_TEMP:
delta = min(temperature, MAX_TEMP) - MIN_TEMP
fan.start(FAN_LOW + delta * FAN_GAIN)
elif temperature < OFF_TEMP:
fan.start(FAN_OFF)
try:
signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW)
fan = GPIO.PWM(FAN_PIN, PWM_FREQ)
while True:
handleFanSpeed(fan, getCpuTemperature())
time.sleep(WAIT_TIME)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()