Frage:
Wie blinken LEDs kontinuierlich ein / aus, während die Ausführung eines Skripts fortgesetzt wird?
Stephen Lead
2015-03-25 03:53:15 UTC
view on stackexchange narkive permalink

Ich habe rote und grüne LEDs über GPIO angeschlossen und kann sie mit RPi.GPIO erfolgreich ein- und ausschalten - jetzt möchte ich:

  • Starten Sie alle 1 Sekunde ein LED-Blinken.
  • Lassen Sie das Skript seine Ausführung fortsetzen.
  • Verhindern Sie, dass die LED bei einem anderen Signal blinkt.

Ein ähnliches Beispiel ist das Projekt Raspberry Pi E-Mail-Benachrichtigung mit LEDs, außer dass in diesem Fall die LEDs dauerhaft leuchten und das Skript nur bis zur nächsten Überprüfung wartet:

  if newmails > NEWMAIL_OFFSET: GPIO.output (GREEN_LED, True) GPIO.output (RED_LED, False) else: GPIO.output (GREEN_LED, False) GPIO.output (RED_LED, True) time.sleep (MAIL_CHECK_F) > 

Ist es möglich, so etwas wie diesen Pseudocode zu tun?

  cont = Truewhile cont: Nach E-Mails suchen, wenn neue E-Mails: flashLed (grün) else: flashLed ( rot) mache andere Dinge, während das entsprechende Licht blinkt (nicht nur time.sleep) def flashLed (Farbe): hör auf zu blinken, die andere Farbe beginnt zu blinken Wenn diese Farbe zum aufrufenden Programm zurückkehrt  

Damit dies funktioniert, muss die Funktion flashLed das entsprechende LED-Flashen starten und dann die Ausführung an das zurückgeben Hauptskriptkörper.

Ist dies mit Python möglich? Gibt es einen besseren Ansatz?

Fünf antworten:
Stephen Lead
2015-03-26 05:51:55 UTC
view on stackexchange narkive permalink

Vielen Dank an @ user451777 für den Tipp zum Einfädeln. Ich habe das Skript Signalisierung zwischen Threads geändert und Folgendes gefunden:

  Threading importieren, Zeit vom zufälligen Import randintdef flashLed (e, t): "" "flash the spezifizierte LED jede Sekunde "" "ohne e.isSet (): print (color) time.sleep (0.5) event_is_set = e.wait (t) wenn event_is_set: print ('LED nicht mehr blinken lassen') else: print (' LEDs aus ') time.sleep (0.5) color = "red" e = threading.Event () t = threading.Thread (name =' non-block ', target = flashLed, args = (e, 2)) t. start () für i im Bereich (0, 10): # Weisen Sie zufällig alle 10 Sekunden Rot oder Grün zu. randomNumber = randint (0,10) print (randomNumber) if (randomNumber < 5): color = "green" else: color = "rot" time.sleep (10) e.set ()  

Dies simuliert das Ein- und Ausschalten der entsprechenden LED in einem Thread, während die Programmausführung im Hauptthread fortgesetzt wird. Entscheidend ist, dass die Funktion flashLed die Ausführung nicht blockiert, während die LEDs blinken.

Der Hauptthread verwendet eine globale Variable, um die LED-Farbe festzulegen, während der andere Thread die Funktion verwendet globale Variable zum Einschalten der entsprechenden LED. Ich glaube, dass globale Variablen im Allgemeinen verpönt sind, daher würde ich mich über bessere Ansätze freuen.

Stephen, vielen Dank, dass Sie Ihre Lösung veröffentlicht haben - äußerst hilfreich
`event_is_set = e.wait (t)` sollte durch` event_is_set = e.is_set () `ersetzt werden. Andernfalls fügen Sie für jeden Anruf eine Verzögerung von "t" hinzu, wenn das Flag ausgeschaltet ist.
josxou15
2017-07-18 00:55:11 UTC
view on stackexchange narkive permalink

Ich bin relativ neu in Python, aber ich konnte die LEDs blinken lassen, während ich die Ausführung fortsetzte, indem ich die im RPi.GPIO-Modul integrierte Pulsweitenmodulation (PWM) verwendete. Dies war meiner Meinung nach viel einfacher und einfacher als das Einfädeln, wie andere Antworten vermuten lassen, jedoch würden beide Methoden gut funktionieren.

