Probleme mit Schleifen / Hysterese

  • Hallo zusammen,


    irgendwie stehe ich auf dem Schlauch.


    folgendes will ich lösen:
    ich habe 2 Temperaturwerte Kachelofen (KO) und Puffer. Mein Programm soll eine Pumpe schalten wenn eine der Temperaturen einen bestimmten Wert überschritten hat.
    Soweit funktioniert das auch mit dem Code:



    Da die Werte aber pendeln und zB. zwischen 59.9 und 60 hin und her springen, wollte ich das else durch ein elif ersetzten.


    Code
    elif ( KO < 59 ) & ( Puffer < 39 ):


    Das funktioniert aber so leider nicht. Und ich kann das Programm auch mit STRG+C auch nicht mehr abbrechen.


    Irgendwie hab ich da einen Denkfehler. Könnte mir einer auf die Sprünge helfen - DANKE schon mal


    VG
    Roland

  • Hallo. Prüfe es mal in umgekehrter Reihenfolge. Erst if "pumpe an" und dann elif "pumpe aus". Du könntest dir aber auch einen Toleranz Bereich erstellen

  • Hallo,


    [code=php]elif ( KO < 59 ) & ( Puffer < 39 )[/php]
    macht auch nicht das, was du beabsichtigst.


    `&` ist ein bitweises und in Python. Schreib' mal `and`dazwischen.


    Gruß, noisefloor

  • @PIter
    die Bedingungen habe ich jetzt mal gedreht, funktioniert aber auch nicht :-(
    Wie meinst Du das mit dem Toleranzbereich?


    @noisefloor
    Danke für den Tipp habs jetzt geändert auf "or" wenn eine Bedingung eintritt reicht es zum Start der Pumpe.
    mit dem elif komme ich aber dennoch nicht weiter.



    wie macht Ihr das?? die Anforderung ist doch nichts besonderes.



    bin für jeden Tipp dankbar.

  • Hallo,


    also dein Code sieht nun so aus oder?:



    bedeutet für mich mal in Worte gefasst:


    Wenn KO Temp kleiner als 60 oder puffer temp kleiner 40 -> Pumpe aus


    ansonsten wenn KO Temp kleiner als 59 oder puffer temp kleiner 39 -> Pumpe aus


    Irgendwie nich beabsichtigt oder?

  • F11:


    Ich würde hier einen klassichen Zweipunkt-Regler mit Hysterese bauen. Einfach mal googeln, dann wird das schon klappen. Und hier noch eine kleine Hilfestellung:


    [code=php]#!/usr/bin/env python
    # -*- coding: utf-8 -*-



    from time import sleep



    def get_puffer():
    return 40



    def get_ofen():
    return 60


    # hysterese
    hysterese = 2


    # limits für puffer
    set_point_1 = 40
    top_1 = set_point_1 + hysterese / 2
    bottom_1 = set_point_1 - hysterese / 2


    # limits für ofen
    set_point_2 = 60
    top_2 = set_point_2 + hysterese / 2
    bottom_2 = set_point_2 - hysterese / 2



    while True:
    if bottom_1 < get_puffer() < top_1 and bottom_2 < get_ofen() < top_2:
    print 'Pumpe an'
    sleep(1)



    [/php]


    Und gleich vorweg als Tipp. Um unnötige Schaltvorgänge zu minimieren solltest du dir den "Zustand" der Pumpe in einem Status-Objekt oder Ähnlichem merken.

  • Korikatzo
    Ja sorry hatte ich mich vertan, sollte eher so sein. :blush:


    Code
    if (KO >= 60) or (Puffer >= 40):
    print "Pumpe an"
    Pumpe_an()
    # time.sleep(1)
    if (KO <= 58) and (Puffer <= 38):




    mobby
    ich wusste bisher nicht, dass ich nach eine Zweipunkt Regler suchen sollte, das hole ich aber nach ;)
    Deinen Code habe ich mir schon angeschaut werde ihn noch testen. Kann es aber sein, dass in der while Schleife noch was fehlt?
    Wie geht die Pumpe aus?


    Danke auch für den Tipp mit den Schaltvorgängen. Mir ist bei meinen Versuchen schon aufgefallen, dass ich die Pumpe immer wieder einschalte, obwohl sie schon an ist. Schau ich mir noch an, wie ich das lösen kann. :s

  • Ja war ja klar und passiert mal :thumbs1:


    Aus Interesse, würde das ganze nun so funktionieren? Sollte es ja eig :P Evtl noch ne kleine "Status Variable" wie mobby bereits meinte:


    Code
    if (KO >= 60) or (Puffer >= 40) and status == "Off":
    print "Pumpe an"
    Pumpe_an()
    # time.sleep(1)
    if (KO <= 58) and (Puffer <= 38) and status == "On":
    print "Pumpe aus"
    Pumpe_aus()


    Klar ist Mobbys Lösung die sauberere, aber zumindest ich finde es immer spannend mir auch zuerst selbst eine Lösung zu überlegen, die dann zwar evtl langsamer ist oder so, aber selbst geschaffen ist :D Danach kann man sich dann immernoch an der "perfekten" Lösung inspirieren :D .

  • Kannst du nicht einfach mehrere Werte ermitteln lassen und davon dann den Durchschnitts Wert verwenden?
    Also zum Beispiel führst du 3 Messungen durch: 59.9 , 60 , 60.9
    Alle 3 Werte addieren und dann durch die Anzahl der Messungen teilen: 59.9 + 60 + 60.9 / 3 = 60.27
    Die Messungen sollten aber nicht in einem zu schnellen Intervall stattfinden da viele Sensoren dazu neigen dann falsche Werte anzuzeigen (Eigenerwärmung usw). Auch sollten Grenzen festgelegt werden ab wann ein Wert als "valid" zählt, also um zB 0 oder negative Werte zu ignorieren

  • Guten Morgen,


    Korikatzo
    den Code werde ich am WE so nochmal testen - Danke



    mobby
    über Deinen Code habe ich heute Nacht nochmal nachgedacht. Ich glaube nicht dass Du mich richtig verstanden hast, oder ich mich richtig ausgedrückt habe. Bie Deinem Code sind jetzt Werte von 59 - 61 erlaubt. Ich meinte aber:
    wenn der Wert ansteigt und den Grenzwert bei 60 überschreitet, kann es sein dass die nächste Messung 59.999 ist und die Pumpe wieder aus ist. Kurze Zeit später wieder 60.555 ist und wieder einschaltet. Das möchte ich verhindern, indem bei Überschreiten von 60 EIN und dann, erst wenn der Wert unter 59 fällt aus geht.


    meigrafd
    Dein Vorschalg das würde nicht viel ändern. Die Werte könnten dennoch für kurze Zeit über und unter 60 pendeln.



    ich hab mir überlegt ob das so gehen könnte:


    Grenzwert = 60
    if KO >= Grenzwert
    Pumpe an
    Grenzwert = 59
    elif KO <= Grenzwert
    Pumpe aus
    Grenzwert = 60


    geht das???
    kann es erst am WE testen

  • Ich habe mal auf dein Kommentar angepasst und gleich das Status-Objekt eingefügt. So vermeidest du jetzt die unnötigen Schaltzeiten und es sollte deine Anforderungen erfüllen. Anbei ist eine grafische Beschreibung fürs Verständnis. Hoffe es hilft.


    [code=php]#!/usr/bin/env python
    # -*- coding: utf-8 -*-



    from time import sleep



    class Status(object):
    def __init__(self, bol_status):
    self.status = bol_status


    def get_status(self):
    return self.status


    def set_status_on(self):
    self.status = True


    def set_status_off(self):
    self.status = False



    def get_ofen():
    # Hier kommt deine Temperatur her
    return 60


    # Grenzen
    top = 60
    bottom = 59


    # Status-Objekt setzen, heißt beim "Start" des Skripts ist Pumpe AUS (False)
    status = Status(False)


    while True:
    if get_ofen() > top and status.get_status() is False:
    print 'Pumpe an'
    # Über Objekt merken, dass Pumpe AN ist
    status.set_status_on()
    elif get_ofen() < bottom and status.get_status() is True:
    print 'Pumpe aus'
    # Über Objekt merken, dass Pumpe AUS ist
    status.set_status_off()
    sleep(1)



    [/php]

  • Wieso so kompliziert, nur Status über nen extra Objekt? :-/ Welchen Vorteil hat das? :s


    Also nehmen wir mal die Basis ohne unnötigen Schnickschnack:

  • Guten Morgen!


    genau so hab ich mir das vorgestellt!! :) Funktioniert alles! nur noch den Code fertig machen und ich kann löten. :D


    echt super von Euch Zweien :thumbs1: :bravo2:



    Viele Grüsse
    Roland


    :danke_ATDE:

  • ich hätte da noch einen Nachtrag...
    Die Regelung mit der Hysterese funktioniert jetzt echt gut. Ich wollte das ganze jetzt noch mit einer Tag-Nacht-Schaltung versehen. Dazu habe ich den Code so geändert:




    so funktioniert das aber leider nicht wie ich mir das wünsche. Die Freigabe der Pumpe soll nur an bestimmten Wochentagen zu bestimmten Stunden freigegeben werden.
    An für sich funktioniert das mit den Wochentagen und Stunden. Aber nur wenn das Programm gestartet wurde, dann springt es in den entsprechenden Zweig kommt aber nicht mehr eine Ebene zurück.
    Noch eine Zusatzfrage, ich hab die Zeit jetzt auf Stunden reduziert, das geht vielleicht auch eleganter. Wie macht man das wenn ich zB um 5:30 starten will, bis 7:15???