Autor Beitrag
Serge
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 11:46 
Hallo erst mal an allen Helfer und Forumbesucher!

Ich habe ein Problem mit dem Array of char.

und zwar ich lese von der serielle Schnittstelle einen nullterminierten String
in ein Array of Char, aber ich brauche einen String, um ihn dann im EditFeld
anzuzeigen oder in eine Zahl umzuwandeln.


ausblenden 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:
const
  TempBufSize = 2048;
  var
  InQue, OutQue : longint;
  {$IFDEF DELPHI4UP}
   ToRead, HasRead : cardinal;
  e : cardinal;
  i : cardinal;
  {$ELSE}
  ToRead, HasRead : longint;
  e : longint;
  i : integer;
  {$ENDIF}
   Buf : array[0..20of char;
      begin  // Daten stehen im Empfangspuffer
        ToRead:=InQue;
        if (ToRead>TempBufSize) then ToRead:=TempBufSize;
        ReadFile(Form1.Cid,Buf,ToRead,HasRead,@Overlapped);
           end;
        // Empfangene Zeichen in MemoRxD übernehmen

       Buf[HasRead]:=#0;
      
       Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+Buf;
       i:=i+HasRead;
      Form1.LabelRxD.Caption:=IntToStr(i);
     end;
    end;


Ich versuchte die Daten in String auszulezen
so:
Empfangstr: String [12]; // 11 stellige Zahl + <lf><cr> Also noch zwei stellen ??

ReadFile(Form1.Cid,EmpfangStr,12,HasRead,@Overlapped);


aber das hat auch nicht ganz geklappt, etste Vorzeichen wurde einfach ausgelassen.

bestimmt mache ich was falsch, aber der Code für die Serielle ist nicht meins und in Delphi bin ich auch ein Anfänger..kann mir vielleicht jemand irgendwie weiter helfen??
wulfskin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1349
Erhaltene Danke: 1

Win XP
D5 Pers (SSL), D2005 Pro, C, C#
BeitragVerfasst: Do 22.03.07 11:53 
ausblenden Delphi-Quelltext
1:
  ReadFile(Form1.Cid,EmpfangStr[1],12,HasRead,@Overlapped);					

Oder du benutzt die Funktion StrPCopy, Move o.ä die einen Array in einen String kopiert!

Edit: Du bist sicher, dass die Zahl nicht binär ankommt?

Gruß Hape!
Serge Threadstarter
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 12:14 
das Gerät wandelt alles in ASCII Code um

ich habe ein Programm unter Excel, das serielle abfragt, da bekomme ich das
Ausgelesenes in sauberen Strings. Aber um das programm zum Laufen zu bringen, verwende ich eine fertige DLL,
mit fertigen Funktionen für die serielle Schnittstelle. Das macht vieles leichter.

aber in VBA habe ich leider keine Möglichkeit, einigen Abfrage-Schleifen in treads zu packen.
Serge Threadstarter
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 12:44 
Bei der Bearbeitung von nullterminierten Strings ist häufig der Einsatz von Zeigern erforderlich (siehe Zeiger und Zeigertypen). String-Konstanten sind zuweisungskompatibel zu den Typen PChar und PWideChar, die Zeiger auf nullterminierte Arrays mit Char- und WideChar-Werten darstellen. Im folgenden Beispiel zeigt P auf einen Speicherbereich, der eine nullterminierte Kopie von Hello world! enthält:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
var P: PChar;

 ...
P := 'Hello world!';


Die folgenden Programmzeilen sind mit den obigen Zeilen identisch:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
const TempString: array[0..12of Char = 'Hello world!'#0;

var P: PChar;
 ...
P := @TempString;


wie kann man das irgendwie weiter benutzen??

Moderiert von user profile iconChristian S.: Delphi-Tags hinzugefügt
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 22.03.07 14:01 
Wenn Du direkt den String schon in einem Array of Char hast, kannst Du ab Delphi 7 einfach dieses Array (ohne angabe eines Startindex) an den String zuweisen ...

Bei vorhergehenden Delphi-Versionen empfiehlt sich die Nutzung der Funktion StrPas, der Du einen Zeiger auf das erste Zeichen übergibst.

Also z.B. StringVariable := StrPas(@DeinArray[0]);

Ansonsten wie die anderen das bereits beschrieben haben ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Serge Threadstarter
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 14:37 
Danke BenBE!!!
das geht:))))

gestatten sie mir noch eine frage...
Warum im Memofeld :

ausblenden Delphi-Quelltext
1:
  Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr;					


gibtes dies Form1.MemoRxD.Lines.Text+empfangstr?? was soll hier dieses
plus Zaichen?

und warum sehe ich in Form1.Edit1.Text:=trim(empfangstr); nur letzte 3 Zeichen??

In Memofeld steht -002191.500 in Editfeld nur 500

Wie bekomme ich eine Laufende Anzeige im Editfeld???
z.B jede sekunde wird ein Wert von der serielle ausgelesen und ans Editfeld
weitergeben.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 22.03.07 14:44 
Das Plus bei 2 Strings bedeutet String-Konkatenation (Zusammensetzen der beiden Operanden).

