• Benvenuti su RaspberryItaly!
Benvenuto ospite! Login Login con Facebook Registrati Login with Facebook


Valutazione discussione:
  • 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5

[-]
Tags
led uso interrupt detect add event strano comportamento con gpio dell del e

[Problema] Uso dell'interrupt con GPIO.add_event_detect() e strano comportamento del LED
#1
Sad 
Salve a tutti,

Ho da pochissimo un Raspberry 3 B+. 
Mentre cerco di familiarizzare con la libreria Gpiozero (su suggerimento di @Zzed), sto nel frattempo facendo un po’ di pratica con la libreria classica RPi e il rilevamento dei cambi di stato in input (Edge) tramite interrupt.

Semplice esperimento: pulsante collegato a 3.3V e BCM15, con resistenza da 220Ω; LED collegato a BCM17 e massa, con resistenza da 330Ω.
Nella mia intenzione, premendo una volta il pulsante il LED dovrebbe accendersi, premendo nuovamente dovrebbe spegnersi.

In realtà il programma non funziona bene: spesso non accende o non spegne il LED oppure accende e spegne consecutivamente e altre cose bizzarre.
Pare quasi che la parte di programma con if… else… non sia ben sincronizzata con il callback di GPIO.add_event_detect().

Non capisco dove sia l’errore…

Di seguito il listato e lo schema dell’esperimento.
Grazie a tutti.

----------------------

Codice:
# Accensione-spegnimento LED con interrupt

from RPi import GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.OUT) # pin 17 (LED) impostato OUT
GPIO.output(17,GPIO.LOW)

def richiamo_pulsante(channel): # funzione: channel = pin 15
    print('Pulsante premuto!')
    if(GPIO.input(17) == GPIO.LOW):
        GPIO.output(17,GPIO.HIGH)
        print('LED acceso!')
    else:
        GPIO.output(17,GPIO.LOW)
        print('LED spento!')
    
# Pin BCM 15 come INPUT e
# definirlo come PULL-DOWN = OFF = 0
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# Creazione di un EVENTO (INTERRUPT) per il pin BCM 15
GPIO.add_event_detect(15, GPIO.RISING, callback=richiamo_pulsante)

messaggio = input('Premi INVIO per uscire\n\n')

GPIO.cleanup()

------------


Allegati Anteprime
   
Risposta
#2
Forse devi utilizzare una pausa di qualche millisecondo per l’antirimbalzo


Inviato dal mio iPhone utilizzando Tapatalk
Risposta
#3
(01/04/2019, 20:33)Luca Charruaz Ha scritto: Forse devi utilizzare una pausa di qualche millisecondo per l’antirimbalzo

Ciao Luca, grazie per la risposta,

ho provato ad inserire delle pause nella sezione if... else... con un ritardo di 10 millisecondi:

Codice:
...
 if(GPIO.input(17) == GPIO.LOW):
        GPIO.output(17,GPIO.HIGH)
        print('LED acceso!')

        time.sleep(0.01) # <-- PAUSA 10 millisecondi
    
else:
        GPIO.output(17,GPIO.LOW)
        print('LED spento!')

        time.sleep(0.01) # <-- PAUSA 10 millisecondi

Ma purtroppo il risultato non cambia  Dodgy

Sono un novellino del Raspb Pi e non so cosa sia l'antirimbalzo...
Risposta
#4
So che lo ho già detto, ma da qualche anno, la libreria di riferimento per comandare il GPIO è gpiozero.
Impara quella invece di Rpi.GPIO. Te lo dico dopo qualche mese in cui ho provato a fare il percorso contrario: già conoscendo gpiozero, per studio, nella realizzazione di un progetto, ho voluto provare a farlo tutto con Rpi.GPIO, cogliendo l'occasione per approfondire le mie conoscenze. Bèh, sono arrivato alla conclusione che non ne vale la pena! Meglio non perdere tempo in una marea di indicazioni al GPIO e concentrarsi sulla pura programmazione!
Gpiozero molto più amichevole, e internamente usa sempre Rpi.GPIO (volendo si può cambiare "motore", per altre esigenze, tipo comandare il GPIO di un Raspberry remoto ad esempio, ma di default usa Rpi.GPIO), ma in una forma molto più "umana".
Inoltre molte cosette sono impostate di default su valori che la pratica ha mostrato i migliori per la maggior parte delle applicazioni (tipo numerazione BCM, resistenze pull up, pull down ecc)..
Suggerimento: per convenzione la definizione delle funzioni si fa all'inizio dello script Python, subito dopo aver importato le librerie e prima del programma principale.

