Domanda:
Come si accendono / spengono i LED continuamente mentre si continua l'esecuzione di uno script?
Stephen Lead
2015-03-25 03:53:15 UTC
view on stackexchange narkive permalink

Ho collegato i led rosso e verde tramite GPIO e posso accenderli / spegnerli con successo usando RPi.GPIO - ora vorrei:

  • avvia un led lampeggiante ogni 1 secondo
  • fai in modo che lo script continui la sua esecuzione
  • ferma il led dal lampeggiare ad un altro segnale

Un esempio simile è il progetto Raspberry Pi E-mail Notifier Using LEDs, tranne in questo caso i LED sono accesi in modo fisso e lo script attende solo il controllo successivo:

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

È possibile fare qualcosa di simile a questo pseudo-codice?

  cont = Truewhile cont: controlla la posta in caso di nuova posta: flashLed (verde) else: flashLed ( rosso) fare altre cose mentre la spia relativa lampeggia (non solo time.sleep) def lampeggiante LED (colore): smetti di lampeggiare l'altro colore inizia a lampeggiare reimpostando questo colore ritornare al programma chiamante  

Affinché funzioni immagino che la funzione flashLed debba far partire il led corrispondente lampeggiante, quindi riportare l'esecuzione al corpo principale dello script.

È possibile utilizzare Python? C'è un approccio migliore?

Cinque risposte:
Stephen Lead
2015-03-26 05:51:55 UTC
view on stackexchange narkive permalink

Grazie a @ user451777 per il suggerimento sul threading. Ho modificato lo script Signaling Between Threads e ho ottenuto quanto segue:

  import threading, timefrom random import randintdef flashLed (e, t): "" "flash the led specificato ogni secondo "" "mentre non e.isSet (): print (color) time.sleep (0.5) event_is_set = e.wait (t) if event_is_set: print ('stop led from flashing') else: print (' led off ') time.sleep (0.5) color = "red" e = threading.Event () t = threading.Thread (name =' non-block ', target = flashLed, args = (e, 2)) t. start () for i in range (0, 10): # Assegna casualmente il rosso o il verde ogni 10 secondi randomNumber = randint (0,10) print (randomNumber) if (randomNumber < 5): color = "green" else: color = "red" time.sleep (10) e.set ()  

Questo simula l'accensione / spegnimento del relativo led in un thread mentre l'esecuzione del programma continua nel thread principale. Fondamentalmente, la funzione flashLed non blocca l'esecuzione mentre i led lampeggiano.

Il thread principale utilizza una variabile globale per impostare il colore del led, con l'altro thread che utilizza il variabile globale per accendere il relativo led. Credo che le variabili globali siano generalmente disapprovate, quindi sarei interessato a conoscere eventuali approcci migliori.

Stephen grazie per aver pubblicato la tua soluzione - estremamente utile
"event_is_set = e.wait (t)" dovrebbe essere sostituito con "event_is_set = e.is_set ()". Altrimenti, stai aggiungendo un ritardo di "t" per ogni chiamata quando il flag è disattivato.
josxou15
2017-07-18 00:55:11 UTC
view on stackexchange narkive permalink

Sono relativamente nuovo in Python, ma sono stato in grado di far lampeggiare i LED mentre continuo l'esecuzione utilizzando Pulse Width Modulation (PWM) che è integrato nel modulo RPi.GPIO. Questo secondo me era un modo molto più semplice e semplice del threading come suggeriscono altri anwsers, tuttavia entrambi i metodi funzionerebbero bene.

Crea semplicemente un oggetto PWM con la frequenza desiderata e quindi chiama PWM.start (DC) e PWM.ChangeDutyCycle (DC) per avviare / modificare il ciclo di lavoro dei LED. Continua con il tuo codice e poi chiama PWM.stop () per fermare il LED.

  #setup pin GPIO e importa il modulo GPIO g = GPIO.PWM (pin1,1) r = GPIO. PWM (pin2,1) g.start (0) r.start (0) greenStatus = False redStatus = False def flashLED (color): global greenStatus, redStatus if color == 'green': if redStatus: r.ChangeDutyCycle (0 ) redStatus = False if not greenStatus: g.ChangeDutyCycle (50) greenStatus = True elif color == 'red': if greenStatus: g.ChangeDutyCycle (0) greenStatus = False se non redStatus: r.ChangeDutyCycle (50) redStatus = True prova: while True: if newMail (): flashLED ('green') else: flashLED ('red') # fai altre cose qui e il LED continuerà a lampeggiare tranne KeyboardInterrupt: g.stop () r.stop () GPIO.cleanup ()  

Fondamentalmente questo codice avvia entrambi i LED con un duty cycle di 0 in modo che appaiano spenti. Ogni volta che viene chiamato flashLED (colore), verifica che il LED opposto sia spento, in caso contrario il suo ciclo di lavoro viene ripristinato a 0. Quindi si accende l'altro LED se non è già acceso. Il codice è racchiuso in un try / tranne che alla fine entrambi gli oggetti PWM vengono fermati e i pin GPIO vengono puliti.

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

Consiglierei il threading. Non l'ho usato in Python per dare un esempio, ma creerà un altro thread di esecuzione che corre parallelo al thread principale di esecuzione. Si spera che seguano alcuni esempi di codice per te.

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

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

@Stephen Lead, sei una domanda sui globali. A volte, con cose come funzioni di threading, le variabili globali sembrano un'opzione ragionevole in quanto le alternative possono essere più complicate. Tuttavia è una buona abitudine dichiararli sempre esplicitamente come globali

  def flashLed (e, t): "" "lampeggia il led specificato ogni secondo" "" colore globale mentre non e.isSet ( ):  

perché a un certo punto proverai ad assegnare la variabile e farai fatica a capire perché non sembra avere alcun effetto.

Puoi passa argomenti alla funzione che sono alterati da altre parti del tuo programma o sono alterati dalla tua funzione ma gli argomenti devono essere oggetti mutabili. L'esempio più semplice sarebbe un elenco, quindi si finisce con il, solo leggermente artificiale:

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

Se disponi di informazioni più ampie per comunicare tra i due thread, un elenco potrebbe sembrare più logico. Le code sono anche abbastanza semplici da usare e vale la pena verificarle nella documentazione.

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

Potresti fare qualcosa del genere:

  while True: if newMail (): # restituisce true se nuova posta, false se non flashLED ("green") else: flashLED ("red ") def flashLED (color): if color ==" red ": pin = 18 # sostituisce il numero con il numero GPIO if color ==" green ": pin = 24 # sostituisce il numero con il numero GPIO GPIO.output (pin, True) # sostituisci il pin con il numero GPIO time.sleep (1) GPIO.output (pin, False)  

Il vantaggio di questo è che non è coinvolto alcun threading. Dovresti costruire newMail () tu stesso, a meno che non sia disponibile una funzione simile in una libreria ( questa risposta fornisce una soluzione per Gmail e POP)

Grazie per il consiglio. Ma a meno che non mi sbagli, questo farà lampeggiare i LED solo una volta, quindi uscirà dalla funzione. Speravo di far lampeggiare il led, mantenerlo lampeggiante mentre eseguivo altre attività, quindi smettere di lampeggiare a un segnale successivo. Sembra che questo possa effettivamente richiedere un thread separato
Quel codice manterrà il LED lampeggiante, una volta ogni volta che viene eseguito il ciclo. Se vuoi svolgere altre attività, inseriscile dopo if / else.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 3.0 con cui è distribuito.
Loading...