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

Déploiement/Installation Python Discussion :

Capteur de pollution SDS011 via rapsberry pi [Python3]


Sujet :

Déploiement/Installation Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Santé
    Inscrit en
    Août 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Août 2018
    Messages : 29
    Par défaut Capteur de pollution SDS011 via rapsberry pi [Python3]
    Bonjour à tous,

    J'ai deux capteurs sur mon Raspberry 3+ (température et détection de son).
    J'ai acheté le capteur de particules SDS011 Nova.

    Je souhaite l'intégrer à mon premier projet avec les capteurs précédents.

    Je fais donc un code python pour récupérer la valeur du capteur :

    Code : 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
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
     
    """This module provides an abstraction for the SDS011 air partuclate densiry sensor.
    """
    import struct
    import serial
    import time
     
    #TODO: Commands against the sensor should read the reply and return success status.
     
    class SDS011(object):
        """Provides method to read from a SDS011 air particlate density sensor
        using UART.
        """
     
        HEAD = b'\xaa'
        TAIL = b'\xab'
        CMD_ID = b'\xb4'
     
        # The sent command is a read or a write
        READ = b"\x00"
        WRITE = b"\x01"
     
        REPORT_MODE_CMD = b"\x02"
        ACTIVE = b"\x00"
        PASSIVE = b"\x01"
     
        QUERY_CMD = b"\x04"
     
        # The sleep command ID
        SLEEP_CMD = b"\x06"
        # Sleep and work byte
        SLEEP = b"\x00"
        WORK = b"\x01"
     
        # The work period command ID
        WORK_PERIOD_CMD = b'\x08'
     
        def __init__(self, serial_port, baudrate=9600, timeout=2,
                     use_query_mode=True):
            """Initialise and open serial port.
            """
            self.ser = serial.Serial(port=serial_port,
                                     baudrate=baudrate,
                                     timeout=timeout)
            self.ser.flush()
            self.set_report_mode(active=not use_query_mode)
     
        def _execute(self, cmd_bytes):
            """Writes a byte sequence to the serial.
            """
            self.ser.write(cmd_bytes)
     
        def _get_reply(self):
            """Read reply from device."""
            raw = self.ser.read(size=10)
            data = raw[2:8]
            if len(data) == 0:
                return None
            if (sum(d for d in data) & 255) != raw[8]:
                return None  #TODO: also check cmd id
            return raw
     
        def cmd_begin(self):
            """Get command header and command ID bytes.
            @rtype: list
            """
            return self.HEAD + self.CMD_ID
     
        def set_report_mode(self, read=False, active=False):
            """Get sleep command. Does not contain checksum and tail.
            @rtype: list
            """
            cmd = self.cmd_begin()
            cmd += (self.REPORT_MODE_CMD
                    + (self.READ if read else self.WRITE)
                    + (self.ACTIVE if active else self.PASSIVE)
                    + b"\x00" * 10)
            cmd = self._finish_cmd(cmd)
            self._execute(cmd)
            self._get_reply()
     
        def query(self):
            """Query the device and read the data.
            @return: Air particulate density in micrograms per cubic meter.
            @rtype: tuple(float, float) -> (PM2.5, PM10)
            """
            cmd = self.cmd_begin()
            cmd += (self.QUERY_CMD
                    + b"\x00" * 12)
            cmd = self._finish_cmd(cmd)
            self._execute(cmd)
     
            raw = self._get_reply()
            if raw is None:
                return None  #TODO:
            data = struct.unpack('<HH', raw[2:6])
            pm25 = data[0] / 10.0
            pm10 = data[1] / 10.0
            return (pm25, pm10)
     
        def sleep(self, read=False, sleep=True):
            """Sleep/Wake up the sensor.
            @param sleep: Whether the device should sleep or work.
            @type sleep: bool
            """
            cmd = self.cmd_begin()
            cmd += (self.SLEEP_CMD
                    + (self.READ if read else self.WRITE)
                    + (self.SLEEP if sleep else self.WORK)
                    + b"\x00" * 10)
            cmd = self._finish_cmd(cmd)
            self._execute(cmd)
            self._get_reply()
     
        def set_work_period(self, read=False, work_time=0):
            """Get work period command. Does not contain checksum and tail.
            @rtype: list
            """
            assert work_time >= 0 and work_time <= 30
            cmd = self.cmd_begin()
            cmd += (self.WORK_PERIOD_CMD
                    + (self.READ if read else self.WRITE)
                    + bytes([work_time])
                    + b"\x00" * 10)
            cmd = self._finish_cmd(cmd)
            self._execute(cmd)
            self._get_reply()
     
        def _finish_cmd(self, cmd, id1=b"\xff", id2=b"\xff"):
            """Add device ID, checksum and tail bytes.
            @rtype: list
            """
            cmd += id1 + id2
            checksum = sum(d for d in cmd[2:]) % 256
            cmd += bytes([checksum]) + self.TAIL
            return cmd
     
        def _process_frame(self, data):
            """Process a SDS011 data frame.
            Byte positions:
                0 - Header
                1 - Command No.
                2,3 - PM2.5 low/high byte
                4,5 - PM10 low/high
                6,7 - ID bytes
                8 - Checksum - sum of bytes 2-7
                9 - Tail
            """
            raw = struct.unpack('<HHxxBBB', data[2:])
            checksum = sum(v for v in data[2:8]) % 256
            if checksum != data[8]:
                return None
            pm25 = raw[0] / 10.0
            pm10 = raw[1] / 10.0
            return (pm25, pm10)
     
        def read(self):
            """Read sensor data.
            @return: PM2.5 and PM10 concetration in micrograms per cude meter.
            @rtype: tuple(float, float) - first is PM2.5.
            """
            byte = 0
            while byte != self.HEAD:
                byte = self.ser.read(size=1)
                d = self.ser.read(size=10)
                if d[0:1] == b"\xc0":
                    data = self._process_frame(byte + d)
                    return data
     
    sensor = SDS011("/dev/ttyUSB0", use_query_mode=True)
    print('ready')
    sensor.sleep(sleep=False)
    time.sleep(5)
    sensor.query()
    J'ai bien le ready qui apparaît mais rien d'autres, rien ne se passe.

    Avez vous des idées pour récupérer simplement les valeurs des particules 2.5 et 10 pm.

    Merci pour votre aide précieuse,

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 778
    Par défaut
    Salut,

    Citation Envoyé par tacleur Voir le message
    Je fais donc un code python pour récupérer la valeur du capteur
    Impossible d'écrire ce code sans maîtriser un minimum Python (et bien d'autres techno.) et le savoir faire d'un programmeur. Vous avez juste pompé çà sur GitHub.
    C'est pas interdit... Mais pourquoi ne pas le dire?

    Ce code étant une bibliothèque Python, il ne doit pas être "recopié" mais installé via la commande "pip install py-sds011".
    Puis pour voir si çà fonctionne, l'auteur n'est pas très bavard mais il donne quelques commandes à taper sur la console pour vérifier: il faut déjà commencer par là.
    note: il manque juste la commande from sds011 import SDS011 à entrer en premier.

    Après si la question est juste de récupérer du code pour faire tourner votre SDS011 sur Raspberry, vous avez toute une rubrique dédié au Raspberry où trainent les gens qui savent.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Homme Profil pro
    Santé
    Inscrit en
    Août 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Août 2018
    Messages : 29
    Par défaut
    Bonjour,

    Je vous remercie pour votre réponse.
    Je n'ai jamais caché que j'ai trouvé ce code sur internet.
    Je connais très peu le python.
    J'utilise mes petits projets pour me former, pour apprendre, je me lance des défis personnels.

    Je bidouille et j'apprends progressivement.
    Je ne serai plus vous dire exactement à qui appartenait ce code car depuis hier j'ai du en tester une vingtaine.
    Celui ci me parait plus plus abouti pour mon projet.

    Je vais me diriger vers la partie du forum dédié Raspberry Pi.

    Merci pour votre retour.

  4. #4
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,
    Citation Envoyé par tacleur Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    sensor = SDS011("/dev/ttyUSB0", use_query_mode=True)
    print('ready')
    sensor.sleep(sleep=False)
    time.sleep(5)
    sensor.query()
    J'ai bien le ready qui apparaît mais rien d'autres, rien ne se passe.

    Avez vous des idées pour récupérer simplement les valeurs des particules 2.5 et 10 pm.
    Ben tu lances bien la fonction sensor.query mais tu ne récupères pas le résultat et tu ne l'affiches pas non plus...

    Pour afficher le résultat tu pourrais faire cela par exemple : print(sensor.query()) à la place de sensor.query()...


    EDIT: D’après le lien donné par wiztricks il semble que tu puisses tester directement sans faire de pause avec time.sleep (il semble que la pause soit nécessaire lorsque tu passes du mode "veille" au mode "éveil")...

    Tu peux donc tester juste comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ...
    sensor = SDS011("/dev/ttyUSB0", use_query_mode=True)
    print('ready')
    print(sensor.query())

  5. #5
    Membre averti
    Homme Profil pro
    Santé
    Inscrit en
    Août 2018
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Août 2018
    Messages : 29
    Par défaut
    bonjour à tous,

    Un immense Merci Beginner !!!!!

    Cela a fonctionné immédiatement en faisant le print !

    Citation Envoyé par Beginner. Voir le message
    Salut,
    Ben tu lances bien la fonction sensor.query mais tu ne récupères pas le résultat et tu ne l'affiches pas non plus...

    Pour afficher le résultat tu pourrais faire cela par exemple : print(sensor.query()) à la place de sensor.query()...
    Merci beaucoup, je peux continuer à avancer dans mon petit projet !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 22/11/2017, 19h31
  2. Réponses: 2
    Dernier message: 14/05/2013, 09h26
  3. Réponses: 9
    Dernier message: 01/01/2011, 04h28
  4. [Kylix] PostgreSql via ODBC
    Par doykati dans le forum EDI
    Réponses: 3
    Dernier message: 08/02/2007, 10h10
  5. [TP7] Calculer sin, cos, tan, sqrt via le FPU
    Par zdra dans le forum Assembleur
    Réponses: 8
    Dernier message: 25/11/2002, 04h09

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