Erstellen Sie einfach ein PWM-Objekt mit der gewünschten Frequenz und rufen Sie dann PWM.start (DC) auf. und PWM.ChangeDutyCycle (DC) zum Starten / Ändern des LED-Arbeitszyklus. Fahren Sie mit Ihrem Code fort und rufen Sie PWM.stop () auf, um die LED zu stoppen.

  # GPIO-Pins einrichten und GPIO-Modul importieren g = GPIO.PWM (Pin1,1) r = GPIO. PWM (Pin2,1) g.start (0) r.start (0) greenStatus = False redStatus = False def flashLED (Farbe): global greenStatus, redStatus wenn color == 'green': wenn redStatus: r.ChangeDutyCycle (0 ) redStatus = False wenn nicht greenStatus: g.ChangeDutyCycle (50) greenStatus = True elif color == 'red': wenn greenStatus: g.ChangeDutyCycle (0) greenStatus = False wenn nicht redStatus: r.ChangeDutyCycle (50) redStatus = True try: while True: if newMail (): flashLED ('grün') else: flashLED ('rot') #do andere Dinge hier und die LED blinkt weiter außer KeyboardInterrupt: g.stop () r.stop () GPIO.cleanup ()  

Grundsätzlich startet dieser Code beide LEDs mit einem Tastverhältnis von 0, sodass sie ausgeschaltet erscheinen. Jedes Mal, wenn flashLED (Farbe) aufgerufen wird, wird überprüft, ob die gegenüberliegende LED ausgeschaltet ist. Wenn dies nicht der Fall ist, wird das Tastverhältnis auf 0 zurückgesetzt. Anschließend wird die andere LED eingeschaltet, wenn sie noch nicht eingeschaltet ist. Der Code wird in einen Versuch / eingeschlossen, außer dass am Ende beide PWM-Objekte gestoppt und die GPIO-Pins bereinigt werden.

user451777
2015-03-25 09:11:08 UTC
view on stackexchange narkive permalink

Ich würde Threading empfehlen. Ich habe es in Python nicht als Beispiel verwendet, aber es wird ein weiterer Ausführungsthread erstellt, der parallel zum Hauptausführungsthread ausgeführt wird. Hoffentlich folgen einige Codebeispiele für Sie.

http://pymotw.com/2/threading/

paddyg
2015-04-03 22:30:09 UTC
view on stackexchange narkive permalink

@Stephen Lead, Sie haben Fragen zu Globals. Bei Dingen wie Threading-Funktionen scheinen Globals manchmal eine vernünftige Option zu sein, da die Alternativen komplizierter sein können. Es ist jedoch eine gute Angewohnheit, sie immer explizit als global zu deklarieren.

  def flashLed (e, t): "" Flashen Sie die angegebene LED jede Sekunde "" "globale Farbe, ohne e.isSet ( ):  

, weil Sie irgendwann versuchen werden, die Variable zuzuweisen, und sich bemühen, herauszufinden, warum sie keine Wirkung zu haben scheint.

Sie können Übergeben Sie Argumente an die Funktion, die von anderen Teilen Ihres Programms oder von Ihrer Funktion geändert wurden. Die Argumente müssen jedoch Objekte sein, die veränderbar sind. Das einfachste Beispiel wäre eine Liste, dann erhalten Sie die nur geringfügig künstliche:

  def flashLed (e, t, color): ... print (color [0]) color = ["rot"] e = threading.Event () t = threading.Thread (name = 'non-block', target = flashLed, args = (e, 2, color)) ... if (randomNumber < 5) : color [0] = "green"  

Wenn Sie umfangreichere Informationen für die Kommunikation zwischen den beiden Threads hätten, wäre eine Liste möglicherweise logischer. Warteschlangen sind auch recht einfach zu verwenden und sollten in den Dokumenten überprüft werden.

developius
2015-03-25 16:22:02 UTC
view on stackexchange narkive permalink

Sie könnten Folgendes tun:

  while True: if newMail (): # gibt true zurück, wenn neue Mail gesendet wird, false, wenn nicht flashLED ("grün") else: flashLED ("red") ") def flashLED (Farbe): wenn Farbe ==" rot ": Pin = 18 # Nummer durch GPIO-Nummer ersetzen, wenn Farbe ==" grün ": Pin = 24 # Nummer durch GPIO-Nummer ersetzen GPIO.output (Pin, True) # Pin durch GPIO-Nummer ersetzen time.sleep (1) GPIO.output (Pin, False)  

Der Vorteil ist, dass kein Threading erforderlich ist. Sie müssten erstellen newMail () selbst, es sei denn, in einer Bibliothek ist eine ähnliche Funktion verfügbar ( diese Antwort bietet eine Lösung für Google Mail und POP)

Danke für den Tipp. Aber wenn ich mich nicht irre, blinkt die LED nur einmal und beendet dann die Funktion. Ich hatte gehofft, das LED-Blinken zu starten, es zu blinken, während ich andere Aufgaben erledigte, und dann das Blinken bei einem späteren Signal zu stoppen. Es sieht so aus, als ob dies tatsächlich einen separaten Thread erfordert
Dieser Code lässt die LED jedes Mal blinken, wenn die Schleife ausgeführt wird. Wenn Sie andere Aufgaben ausführen möchten, setzen Sie sie einfach nach dem if / else.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...