1. #1
    Membre habitué
    Profil pro
    Inscrit en
    mars 2010
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 136
    Points : 134
    Points
    134

    Par défaut Composant TSerial : Données émises par le port série – Les utiliser

    Bonjour à tous,

    Je reviens encore vers vous car, si en suivant les conseils de J. Pork (un grand merci !!) j'ai pu accéder aux données émises par le port Com :
    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
    procedure TF_balanc.Laz_serieRxData(Sender: TObject);  // accès au Port série - lecture des données
        Var CurPos : integer ;
        Var Strbal : String ; // chaine lecture du port série
      //  Var chainStock , Caract_lu2 : String ;
        Var Totol : integer ;
        Var  iii, ijk  : integer ;
    begin
     
        Strbal := Laz_serie.readData ; // instruction de lecture des données émises
        Sleep(200) ;
        CurPos :=Pos(Char(10), Strbal) ;
        if length(StrPoidsActu) > 10 then StrPoidsActu:= '' ;  // Chaine de carcatère à stocker
        if CurPos = 0 then
           Begin
              StrPoidsActu := StrPoidsActu + Strbal ;
            end
           Else
           Begin
              StrPoidsActu := StrPoidsActu + Copy(StrBal , 1, CurPos -1) ;
          end;
    Je n'arrive pas à isoler dans la chaine constituée StrPoidsActu Les données qui m'intéressent qui sont la suite de carcatères Nombres ( 0 ..9) et le point décimal (.) pour pouvoir ensuite les utiliser pour la suite du programme.
    J'obtiens par exemple dans StrPoidsActu ' + 1025.3 g' #13et il m'est impossible d'isoler 1025.3 .

    Dans mon ancien programme sous Delphi4 je stoppais la lecture du port série par Laz_Serie.PurgeRead et je travaillais ensuite la chaine StrPoidsActu pour en sortir une chaine ne contenat que ce qui pouvait constituer un nombre, mais je n'ai pas trouvé pour LazSerial l'instruction adéquate.

    Qui peut me renseigner sur la dynamique détaillée des instructions déjà écrites et à écrire pour arriveer à mes fins ?

    Merci

    R.O.

  2. #2
    Membre expert
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    décembre 2008
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2008
    Messages : 1 480
    Points : 3 508
    Points
    3 508

    Par défaut

    hello,
    tu peux essayer d'utliser les expressions régulières pour extraire un flottant d'une chaîne de caractère comme ceci par exemple :

    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
    implementation
    uses regexpr;
    {$R *.lfm}
    { TForm1 } 
    procedure TForm1.Button1Click(Sender: TObject);
     var ChaineATester : string;
           re: TRegExpr;
    begin
    try
      ChaineATester :=  '+ 1025.3 g' +  #13;
      re := TRegExpr.Create;
      // pattern to extract float number
      re.Expression := '[+-]?([0-9]*[.])?[0-9]+';
      if re.Exec(ChaineATester) then
         showMessage('Extraction valeur : ' + re.Match[0]);
    finally
      re.Free;
    end;
    end;
    Ami calmant, J.P
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  3. #3
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 898
    Points : 7 835
    Points
    7 835

    Par défaut

    Je pense que la logique d'utilisation de l'ensemble n'est pas adéquate.

    Je comprends que lorsque le composant série détecte l'envoi de caractère, il déclenche l'événement OnRxData où on va lire le tampon et traiter ce qui a été reçu. Par exemple l'ajouter à une chaîne.

    Il faut donc lire et analyser ce caractère. Et lorsqu'on reçoit le caractère de fin de trame (#10 = LF), il faut déclencher le traitement de la chaîne.

    Au passage, je pense qu'il serait souhaitable de ne pas mettre de Sleep(200) après le ReadData : à quoi sert-il ?

    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
    procedure TF_balanc.Laz_serieRxData(Sender: TObject);  // accès au Port série - lecture des données
        Var CurPos : integer ;
        Var Strbal : String ; // chaine lecture du port série
      //  Var chainStock , Caract_lu2 : String ;
        Var Totol : integer ;
        Var  iii, ijk  : integer ;
    begin
     
        Strbal := Laz_serie.readData ; // instruction de lecture des données émises
     
        CurPos :=Pos(Char(10), Strbal) ;
     
        if CurPos = 0 then // pas de LF reçu
           Begin
              StrPoidsActu := StrPoidsActu + Strbal ; // élongation de la chaîne
            end
           Else
           Begin
              StrPoidsActu := StrPoidsActu + Copy(StrBal , 1, CurPos -1) ; // ajout jusqu'au LF
     
              TraiteMessage(StrPoidsActu); // procédure à écrire
     
              if length(Strbal) > CurPos // cela se peut-il ?
                then StrPoidsActu := Copy(StrBal , CurPos +1, length(Strbal)-CurPos); // on colle ce qui suit le LF en début de nouvelle ligne
     
          end;
     
    procedure TraiteMessage(var Chaine: string);
    begin
      // lire les caractères un par un
      // éliminer les caractères non numériques en début de chaîne
      // recopier ceux numériques dont point décimal jusqu'au premier caractère différent
      // envoyer cette chaîne à une fonction TraitePoidsRecu  
     
    end;
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Membre expert
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    décembre 2008
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2008
    Messages : 1 480
    Points : 3 508
    Points
    3 508

    Par défaut

    je n'avais pas trop regardé le code d'OR34A. Effectivement le code de Tourlourou est beaucoup plus adéquate et il suffit d'utiliser le Tregexpr dans son TraiteMessage pour récupérer la valeur numérique. Attention les variables CurPos et StrBal doit être globale et pas locale pour garder la valeur entre 2 appels.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    / variables globales définies  au début : 
    // CurPos : integer;
    //  StrPos: String;
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  5. #5
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    mars 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : mars 2005
    Messages : 2 898
    Points : 7 835
    Points
    7 835

    Par défaut

    jurassic pork a raison ; les variables sont d'ailleurs mal nommées : LFPos plutôt que CurPos, par exemple ? Et +1 à l'utilisation des expressions régulières, que je ne connais pas suffisamment !

    Mais surtout, si on ne veut traiter que certaines trames, le débit d'envoi étant trop important, plutôt que d'utiliser des Sleep ou Timer, il suffit d'ajouter un test dans 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
    Begin
              StrPoidsActu := StrPoidsActu + Copy(StrBal , 1, CurPos -1) ; // ajout jusqu'au LF
     
              if Now > LastDate + IntervalleLecture // intervalle à fixer en global et LastDate à initialiser en dehors de la procédure 
                then begin
                  TraiteMessage(StrPoidsActu); // procédure à écrire
                  Lastdate := Now;
                end;
     
              if length(Strbal) > CurPos // cela se peut-il ?
                then StrPoidsActu := Copy(StrBal , CurPos +1, length(Strbal)-CurPos); // on colle ce qui suit le LF en début de nouvelle ligne
     
          end;
    Delphi 5 Pro - Delphi 10.1 Berlin Starter Edition - CodeTyphon 6.15 sous Win 7 et 5.20 sous Ubuntu 14.04
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  6. #6
    Membre expert
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    décembre 2008
    Messages
    1 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2008
    Messages : 1 480
    Points : 3 508
    Points
    3 508

    Par défaut

    hello,
    bon j'ai transformé le projet de test de simulateur GPS de mon composant série TLazserial en simulateur de balance série .
    Le projet est en pièce jointe.
    Le principe : j'envoie une chaîne de caractères ressemblant à ce qu'envoie la balance série toutes les 10 secondes.
    Pour tester j'ai besoin de deux liaisons séries reliées entre elles par un cordon croisé série. Je lance deux fois le programme. Sur un j'ouvre le port d'entrée et j'attends que les données arrivent. Sur l'autre j'ouvre le port de sortie et je lance le simulateur.
    Dans le programme il y a la procédure AnalyseData(qui utilise un Tregexpr) pour extraire le poids de la chaîne reçue.

    Nom : Balance Simulator-Simu.png