Warum er bei Trim nur die letzten 3 Zeichen zurückgibt wundert mich ein wenig. Dazu müsste man aber ggf. einmal mit dem Debugger im Einzelschritt sich die Variablen-Inhalte anschauen.

Ggf. einfach mal kurz die aktuelle Source-Version posten ...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Serge Threadstarter
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 14:59 
ich entwickle mit Delphi 6,

ohne trim ist das selber..steht um zwei Striche mehr


ausblenden Delphi-Quelltext
1:
Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr;					


da wird alles richtig angezeigt


ausblenden Delphi-Quelltext
1:
Form1.Edit1.Text:=trim(empfangstr);					


da nur die letzten 3 Zeichen..mit trim hat es nicht zu tun...

wenn so ..Form1.Edit1.Text:=Form1.MemoRxD.Lines.Text

wird alles richtig angezeigt, aber in einer Schleife etwa so:

-002191.500-002191.500-002191.500-002191.500

Form1.Label1.Caption:=Form1.MemoRxD.Lines.Text

Wird so angezeigt:

-002191.500
-002191.500
-002191.500
-002191.500

Was ich brauche eine laufenbde anzeige,
wo die letzten Zahl sich um eins ändert.

Die daten kommen wie gesagt , von der serielle Schnittstelle
Serge Threadstarter
Hält's aus hier
Beiträge: 8


D6 Pers
BeitragVerfasst: Do 22.03.07 15:57 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
 Form1.Edit1.Text:=Form1.Edit1.Text+trim(empfangstr);


Form1.Label3.Caption:=Form1.Label3.Caption+trim(empfangstr);


Also so geht es auch...schon wider dieses Plus-Zeichen!!!

Aber immer noch speichert das Editfeld letzter Eintrag
und schreibt alles in einer Zeile.

Aber es soll viel einfacher sein:

Edit1.Text:=StringVariable; !!!!!!!!

Warum geht es bei mir nicht??

Abfrage der serielle ist in einem Tread eingepackt.
Ist das wo möglich der grund, für dieses verhalten???

ausblenden volle Höhe 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:
263:
264:
265:
266:
267:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, ComCtrls,
  DlgCom, Serial;

type
  TSerThread = class(TThread)
    constructor Create;
    procedure Execute;  override;
  end;
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    ButtonSetup: TButton;
    ButtonOpen: TButton;
    ButtonClose: TButton;
    ButtonExit: TButton;
    ButtonSendText: TButton;
    MemoTxD: TMemo;
    MemoRxD: TMemo;
    LabelTxD: TLabel;
    Label1: TLabel;
    LabelRxD: TLabel;
    Label2: TLabel;
    Timer1: TTimer;
    Button1: TButton;
    Edit1: TEdit;
    Label3: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ButtonSetupClick(Sender: TObject);
    procedure ButtonOpenClick(Sender: TObject);
    procedure ButtonCloseClick(Sender: TObject);
    procedure ButtonExitClick(Sender: TObject);
    procedure MemoTxDKeyPress(Sender: TObject; var Key: Char);

    procedure ButtonSendTextClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
     procedure NotifyEvent(Sender: Tobject);


    public
    { Private-Deklarationen }
    IsOpened, IsClosing : boolean;
    SerThread : TSerThread;

    { Public-Deklarationen }
    Cid : THandle;  MyTimer1:TTimer;
  end;

var
  Form1: TForm1;     MyTimer1:TTimer;

implementation

{$R *.DFM}

constructor TSerThread.Create;
begin
  inherited Create(false);
  FreeOnTerminate:=true;
end;

procedure TSerThread.Execute;
const
  TempBufSize = 2048;
