Temperatur-Lüfter

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Guten Tag,
ich möchte einen BeQuiet Lüfter mit meinen Raspberry Pi Pico nach Temperatur über einen DHT11 ansteuern.
Wie man diesen DHT11 ausliest und den Lüfter über PWM steuert weiß ich, nun scheitert es aber daran die Geschwindigkeit des Lüfters in Abhängigkeit zur Temperatur zu bringen.
Wenn jemand dazu ein paar Tipps hätte, wäre ich sehr dankbar.
MfG
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was ist denn das Ziel? Eine reine schwellwert Steuerung? Oder soll eine bestimmte Temperatur erreicht werden?
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@T4m4go,

du kannst den Sensor auslesen und den Lüfter steuern. Das heißt du brauchst jetzt nur noch den Algorithmus um beide zu verbinden?
Das wäre ein schönes Projekt um einen geschlossenen Regelkreis zu programmieren.
Ich glaube hier ist es ganz schön erklärt:
https://www.elektrotechnik-einfach.de/p ... -regelung/

(Da geht es zwar um einen Arduino, aber das Prinzip ist das gleiche)
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

__deets__ hat geschrieben: Mittwoch 24. November 2021, 20:59 Was ist denn das Ziel? Eine reine schwellwert Steuerung? Oder soll eine bestimmte Temperatur erreicht werden?
Der Lüfter soll eine bestimmte Temperatur halten; wenn die Temperatur steigt soll auch die Drehzahl des Lüfters selbständig steigen.
Ich will quasi den duty cycle (z.B. 1000 - 65000) mit einem Temperaturbereich (z.B. 20 -40) gleichsetzen - also 40C = 65000.
Zuletzt geändert von T4m4go am Mittwoch 24. November 2021, 21:13, insgesamt 1-mal geändert.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

rogerb hat geschrieben: Mittwoch 24. November 2021, 21:00 @T4m4go,

du kannst den Sensor auslesen und den Lüfter steuern. Das heißt du brauchst jetzt nur noch den Algorithmus um beide zu verbinden?
Das wäre ein schönes Projekt um einen geschlossenen Regelkreis zu programmieren.
Ich glaube hier ist es ganz schön erklärt:
https://www.elektrotechnik-einfach.de/p ... -regelung/

(Da geht es zwar um einen Arduino, aber das Prinzip ist das gleiche)
Der Lüfter soll eine bestimmte Temperatur halten; wenn die Temperatur steigt soll auch die Drehzahl des Lüfters selbständig steigen.
Also eine Regelung.
Arduino programmiert man doch mit C (?). Ich wollte es in Python machen.
Aber ich habe das vor, was da gezeigt wird.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du widersprichst dir selbst. Mir sagst du, die willst eine Abbildung eines temperaturbereichs auf einen PWM Bereich. Das ist eine Steuerung. Und Rogerb sagt’s du, du möchtest eine Regelung.

Wenn es eine Regelung sein soll, bietet sich zb ein PID Regler an. Dabei vergleichst du ein jedem Zeitschritt soll mit ist, und abhängig vom Unterschied veränderst du die Stellgrösse. Details zu dem Verfahren kannst du dir ergoogeln.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

__deets__ hat geschrieben: Mittwoch 24. November 2021, 21:30 Du widersprichst dir selbst. Mir sagst du, die willst eine Abbildung eines temperaturbereichs auf einen PWM Bereich. Das ist eine Steuerung. Und Rogerb sagt’s du, du möchtest eine Regelung.

Wenn es eine Regelung sein soll, bietet sich zb ein PID Regler an. Dabei vergleichst du ein jedem Zeitschritt soll mit ist, und abhängig vom Unterschied veränderst du die Stellgrösse. Details zu dem Verfahren kannst du dir ergoogeln.
Der Unterschied in diesem Beispiel ist mir jetzt nicht klar. Ich drücke mich wahrscheinlich schlecht aus.
Auf jeden Fall soll das halten einer bestimmten Temperatur über PWM erreicht werden.
Mein Lösungsgedanke war, bei steigender Temperatur den duty cycle zu erhöhen, sodass sich der Wert einpendelt (wie bei einem PC - Lüfter).
Also wahrscheinlich eine Regelung (falls das nicht zu kompliziert ist) , wenn doch dann durch Probieren und Verschieben von Bereichen z.B. 20C - 40C; 0% - 100%; 1000 - 65000% - dazu fehlt mir jedoch die Funktion einer Zuweisung in Python.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Bitte nicht den Post davor einfach zitieren. Der steht da schon.

Und wenn du eine feste Abbildung von Temperatur auf PWM hast, so wie du sie darstellst, dann gibt es eben keine Rückwirkung. Wenn die Zieltemperatur erreicht ist, drehst du trotzdem weiter, auch wenn du aufhören könntest. Die Zieltemperatur spielt bei dir keine Rolle. Also keine Regelung.

