Anweisungen in if-Schleife gleichzeitig ablaufen lassen

  • Hallo,

    ich habe ein Programm geschrieben, bei dem nach einem Tastendruck Relais geschaltet werden sollen.

    Ich möchte gerne, dass alle gleichzeitig eingeschaltet werden und dann ihre definierte Zeit laufen und wieder aus gehen.

    Aktuell laufen diese aber hintereinander ab, sprich:

    Ralei 1 schaltet ein, läuft 10 Sekunden und geht aus - Relai 2 schaltet ein, läuft 5 Sekunden und geht aus - Relai 3 schaltet ein, läuft 2 Sekunden und geht aus

    Das Problem liegt denke ich an der if-Schleife, aber ich finde nichts wie man das richtig Programmiert. Vielleicht könnte mir jemand eine gute Quelle nennen und ggf. eine Idee geben, wie ich mein Programm aufbauen müsste.

    Vielen Dank :)

  • Anweisungen in if-Schleife gleichzeitig ablaufen lassen? Schau mal ob du hier fündig wirst!

  • Zuerst mal der obligatorische Klugschiss: http://if-schleife.de/

    Und dann ist das doch nicht wirklich so schwer. Ueberleg doch mal, wie du das machen wuerdest, wenn ich dir drei Schalter vorsetze, und sage: "alle zum gleichen Zeitpunkt an, und dann jeden einzelnen so-und-so-lange laufen lassen".

    Du wuerdest doch auch nicht hingegen, den ersten druecken, 10 Sekunden warten, und dann den naechsten usw.

    Sondern

    - alle drei Schalter einschalten
    - die kuerzeste Zeit, die einer von denen an sein soll, warten.
    - den 1ten ausschalten.
    - dann noch mal den Rest der Zeit, die der zweitkuerzeste an sein soll warten.
    - den 2ten. ausschalten.
    - dann die Restzeit zum laengsten abwarten.
    - dann den 3ten .ausschalten

    Und so musst du das halt auch machen.

  • Oder Du benutzt Threading. Das ist dann zuerst etwas komplizierter, danach macht es aber alles leichter. Anbei ein kurzer Hack von mir als Beispiel.
    [code=php]#!/usr/bin/python

    import time
    import threading

    class myRelais (threading.Thread):
        
    def __init__(self, pin, delay):
    threading.Thread.__init__(self)
    self.pin = pin
    self.delay = delay

    def getName(self):
    return "Relais with pin %s" % (self.pin)

    def run(self):
    print "%s - Starting %s" % (time.ctime(time.time()), self.getName())
    time.sleep(self.delay)
    print "%s - Turning off pin %s after %s" % (time.ctime(time.time()), self.pin, self.delay)
    print "%s - Exiting %s" % (time.ctime(time.time()), self.getName())

    # Create new relais threads
    relais1 = myRelais(16, 10)
    relais2 = myRelais(18, 7)
    relais3 = myRelais(20, 2)

    # Start new relais Threads
    relais1.start()
    time.sleep(1)
    relais2.start()
    time.sleep(1)
    relais3.start()

    while threading.activeCount() > 1:
    time.sleep(3)

    print "Finished"[/php]


  • Oder Du benutzt Threading. Das ist dann zuerst etwas komplizierter, danach macht es aber alles leichter. Anbei ein kurzer Hack von mir als Beispiel.

    Bitte nicht! Nebenlaeufigkeit ist eines der bittersten Probleme der Softwareentwicklung, und ohne Not sollte man dazu nicht greifen. Die "Interrupt"-Behandlung in den GPIOs des PI bringt - leider, und voellig unnoetig - Threads in's Spiel, und ich habe hier schon genug Code gesehen (und repariert), der daran zugrunde ging.

  • Dein Lösungsvorschlag das Problem zu serialisieren ist pfiffig einfach :thumbs1: und der TE hat ihn ja auch schon aufgenommen.

    Nun kann er entscheiden ob er sich anhand des konkreten Problems in die komplexere Materie des Threadings einarbeitet. Sie ist aber im konkreten Falle er richtigere Weg und - sofern man das Threading verstanden hat - einfacher zu benutzen. :)

  • Das Universum in dem die kombinatorische Explosion der moeglichen Zustandsautomaten in einem *einfacheren* Programmieren endet ist mir - und meinen ~50 Kollegen, und diversen Leuten aus dem Internet http://blog.codinghorror.com/threading-conc…ve-in-the-univ/ - bisher verschlossen geblieben. Wenn du das Sternetor dahin kennst, zeig es mir - bitte :)

    Und "richtiger" erschliesst sich mir jetzt auch nicht. Richtig ist, was richtig funktioniert. Meinst du vielleicht generalisierbarer? Nicht mehr seit Python 3.4, und mit 3.5 sogar mit neuer Syntax:

  • So, ich hab' mich mal ans experimentieren gemacht. Das Thema asyncio in Python3.5 ist neu, da muss man sich ja eh mal auseinandersetzen. Und es klappt *fast* perfekt.

    Leider hat man versaeumt, die speziellen "xlist"-Ereignisse von select in dem Eventloop umzusetzen. Darum muss ich in die Trickkiste greifen, und einen in-process socket machen. Und - Schande, Schande - einen Thread benutzen.

    Wenn ich das allerdings als Bibliothek machen wuerde, dann wuerde ich halt *einen* Hintergrund-Thread haben (so wie jetzt ja auch schon bei RPI.GPIO), und dort auf Ereignisse warten, um die dann in den Mainloop zu propagieren.

    Aber fuer mich steht trotzdem ausser Frage, dass ereignisbasierte Programmierung von Vorteil ist - denn echte Parallelitaet fuehrt schnell ins Chaos.

  • Ich versteh leider nicht was Ihr diskutiert...
    Es ist aber ein neues/altes Problem aufgetreten, das ich schon einmal hatte.

    Wenn ich das Programm starte, aber den Taster nicht betätige, dann kommt es vor, dass das Programm ausgeführt wird. Dies geschieht willkürlich in Minutenabständen. Liegt das an meinem Script, oder an Stromschwankungen in der Elektrik?

    Hat jemand eine Idee??

    Einmal editiert, zuletzt von Forcecon (26. März 2016 um 17:09)


  • So, ich hab' mich mal ans experimentieren gemacht. Das Thema asyncio in Python3.5 ist neu, da muss man sich ja eh mal auseinandersetzen. Und es klappt *fast* perfekt.

    :thumbs1:

    Zitat

    ... denn echte Parallelitaet fuehrt schnell ins Chaos...

    Für ProgrammierAnfänger definitiv.
    Das Gehirn eines Menschen arbeitet parallel - aber leider bereitet diesem Gehirn Denken in parallelen Strukturen ziemliche Probleme :( Dazu kommt das parallel ablaufende Dinge gewisse Herausforderungen beim Debuggen stellen :D

    Forcecon: Du solltest wg Deines neuen Problems einen neuen Thread aufmachen.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!