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

Bibliothèques tierces Python Discussion :

[pySerial] Embedded Computer ARM & RS485


Sujet :

Bibliothèques tierces Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut [pySerial] Embedded Computer ARM & RS485
    Bonjour,

    Je suis face à un problème et je ne trouve plus de piste pour le résoudre

    Je possède deux ordinateurs embarqués (identiques) à base d'un processeur ARM et d'une distrib Debian, je dois faire communiquer ces machines via un port série de type RS485 (la puce est câblée directement aux sorties processeur et pilotable via le ttyS2).

    J'utilise la librairie pySerial afin d'ouvrir le port, d'écrire et lire dessus.
    Ce que j'écris passe bien par les câbles et arrive de l'autre côté (visualisation via oscilloscope...), cependant lorsque j'accède au buffer, aucun caractère n'est disponible. Ce n'est que lorsque j'écris sur le port que j'ai accès aux données précédentes...
    Lorsque j'écris plus de 500 Bytes, un certain nombre apparaît (pas tous !) dans le buffer et y sont lisibles.

    J'espère que quelqu'un pourra aura une idée !

    Voici une partie du code source pour aider à la compréhension :
    Partie commune
    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
     
    import serial,fcntl, struct
     
    ser = serial.Serial(
    	port='/dev/ttyS2', 
    	baudrate=115200, 
    	timeout=10,
    	parity=serial.PARITY_NONE,
    	stopbits=serial.STOPBITS_ONE,
    	bytesize=serial.EIGHTBITS,
    	rtscts=True
    )  
     
    # Use system driver
    fd=ser.fileno()
    serial_rs485 = struct.pack('hhhhhhhh', 1, 0, 0, 0, 0, 0, 0, 0)
    fcntl.ioctl(fd,0x542F,serial_rs485)
     
    ser.flushInput()
    ser.flushOutput()
    Peer 1 (écrit une requête et doit lire la réponse)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ser.write(request)
    s = ser.read(len(request))
     
    # Read char by char until /r/n (
    complete=false
    while not complete:
       ...
       c = ser.read()
       ...

  2. #2
    Membre Expert
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    952
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 952
    Par défaut
    Salut,

    Je te propose une "implémentation minimum" d'une uart. C'est la façon qu'on utilise en "petit embarqué", à savoir une fonction qui envoie un caractère, une fonction qui regarde si on a reçu un caractère et une fonction qui lit un caractère. Sur les PC actuels (même embarqués), le tampon de réception est suffisamment large, on ne s'en occupe pas. Je te conseille d'essayer sans le rtscts=True, car il faut un câblage qui va au delà des 3 fils de base. En espérant que ça t'aide.

    A+

    Pfeuh

    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
    import serial
     
    class UART(serial.Serial):
        def __init__(self, **kwds):
            serial.Serial.__init__(self)
            for key in kwds.keys():
                exec("self.%s = kwds['%s']"%(key, key))
            serial.Serial.open(self)
     
        def inkey(self):
            return self.inWaiting()!=0
     
        def getchar(self):
            car =  self.read(1)
            if car == "" :
                raise Exception('timeout')
            return car
     
        def putchar(self,car):
            self.write(car)
     
    if __name__ == '__main__':
     
        import sys, time
        uart = UART(port='/dev/ttyS2', baudrate=115200, rtscts=True)
        for car in "Hello World!\r\n":
            uart.putchar(car)
        while 1:
            while uart.inkey():
                sys.stdout.write(uart.getchar())
            time.sleep(0.001)

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Merci pour la réponse. J'ai pu tester et malheureusement, je suis obligé d'utiliser le driver système pour le rs485 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # Use system driver
    fd=ser.fileno()
    serial_rs485 = struct.pack('hhhhhhhh', 1, 0, 0, 0, 0, 0, 0, 0)
    fcntl.ioctl(fd,0x542F,serial_rs485)
    Sans cela, les signaux pilotant la puce ne changent jamais...


    Je pense avoir trouvé une solution ce matin (illumination !), utiliser le driver 0x542E niveau système et piloter le port série directement avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ser.setRTS(0) # write
    ser.setRTS(1) # read
    Même si les niveaux semblent inversés, pour moi c'est fonctionnel.

    J'arrive à communiquer entre mes deux systèmes à 8Mbps (ce qui est super).

    Je trouve qu'il n'y a vraiment pas de documentation sur la manière de gérer du RS485 depuis le système Unix et c'est bien dommage, on se retrouve à essayer de nombreuses combinaisons de configurations pas toujours évidentes.
    J'ai dû décortiquer la lib pySerial "serialposix.py" ainsi que le header système "serial.h" pour bien comprendre les interactions du système avec les signaux processeur...


    Pour info et si ça peut aider, je vous communique la configuration que j'ai utilisée.

    Bye.
    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
    import serial, fcntl, struct
     
    ser = serial.Serial(
    	port='/dev/ttyS2', 
    	baudrate=8000000, 
    	timeout=0.25,
    	parity=serial.PARITY_NONE,
    	stopbits=serial.STOPBITS_ONE,
    	bytesize=serial.EIGHTBITS
    )  
     
    # RS485 mode (use kernel driver)
    fd=ser.fileno()
     
    # RS485 feature flags (first short) =
    #       SER_RS485_ENABLED               (1 << 0)
    #       SER_RS485_RTS_ON_SEND           (1 << 1)
    #       SER_RS485_RTS_AFTER_SEND        (1 << 2)
    # No documentation about it (see serial.h)
    serial_rs485 = struct.pack('hhhhhhhh', 1, 0, 0, 0, 0, 0, 0, 0)
    #fcntl.ioctl(fd,0x542F,serial_rs485) #User space
    fcntl.ioctl(fd,0x542E,serial_rs485) #Kernel space
     
    # Flush the port (sometimes '\x00' chars are created)
    ser.flushInput()
    ser.flushOutput()
     
    # Write Mode (it may be reversed for other circuits)
    ser.setRTS(0)
     
    # Send the request
    if request is not None:
           ser.write(request)
           s = ser.read(len(request)) # read the sent request (loop)
     
    # Read mode
    ser.setRTS(1)
     
    # Read the answer line
    r.readline()
    ...

Discussions similaires

  1. [Debutant] Firebird : Version Monoposte ou Embedded ?
    Par buffyann dans le forum Débuter
    Réponses: 5
    Dernier message: 11/06/2004, 10h03
  2. Réponses: 2
    Dernier message: 22/03/2004, 10h50
  3. Interface graphique sous embedded visual C++ !!
    Par acastor dans le forum MFC
    Réponses: 4
    Dernier message: 16/03/2004, 19h35

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