Ich sage es nochmal: lies dir Artikel zum Thema PID Regler durch. Die Sprache spielt dabei auch keine Rolle. Du musst das Prinzip verstehen, dann kannst du das auch in micropython adaptieren.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Der Grundgedanke war also einen Maximal- und Minimalwert zuzuweisen, um mir das für jeden Wert dazwischen zu sparen und einfach die Temperaturvorgabe zu verändern.
Wenn ich es aufwändig mit meinem Wissen machen würde, würde ich für jede Geschwindigkeit eine Temperatur messen und das dann in tausenden if sätzen zuweisen.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Die Temperatur in meinem Druckraum steigt ohne Lüfter stetig an, also muss der Lüfter um die von mir vorgegebene Temperatur zu halten, die Geschwindigkeit zur Temperatur beibehalten.
Wenn ich jetzt eine höhere Temperatur angebe, muss also der Lüfter die Geschwindigkeit so verringern, dass sie zu Temperatur passt.
Jeder Temperatur eine Geschwindigkeit vorzugeben ist eine Steuerung aber wenn er "selbständig" bei Temperaturschwankungen die Geschwindigkeit anpasst eine Regelung.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das bringt nichts. Weil die Temperatur von dem wärme Fluss des zu kühlenden Gegenstandes als auch der Umgebungstemperatur abhängt. Dein Wissen wird wachsen müssen, mit dem Thema PID Regelung.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Das habe ich tatsächlich komplett außer Acht gelassen (die Raumtemperatur).
Wie kann ich jetzt in microPython konkret eine Lüfterregelung mit dem DHT11 und dem PWM Lüfter umsetzen?
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Schonmal vielen Dank, dass Sie solange dran geblieben sind.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Bzw. was ist der Ansatz, mit welchen Funktionen etc.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@T4m4go,

du könntest mit einem einfachen P (Proportional) Controller anfangen:

1) gewünschte Temperatur festlegen
2) Ist-Temperatur messen und Differenz berechnen
3) Je größer die Differenz umso mehr muss die Lüfterdrehzahl über den Anfangswert erhöht werden.

Zum Beispiel:
2° Übertemperatur -> Lüfter 200 Umdrehungen schneller als Anfangsdrehzahl
4° Übertemperatur -> Lüfter 400 Umdrehungen schneller als Anfangsdrehzahl

Man braucht dafür keine if-Anweisungen, denn es lässt sich ja einfach berechnen: Temperaturänderung * 100 = Drehzahlerhöhung

Ob der Faktor 100 jetzt realistisch für dein System ist weiß ich natürlich nicht. Das must du ausprobieren.

Naja, sinkt dann (hoffentlich) die Temperatur, errechnet sich eine niedrigere Lüfterdrehzahl.
Das ganze muss also in einer Endlosschleife laufen. Damit würde ich erstmal anfangen.

Dies ist ein Beispiel, welches so nicht funktioniert, weil ich ja nicht weiß wie du Temperatur liest und Lüfter steuerst. Es soll nur grob skizzieren wie es funktionieren könnte.

Code: Alles auswählen

def main():
    set_temperatur = 20
    start_speed = 1000
    kp = 100  # Skalierungsfaktor stellt die Bezihung zwischen Temperatur und Geschwindigkeit dar

    while True:
        # hier wird eigentlich die Temperatur vom Sensor gelesen
        current_temperature = sensor.get_temperatur()

        temp_difference = set_temperatur - current_temperature

        speed_difference = -temp_difference * kp
        new_speed = start_speed + speed_difference

        # hier wird mit 'new_speed' die neue Geschwindigkeit für den Lüfter eingestellt
        fan.set_speed(new_speed)


if __name__ == "__main__":
    main()
--
Man kann aber noch weiter machen - mit einem PI-Controller:
Bei einem PI (Proportional-Integral Controller) werden auch noch die Differenzwerte zwischen Soll- und Ist-Temperatur über die Zeit aufsummiert (also integriert).
Dazu muss man die Temperaturabweichungen bei jedem Schleifendurchlauf in einer Variablen aufsummieren und durch die verstrichene Zeit teilen.
Diese werden auch mit einem Faktor skaliert und auch der Drehzahl zugerechnet.

Schließlich kann man das noch auf einen PID-Controller erweitern.
Beim D-Anteil, also bei der Differenzierung wird die Änderung der Temperaturdifferenzen pro Zeiteinheit berücksichtig, skaliert und auch der Drehzahl zugerechnet
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Damit werde ich es probieren.
Vielen Dank rogerb!!!
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

from machine import Pin
from machine import PWM
from time import sleep
from dht import DHT11, InvalidChecksum

fan = PWM(Pin(16))
fan.freq(25000)

DHTpin = Pin(21, Pin.OUT, Pin.PULL_DOWN)


while True:
set_temperature = 20
start_speed = fan.duty_u16(1000)
kp = 100 # Skalierungsfaktor stellt die Beziehung zwischen Temperatur und Geschwindigkeit dar


sensor = DHT11(DHTpin)
t = (sensor.temperature)
# hier wird eigentlich die Temperatur vom Sensor gelesen


temp_difference = set_temperature - t

speed_difference = -temp_difference * kp

