Buongiorno a tutti, ho spulciato tutti i thread in cui si parla di RaspberryPi ma non ho trovato niente al riguardo.
Spero sia la sessione giusta, in caso vi chiedo gentilmente di spostare la discussione nel posto più appropriato.
Bene, detto questo veniamo al dunque!
Ho trovato diversi esempi su internet su come utilizzare gli interrupt su questa scheda, tuttavia non riesco a trovare una guida esaustiva al riguardo!
I problemi che ho al momento sono due:
- come passo delle variabili alle funzioni chiamate dall'interrupt?
- come gestisco il rimbalzo?
passiamo direttamente al codice, così ragioniamo su un esempio concreto!
Le domande relative le scrivo direttamente come commenti nel codice:
Code:
import RPi.GPIO as GPIO
import time
GPIO.setmode (GPIO.BCM)
GPIO.setup (20, GPIO.IN, pull_up_down = GPIO.PUD_UP )
time_stamp = time.time()
def switch_detect(channel):
print 'Falling edge detected on pin:', channel
GPIO.add_event_detect(20, GPIO.FALLING, callback=switch_detect, bouncetime=300)
# nella definizione la funzione switch_detect accetta un parametro, qui non gliene viene passato nessuno.
# Come fa a sapere quanto vale "channel"?
GPIO.cleanup() # a cosa serve questo comando?
Inoltre vorrei contare quante volte viene premuto il bottone.
Per farlo pensavo ad una cosa del genere:
Code:
...
n = 0
def switch_detect(channel, n):
print 'Falling edge detected on pin:', channel
print 'n:', n
GPIO.add_event_detect(20, GPIO.FALLING, callback=switch_detect(n), bouncetime=300)
...
Però in questo modo ottengo il seguente errore: TypeError: Parameter must be callable
Come posso passare un parametro ad una funzione chiamata tramite interrupt?
Passiamo al problema del DEBOUNCE.
Per quanto riguarda il debounce faccio riferimento a quanto appreso da questo sito:
raspi.tv/2013/how-to-use-interrupts-with...-and-rpi-gpio-part-2
Quindi aggiungere il parametro bouncetime=300 equivale a modificare la definizione della funzione "switch_detect" nel modo seguente:
Code:
def switch_detect(channel):
global time_stamp
time_now = time.time()
if (time_now - time_stamp) >= 0.3:
print 'Falling edge detected on pin:', channel
time_stamp = time_now
Giusto?
In questo modo si evita che l'interrupt si verifichi due volte consecutive in un intervallo minore di 300ms e questo risolve il problema del rimbalzo in fase di pressione dello switch, tuttavia rimane il problema in fase di rilascio, infatti possono essere generati dei fronti di discesa anche quando il bottone viene rilasciato, sbaglio?
E questo può accadere in un istante di tempo qualsiasi...
Infatti spesso viene stampata la scritta "Falling edge detected on pin: 20" nel momento in cui rilascio lo switch.
Come risolvo questo problema?
Dopo l'esecuzione della funzione aggiungo un controllo sullo stato del bottone in modo che resti in attesa finché non viene rilasciato? Questa parte conviene gestirla tramite polling o interrupt?
Grazie mille a tutti in anticipo!