Je développe actuellement une application pour gérer une carte controleur d'une machine (qui effectue des mesures) via le port série.

Cette carte à un fonctionnement tout à fait basique :
- pour démarrer la machine : envoe du caractère 'D'
- pour demander une mesure : envoi du caractère 'M'
Ce que renvoi la carte :
- machine démarrée : envoi de 'O'+entrée
- mesure (après demande : envoi de la mesure (sur 2 octets) + entrée
- arrêt du processus : envoi de 'E'+entrée

Le développement de l'application dans un formulaire n'a pas pris beaucoup de temps. Mais je n'arrive pas à la faire passer sous forme de thread.

J'ai l'impression que le trigger ne déclenche jamais lorsqu'il est dans le timer.

Je me base sur le composant APro (Async Professionnal) 4.06 pouir la communication via port série.

voici le code de mon thread, mon évènement sur arrivée de caractère dans le port série est désactivé :

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
 
unit Etuve_GeFran_Thread;
interface
uses
  SysUtils, Classes, OoMisc, AdPort, Dialogs, Windows,ExtCtrls;
type
  Thread_Etuve_GeFran = class(TThread)
    Etuve_ComPort : TApdComPort;
    CTimer:TTimer;
    procedure Trigger_EndProcess(CP : TObject; Count : Word);
  private
    process_on : boolean;
    procedure StartProcess;
    // lance le processus
    function GetMesure : double;
    // renvoie la valeur de la mesure en cours
    procedure TakeMesure(Sender: TObject);
    // demande de mesure et
    // sauvegarde du résultat dans la base de données
  protected
    // procedure d'exécution
    procedure Execute; override;
  public
    // constructeur
    constructor create( numPort : integer ; timer : integer );
  end;
implementation
const
  // constantes pour le calcul de la température
  a : double = 0.59814453;
  b : double = -112.5;
///////////////////////////////////////////////////////////////////////////
// Procédures et fonction du Thread ///////////////////////////////////////
// private ///////////////////////////////////////////////////
// Procédure de démarrage du processus //
Procedure Thread_Etuve_GeFran.StartProcess();
var
  buffer : string;
begin
  // envoi de la demande de démarrage
  Etuve_ComPort.Output:='D';
  // Attente des 2 caractères
  while not Etuve_ComPort.CharReady do begin end;//while
  buffer := Etuve_ComPort.GetChar;
  while not Etuve_ComPort.CharReady do begin end;//while
  buffer := buffer+Etuve_ComPort.GetChar;
  if ( (buffer = 'O'+char($0D)) and (not process_on) ) then
  begin
    process_on := true;
    Ctimer.Enabled:=true;
  end;
end;//procedure
// Fonction retournant la valeur en °C que mesure la sonde //
Function Thread_Etuve_GeFran.GetMesure: double;
var
  x : integer;
  buffer : string;
begin
  // demande de température
  Etuve_ComPort.Output:='M';
  while not Etuve_ComPort.CharReady do begin end;//while
  buffer := Etuve_ComPort.GetChar;
  while not Etuve_ComPort.CharReady do begin end;//while
  buffer := buffer+Etuve_ComPort.GetChar;
  if ( (buffer = 'E'+char($0D)) and (process_on) ) then
  begin
    process_on := false;
    Ctimer.Enabled := false;
  end
  else
  begin
    while not Etuve_ComPort.CharReady do begin end;//while
    buffer := buffer+Etuve_ComPort.GetChar;
  end;//if
  x := (byte(buffer[1])*256)+(byte(buffer[2]));
  result := a*x+b;
end;//function
procedure Thread_Etuve_Gefran.TakeMesure(Sender: TObject);
var
  mesure : double;
begin
  // enregistrement de la mesure
  mesure := GetMesure;
  // Stockage de la mesure dans la base de données
  // ...
end;//procedure
// Trigger  de contrôle des entrées de caractères par le port série
Procedure Thread_Etuve_Gefran.Trigger_EndProcess(CP : TObject; Count : Word);
begin
{  setlength(buffer,count);
  Etuve_ComPort.GetBlock(pointer(buffer)^,count);
  // test de la chaîne résultat
  if count = 2 then
  begin
    // mise en marche?
    if ( (buffer = 'O'+char($0D)) and (not process_on) ) then
    begin
      process_on := true;
    end//if
    else
    begin
      // fin de process?
      if ( (buffer = 'E'+char($0D)) and (process_on) ) then
      begin
        process_on := false;
        Etuve_ComPort.Open := false
      end//if
      else
      begin
        // erreur
        // signal d'erreur
      end;//if
    end;
  end
  else
  begin
    if count = 3 then
    begin
    end//if
    else
    begin
      // erreur
      // signal d'erreur
    end;
  end;  }
end;//Trigger
// protected //////////////////////////////////////////////////
// Etuve_GeFran_Thread / Exécutable //
procedure Thread_Etuve_GeFran.Execute;
begin
  // ouverture du port de communication série
  Etuve_ComPort.Open := true;
  StartProcess;
//  Ctimer.Enabled:=true;
  Etuve_ComPort.Open := false;
end;//Execute
// public /////////////////////////////////////////////////////
// constructeur //
constructor Thread_Etuve_GeFran.Create( numPort : integer ; timer : integer );
begin
  FreeOnTerminate := true;
  //timer_thread := timer;       y
  process_on := false;
  inherited Create(false);
  Etuve_ComPort := TApdComPort.Create(nil);
  Ctimer:=TTimer.create(nil);
  Ctimer.enabled:=false;
  CTimer.Interval:=timer;
  CTimer.OnTimer:=TakeMesure;
  with Etuve_ComPort do
  begin
    Open := False;
    Baud := 19200;        // vitesse - baud
    ComNumber := numPort; // numéro de port
    DataBits:=8;
    Parity:=pnone;
//    OnTriggerAvail := Trigger_EndProcess;
   end;//with
end;//constructor
end.//Thread

PS: Je travaille sous Delphi 7