IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Raspberry Pi Discussion :

Erreur lors de la détection d'un switch sur un port gpio


Sujet :

Raspberry Pi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Homme Profil pro
    Aidant
    Inscrit en
    Janvier 2024
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Aidant
    Secteur : Services à domicile

    Informations forums :
    Inscription : Janvier 2024
    Messages : 57
    Par défaut Erreur lors de la détection d'un switch sur un port gpio
    Bonjour à tous,
    Je vous écris ce message car j'ai un problème avec un script python qui me sert à lire et enregistrer des données de météo pour mon raspberry pi.

    Il est principalment basé sur la lecture de température d'une sonde ds18b20 et le lecture de pression et humidité via des détecteusr bmp180 et dht22.

    J'ai aussi un pliviomètre à godet et un anémomètre et j'utilise la fonction add_event_detection() pour détecter et enregistrer la fermeture d'un contact quand le godet du pluviomètre s'abaisse et idem pour détecter la rotation de l'anémomètre.
    Le pluviomètre et l'anémomètre sont connectés à deux ports gpio différents. Pour chacun d'entre eux la détection du switch appelle une fonction qui enregistre dans un fichier l'heure précise de l'évènement pour que je puisse par la suite en déterminer la quantité d'eau tombée en 24h et la vitesse du vent.

    Seulement voilà quand je lance le script la partie lecture des différentes sonde se passe bien mais j'obtiens un erreur :

    Traceback (most recent call last):
    File "/home/pi/Domotique/Programmes/Enregistrement_Data_Meteo.py", line 100, in <module>
    GPIO.add_event_detect(port_gpio_anemometre, GPIO.FALLING, callback=my_callback_Anemometre, bouncetime=1000)
    RuntimeError: Conflicting edge detection already enabled for this GPIO channel
    et le fichier qui contient normalement les mm de pluie tombés dans la journée se remplit d'entrées toutes les 5s (ce qui correspond au paramètre bouncetime que j'ai rentré).

    Voici le code :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    import glob
    import urllib.request
    from lxml import etree
    from urllib.error import URLError, HTTPError
    import base64
    import csv
    import sys
    import os
    import time
    from datetime import datetime
    from pathlib import Path
    import RPi.GPIO as GPIO
    import smbus as smbus
    #import Adafruit_DHT
    #from Adafruit_BMP085 import BMP085
    import Adafruit_BMP085 as BMP085
    import simpletest_BMP
    import AdafruitDHT
    #from AdafruitDHT import temperature
    from AdafruitDHT import humidity
    from simpletest_BMP import Pressure_Ext
    from simpletest_BMP import Altitude_Ext
    #sensor = BMP085.BMP085()
     
    GPIO.setmode(GPIO.BCM)
     
    while  True :
     
        port_gpio_anemometre=13
        port_gpio_pluvio=19
        sonde_exterieure = '/28-3c01f095d48b'
     
        base_dir = '/sys/bus/w1/devices'
        sonde_ext = base_dir + '/28-3c01f095d48b/w1_slave'
        #Définition de la date sous la forme "MoisAnnee" en français.
        current_datetime = datetime.now()
        current_date = current_datetime.strftime("%B%Y") 
        Mois=['Jjanvier','février','mars','avril','mai','juin','juillet','aout','septembre','octobre','novembre','décembre']
        mois = current_datetime.date().month
        Q = Mois[mois-1]
        current_date = Q + current_datetime.strftime("%Y") 
        #print(current_date)
        Record_dir = '/home/pi/Domotique/Donnees_Meteo/' + current_date
        Record_file = Record_dir + f"/{current_date}.txt"
     
     
     
        def extraire_temperature (sonde) :
            f_sonde = open(sonde, 'r')
            lines_sonde = f_sonde.readlines()
            while lines_sonde == []:
                time.sleep(0.5)
        #        print('pas de donnees')
                lines_sonde = f_sonde.readlines()
            donnees_temperature = lines_sonde[1].split(" ")[9]
            Temp = float(donnees_temperature[2:]) / 1000
            return Temp
    #Lecture de la temperature exterieure    
        Temp_exterieure = extraire_temperature(sonde_ext)
    #    print(Temp_exterieure)
     
    #Detection implusion pluviometre gpio19
        def my_callback_Pluviometre(port_gpio_pluvio):
            current_datetime = datetime.now()
            current_date = current_datetime.strftime("%d-%m-%Y")
            current_time = current_datetime.strftime("%H:%M:%S")
            Record_file_Pluviometre = Record_dir + f"/Pluviometre_{current_date}.txt"
            data_to_write = {"Date": current_date, "Heure": current_time}
            with open(Record_file_Pluviometre, "a", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
                writer.writerow(data_to_write)
     
            GPIO.setup(port_gpio_pluvio, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            GPIO.add_event_detect(port_gpio_pluvio, GPIO.RISING, callback=my_callback_Pluviometre, bouncetime=5000) 
     
        def my_callback_Anemometre(port_gpio_anemometre):
            current_datetime = datetime.now()
            current_date = current_datetime.strftime("%d-%m-%Y")
            current_time = current_datetime.strftime("%H:%M:%S")
            Record_file_Anemometre = Record_dir + f"/Anemometre_{current_date}.txt"
            data_to_write = {"Date": current_date, "Heure": current_time}
            with open(Record_file_Anemometre, "a", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
                writer.writerow(data_to_write)
     
        GPIO.setup(port_gpio_anemometre, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.add_event_detect(port_gpio_anemometre, GPIO.FALLING, callback=my_callback_Anemometre, bouncetime=1000) 
     
        try:
            root = {"Temp_Ext": Temp_exterieure,"Pression_Ext": Pressure_Ext/100,"Alt_Ext": round(Altitude_Ext,2),"Humidite" : round(humidity,2)/100}
            current_datetime = datetime.now()
            current_time = current_datetime.strftime("%H:%M:%S")
            Record_file = Record_dir + f"/{current_date}.txt"  
            current_date = current_datetime.strftime("%d-%m-%Y")
            data_to_write = {"Date": current_date, "Heure": current_time}
            data_to_write.update(root)
            file_exists = os.path.isfile(Record_file)
     
            with open(Record_file, "a", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
     
                # Écrire l'en-tete si le fichier est nouveau
                if not file_exists:
                    writer.writeheader()
     
                # Écrire les donnees
                writer.writerow(data_to_write)
     
        except HTTPError as e:
            print(f"Erreur HTTP : {e.code} {e.reason}")
     
        except URLError as e:
            print(f"Erreur d'URL : {e.reason}")
     
        except etree.XMLSyntaxError as e:
            print(f"Erreur de syntaxe XML : {e}")
     
        f.close()
        time.sleep(10)

    Sauriez-vous ce qui cloche ?

    Merci d'avance !!

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 269
    Billets dans le blog
    48
    Par défaut
    Bonsoir,

    Tu déclares des constantes et des fonctions dans une boucle infinie while True. Tu ne penses pas que les déclarer une seule fois avant d'entrer dans la boucle devrait suffire ?

    De plus, tu as mis le setup du port gpio du pluvio et la détection d'événement associée à l'intérieur de la fonction callback.

  3. #3
    Membre actif
    Homme Profil pro
    Aidant
    Inscrit en
    Janvier 2024
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Aidant
    Secteur : Services à domicile

    Informations forums :
    Inscription : Janvier 2024
    Messages : 57
    Par défaut
    Merci f-leb pour tes remarques. J'ai fait ce script par ajouts ponctuels et j'en ai perdu de vue les bases importantes. Je vais réorganiser tout ça pour me mettre que l'essentiel dans la boucle while. Je vous redis tout ça demain.
    Merci encore pour ton coup d'œil, a force d'avoir le nez dans son script le débutant que je suis fait des bourdes...

  4. #4
    Membre actif
    Homme Profil pro
    Aidant
    Inscrit en
    Janvier 2024
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Aidant
    Secteur : Services à domicile

    Informations forums :
    Inscription : Janvier 2024
    Messages : 57
    Par défaut
    Bonjour f-leb.

    j'ai fait les modifications du code pour ne mettre dans la boucle while ce qui doit l'être et pas plus. Mais j'ai toujours ce même problème de conflit :

    Traceback (most recent call last):
    File "/home/pi/Domotique/Programmes/Enregistrement_Data_Meteo.py", line 105, in <module>
    GPIO.add_event_detect(port_gpio_anemometre, GPIO.FALLING, callback=my_callback_Anemometre, bouncetime=1000)
    RuntimeError: Conflicting edge detection already enabled for this GPIO channel
    J'ai aussi un problème récurrent avec un de mes capteurs, celui d'humidité, le DHT22. Est-ce que tu connais ? J'ai du mal à obtenit des données régulière provenant de ce capteur. Pour une valeur enregistrée dans le fichier j'ai au moins 10 ou 15 retours (None None).
    J'ai rajouté une boucle while dans le code pour qu'il relise le capteur s'il retourne None/none mais du coup j'ai presque rien en sortie. Est-ce que tu aurais un idée ?

    Voilà le code :

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    import glob
    import urllib.request
    from lxml import etree
    from urllib.error import URLError, HTTPError
    import base64
    import csv
    import sys
    import os
    import time
    from datetime import datetime
    from pathlib import Path
    import RPi.GPIO as GPIO
    import smbus as smbus
    #import Adafruit_DHT
    #from Adafruit_BMP085 import BMP085
    import Adafruit_BMP085 as BMP085
    import simpletest_BMP
    import Adafruit_DHT
    #from AdafruitDHT import temperature
    #from AdafruitDHT import humidity
    from simpletest_BMP import Pressure_Ext
    from simpletest_BMP import Altitude_Ext
    #sensor = BMP085.BMP085()
     
    GPIO.setmode(GPIO.BCM)
    port_gpio_anemometre=13
    port_gpio_pluvio=19
    #parametres capteur humidite
    sensor = 22
    pin = 12
     
     
    sonde_exterieure = '/28-3c01f095d48b'
     
    base_dir = '/sys/bus/w1/devices'
    sonde_ext = base_dir + '/28-3c01f095d48b/w1_slave'
    #Definition de la date sous la forme "MoisAnnee" en francais.
    current_datetime = datetime.now()
    current_date = current_datetime.strftime("%B%Y") 
    Mois=['janvier','février','mars','avril','mai','juin','juillet','aout','septembre','octobre','novembre','décembre']
    mois = current_datetime.date().month
    Q = Mois[mois-1]
    current_date = Q + current_datetime.strftime("%Y") 
    #print(current_date)
    Record_dir = '/home/pi/Domotique/Donnees_Meteo/' + current_date
    Record_file = Record_dir + f"/{current_date}.txt"
     
     
     
    def extraire_temperature (sonde) :
        f_sonde = open(sonde, 'r')
        lines_sonde = f_sonde.readlines()
        while lines_sonde == []:
            time.sleep(0.5)
        #        print('pas de donnees')
            lines_sonde = f_sonde.readlines()
        donnees_temperature = lines_sonde[1].split(" ")[9]
        Temp = float(donnees_temperature[2:]) / 1000
        return Temp
     
    #    print(Temp_exterieure)
    #    sys.path.append("simpletest")
     
    #    print('Temp = {0:0.2f} *C'.format(sensor.read_temperature()))
    #    print('Pressure = {0:0.2f} Pa'.format(sensor.read_pressure()))
    #    print('Altitude = {0:0.2f} m'.format(sensor.read_altitude()))
    #    print('Sealevel Pressure = {0:0.2f} Pa'.format(sensor.read_sealevel_pressure()))
     
    #    Pressure_Ext = sensor.read_pressure()/100
    #    print(Pressure_Ext/100)
    #    Altitude_Ext = sensor.read_altitude()
    #    print(round(Altitude_Ext,2))
    #    print(round(temperature,2)*2)
    #    print(round(humidity/100,2))
     
     
    #Detection implusion pluviometre gpio19
    def my_callback_Pluviometre(port_gpio_pluvio):
        current_datetime = datetime.now()
        current_date = current_datetime.strftime("%d-%m-%Y")
        current_time = current_datetime.strftime("%H:%M:%S")
        Record_file_Pluviometre = Record_dir + f"/Pluviometre_{current_date}.txt"
        data_to_write = {"Date": current_date, "Heure": current_time}
        with open(Record_file_Pluviometre, "a", newline="", encoding="utf-8") as f:
            writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
            writer.writerow(data_to_write)
     
    def my_callback_Anemometre(port_gpio_anemometre):
        current_datetime = datetime.now()
        current_date = current_datetime.strftime("%d-%m-%Y")
        current_time = current_datetime.strftime("%H:%M:%S")
        Record_file_Anemometre = Record_dir + f"/Anemometre_{current_date}.txt"
        data_to_write = {"Date": current_date, "Heure": current_time}
        with open(Record_file_Anemometre, "a", newline="", encoding="utf-8") as f:
            writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
            writer.writerow(data_to_write)
     
    while True :
     
        humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
        while humidity is None and temperature is None:
            time.sleep(2)
            humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
        GPIO.setup(port_gpio_anemometre, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.add_event_detect(port_gpio_anemometre, GPIO.FALLING, callback=my_callback_Anemometre, bouncetime=1000) 
        Temp_exterieure = extraire_temperature(sonde_ext)
        GPIO.setup(port_gpio_pluvio, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(port_gpio_pluvio, GPIO.RISING, callback=my_callback_Pluviometre, bouncetime=5000) 
     
        try:
            root = {"Temp_Ext": Temp_exterieure,"Pression_Ext": Pressure_Ext/100,"Alt_Ext": round(Altitude_Ext,2),"Humidite" : round(humidity,2)}
            current_datetime = datetime.now()
            current_time = current_datetime.strftime("%H:%M:%S")
            Record_file = Record_dir + f"/{current_date}.txt"  
            current_date = current_datetime.strftime("%d-%m-%Y")
            data_to_write = {"Date": current_date, "Heure": current_time}
            data_to_write.update(root)
            file_exists = os.path.isfile(Record_file)
     
            with open(Record_file, "a", newline="", encoding="utf-8") as f:
                writer = csv.DictWriter(f, fieldnames=data_to_write.keys())
     
                # Écrire l'en-tete si le fichier est nouveau
                if not file_exists:
                    writer.writeheader()
     
                # ecrire les donnees
                writer.writerow(data_to_write)
     
        except etree.XMLSyntaxError as e:
            print(f"Erreur de syntaxe XML : {e}")
     
        f.close()
        time.sleep(2)

    Merci d'avance !
    Antoine

  5. #5
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 269
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 269
    Billets dans le blog
    48
    Par défaut
    Bonjour,

    Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        GPIO.setup(port_gpio_anemometre, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
        GPIO.add_event_detect(port_gpio_anemometre, GPIO.FALLING, callback=my_callback_Anemometre, bouncetime=1000) 
     
        ...
     
        GPIO.setup(port_gpio_pluvio, GPIO.IN, pull_up_down=GPIO.PUD_UP)
        GPIO.add_event_detect(port_gpio_pluvio, GPIO.RISING, callback=my_callback_Pluviometre, bouncetime=5000)

    Bis repetita placent
    La configuration des broches et des événements devrait être en dehors du while True.

    Dans une boucle infinie, tu ajoutes une détection d'événement sur un port déjà configuré pour détecter un front, d'où le message : RuntimeError: Conflicting edge detection already enabled for this GPIO channel.

    boucetime=5000 signifie aussi que si le godet bascule plusieurs fois en 5 secondes, seul le 1er basculement sera pris en compte. Le système ne risque-t-il pas d'"oublier" des basculements en cas de forte pluie ?
    Je me pose la même question pour l'anémomètre avec bouncetime=1000...

    Je n'ai pas trop de temps maintenant, je reviens plus tard pour le reste

  6. #6
    Membre actif
    Homme Profil pro
    Aidant
    Inscrit en
    Janvier 2024
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Aidant
    Secteur : Services à domicile

    Informations forums :
    Inscription : Janvier 2024
    Messages : 57
    Par défaut
    Merci f-leb pour ta réponse.

    Par contre pour cette histoire de conflit, pardonne moi mais je ne comprends pas. Les deux GPIO.setup, les deux add_event_detection et les fonctions associées sont sur deux ports GPIO différents : port_gpio_pluvio (port 13) et port_gpio_anemometre (port 19).
    Pourquoi ce conflit, dois-je faire deux scripts différents ?

    Pour le paramètre bouncetime tu as entièrement raison il est mal réglé. Je l'avais au départ réglé sur 1000 pour le pluviomètre, pour laisser le temps au godet de se remettre en position après s'être vidé mais mon fichier de sortie se remplissait de lignes une fois par seconde. J'ai changé sur 5000 et le fichier de sortie s'est rempli de lignes toutes les 5s... Je me doute que cela est dû à la boucle while True mais si je sors les détections d'évènement de la boucle est-ce que celles-ci se feront toujours à tout moment alors que l'enregistrement des données des capteurs tourne derrière ?


    Merci d'avance !

Discussions similaires

  1. Erreur lors du chargement d'un nouveau JAR sur TomCat
    Par Lolitaaa dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 21/01/2010, 13h29
  2. Réponses: 0
    Dernier message: 07/10/2009, 11h38
  3. Erreur lors de l'execution d'eclipse j2ee sur vista
    Par coolio971 dans le forum Eclipse
    Réponses: 1
    Dernier message: 10/03/2009, 19h25
  4. Réponses: 2
    Dernier message: 29/08/2008, 22h51
  5. Réponses: 3
    Dernier message: 29/10/2006, 23h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo