This commit is contained in:
2026-05-09 16:31:36 +08:00
commit 9f785a17f5
8 changed files with 340 additions and 0 deletions

105
fan_autopid.py Normal file
View File

@@ -0,0 +1,105 @@
import pigpio
import time
PWM_PIN = 18
TACH_PIN = 23
TARGET_TEMP = 40.0
# 初始参数
Kp = 1.0
Ki = 0.0
Kd = 0.0
integral = 0
last_error = 0
last_temp = None
pulse_count = 0
last_time = time.time()
pi = pigpio.pi()
pi.set_PWM_frequency(PWM_PIN, 25000)
pi.set_PWM_range(PWM_PIN, 255)
def tach_cb(gpio, level, tick):
global pulse_count
pulse_count += 1
pi.set_mode(TACH_PIN, pigpio.INPUT)
pi.set_pull_up_down(TACH_PIN, pigpio.PUD_UP)
pi.callback(TACH_PIN, pigpio.FALLING_EDGE, tach_cb)
last_tem = 0
def get_temp():
global last_tem
with open("/sys/class/thermal/thermal_zone0/temp") as f:
temp_filtered = 0.8 * last_tem + 0.2 * int(f.read()) / 1000
last_tem = temp_filtered
return temp_filtered
def get_rpm():
global pulse_count, last_time
now = time.time()
dt = now - last_time
count = pulse_count
pulse_count = 0
last_time = now
return (count / 2) / dt * 60
def adaptive_pid(temp):
global Kp, Ki, Kd, integral, last_error, last_temp
error = temp - TARGET_TEMP
integral += error
integral = max(min(integral, 100), -100)
derivative = error - last_error
# ===== 自适应调参 =====
if last_temp is not None:
temp_rate = temp - last_temp
# 响应太慢 → 增大 Kp
if abs(error) > 5 and abs(temp_rate) < 0.1:
Kp += 0.001
# 震荡 → 降低 Kp提高 Kd
if abs(temp_rate) > 0.5:
Kp *= 0.95
Kd += 0.0005
# 长期偏差 → 增大 Ki
if abs(error) > 2:
Ki += 0.0001
last_temp = temp
last_error = error
output = Kp * error + Ki * integral + Kd * derivative
return output
try:
while True:
temp = get_temp()
rpm = get_rpm()
out = adaptive_pid(temp)
duty = max(10, min(255, int(out * 5)))
pi.set_PWM_dutycycle(PWM_PIN, duty)
print(f"\rT={temp:.1f}C RPM={rpm:.0f} PWM={duty} Kp={Kp:.2f} Ki={Ki:.2f} Kd={Kd:.2f} ", end="")
time.sleep(0.05)
except KeyboardInterrupt:
pass
finally:
pi.set_PWM_dutycycle(PWM_PIN, 0)
pi.stop()