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

C++Builder Discussion :

Reception série avec TComPort


Sujet :

C++Builder

  1. #1
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut Reception série avec TComPort
    Bjr,
    j'ai une appli qui doit lire des données texte à la sortie d'un automate.
    La liaison est une RS232 avec config standard (9600bps, 8 bits data, 1bit stop, sans controle de flux). On reçoit une chaine de caractères simples (20 à 40 caractères) contenant les paramètres machine (séparés par un caractère 'NULL').

    En branchant sur HyperTerminal, je reçois sans problème la chaine.
    Par contre, avec mon appli, j'utilise TComPort pour recevoir et ces événements :
    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
    void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
    {
            AnsiString temp="";
            ComPort1->ReadStr(temp, Count);   // lit les 'Count' octets du buffer et les affecte à temp
     
            Timer1->Enabled = true;   // Démarrage du Timer
            capture += temp;    // On concatène le contenu du buffer à l'ansistring capture
     
            TCapture->Text = capture;  // pour finalement afficher la chaine reconstituée dans une editbox
    }
     
    void __fastcall TForm1::Timer1Timer(TObject *Sender)
    {
            if (Tag)    // Traitement des données au bout de 5s de réception               
            {
                    Timer1->Enabled = false;
                    Tag = 0;
                    TCapture->Clear();
     
                    Memo1->Lines->Add(capture);  // ajout dans le Memo
                    num++;   // on incrémente num après chaque réception
                    capture = "";   // on vide la variable de récupération
            }
            else
                    Tag++;   // on attend 5s avant de faire le traitement
    }
    Le Timer est réglé sur 5000ms.

    Le résultat est que j'obtiens toujours seulement le début de chaine, jusqu'au caractère 'NULL'. Est-ce normal avec TComPort ? Comment modifier mon code pour dire que si on rencontre un caractère 'NULL' on le remplace par un espace ?? Cela peut-il être un pb avec la gestion du Timer ?

    Ex pour une chaine : 240507 T1 1340 0056
    Je reçois : 240507

    Précision: la chaine est envoyée en une seule fois.

    Merci de m'éclairer...

  2. #2
    Membre actif Avatar de cfdev
    Homme Profil pro
    Passionné
    Inscrit en
    Octobre 2004
    Messages
    220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Passionné

    Informations forums :
    Inscription : Octobre 2004
    Messages : 220
    Points : 210
    Points
    210
    Par défaut
    Lut,

    je dirais que c'est normal, car en lisant une String le char NULL signifie fin de chaine!

    le mieux serai de travailler avec le Read non string
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        unsigned char *Buf = new unsigned char [Count];
        ComPort1->Read(Buf, Count);
    ++
    mcercle facturation - Logiciel de facturation Win/Mac/Linux

  3. #3
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut
    Haaa, c'est pas bête ça !
    Est-ce que 'NULL' correspond au '\0' caractéristique de fin de chaine ?
    Dans ce cas là, ne va t-il pas se passer la même chose avec Read ?

  4. #4
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    Le String fonctionne comme une AnsiString, si ton premier caractère recu est 0x00, c'est le caractère NULL et la chaîne sera donc considéré comme terminée.

    Dans une chaîne de type char comme l'a déclaré virtuA, ca fonctionnera nikel puisque c'est une chaîne d'octet (char) de longueur Count et non une char* se terminant par \0.

    Il te suffira de la lire de 0 à Count-1 et tu verras tous tes octets comme virtuA l'a décrit.

  5. #5
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut
    Oki je comprends.
    J'avais déjà utilisé ce programme avec d'autres automates mais il n'y avait pas de caractères NULL entre les paramètres donc je ne voyais pas de problème.

    Euh, comment je fais pour ajouter les caractères reçus à une AnsiString du coup ?
    Sinon dois-je les concatèner dans un autre tableau de char pour l'afficher ?
    Comment vider ce tableau pour la réception de nouvelles données ?

    Merki.

    Arf, j'ai l'impression que c'est tout simple mais je m'embrouille les pinceaux là...
    Mon appli doit afficher les caractères reçus à l'écran puis les stocker dans un Memo avant d'être sauvegardé dans un fichier journal et une BDD.

  6. #6
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    Tu peux faire un truc de style:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    unsigned char *Buf = new unsigned char [Count];
    ComPort1->Read(Buf, Count);
    AnsiString Trame;
    for(int i=0;i<Count;i++)
        Trame += IntToStr((int)Buf[i])+",";
    Et tu auras ta trame dans une AnsiString avec chaque octet séparé par des ",".

  7. #7
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut
    On y est presque !
    Quand j'affiche la "Trame" (que j'appelle "capture"), il m'affiche les valeurs décimales des caractères ASCII

    Après il faut aussi que j'arrive à détecter les 'NULL' pour les remplacer par des espaces.

    J'ai tenté de modifier direct la chaine Buf pour l'affichage mais ça ne marche pas, voici le code:

    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
    void __fastcall TForm1::ComPort1RxChar(TObject *Sender, int Count)
    {
            char *Buf = new char [Count];
            ComPort1->Read(Buf, Count);
     
            Buf[Count - 1] = '\0';   // Ajout du caractère fin de chaine
            for(int i=0;i<Count;i++)
            {
                    // suppression caractère NULL, remplacement par un espace
                    if (Buf[i] == NULL) Buf[i] = ' ';
            }
     
            strcpy(capt, Buf);   // copie de Buf dans une variable globale
     
            Timer1->Enabled = true;
            TCapture->Text = Buf;
            delete [] Buf;
            Buf = NULL;
    }
    Merci pour l'aide en tout cas.

  8. #8
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut
    plz help.... j'y suis presque, c'est trop bête !

  9. #9
    Membre éprouvé
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Points : 1 007
    Points
    1 007
    Par défaut
    De quel type est ta variable capt ?
    Comment l'affiches tu?

    Tu peux l'afficher comme ca:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
       unsigned char *Buf = new unsigned char [Count];
       ComPort1->Read(Buf, Count);
       AnsiString Capt;
     
       for(int i=0;i<Count;i++)
       {
           if(Buf[i] == NULL)  Capt += " ";
           else                Capt += Buf[i];
       }
       Memo1->Lines->Add(Capt);
    Il faut que tu sois cohérent entre les variables que tu recois et que tu affiches. Si tu as lu les valeurs décimales c'est que tu as affiché ta variable en tant qu'un entier.
    Si tu travails uniquement sur des char, char* ou AnsiString tu ne devrait pas avoir ce problème. Par contre, dans le cas où l'octet recu n'est pas un caractère tu risques d'obtenir des affichages bizarre.

  10. #10
    Membre du Club Avatar de Revan777
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    87
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mars 2005
    Messages : 87
    Points : 52
    Points
    52
    Par défaut
    Ca marche ! Merci beaucoup bandit boy !
    Je savais que je n'étais pas loin....
    Je m'emmêle encore pas mal avec les chaines de caractères !

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

Discussions similaires

  1. Problème pour piloter le port série avec TComPort
    Par Jayceblaster dans le forum Composants VCL
    Réponses: 6
    Dernier message: 08/12/2005, 15h21
  2. buffer de réception avec TComport
    Par yoyo72 dans le forum Composants VCL
    Réponses: 3
    Dernier message: 31/08/2005, 22h28
  3. Reception de trame avec Tcomport
    Par Amazone83 dans le forum API, COM et SDKs
    Réponses: 6
    Dernier message: 19/06/2005, 01h18
  4. Reception avec Tcomport
    Par web-angel dans le forum C++Builder
    Réponses: 16
    Dernier message: 27/01/2004, 17h20
  5. [Débutant] Lenteur avec TComPort
    Par PhDt76 dans le forum C++Builder
    Réponses: 22
    Dernier message: 27/09/2003, 22h43

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