Raspberry 4 - Temperaturgesteuerte Lüfterregelung - Teil 2

Ich habe mir ein Raspberry Pi 4 Komplettset (Werbung) zugelegt, da mir der Raspi 3 als NAS doch etwas zu langsam war.

Da der dazugehörige Lüfter auf Dauer doch etwas laut ist, habe ich mir eine temperaturgesteuerte Lüfterregelung eingerichtet.

In Teil 2 zeige ich das Python-Skript, das den Lüfter steuert.

(Update 07.03.2021)

Nachdem ich in Teil 1 die Hardware der Lüftersteuerung vorgestellt habe, geht es nun weiter mit der Software, die aus einem Python-Skript besteht.

2. Die Software

Bei der Software handelt es sich um ein Python-Script, das sich um die Regelung des Lüfters kümmert. Das Script ist aus verschiedenen Quellen im Netz zusammengeklaubt und von mir noch etwas angepasst worden. Um das Script zu erstellen, kann man folgendermaßen vorgehen:

- Script anlegen

Nach der Installation von Raspbian und dem Zugang zum System über SSH (was hier nicht weiter beschrieben wird, da es dazu bereits viele Anleitungen gibt), erstellen wir uns (als User pi) ein Python-Script "fancontrolpwm.py" im Unterordner scripts in unserem Homeverzeichnis.

  1. Kommando cd (+ anschließend ENTER-Taste) in der Shell eingeben, um ins Homeverzeichnis zu wechseln:
    cd
  2. Und weiter
    mkdir scripts cd scripts nano fancontrolpwm.py
  3. Dann den Inhalt dieses Scripts kopieren und im Editor-"Fenster" von nano einfügen (bei Putty z.B durch Drücken der rechten Maustaste)
  4. Jetzt muss das eingegebene (reinkopierte...) Script noch gespeichert werden. Dazu die Tastenkombination STRG+x, danach y und danach ENTER drücken.

- Fehlende Libraries in Python installieren

  1. Bevor wir das Script testweise starten können, müssen wir erst noch pip und im Anschluss eine fehlende Python-Libraray installieren:
    sudo apt install python-pip
    y und danach ENTER drücken.
  2. pip install gpiozero
    (Beim Installieren der Python-Library mit pip sind mir Warnungen wegen irgendwelcher bin-Pfade angezeigt worden, was aber hier nicht weiter stört.)

- Testen des Scripts

  1. Jetzt sollten wir das Script ausprobieren können:
    python fancontrolpwm.py
    Das Script sollte starten, dabei muss der Lüfter für drei Sekunden anlaufen und sollte danach wieder abschalten (falls der Raspi nicht schon heiß geworden ist). Das Script muss jetzt alle zwei Sekunden die aktuelle CPU-Temperatur ausgeben.
  2. Hat das soweit geklappt, stoppen wir das Script mit der Tastenkombination STRG+c.
  3. Um zu überprüfen, ob der Lüfter auch temperaturabhängig gesteuert wird, bringen wir die CPU auf Trab, sodass die Temperatur steigt:
    1. Erst wird stress-ng installiert (zum Ausführen von Stresstests):
      sudo apt install stress-ng
      y und danach ENTER drücken.
    2. Jetzt lassen wir unser Script im Hintergrund laufen:
      python fancontrolpwm.py &
      Hier auf das abschließende & achten, damit wir weitere Kommandos eingeben können. Unser Script gibt die Temperatur weiterhin auf der Konsole aus, es ist aber dennoch möglich, Eingaben zu tätigen!
    3. Danach wird die CPU "gestresst", damit sie sich erhitzt und die Lüftersteuerung geprüft werden kann:
      stress-ng -c 4
    4. Die Temperaturausgaben, die das Script im Hintergrund immer noch ausgibt, sollten anzeigen, dass die CPU sich erhitzt und nach einiger Zeit sollte der Lüfter anlaufen.
    5. Hat das geklappt, stoppen wir den Stresstest durch Drücken von STRG+c.
    6. Die Temperatur sollte langsam sinken und der Lüfter langsamer werden und schließlich wieder stoppen.
    7. Zum Schluss bringen wir das Python-Script in den Vordergrund und beenden es:
      fg
      und danach mit STRG+c beenden.

In Teil 3 richten wir es so ein, dass das Python-Script beim Booten des Raspberry Pi automatisch startet.


