Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Messwerte aus einem String extrahieren.


adina83 - Do 13.07.06 18:58
Titel: Messwerte aus einem String extrahieren.
Hallo ich versuchen Messwerte die mir über die RS232 geschickt werden zu analysieren. Sobald ein Zeichen empfangen wird eine Interruptroutine aufgerufen und in dieser die emfangene Zeichen in einem String aufsummiert. Empfange ich das Zeichen "#$D#$A#3" so weiss ich das das Ende der Message erreich ist. Der nun entstandene String hat folgendes Aussehen:

'P04'#$D#$A'MEMORY: '#$D#$A'DATE: 13.07.06'#$D#$A'18:38:58.77 00: +00.010 V Volt Spannung '#$D#$A' 01: +00.000 A mA Strom '#$D#$A' 02: +0026.1 øC NiCr Temp '#$D#$A' 03:!+100.00 % Inp Kontakt_L '#$D#$A' 13: +000.00 % Inp Kontakt_R '#$D#$A'18:38:58.93 00: +00.010 V Volt Spannung '#$D#$A' 01: +00.000 A mA Strom '#$D#$A' 02: +0026.1 øC NiCr Temp '#$D#$A' 03: +000.00 % Inp Kontakt_L '#$D#$A' 13: +000.00 % Inp Kontakt_R '#$D#$A'18:38:59.09 00: +00.010 V Volt Spannung '#$D#$A' 01: +00.000 A mA Strom '#$D#$A' 02: +0026.1 øC NiCr Temp '#$D#$A' 03: +000.00 % Inp Kontakt_L '#$D#$A#$3

Nun beginne ich nach Trennzeichen zu Suchen und Versuche die Messwerte entsprechend zu extrahieren. Dazu benutze ich die Befehle pos(), copy(). Wenn ich einen Teil analysiert habe lösche ich diesen und beginne wieder mit der Such nach einem Zeichen. Nun meine Frage:

Gibt es eine elegantere Lösung für mein Problem. Ich dachte da an Stringlisten und Funktionen wie ExtractStrings.
Hier mal mein Versuch. Es funktioniert sieht aber wirklich nicht schön aus. Ach ja am Anfang einer jeden Message steht als erstes der Befehl. Deshalb hab ich es so gelöst das ich als erstes den Befehl extrahiere und danach das ganz über "if then" aufsplitte da case leider keine Strings verarbeitet.

Ich hoffe ihr könnt mir weiterhelfen.




Delphi-Quelltext
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:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
procedure THauptfenster.VaComm1RxChar(Sender: TObject; Count: Integer);
var
  Tmp,MWa,Rbef,t_str0, t_str1: string;
  ix,iy,i :integer;
  v:real;
const
  est=Chr($03); //ETX
  cr_lf=Chr($0D)+Chr($0A);
begin

  Tmp := VaComm1.ReadText;
  RxData:=RxData + Tmp;
  if Pos(est,RxData)>0 then       // ETX wurd erkannt --> beginne mit der Auswertung
  begin
    ix:=Pos(est,RxData);
    iy:=Pos(cr_lf,RxData);
    AL_Bef:=copy(RxData,1,iy-1);

    if AL_Bef='G00' then
    begin
    end;

    if AL_Bef='P01' then
    begin
      // 'P01'#$D#$A'19:00:00 01: -00.004 mV'#$D#$A#3
      //1. Uhrzeit auslesen
      t_str0:=copy(RxData,iy+2,8);
      Mw_Time:=strtotime(t_str0);


      //2. Welcher Messwertnummer
      t_str0:=copy(RxData,iy+11,2);
      Mw_Nr:=StrToInt(t_str0);

      //3. Messwert verarbeiten
      case MW_Nr of
        00:
        begin
          ix:=Pos(cr_lf,RxData);
          t_str0:=RxData;
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          delete(t_str0,1,8);     // Lösche Datum + Leerzeichen
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Kanalnummer + : +nachf. Zeichen
          ix:=Pos(' ',t_str0);
          t_str1:=copy(t_str0,1,ix-1);
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          delete(t_str0,1,ix);
          ix:=Pos(est,t_str0);
          Mw_Eh00:=trim(copy(t_str0,1,ix-3));
          try
          Mw_00:=StrToFloat(trim(t_str1));
          Panel1.Caption:=FloatToStrf(Mw_00,ffFixed,8,1)+' '+Mw_Eh00;
          except



          end;

        end;

        01:
        begin
          ix:=Pos(cr_lf,RxData);
          t_str0:=RxData;
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          delete(t_str0,1,8);     // Lösche Datum + Leerzeichen
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Kanalnummer + : +nachf. Zeichen
          ix:=Pos(' ',t_str0);
          t_str1:=copy(t_str0,1,ix-1);
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          delete(t_str0,1,ix);
          ix:=Pos(est,t_str0);
          Mw_Eh01:=copy(t_str0,1,ix-3);
          try
            Mw_01:=StrToFloat(trim(t_str1));
            Panel2.Caption:=FloatToStrf(Mw_01,ffFixed,8,1)+' '+Mw_Eh01;
          except
            Panel2.Caption:='Error';
          end;
        end;


        02:
        begin
          ix:=Pos(cr_lf,RxData);
          t_str0:=RxData;
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          delete(t_str0,1,8);     // Lösche Datum + Leerzeichen
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Kanalnummer + : +nachf. Zeichen
          ix:=Pos(' ',t_str0);
          t_str1:=copy(t_str0,1,ix-1);
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          delete(t_str0,1,ix);
          ix:=Pos(est,t_str0);
          Mw_Eh02:=copy(t_str0,1,ix-3);
          try
            Mw_02:=StrToFloat(trim(t_str1));
            Panel3.Caption:=FloatToStrf(Mw_02,ffFixed,8,1)+' '+Mw_Eh02;
          except
            Panel3.Caption:='Error';
          end;
        end;


        03:
        begin
          ix:=Pos(cr_lf,RxData);
          t_str0:=RxData;
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          delete(t_str0,1,8);     // Lösche Datum + Leerzeichen
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Kanalnummer + : +nachf. Zeichen
          ix:=Pos(' ',t_str0);
          t_str1:=copy(t_str0,1,ix-1);
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          delete(t_str0,1,ix);
          ix:=Pos(est,t_str0);
          Mw_Eh03:=copy(t_str0,1,ix-3);
          try
            Mw_03:=StrToFloat(trim(t_str1));
            Panel4.Caption:=FloatToStrf(Mw_03,ffFixed,8,1)+' '+Mw_Eh03;
          except
            Panel4.Caption:='Error';
          end;
        end;


        13:
        begin
          ix:=Pos(cr_lf,RxData);
          t_str0:=RxData;
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          delete(t_str0,1,8);     // Lösche Datum + Leerzeichen
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Kanalnummer + : +nachf. Zeichen
          ix:=Pos(' ',t_str0);
          t_str1:=copy(t_str0,1,ix-1);
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          delete(t_str0,1,ix);
          ix:=Pos(est,t_str0);
          Mw_Eh13:=copy(t_str0,1,ix-3);
          try
            Mw_13:=StrToFloat(trim(t_str1));
            Panel5.Caption:=FloatToStrf(Mw_13,ffFixed,8,1)+' '+Mw_Eh13;
          except
            Panel5.Caption:='Error';
          end;
        end;
      else

      end;
    end;

    if AL_Bef='P04' then
    begin

