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

Mittwoch 24. November 2021, 23:21

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

Donnerstag 25. November 2021, 00:07

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

Donnerstag 25. November 2021, 00:22

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

Donnerstag 25. November 2021, 02:16

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: 704
Registriert: Dienstag 26. November 2019, 23:24

Donnerstag 25. November 2021, 08:35

@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.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 13:39

Vielen Dank!
Die map Funktion wollte ich schon verwenden, nur nicht für die Lüfter, sondern für das Poti.
Sonst kann ich ja keine Temperatur einstellen, ohne den Pi anzuschließen.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 14:07

Code: Alles auswählen

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 = 20 #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")  
Das Alte jetzt richtig dargestellt.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 14:27

Also das umgeschriebene Script funktioniert nicht, da es mit diesen min max Werten nicht stimmt.
Durch die Rechnung ergeben sich nämlich auch bei einer höheren gewünschten Temperatur zur tatsächlichen Temperatur eine Differenz, die die Lüftergeschwindigkeit erhöht - das wollte ich nicht, da es keinen Sinn macht.
__deets__
User
Beiträge: 10711
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 25. November 2021, 14:34

Wenn die Temperaturdifferenz negativ ist, sollte auch die Geschwindigkeit negativ werden (spaetestens nach einer kurzen Zeit). Das ist logisch, weil natuerlich aus einem kuehlen dann ein heizen werden muesste. Das kann dein Luefter natuerlich nicht, aber der Algorithmus an sich stimmt. Alles, was du tun kannst, ist bei negativen Werten einfach die PWM auf 0 zu setzen.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 15:13

Das habe ich ja bei meinem Script gemacht (auf 1000).
Das Nächste wäre eine Veränderung des Potis zu erkennen und auf meinem LCD Display nur bei Veränderung die eingestellte Temperatur anzuzeigen.
Hab es schon mit button press... probiert, funktioniert aber nicht.
Ich hab noch add_action_detect (oder so ähnlich) im Kopf, finde dazu aber nichts.
Die print Geschichten sind nur zum probieren.
Mein Script mit dem LCD Display:

Code: Alles auswählen

from machine import I2C, ADC, Pin
from machine import PWM
from machine_i2c_lcd import I2cLcd
from time import sleep
from dht import DHT11, InvalidChecksum

i2c = I2C(0, sda=Pin(16), scl=Pin(17), freq=400000)
i2c_scan=i2c.scan()[0]
i2c_scan_hex=hex(i2c_scan)

I2C_ADDR = i2c_scan

lcd = I2cLcd(i2c, I2C_ADDR, 2, 16)

fan = PWM(Pin(18))
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
    lcd.hide_cursor()
    lcd.move_to(0,0)
    lcd.putstr("Temp:    " + str(t) + " C")
    lcd.move_to(0,1)
    lcd.putstr("Luftf.:  " + str(h) + " %")

    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")
__deets__
User
Beiträge: 10711
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 25. November 2021, 15:18

Ich verstehe deine Frage nicht.
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 15:24

Wenn sich der Analog Wert des Potis beim drehen verändert (egal wie) soll auf meinem Display die eingestellte Temperatur (in diesem Fall tempp) angezeigt werden.
Also quasi

Code: Alles auswählen

 lcd.putstr(str(tempp) + " C") 
, wenn ich tempp verändere, damit ich beim Einstellen auch sehe was ich einstelle und danach das Display wieder wie gewohnt die tatsächliche Temperatur und Luftfeuchtigkeit anzeigt(wie schon im Script:

Code: Alles auswählen

lcd.hide_cursor()
    lcd.move_to(0,0)
    lcd.putstr("Temp:    " + str(t) + " C")
    lcd.move_to(0,1)
    lcd.putstr("Luftf.:  " + str(h) + " %")
    
).
Zu dieser Veränderung des poti oder eingestellten Temperatur(tempp) - Wertes hab ich schon mal sowas wie add_action_detect ( oder so ähnlich) gesehen.
Zuletzt geändert von T4m4go am Donnerstag 25. November 2021, 15:27, insgesamt 1-mal geändert.
__deets__
User
Beiträge: 10711
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 25. November 2021, 15:26

Und was geht nicht? Was ist denn da unklar? Du liest das poti ein, du schreibst auch schon Werte auf das Display, was ist jetzt die Huerde, den Sollwert zu schreiben?
T4m4go
User
Beiträge: 38
Registriert: Samstag 3. Juli 2021, 16:54

Donnerstag 25. November 2021, 15:28

Der Sollwert soll nur am Display angezeigt werden, wenn er verändert wird.
__deets__
User
Beiträge: 10711
Registriert: Mittwoch 14. Oktober 2015, 14:29

Donnerstag 25. November 2021, 15:33

Warum? Dem Display ist doch egal, wenn du das einfach andauernd neu schreibst. Dein Monitor schreibt auch andauernd die Pixel neu, waehrend du nichts tust.
Antworten