Ad esempio il tuo programma:
Codice:
# Accensione-spegnimento LED con interrupt

from RPi import GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.OUT) # pin 17 (LED) impostato OUT
GPIO.output(17,GPIO.LOW)

def richiamo_pulsante(channel): # funzione: channel = pin 15
   print('Pulsante premuto!')
   if(GPIO.input(17) == GPIO.LOW):
       GPIO.output(17,GPIO.HIGH)
       print('LED acceso!')
   else:
       GPIO.output(17,GPIO.LOW)
       print('LED spento!')
   
# Pin BCM 15 come INPUT e
# definirlo come PULL-DOWN = OFF = 0
GPIO.setup(15, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# Creazione di un EVENTO (INTERRUPT) per il pin BCM 15
GPIO.add_event_detect(15, GPIO.RISING, callback=richiamo_pulsante)

messaggio = input('Premi INVIO per uscire\n\n')

GPIO.cleanup()

con gpiozero può diventare
Codice:
# Accensione-spegnimento LED con interrupt e gpiozero
from gpiozero import LED, Button  # importo le librerie
from signal import pause

led = LED(17)                             # assegno il LED al pin GPIO 17
pulsante = Button(15)            # assegno il pulsante al pin GPIO 15

led.source = pulsante               # associo il LED al pulsante

pause()
molto più leggibile, con zero fronzoli e zero sbatti.
dicendo alla libreria che collegherò un LED, automaticamente imposta il pin come OUT o dicendo che è un pulsante automaticamente lo imposta come IN e attiva la resistenza di pull-up..
Si volesse mettere un antirimbalzo (approfondisci qui cosa si intende), basterebbe sostituire la sesta riga del codice qui su con
Codice:
pulsante = Button(15,bounce_time=0.05)
Risposta
#5
Ciao Zzed,
grazie infinite per l'aiuto (e per il suggerimento di porre le definizioni di funzione nel luogo giusto all'interno del programma... purtroppo non sono esperto di Python).
Gpiozero è sicuramente conciso e più efficace di Rpi. Purtroppo ho problemi nella gestione dell'input con pulsante.  Sad
Ad esempio, con il codice di https://gpiozero.readthedocs.io/en/stable/ :

Codice:
from gpiozero import LED
from time import sleep

led = LED(17)

while True:
    led.on()
    sleep(1)
    led.off()
    sleep(1)

il LED lampeggia perfettamente, ma provando il codice successivo:

Codice:
from gpiozero import LED, Button
from signal import pause

led = LED(17)
button = Button(15)

button.when_pressed = led.on
button.when_released = led.off

pause()

ebbene il programma non rileva il pulsante premuto e il LED non si accende. Forse perché nel circuito il pulsante riceve il positivo dal pin fisico 1 (3.3V) e GPIO 15 costituisce il negativo... non so proprio. Può essere dovuto alle resistenze (fisiche, non software)? O forse con Gpiozero occorre che un pulsante abbia il positivo collegato ad un pin GPIO e il negativo a GROUND? Davvero non so come farlo funzionare.

Infatti il programma che mi suggerisci sopra (con gpiozero) non funziona, Undecided  pare che non rilevi affatto il pulsante quando premuto. Ho anche provato a modificare la sesta riga di codice per l'antirimbalzo.

Nel frattempo sto esaminando il tuo link su Wikipedia sull'antirimbalzo: piuttosto tecnico... non sono così competente in elettronica, mi sforzo di capirci qualcosa. Wink

Gentilissimo come sempre, grazie!
Risposta
#6
Lightbulb 
Ciao, Zzed, aggiornamento:

Esperimento: modifica del pulsante con nuova connessione a GPIO

Nuovo pulsante collegato a GPIO 3 come positivo e GROUND (pin fisico 25).

Ora funziona!

Evidentemente Gpiozero non ammette che un pulsante sia collegato a un pin 3.3V e a un GPIO "generico" come massa.
Però, che strano...  Huh

Codice:
from gpiozero import LED, Button
from signal import pause

led = LED(17)
button = Button(3)

