Delphi par l'exemple

 

Retour accueil

Part 1 Partie 2 : lecture des données sur un port COM >> Partie 3 : utilisation d'un thread

 

Pour cet exercice nous avons besoin des composants suivants :

- trois éditeurs de texte (le quatrième ne servait qu'à un contrôle)
- un bouton pour lancer la lecture

Code source de l'unité :

unit u_LitCom;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    { Button2: TButton }
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit4: TEdit;
    procedure Button1Click(Sender: TObject);
    { procedure Button2Click(Sender: TObject); }
    procedure LectureNMEA;

  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;
  g_Ligne: String;
  { g_OK: Boolean }

implementation

{$R *.DFM}

{--------------------------------------------------------------------}
{ la procédure LectureNMEA lit les données provenant du port COM     }
{ qui peut être un port usb                                          }
{ avant: les textes des edits sont vides                             }
{ après: les textes des edits sont mis à jour en fonction de la      }
{        trame lue                                                   }
{ documentation:                                                     }
{ http://www.delphifr.com/codes/LECTURE-ECRITURE-PORT-COM_12482.aspx }
{ auteur : graccus                                                   }
{ première implémentation : 07 avril 2007                            }
{ dernière modification :                                            }
{--------------------------------------------------------------------}
Procedure TForm1.LectureNMEA;
var
  l_i,l_j: Integer;
  Serial: TFILEStream;
  Buff: Byte;

begin
  try
    g_Ligne := '';
    Serial := TFileStream.Create('COM4', fmOpenRead);
    try
      begin
        repeat
          Serial.Read(Buff, 1)
        until
          Chr(Buff) = '$';
          g_Ligne := g_Ligne + Chr(Buff);
        while Buff <> 10 do begin
          Serial.Read(Buff, 1);
          g_Ligne := g_Ligne + Chr(Buff)
        end
     end;
  finally
    Serial.free
  end;
  except
  end
end; { LectureNMEA }

{
procedure TForm1.Button2Click(Sender: TObject);
begin
  g_OK := false
end;
}

procedure TForm1.Button1Click(Sender: TObject);
var
  l_i: Byte;
begin
  { g_OK := true }
  Edit1.Text := '';
  Edit2.Text := '';
  Edit3.Text := '';
  Edit4.Text := '';
  { for l_i := 1 to 10 do begin  }
  { repeat
  Application.ProcessMessages } 
  LectureNMEA ;
    if Copy(g_Ligne, 4, 3) = 'GGA' then
      Edit1.Text := g_Ligne
    else
      if Copy(g_Ligne, 4, 3) = 'RMC' then
        Edit2.Text := g_Ligne
      else
        Edit3.Text := g_Ligne;

  Edit4.Text := g_Ligne
  { until not g_OK }
  { end } { boucle for }
end;

end.
Il y a des temps lointains, pour lire les données
d'un port série, ou imprimante, les choses étaient
 relativement faciles. Quelques lignes écrites en
assembleur et le tour était joué. Malheureusement
depuis les versions Windows qui ont suivi Win98,
ce n'est plus possible pour des raisons de sécurité.
Alors il faut désormais utiliser des composants
comme TComPort ou autres. Il n'en manque pas.
Mais il existe une méthode simple en utilisant les
flux (Stream). C'est celle-ci qui est utlisée dans ce
programme.
Inconvénient : on ne peut pas gérer les paramètres
du port comme la  vitesse de transmission (bauds).
Mais cela fait partie des améliorations à apporter.

Les donnés lues sont de type Byte. Il faut donc les 
transformer en caractères en utilisant la fonction
Chr.

Ici c'est le port COM4 qui est utilisé, car c'est le port
usb qui lit les données du gps sur mon ordinateur.
Il faut le modifier si ce n'est pas le cas sur votre
machine.

Par la suite, nous utiliserons le programme précédent
pour sélectionner le port série.

Les deux barres qui apparraissent à la fin de la trame
sont dues aux valeurs de CR et LF.

En cliquant sur le bouton vous obtenez le résultat de
la lecture d'une trame.

Essayer d'activer la boucle for l_i et vous verrez
pourquoi il faut utiliser un thread pour obtenir une
lecture continue des données.

Quoique !

- ajouter à la fiche un deuxième bouton avec la
   propriété 
   caption = 'Stop'
- ajouter une variable globale g_OK: Boolean;
- dans la procédure Button2Click mettez l'instruction
   g_OK := false
- dans la procédure Button1Click  :
  ajouter au début g_OK := true;
  remplacer la boucle for par une boucle repeat

   repeat
      Application.ProcessMessages;
      LectureNMEA;
       ...
    until not g_OK;

Observez le résultat.

Nous utiliserons par la suite un thread, puisque ces
pages sont destinées à un tutoriel.

Remarque :
les instructions

  Serial := TFileStream( 'COM4', fmOpenRead);
et
  Serial.free

seront mises,  dans le projet final, dans la procédure
Button1Click, et la variable Serial devra être globale.   

Fichiers source litcom.zip

Retour accueil

Part 1 Partie 3 : utilisation d'un thread