Affichages : 42
Taille : 14,7 Ko

    Nom : Balance Simulator-Reception.png
Affichages : 41
Taille : 16,7 Ko

    Ami calmant, J.P
    Fichiers attachés Fichiers attachés
    Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    mars 2010
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 136
    Points : 134
    Points
    134

    Par défaut LazSerial - Utiiser les données -Suite

    Bonjour,


    Merci beaucoup d'être aussi réactif à mon problème.

    Je récupère le fichier Zip à l'instant et vais le regarder avec attention.

    Cordialement

    R.O.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    mars 2010
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2010
    Messages : 136
    Points : 134
    Points
    134

    Par défaut TLazSerial - Utiliser les données - Suite et fin ..

    Bonjour à tous et tout particulièrement à J.P.

    J'ai testé le programme envoyé par J.P. en liaison avec la balance en question et cela fonctionne très bien pour ce qui est de l’affichage du poids et le listing du programme m'a laissé admiratif par sa concision et s'est avéré bien trop sophistiqué (pour moi) pour que je puisse en intégrer des parties dans mon travail. Heureusement il en va en informatique comme pour les voyages, plusieurs chemins mènent à Rome que ce soient des autoroutes ou des sentiers muletiers.
    J'ai donc continué mes tests et la solution est venue d'une instruction de LazSerial qui permet de récupérer les données reçues par blocs compris entre deux CRLF.
    Le code que j'ai écrit est le suivant :
    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
    procedure TF_balanc.Laz_serieRxData(Sender: TObject);  // accès au Port série - lecture des données
     
        Var Strbal : String ; // chaine lecture du port série
        Var chainStock , Caract_lu2 : String ;
        Var  i: integer ;
    begin
       Try
        Laz_serie.RcvLineCRLF:= True ;
        Strbal := Laz_serie.readData ; // instruction de lecture des données émises
        Ed_Plu.text := STrBal ;
        Edit1.Text := IntToStr(length(StrBal)) ;  // affichage de la chaine de caractères lue
        // écrèmage de la chaine de caractères lue pour ne garder que le nombre décimal
        For i := 1 To 17 Do
          Begin
          Caract_Lu2 := Copy(StrBal, i, 1) ;
          if Caract_Lu2 = '.' Then ChainStock := ChainStock + ','  ; // nécessité de remplacer le point décimal par une dans LAZARUS
          if Caract_Lu2 = '0' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '1' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '2' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '3' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '4' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '5' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '6' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '7' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '8' Then ChainStock := ChainStock + Caract_Lu2 ;
          if Caract_Lu2 = '9' Then ChainStock := ChainStock + Caract_Lu2 ;
          end;
          // Fin d'écrèmage de la chaine de caractères lue pour ne garder que le nombre
          Ed_PLu.Text := ChainStock ;
          Edit2.Text := IntToStr(Length(ChainStock));
       Except
        ShowMessage ('La communication entre la balance et l''ordinateur est défectueuse') ;
       End ;
    end;
    Les composants Edit1 et Edit2 sont provisoires et n'ont servi que pour vérifier la longueur des chaines de caractères constituées. L'affaire est donc résolue mais me laisse une petite insatisfaction car la la liaison est continue entre la balance et l'ordinateur or, ce programme a été conçu pour gérer la prise d’information d'une manip. qui peut durer plusieurs semaines et où la liaison n'est nécessaire que quelques secondes toutes les demi-heures ou heure. Il serait donc plus adéquat que cette liaison ne soit pas active lorsqu'elle n'est pas nécessaire mais pour l'instant cela fonctionne bien et c'est l'essentiel.
    Cordialement

    R.O.

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/07/2017, 08h18
  2. [Embarqué] Lire des données par le port série (Qt ExtSerialPort) sans fausse mesure
    Par Jugulaire dans le forum Plateformes
    Réponses: 1
    Dernier message: 01/04/2015, 09h22
  3. Réponses: 0
    Dernier message: 29/09/2014, 19h59
  4. Gestion de données arrivant par le port série
    Par altivisio dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 16/02/2009, 21h15
  5. codage des données à l'entrée du port série
    Par sanatou dans le forum Windows
    Réponses: 4
    Dernier message: 09/11/2006, 11h22

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