button.when_pressed = led.on
button.when_released = led.off

pause()

Codice:
# Accensione-spegnimento LED con interrupt e gpiozero
from gpiozero import LED, Button  # importo le librerie
from signal import pause

led = LED(17)                             # assegno il LED al pin GPIO 17
pulsante = Button(3)            # ora assegno il pulsante al --> pin GPIO 3

led.source = pulsante               # associo il LED al pulsante

pause()


Allegati Anteprime
   
Risposta
#7
Non è che "non lo ammette". È che di default è predisposto per quel tipo di connessione.
[Immagine: button_bb.svg]
Tramite la resistenza di pull-up puoi impostare se rilevare la chiusura verso massa o verso il positivo (altro motivo per cui è comodo usare le resistenze interne).

Inviato dal mio A0001 utilizzando Tapatalk
Risposta
#8
(02/04/2019, 21:42)Zzed Ha scritto: Non è che "non lo ammette". È che di default è predisposto per quel tipo di connessione.
[Immagine: button_bb.svg]
Tramite la resistenza di pull-up puoi impostare se rilevare la chiusura verso massa o verso il positivo (altro motivo per cui è comodo usare le resistenze interne).

Inviato dal mio A0001 utilizzando Tapatalk

Ok, forse ho capito, ma evidentemente non ho ben chiari a fondo i concetti di pull-up/pull-down.
La chiusura verso massa è quella di un circuito che utilizza un pin GROUND? E quella verso il positivo utilizza un pin 3.3V?

P.S.: Nessuna resistenza per il pulsante, perché ci pensa Gpiozero ad impostare una resistenza "software"? 
(forse è per questo che se uso una resistenza "fisica" di 1k Ohm Gpiozero non rileva il bottone premuto: la somma di resistenza fisica+resistenza software è eccessiva?)
Risposta
#9
si!
per chiarirti i concetti di pull up e pull down, leggi qui.
La teoria è importante, e l'elettrotecnica e l'elettronica sono scienze basate su molti concetti teorici che è bene conoscere. Ma nella filosofia di gipiozero, usa il metodo di collegamento consigliato e i valori di default e con zero problemi sei già operativo!
Risposta
#10
(03/04/2019, 22:39)Zzed Ha scritto: si!
per chiarirti i concetti di pull up e pull down, leggi qui.
La teoria è importante, e l'elettrotecnica e l'elettronica sono scienze basate su molti concetti teorici che è bene conoscere. Ma nella filosofia di gipiozero, usa il metodo di collegamento consigliato e i valori di default e con zero problemi sei già operativo!

Grazie per il link, finalmente qualcosa in italiano!  Smile 
Con tutti quei siti in inglese mi stavo accartocciando il cervello.
L'elettronica è una scienza esatta - dici bene! E si basa sulla matematica.
Infatti per questo ho comprato diversi e-book (e qualcosa in cartaceo) e li sto studiando, ma non è che ci capisca tutto.
Peccato poi che io in matematica sia sempre stato negato, anche se negli anni '80 mi divertivo ad assemblare i componenti (enormi, a quel tempo) saldandoli sulle piastrine per lo SpeedDos del mio mitico C64 collegato a drive 1541 (floppy da 5' e 1/4'). Caricamento 10 volte più veloce! Un miracolo per quell'epoca!
... sì... insomma, sto parlando dell'epoca dei DINOSAURI... 
... io stesso sono un dinosauro, spesso disorientato dalla tecnologia attuale, anche se ho sempre avuto un computer  da quando avevo 12 anni (iniziando con il Commodore Vic20)
Nostalgia... Tongue 

Ti ringrazio ancora e tantissimo per i tuoi preziosi suggerimenti.

PS: finalmente sono riuscito a connettere il Raspb. al Mac con VNC con pochi passaggi per avere una finestra remota del desktop di Raspbian: tutto perfettamente sincronizzato e operativo da ambo le parti, dallo schermo del Pi (davvero piccolo) o da Mac, impressionante!
Queste cose mi esaltano.  Big Grin
Sarà più facile scrivere i programmi in Python.
Meraviglie dei tempi moderni (per chi come me è un po' rimasto agli anni '80)
Risposta
  


Vai al forum:


Navigazione: 1 Ospite(i)
Forum con nuovi Post
Forum senza nuovi post
Forum bloccato
Forum Redirect