new_speed = start_speed + speed_difference #Zeile 27

# hier wird mit 'new_speed' die neue Geschwindigkeit für den Lüfter eingestellt
fan.duty_u16(new_speed)
Zuletzt geändert von T4m4go am Donnerstag 25. November 2021, 00:35, insgesamt 2-mal geändert.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

ist das jetzt noch richtig?
new_speed = round(start_speed) + round(speed_difference)

Geht das auch einfacher?
if new_speed < 0:
fan.duty_u16(1000)

if new_speed > 65000:
fan.duty_u16(65000)
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Ich habe jetzt noch einen Poti mit integriert, mit dem ich die Temperatur einstellen kann.
Hab jetzt nur leider 3 Potis abgeraucht, weil zur späten Stunde die Konzentration nachlässt.
Hier ist das Script:
from machine import ADC, Pin
from machine import PWM
from time import sleep
from dht import DHT11, InvalidChecksum


fan = PWM(Pin(16))
fan.freq(25000)
pot = ADC(26)

DHTpin = Pin(21, Pin.OUT, Pin.PULL_DOWN)

def map(x, in_min, in_max, out_min, out_max):
return int((x-in_min) * (out_max-out_min) / (in_max - in_min) + out_min)

while True:
tempp = map(pot.read_u16(),288, 65535,0,40)
set_temperature = tempp
print("Tempp:", tempp, "ADC, ", pot.read_u16())
start_speed = 1000
kp = 10000 # Skalierungsfaktor stellt die Beziehung zwischen Temperatur und Geschwindigkeit dar

sensor = DHT11(DHTpin)
sleep(1.5)
t = sensor.temperature
h = sensor.humidity
# hier wird eigentlich die Temperatur vom Sensor gelesen


temp_difference = set_temperature - t

speed_difference = -temp_difference * kp

new_speed = round(start_speed) + round(speed_difference)

# hier wird mit 'new_speed' die neue Geschwindigkeit für den Lüfter eingestellt
fan.duty_u16(new_speed)

if new_speed <= 0:
fan.duty_u16(1000)

if new_speed > 65000:
fan.duty_u16(65000)

print(t, "C")
print(h, "%")
print(fan.duty_u16(), "DutyCycle")

Diese map Funktion war das, was ich am Anfang gesucht habe um den Lüfter zu steuern, was aber, wie ich begriffen habe, schlecht funktioniert.
Als nächstes werde ich wahrscheinlich noch das I2C Bus LCD Display mit einbauen.
ps: Ich weiß immernoch nicht wie man das richtig einfügt.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@T4m4go,

zeig deinen Code bitte immer in Code -Tags </> (Vollständiger Editor), damit man die Formatierung erkennt.
Ich habe mir erlaubt den Code mal etwas aufzuräumen, die Funktionalität dürfte sich aber nicht geändert haben:
Jetzt auch ohne map() Funktion, die willst du ja nicht mehr verwenden. (map ist übrigens auch ein reservierter Name in Python und sollte daher nicht für eigene Funktionen verwendet werden)

Ansonsten hoffe ich, es ist lesbar und selbsterklärend, sonst frag einfach nochmal nach.
Die vorletzte Zeile must du ändern, da ich nicht weiß, welcher Wert sinnvoll ist.
Ansonsten sollte es so funktionieren. Da ich es aber nicht selber ausprobieren kann, könnten sich immer noch Fehler eingeschlichen haben.

Code: Alles auswählen

from time import sleep
from machine import ADC, Pin
from machine import PWM
from dht import DHT11


def controller(start_speed, set_temperature, sensor, fan, kp):
    while True:
        # Temperatur vom Sensor lesen
        actual_temperature = sensor.temperature
        actual_humidity = sensor.humidity

        new_speed = start_speed + (set_temperature - actual_temperature) * kp

        # Geschwindigkeitswerte limitieren
        new_speed = max(1000, min(65000, new_speed))

        # Geschwindigkeit für den Lüfter eingestellt
        fan.duty_u16(int(new_speed))

        print(f"Tempp:               {set_temperature} °C")
        print(f"Actual temeperature: {actual_temperature} °C")
        print(f"Actual humidity:     {actual_humidity} %")
        print(f"DutyCycle:           {fan.duty_u16()}")

        sleep(1.5)


def main():
    fan = PWM(Pin(16))
    fan.freq(25000)

    start_speed = 1000
    sensor = DHT11(Pin(21, Pin.OUT, Pin.PULL_DOWN))
    kp = 10000  # Skalierungsfaktor stellt die Beziehung zwischen Temperatur und Geschwindigkeit dar

    # Achtung statt mit der map-Funktion aus dem Poti einen Wert auszulesen,
    # wird hier irgend eine Temperatur eingetragen
    set_temperature = 42

    controller(start_speed, set_temperature, sensor, fan, kp)

if __name__ == "__main__":
    main()
Wenn das funktioniert, kannst du es ja erweitern. Wenn du weitere Hilfe brauchst, erklär bitte genau was du machen möchtest.
Antworten