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

VB.NET Discussion :

Problème réception Port Série Arduino


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Par défaut Problème réception Port Série Arduino
    Salut tout le monde,

    Je développe un actuellement un projet mélangeant un Arduino Zero et une application en VB .net.
    L'Arduino doit envoyer par USB un peu prés 8000 bytes par secondes par paquet de 6 bytes. (6 bytes, delay de 500µs, 6 bytes, delay de 500 µs, etc..).

    Le problème, c'est que j'ai des octets qui sautent de temps de en temps...

    Voici ma fonction Arduino, j'utilise oui le port série, pas de soucis la dessus, il travaille bien en 115200 8N1. :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SerialUSB.write(Buffer_Gypro, 6);
    Et ma fonction de reception VB.net, c'est ici que j'observe un décalage au bout de 200 lectures à peu près: IncomingBytes(4) contient la valeur de IncomingBytes(5)..:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SerialPort1.Read(IncomingBytes, 0, 6)
          Byte0 = IncomingBytes(0)
          Byte1 = IncomingBytes(1)
          Byte2 = IncomingBytes(2)
          Byte3 = IncomingBytes(3)
          Byte4 = IncomingBytes(4)
          Byte5 = IncomingBytes(5)
    J'utilise read comme je souhaite travailler en byte et non en chaine de caractères pour optimiser mes traitements de données.

    Je n'ai pas de soucis avec la fonction ReadByte, toutefois celle ci fait ralentir le transfert de données et n'arrive pas à supporter un débit supérieure à 4000 bytes/sec (les octets s'accumulent dans le buffer du port jusqu'à leurs traitements...)

    J'observe également le même problème lorsque j'augmente l'intervalle entre chaque paquet (en changent 500µs a 100ms).
    Le problème vient bien de l'appli, je n'ai aucun soucis de pertes de données avec mes 3 hyperterminal (putty, termite et celui de l'IDE d'Arduino).

    Y-a t'il un moyen pour rendre solide et sans pertes cette communication ?

    Voilà comment est configuré mon port série dans l'appli, je pense pas avoir fait d'erreur ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    With SerialPort1
         .PortName = COM_Port_Detected
         .BaudRate = 115200 
         .Encoding = System.Text.Encoding.Default
         .RtsEnable = True
         .DtrEnable = True
         .Parity = Parity.None
         .StopBits = StopBits.One
         .Open() 
    End With


    Merci pour votre aide,

    Bonne journée

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    ce n'est pas comme ca que s'opère une réception, surtout sur un port sans correction d'erreur

    le principe est de récupérer tout ce que tu peux, et de traiter quand tu as tout ce qu'il te faut (donc pas de readbyte déjà, qui comme tu le dis ralenti sensiblement)
    ensuite il faut pouvoir détecter une erreur de dialogue, le port série est sensible aux interférences, et contrairement au tcp/ip par exemple, les données peuvent être corrompues (manque, ajout ou altération de bits ou d'octets)

    c'est pour ca qu'en général on se créé une norme de dialogue, le plus couramment il y a un caractère de début, un caractère de fin ou une longueur encodée en début de trame, et un checksum permettant de voir s'il y a eut erreur
    la réception d'une trame complète peut se faire en plusieurs fois (le mieux est d'utiliser l'event qui te dis que tu as reçu quelque chose et de lire tout le tampon, concaténé dans un buffer locale en attendant une trame complète)
    si une trame pose problème tu la jette ; tu reposes la question si la trame était une réponse, ou tu attends la prochaine trame si c'est une trame automatique avec une périodicité

    et vu que c'est toi qui code l'arduino, tu peux intégrer ça, et choisir techniquement comment l'appliquer
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Par défaut
    Merci de ta réponse Pol,

    Peut être que je me trompe, mais je pense pas pouvoir imposer un caractère de début, ni de fin de ma trame. Les valeurs de mes bytes peuvent prendre n'importe quoi (0 à 255) et donc peut être égales à ces caractères de début ou de fin.
    Je ne peux de plus rater aucune trame, je peux pas me permettre de jeter un paquet de bytes possédant une erreur.
    Je me trompe sûrement, mais je ne vois pas comment utiliser l’événement de réception de données, ma fonction read(buf, offset, count) se trouve à l'intérieur d'un backgroundworker puisque je lis, traite les données et affiche les résultats en temps réels sur un chart.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    l'event tu peux t'en passer si tu as un thread oui, mais la lecture globale ca serait dommage de s'en passer
    il faut décomposer la lecture et les données = lire 6 octets par 6 octets n'est pas une bonne idée

    après tu dis que tu ne peux pas faire ce que je dis, mais le mieux serait que tu nous dises ce que sont ces 6 octets et à quoi équivaut la trame complète, là je pourrais surement t'expliquer comment gérer ça
    et que tu ne puisses pas ignorer quelque chose va à l'encontre du matériel, le matériel ne peut te garantir que ce que tu envoies sera reçu, et à l'identique ... donc il faut prendre cette contrainte en considération (même si ce n'est pas forcément courant je te l'accorde, enfin plus le débit augmente et plus le cable est long plus ca peut arriver)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2016
    Messages : 9
    Par défaut
    D'accord je comprend un peu mieux. Les 6 octets une fois traités (concaténation + bitmask) donnent 3 valeurs d'un accéléromètre 3 axes (accélération X, Y et Z) communiquant avec l'arduino par SPI.
    Je souhaite pouvoir faire 2000 mesures par secondes de ce capteur (qui est son max). J'ai besoin de tout les points de mesure pour pouvoir traiter correctement derrière (filtrage, intégrateur, calibration, etc...)

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    déjà si ton arduino émet en continu, comment être sur qu'au moment où tu le branches ta tombe pile entre 2 envois ? (/ je ne suis pas expert sur le matériel il n'est pas exclu que je dise une connerie quand même)
    parce que si le 1er octet est parti dans le vent, tu auras un décalage à vie dans ta lecture
    donc il faut bien un début
    200k *6o < 115200 bauds, donc tu peux te permettre de rajouter un peu d'octets sans perdre le débit

    genre x fois telle valeur (la moins probable) de suite = caractère de début
    ce caractère de début est à renouveler genre une fois par seconde (à toi de voir, une fois tous les tant de valeur ca permet de simplifier le code .net, une fois tous les tant de temps ca permet de vérifier la vitesse du flux)
    ensuite tu envoies tes 6 octets + 1 octet de checksum
    puis 6 autres octets + 1 chk
    ...
    puis donc de temps en temps une chaine d'octets de synchro

    comme ca peu importe quand tu branches en moins d'une seconde tu es sur te pouvoir te recaller sur le flux

    le chk te permettra de détecter qu'une série de 6 octets est fausse (tu verras donc si ca arrive jamais ou pas)

    115200bauds, si c'est réellement les bits utiles (hors bit de stop ou autre) ca te fait 14,4 ko
    7 octets par truc = 14ko donc il te reste un peu de marge pour mettre le signal de synchro

    après il reste à voir ce qui se passe si tu n'arrives pas à lire assez vite, ou si tu as plus de choses à envoyer que ce que le débit le permet réellement
    ca par contre je vois pas trop comment le détecter, il faudrait déjà voir si c'est l'arduino qui bloque pour buffer plein ou pas
    parce que si tu affiches des infos qui en fait datent, et que la dérive augmente ca n'ira pas


    concernant la lecture côté .net, le but c'est de lire tous les octets que tu peux quand il y en a dans le buffer de réception
    tu les ajoutes à une collection
    parallèlement (ou pas) dans cette collection tu cherches la trame de synchro, si tu la trouves, tu peux alors découper des morceaux de 7 octets s'il y en a plusieurs dans le buffer, vérifier le chk et utiliser ta valeur
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. problème réception port série.
    Par hppp01 dans le forum Débuter
    Réponses: 1
    Dernier message: 09/03/2012, 17h45
  2. [Débutant] c# problème réception port série windows ce 6
    Par kliel dans le forum C#
    Réponses: 2
    Dernier message: 06/03/2012, 16h39
  3. Réception port série (API javax.comm)
    Par trifly dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 10/06/2009, 09h13
  4. Problème de ports série sous linux
    Par Imaging dans le forum Matériel
    Réponses: 0
    Dernier message: 15/05/2009, 19h24
  5. Problème avec port Série sur Win XP
    Par alexorel dans le forum MFC
    Réponses: 9
    Dernier message: 27/10/2005, 15h32

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