var
  InQue, OutQue : longint;
  {$IFDEF DELPHI4UP}
  ToRead, HasRead : cardinal;
  e : cardinal;
  i : cardinal;
  {$ELSE}
  ToRead, HasRead : longint;
  e : longint;
  i : integer;
  {$ENDIF}
   Buf : array[0..32of char;
  empfangstr: string [32];
  len:dword;
   j:integer;
begin
  // Thread-Routine, wird beim Start des Thread durchlaufen
  i:=0;
  while (not Terminated) do
  begin
    if WaitCommEvent(Form1.Cid,e,nilthen
    begin   // An der Schnittstelle ist vorgegebenes Ereignis aufgetreten
      DataInBuffer(Form1.Cid,InQue,OutQue);
      Form1.LabelTxD.Caption:=IntToStr(OutQue);
      if InQue>0 then
      begin  // Daten stehen im Empfangspuffer
        ToRead:=InQue;
        if (ToRead>TempBufSize) then ToRead:=TempBufSize;
       ReadFile(Form1.Cid,buf,ToRead,HasRead,@Overlapped);

        // Empfangene Zeichen in MemoRxD übernehmen
       Buf[HasRead]:=#0;
        empfangstr := StrPas(@buf[0]);
       Form1.MemoRxD.Lines.Text:=Form1.MemoRxD.Lines.Text+empfangstr;




        //Form1.MemoRxD.Lines.Text:=empfangstr;
        Form1.Edit1.Text:=trim(empfangstr);//[0]+' '+empfangstr[1]+' '+empfangstr[2]+'        '+empfangstr[10];
        Form1.Label3.Caption:=trim(empfangstr);
         empfangstr:='';
        i:=i+HasRead;
        Form1.LabelRxD.Caption:=IntToStr(i);
      end;
    end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  IsOpened:=false;  // Schnittstelle ist nicht geöffnet
  IsClosing:=false;
  Cid:=INVALID_HANDLE_VALUE;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  IsClosing:=true;
  ButtonCloseClick(Sender);  // Schnittstelle schließen, Thread beenden
end;

procedure TForm1.ButtonSetupClick(Sender: TObject);
begin
  FormCOMSetup.ShowModal; // Konfigurationsdialog
end;

procedure TForm1.ButtonOpenClick(Sender: TObject);
begin
  if (not IsOpened) then
  begin
     // Schnittstelle öffnen
     Cid:=OpenComm(FormCOMSetup.UsedPort,FormCOMSetup.dcb,FormCOMSetup.BufSizeR,FormCOMSetup.BufSizeT);
     IsOpened:=Cid<>INVALID_HANDLE_VALUE;
     if IsOpened then
     begin
       // Schnittstelle konnte geöffnet werden
       SetCommMask(Cid,EV_RXCHAR);  // auf Zeichenempfang reagieren
       SerThread:=TSerThread.Create;  // Thread anlegen
       StatusBar1.SimpleText:='Schnittstelle ist geöffnet.';
       MemoTxD.Enabled:=true;
       MemoTxD.Clear;
       MemoRxD.Clear;
     end
     else
     begin
       // Schnittstelle konnte nicht geöffnet werden
       MessageBeep(0);
       StatusBar1.SimpleText:='Schnittstelle konnte nicht geöffnet werden!';
     end;
  end
  else
  begin
    MessageBeep(0);
    StatusBar1.SimpleText:='Schnittstelle ist bereits geöffnet!';
  end;
end;

procedure TForm1.ButtonCloseClick(Sender: TObject);
begin
  if IsOpened then
  begin
    // Schnittstelle schließen
    SerThread.Terminate;  // Thread zum Beenden auffordern
    SetCommMask(Cid,0);
    if CloseComm(Cid) then
    begin
      IsOpened:=false;
      MemoTxD.Enabled:=false;
      StatusBar1.SimpleText:='Schnittstelle wurde geschlossen.';
    end
    else
    begin
      MessageBeep(0);
      StatusBar1.SimpleText:='Schnittstelle konnte nicht geschlossen werden!';
    end
  end
  else
  begin
    if (not IsClosing) then
    begin
      MessageBeep(0);
      StatusBar1.SimpleText:='Schnittstelle ist bereits geschlossen.';
    end;
  end;
end;

procedure TForm1.ButtonExitClick(Sender: TObject);
begin
  Close;
end;

procedure TForm1.MemoTxDKeyPress(Sender: TObject; var Key: Char);
var
  {$IFDEF DELPHI4UP}
  w : cardinal;
  {$ELSE}
  w : longint;
  {$ENDIF}
begin
  // eingegebenes Zeichen senden
  if IsOpened then WriteFile(Cid,Key,1,w,@Overlapped);
end;

 



procedure TForm1.ButtonSendTextClick(Sender: TObject);
begin
(* Timer1 intantiieren *)
MyTimer1 := TTimer.Create(Self); //NIL
(* Eigenschaften von Timer1 festlegen *)
(* (hier nur "Interval")              *)
MyTimer1.Interval := 1000//alle 1000ms=1s ein OnTimerEvent
MyTimer1.Enabled := TRUE; //aktiviert timer
MyTimer1.OnTimer := NotifyEvent; //OnTimer := NotifyEvent
//Prozedur dem OnTimerEvent zuordnen
// resume;



(* Ereignisverknüpfung für Timer1 festlegen *)
 (* (hier nur "OnTimer")                     *)
 end;


 procedure TForm1.NotifyEvent(Sender: TObject);

  const
  Data : array[0..6of char =
    'dis,g'+chr(13)+chr(10);
var
  {$IFDEF DELPHI4UP}
  w : cardinal;
  {$ELSE}
  w : longint;
  {$ENDIF}
  i:integer;
begin
   // for i:=1 to 100
//do

  WriteFile(Cid,Data,sizeof(Data),w,@Overlapped);
  //sleep(100);
  //Application.ProcessMessages;

end;



procedure TForm1.Button1Click(Sender: TObject);

 begin
 (* Timer1 lebewohl sagen *)
 MyTimer1.Destroy ;
 end;
 end.


Moderiert von user profile iconTino: Beiträge zusammengefasst


Zuletzt bearbeitet von Serge am Do 22.03.07 16:09, insgesamt 1-mal bearbeitet