Kompletter Quelltext des Python-Scripts (Download):

  1.  
  2. #!/usr/bin/python
  3.  
  4. import sys
  5. import time
  6. from gpiozero import PWMLED # doc: https://gpiozero.readthedocs.io/
  7.  
  8. # ---------------- version info ----------------
  9. # Version 2021-03-07 (2. Release): Einrueckungsfehler in Zeilen 77/78 (Alt 74/75)
  10.  
  11. # ---------------- parameter -------------------
  12.  
  13. # GPIO fuer den Luefter
  14. fan = PWMLED(21,True,0,20)
  15.  
  16. # Temperatur in Celsius, ueber der der Luefter mit pwm-wert dutycycleatmax (s.u.) einschaltet
  17. maxt = 55.0
  18. # Temperatur in Celsius, unter der der Luefter aus ist
  19. mint = maxt - 10
  20. # Temperatur in Celsius, bis zu der die pwm linear geregelt wird
  21. pwmt = maxt - 5
  22. # Temperatur in Celsius, ab der der luefter (wegen zu grosser hitze) mit 100 prozent laeuft
  23. fult = maxt + 5
  24.  
  25. # pwm-aussteuerung bei maxt (anpassen, falls der luefter unangenehm oder laut klingt)
  26. dutycycleatmax = 0.7
  27.  
  28. # pwm-aussteuerung bei mint (anpassen, falls der luefter unangenehm oder laut klingt oder
  29. # der wert zu niedrig ist, sodass der luefter nicht anspringt)
  30. dutycycleatmin = 0.4
  31.  
  32.  
  33. # ---------------- programmcode ab hier -------------------
  34.  
  35. def translate(value, leftMin, leftMax, rightMin, rightMax):
  36.     # Figure out how 'wide' each range is
  37.     leftSpan = leftMax - leftMin
  38.     rightSpan = rightMax - rightMin
  39.  
  40.     # Convert the left range into a 0-1 range (float)
  41.     valueScaled = float(value - leftMin) / float(leftSpan)
  42.  
  43.     # Convert the 0-1 range into a value in the right range.
  44.     return rightMin + (valueScaled * rightSpan)
  45.  
  46. def cpu_temp():
  47.     with open("/sys/class/thermal/thermal_zone0/temp", 'r') as f:
  48.         return float(f.read())/1000
  49.  
  50.  
  51. def main():
  52.     # luefter kurz anlaufen lassen
  53.     is_close = True
  54.     fan.value = 1.0
  55.     time.sleep(3.0) # nach 3 s wieder ausschalten und regelung beginnen
  56.     fan.off()
  57.     while True:
  58.  
  59.         temp = cpu_temp()
  60.         if is_close:
  61.             if temp > maxt: # obergrenze, einschalten des luefters
  62.                 print time.ctime(), temp, 'Fan ON'
  63.                 fan.value = dutycycleatmax
  64.                 is_close = False
  65.         else:
  66.             if temp < mint: # untergrenze, ausschalten des luefters
  67.                 print time.ctime(), temp, 'Fan OFF'
  68.                 fan.value = 0.0
  69.                 is_close = True
  70.             else:
  71.                 if temp < pwmt: # lineare pwm-steuerung
  72.                     dc  = translate(temp, mint, maxt, dutycycleatmin, dutycycleatmax)
  73.                     if dc > 1:
  74.                        dc = 1
  75.                 else: # entweder max. pwm-wert oder bei zu grosser hitze vollaussteuerung
  76.                     dc = dutycycleatmax if temp < fult else 1.0
  77.                 print time.ctime(), "FAN PWM: ", dc
  78.                 fan.value = dc
  79.  
  80.  
  81.         time.sleep(2.0) # alle zwei sekunden neu messen und regeln
  82.         print time.ctime(), temp
  83.  
  84.  
  85. if __name__ == '__main__':
  86.     main()
  87.  


(Update 07.03.2021):
Vielen Dank an meinen Namensvetter Markus Mueller aus der Schweiz, der mich auf einen Einrückungsfehler in den Zeilen 74 und 75 im Script hingewiesen hat! :-)



Trackbacks

Trackback-URL für diesen Eintrag

Dieser Link ist nicht aktiv. Er enthält die Trackback-URI zu diesem Eintrag. Sie können diese URI benutzen, um Ping- und Trackbacks von Ihrem eigenen Blog zu diesem Eintrag zu schicken. Um den Link zu kopieren, klicken Sie ihn mit der rechten Maustaste an und wählen "Verknüpfung kopieren" im Internet Explorer oder "Linkadresse kopieren" in Mozilla/Firefox.

Keine Trackbacks

Kommentare

Ansicht der Kommentare: Linear | Verschachtelt

Noch keine Kommentare

Die Kommentarfunktion wurde vom Besitzer dieses Blogs in diesem Eintrag deaktiviert.