//      extractStrings(cr_lf,PChar(RxData),Stringlist01);




      t_str0:=RxData;
      Mw_anzahl:=0;
      while Pos(cr_lf,t_str0)>0 do
      begin
        ix:=Pos(cr_lf,t_str0);
        delete(t_str0,1,ix+1);
        inc(Mw_anzahl);
      end;
      Mw_anzahl:=Mw_anzahl-3;
      SetLength(Mw_Sp00, Mw_anzahl);
      SetLength(Mw_Sp01, Mw_anzahl);
      SetLength(Mw_Sp02, Mw_anzahl);
      SetLength(Mw_Sp03, Mw_anzahl);
      SetLength(Mw_Sp13, Mw_anzahl);



      ix:=Pos(cr_lf,RxData);
      t_str0:=RxData;
      delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
      ix:=Pos(cr_lf,t_str0);
      Mw_Bez:=trim(copy(t_str0,1,ix-1));
      delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A

      ix:=Pos(cr_lf,t_str0);
      t_str1:=trim(copy(t_str0,6,ix-6));
      Mw_Date:=strtodate(t_str1);
      delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
      t_str1:=trim(copy(t_str0,1,8));
      Mw_Sp_Time_Start:=strtotime(t_str1);

      z_nr:=0;
      sp_nr:=0;
      while(Pos(est,t_str0)>0do
      begin
        while (Pos(cr_lf,t_str0)>0do
        begin
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          t_str1:=trim(copy(t_str0,1,ix));
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          Mw_Sp00[z_nr]:=StrToFloat(trim(t_str1));
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          t_str1:=trim(copy(t_str0,1,ix));
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          Mw_Sp01[z_nr]:=StrToFloat(trim(t_str1));
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          t_str1:=trim(copy(t_str0,1,ix));
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          Mw_Sp02[z_nr]:=StrToFloat(trim(t_str1));
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          t_str1:=trim(copy(t_str0,1,ix));
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          Mw_Sp03[z_nr]:=StrToFloat(trim(t_str1));
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          delete(t_str0,1,ix);  // Löschen der Zeit
          ix:=Pos(':',t_str0);
          delete(t_str0,1,ix+1);  // Löschen der Zeit
          ix:=Pos(' ',t_str0);
          t_str1:=trim(copy(t_str0,1,ix));
          if Pos('.', t_str1) > 0 then t_str1[Pos('.', t_str1)] := ',';
          Mw_Sp13[z_nr]:=StrToFloat(trim(t_str1));
          ix:=Pos(cr_lf,t_str0);
          delete(t_str0,1,ix+1);  // Löschen des Befehls + #D#A
          inc(z_nr);
        end;
        delete(t_str0,1,Pos(est,t_str0));
      end;
    end;

    inc(Rxix);
    if Rxix>High(bef) then Rxix:=0;

  end;
end;


Narses - Do 13.07.06 20:01

Moin!

Sieht für mich nach einem klassischen Fall für einen Protokoll-Parser aus. Schau mal hier [http://www.delphi-library.de/topic_ProtokollChatTutorial+V300_54269.html], damit solltest du weiter kommen (geht da zwar um einen Chat, aber die Art und Weise der Datenverarbeitung beim Datenempfang ist genau das, was du brauchst ;)).

cu
Narses


adina83 - Do 13.07.06 21:28

Super Tutorial. Ich schau es mir gleich mal an. Es passt aber genau zum Thema.
Danke für den Tipp