Created
May 28, 2021 05:43
-
-
Save mutoo/f86d09ec35ce64501f788a60fd27c4a3 to your computer and use it in GitHub Desktop.
fan control with pm2 service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require('path'); | |
module.exports = { | |
apps: [ | |
{ | |
name: 'fan-ctrl', | |
cwd: path.resolve(__dirname), | |
interpreter: 'python3', | |
cmd: 'fan_ctrl.py', | |
// Options reference: https://pm2.keymetrics.io/docs/usage/application-declaration/ | |
instances: 1, | |
autorestart: true, | |
watch: true, | |
max_memory_restart: '1G', | |
env: { | |
NODE_ENV: 'development', | |
}, | |
env_production: { | |
NODE_ENV: 'production', | |
}, | |
}, | |
], | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# -*- coding: utf-8 -*- | |
import sys | |
print(sys.path) | |
import time | |
import RPi.GPIO as GPIO | |
# Configuration | |
FAN_PIN = 21 # BCM pin used to drive transistor's base | |
WAIT_TIME = 10 # [s] Time to wait between each refresh | |
FAN_MIN = 20 # [%] Fan minimum speed. | |
PWM_FREQ = 25 # [Hz] Change this value if fan has strange behavior | |
# Configurable temperature and fan speed steps | |
#tempSteps = [55, 58, 58.1, 60, 70] # [°C] | |
#speedSteps = [0, 0, 30, 70, 100] # [%] | |
tempSteps = [40, 50, 70] | |
speedSteps = [30, 80, 100] | |
# Fan speed will change only of the difference of temperature is higher than hysteresis | |
hyst = 1 | |
# Setup GPIO pin | |
GPIO.setmode(GPIO.BCM) | |
GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW) | |
fan = GPIO.PWM(FAN_PIN, PWM_FREQ) | |
fan.start(0) | |
i = 0 | |
cpuTemp = 0 | |
fanSpeed = 0 | |
cpuTempOld = 0 | |
fanSpeedOld = 0 | |
# We must set a speed value for each temperature step | |
if len(speedSteps) != len(tempSteps): | |
print("Numbers of temp steps and speed steps are different") | |
exit(0) | |
try: | |
while 1: | |
# Read CPU temperature | |
cpuTempFile = open("/sys/class/thermal/thermal_zone0/temp", "r") | |
cpuTemp = float(cpuTempFile.read()) / 1000 | |
cpuTempFile.close() | |
# Calculate desired fan speed | |
if abs(cpuTemp - cpuTempOld) > hyst: | |
# Below first value, fan will run at min speed. | |
if cpuTemp < tempSteps[0]: | |
fanSpeed = speedSteps[0] | |
# Above last value, fan will run at max speed | |
elif cpuTemp >= tempSteps[len(tempSteps) - 1]: | |
fanSpeed = speedSteps[len(tempSteps) - 1] | |
# If temperature is between 2 steps, fan speed is calculated by linear interpolation | |
else: | |
for i in range(0, len(tempSteps) - 1): | |
if (cpuTemp >= tempSteps[i]) and (cpuTemp < tempSteps[i + 1]): | |
fanSpeed = round((speedSteps[i + 1] - speedSteps[i]) | |
/ (tempSteps[i + 1] - tempSteps[i]) | |
* (cpuTemp - tempSteps[i]) | |
+ speedSteps[i], 1) | |
if fanSpeed != fanSpeedOld: | |
if (fanSpeed != fanSpeedOld | |
and (fanSpeed >= FAN_MIN or fanSpeed == 0)): | |
fan.ChangeDutyCycle(fanSpeed) | |
fanSpeedOld = fanSpeed | |
cpuTempOld = cpuTemp | |
# Wait until next refresh | |
time.sleep(WAIT_TIME) | |
# If a keyboard interrupt occurs (ctrl + c), the GPIO is set to 0 and the program exits. | |
except KeyboardInterrupt: | |
print("Fan ctrl interrupted by keyboard") | |
GPIO.cleanup() | |
sys.exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment