Problème GPIO.add_event_detect()

Bonjour,

J’ai un problème avec mon code plus particulièrement sur la partie GPIO.add_event_detect()
J’ai un message d’erreur quand j’appuie sur mon bouton poussoir qui me dit :

TypeError: bouton() takes 0 positional arguments but 1 was given

Je me suis renseigné, j’ai mis des self un peu partout notamment bouton(self).
Je n’ai plus de message d’erreur mais rien ne se passe.
J’ai l’impression qu’il rentre bien dans ma fonction bouton mais que le if de mon main n’est jamais validé.
J’ai aussi mis un global devant mon flag mais rien n’y fait.

Si vous avez une piste, merci.

Voici le code :

import RPi.GPIO as GPIO
import picamera
import datetime
from time import sleep
import cv2

# variable globale qui sera vue dans toutes les fonctions

flag_callback = False

def camera():
    camera = picamera.PiCamera()
    
    camera.resolution = (3280,2464)
    

def init():
    # configuration de la broche 7 en entree
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(2, GPIO.IN)
    # definition de l'interruption
    GPIO.add_event_detect(2, GPIO.RISING, callback = bouton, bouncetime=300)
    # initialisation du flag
    flag_callback = False


def bouton():
    # fonction qui sera appelée lorsque le programme sera interrompu
    flag_callback = True


def process_my_callback():
    print("ok")
    camera.start_preview()
    sleep(2)
    camera.capture(str(datetime.datetime.now())+'.jpg')
    camera.close()


if __name__ == '__main__':
    # 1- initialise la camera
    camera()
    # 2- initiation de la l'interruption
    init()
    # 3- boucle infini = tache principale
    while True:
        if flag_callback == True:
            process_my_callback()
    pass #Permet d'éviter des erreurs lors d'une boucle vide

hello,

pourquoi j’ai l’impression qu’il manque deux parenthèses après bouton ?

Yo,

Je comprends mais j’ai vu plusieurs exemples sans et ma fonction à bien l’air d’être appelée.
Le problème est que le flag au niveau du if n’est jamais True. Ma variable est pourtant globale donc je comprends pas

J’ai fait quelques changement pour esquiver le problème du True.
Voici le nouveau programme :

import RPi.GPIO as GPIO
from picamera import PiCamera
import datetime
from time import sleep
import cv2

# variable globale qui sera vue dans toutes les fonctions

#global flag_callback 
pin = 2
#flag_callback = False
#print(flag_callback)
def camera():
    camera = PiCamera()
    camera.resolution = (3280,2464)
    return camera
    

def init():
    # configuration de la broche 7 en entree
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(pin, GPIO.IN)
    # definition de l'interruption
    GPIO.add_event_detect(pin, GPIO.FALLING,callback = process_my_callback)
    # initialisation du flag



#def bouton(self):
 #   print("bouton")
    # fonction qui sera appelée lorsque le programme sera interrompu
  #  flag_callback = True
   # print(flag_callback)


def process_my_callback(camera):
    print("photo")
    camera.start_preview()
    print("preview")
    sleep(2)
    camera.capture(str(datetime.datetime.now())+'.jpg')
    camera.close()



if __name__ == '__main__':
    # 1- initialise la camera
    camera()
    # 2- initiation de la l'interruption
    init()
    # 3- boucle infini = tache principale
    while True:
        pass #Permet d'éviter des erreurs lors d'une boucle vide

Mon problème est le suivant :
‹ int › object has no attribute ‹ start_preview ›

Je suppose que ce int object c’est ma camera mais pourquoi je n’ai pas l’attribut ?
Je pense que c’est un problème au niveau des paramètres de fonctions mais je vois pas comment le résoudre.

Merci d’avance.

le problème de l’event:

GPIO.add_event_detect(pin, GPIO.FALLING,callback = process_my_callback)

tu ne le fait qu’une fois dans l’init or il faut tester l’event dans une boucle genre :

while True:
   GPIO.add_event_detect(pin, GPIO.FALLING,callback = process_my_callback)

si j’en crois : https://deusyss.developpez.com/tutoriels/RaspberryPi/PythonEtLeGpio/

le problème de « object has no attribute »
est du à une sordide histoire de variable local; en fait la variable camera n’est définie que dans def camera …
pour récupérer le « return » tu peux appeler ta fonction avec camera = camera() et la elle « devient » globale… magic :wink:

a noter que tu pourrais aussi avoir :

process_my_callback(camera())

Merci pour la réponse,

J’avais réussi à résoudre mon problème en supprimant ma fonction camera et en mettant les instructions dans mon main^^. Je vais pouvoir la recréer avec ce que tu m’as dit.

Pour l’histoire du GPIO.add_event_detect, je n’ai pas besoin de le mettre dans une boucle while car cette fonction définit la pin tout le temps. Donc si je reçois le front sur cette dernière la fonction interruption prend le dessus. Je dois notamment mettre GPIO.cleanup() à la fin de me programme pour la désaffecter.

Sinon pour en revenir à mon histoire de true et false, pour voir si le problème venait d’une variable locale, j’ai pris une sortie de pin pour pallier à cela et ça fonctionne. Je sais pas pourquoi ma fonction appelée par l’interruption donne bien la valeur True à mon flag mais sans pour autant la garder en mémoire comme si elle créait son propre flag.

c’est peut être lié au problème de l’initialisation de ton pin en entrée…

# initialiser à on
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# initialiser a off
GPIO.setup(channel, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 

apparemment sans ça l’entrée serait flottante ! reste à voir quel paramètre coller a la gestion d’interruption ( effectivement pas besoin de while )

GPIO.RISING, GPIO.FALLING ou GPIO.BOTH ?

je parierai sur un initialisation a LOW avec GPIO.RISING mais pas cher lol

PS : j’avais proposé pour un autre sujet mais avec le même principe de bouton qui déclenche une action une autre solution ( plus simple ) ici : Gestion d'acces affichage covid - #2 par bof