Skip to content

Instantly share code, notes, and snippets.

@choryuidentify
Last active October 5, 2022 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save choryuidentify/7ad4873eb7fe5ef2b2e1acb399e1500a to your computer and use it in GitHub Desktop.
Save choryuidentify/7ad4873eb7fe5ef2b2e1acb399e1500a to your computer and use it in GitHub Desktop.
fan_ctrl_opi.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# For Orange Pi
# Tested on Orange Pi Plus 2
import OPi.GPIO as GPIO
import time
import sys
# Configuration
FAN_PIN = 21 # Chip pin used to drive transistor's base
WAIT_TIME = 1 # [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 = [50, 70] # [°C]
speedSteps = [0, 100] # [%]
# Fan speed will change only of the difference of temperature is higher than hysteresis
hyst = 1
# Setup GPIO pin
GPIO.setboard(GPIO.PLUS2E)
GPIO.setmode(GPIO.BOARD)
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()
@yashu88
Copy link

yashu88 commented Oct 5, 2022

Hello...I am sorry to bother you....but how does it work...I want to control POE module on my Rspberry Pi system. I installed ubuntu 22.04 server image on Raspberry Pi. I installed OPi.GPIO for ubuntu OS. Then I run your script but on my machine it gives error
"python3 fan_control.py
Traceback (most recent call last):
File "/home/ubuntu/fan_control.py", line 27, in
fan = GPIO.PWM(FAN_PIN, PWM_FREQ)
TypeError: PWM.init() missing 2 required positional arguments: 'frequency' and 'duty_cycle_percent'
".

Your help will be valuable to me.

Thank you.

@choryuidentify
Copy link
Author

choryuidentify commented Oct 5, 2022

Hello...I am sorry to bother you....but how does it work...I want to control POE module on my Rspberry Pi system. I installed ubuntu 22.04 server image on Raspberry Pi. I installed OPi.GPIO for ubuntu OS. Then I run your script but on my machine it gives error "python3 fan_control.py Traceback (most recent call last): File "/home/ubuntu/fan_control.py", line 27, in fan = GPIO.PWM(FAN_PIN, PWM_FREQ) TypeError: PWM.init() missing 2 required positional arguments: 'frequency' and 'duty_cycle_percent' ".

Your help will be valuable to me.

Thank you.

This is for Orange Pi, Not a Raspberry Pi.
so you need find other script.

@yashu88
Copy link

yashu88 commented Oct 5, 2022

Thank you so much for your reply. I modify your code with "import RPi.GPIO as GPIO "and it's executing fine on my system. The only issue is that I don't find any details for how to check its performance....I am very new in this area so trying to find out details online.
In code I set tempSteps = [50, 70, 80, 90, 100], speedSteps = [0, 20, 30, 40, 100] but couldn't see any changes in fan speed.

I am sorry for taking so much of your precious time. Can you please let me know how to verify performance?

Thank you & Regards,
Yashashree

@choryuidentify
Copy link
Author

choryuidentify commented Oct 5, 2022

Thank you so much for your reply. I modify your code with "import RPi.GPIO as GPIO "and it's executing fine on my system. The only issue is that I don't find any details for how to check its performance....I am very new in this area so trying to find out details online. In code I set tempSteps = [50, 70, 80, 90, 100], speedSteps = [0, 20, 30, 40, 100] but couldn't see any changes in fan speed.

I am sorry for taking so much of your precious time. Can you please let me know how to verify performance?

Thank you & Regards, Yashashree

Maybe your fan device not compatible to this script.

Basically I just following this post but I make an changes to match OPi. So you need DIY control board.

And this source are control Fan speed by CPU tempurature.
I don't know your environment, but firstly you need choose correct tempurature sensor (CPU, or something...) and it's maximum tempurature.

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