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
Partager