Autor Beitrag
Smartie
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 07:20 
Servus!

Ich versuche gerade, ASCII-Dateien über Delphi zwischen meinem PC und dem LABOR-Laptop über die serielle Schnittstelle hin und her zu schicken.
Zum Test hatte ich auf dem Schlepptop erstmal nur über WIndows-Hyperterminal gearbeitet.
Mein Programm hatte folgenden Sourcecode:

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:
interface

uses
  WinTypes, WinProcs, SysUtils, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, AdPort, OoMisc;

type
  TForm1 = class(TForm)
    ApdComPort1: TApdComPort;
    Test: TButton;
    Label1: TLabel;
    Label2: TLabel;

    procedure TestClick(Sender: TObject);
    procedure ApdComPort1TriggerAvail(CP: TObject; Count: Word);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.TestClick(Sender: TObject);
  {Click Button Click - Send Output}
begin
  ApdComPort1.OutPut := ' Hier kommt ein String;  
end;

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
  {Event OnTriggerAvail - Example how OnTriggerAvail works}
var
  I : Word;
  C : Char;
  S : String;
begin
  S := '
';
  for I := 1 to Count do begin
    C := ApdComPort1.GetChar;
    case C of
      #0..#31 : {Don'
t display} ;
      else S := S + C;
    end;
  end;
  Label1.Caption := S;
  ShowMessage('Got an OnTriggerAvail event for: ' + S + 'count= '+ Count);
end;

end.



Oki, so weit alles klar. Nur: Wenn ich eine ASCII-Datei vom Schlepptop mit Hyperterminal an PC schick, so schneidet er immer das erste Zeichen ab, und versendet es separat. Ich bekomme also immer zwei Datein. Wenn der Inhalt der Datei z.B. lautet "Dies hier ist ein Test"
So erhalte ich folgende zwei Strings raus:
s1 := 'D'
s2 := 'ies hier ist ein Test'

"Ok, ok, Windows", dacht ich mir "Ich muß zur späteren Komunikation eh ohne den Hyperterminal arbeiten". Also, einfach ein zweites sehr ähnliches Programsche geschrieben, für den Laptop, um einfach Zeichenketten zu senden.
Dieses sah wie folgt aus:


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:
interface

uses
  WinTypes, WinProcs, SysUtils, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, AdPort, OoMisc;

type
  TForm1 = class(TForm)
    ApdComPort1: TApdComPort;
    Test: TButton;
    Label1: TLabel;
    Edit1: TEdit;
    procedure TestClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.TestClick(Sender: TObject);
  {Click Button Click - Send Output}
var text : String;
begin
  text := Edit1.Text;
  ApdComPort1.OutPut := text; // wahlweise auch ApdComPort1.PutString(text);
  label1.Caption := '"'+ text + '"' + ' wurde erfolgreich versendet.'
end;


end.




Gut, die gute Nachricht, er versendet es nicht mehr in zwei Teilen :dance:

Die schlechte Nachricht, er versendet immer nnur (maximal) 8 Zeichen :autsch:

Wenn ich einfach im Textfeld "Hallo" eingabe, so bekomme ich auch Hallo raus.
Wenn ich aber "Hallo du schöne Welt" eingebe, so bekomme ich "Welt"
Wenn ich nur "Hallo Welt" eingebe, so bekomme ich "lt"
Bei "Hi Welt" kommt auch "Hi Welt" raus, sind ja auch nur 7 zeichen.
Also, wenn mein String <= 8 Zeichen ist, sendet er diesen komplett. Wenn dieser > 8 Zeichen ist, schneidet er die ersten 8 ab, und schreibt nur den Rest.

Kann mir hier einer bitte weiterhelfen?

Ich freu mich auf Antwort,

Fuß zum Gruß

Smartie

Moderiert von user profile iconGausi: Code- durch Delphi-Tags ersetzt.
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 08:33 
Das Problem entsteht, da der UART Chip des Computers bei einem bestimmten Füllstand ein Interrupt auslöst und den PC damit auffordert den Buffer zu leeren (auszulesen).
Die Delphi Komponente liest nun über die Windows API's den Buffer der Schnittstelle aus und zeigt ihn an (das sind die 8 Zeichen, die vorherigen wurden dann überschrieben.

Es sind als Lösung zwei Vorgehensweisen üblich:

1. Einen Start- (am Anfang der Übermittlung) und Stopstring (am Ende der Übermittlung) senden und alles was dazwischen empfangen wird gehört zur Datei. (Bsp.: ##Start##Hallo Welt##Stop##)
Start- und Stopstring wieder entfernen.
2. Alles was innerhalb eines bestimmten Zeitabschnittes reinkommt gehört noch zur Datei (Bsp.: Wenn Pause zwischen den Zeichen < 2 Sekunden, dann anhängen, sonst neue Datei)


Dies lässt sich relativ einfach mit der Delphi Komponente TComPort realisieren, da sie bereits ein Object TDataPacket enthält, in dem man nur noch Start- und Stopstring angeben muss, um einen String zu erhalten.


Hoffe ich konnte helfen


Chris

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 08:43 
Tausend Dank!

Ichdenke, ich versuche is mit Variante 2.

kannst du mir sagen wie genau ich das realisiere. (Bin noch Delphi-Newbie, und kenn mich auch mit der Syntax noch nicht ganz so gut aus, sorry).

Lieben Gruß

Smartie
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 09:10 
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:
//globale variable
RS232Active : Boolean;

//im OnCreate der Form
RS232Active := False;
//Einen Timer einfügen in dem nach 2 Sekunden (2000 im Interval eintragen) 
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  RS232Active := False;
end;


procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);  
  {Event OnTriggerAvail - Example how OnTriggerAvail works}  
var  
  I : Word;  
  C : Char;  
  S : String;  
begin  
  RS232Active := True;
  Timer1.enabled := False; // Timer neustarten !!
  Timer1.enabled := True;
  S := '';  
  for I := 1 to Count do begin  
    C := ApdComPort1.GetChar;  
    case C of  
      #0..#31 : {Don't display} ;  
      else S := S + C;  
    end;  
  end;  
  Label1.Caption := S;  
  ShowMessage('Got an OnTriggerAvail event for: ' + S + 'count= '+ Count);  
end;


So in etwa (nicht getestet, da ich eine andere RS232 Komponente nutze)

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 10:06 
Danke schn.

Hm.. .sehr seltsam, aber ich komme glaub ich dank dir dem Problem näher:

Er zerstückelt immer noch, aber ands:

wenn ich das "showMessage" weglasse (nur über das label aberbeitend), so bleibt alles beim alten, er zeigt mir nur den letzten 8-Byte-Block
Wenn ich es lasse, so zerstückelt er es einfach in den dersten 8-Byte-Block plus den Rest.

Der code sieht ziemlich so aus, wie du ihn vorgeschlagen hast, muß ihn glaubi ch also nicht neu hier rein setzten.

Mir fällt nur grad ein, ich könnte versuchen, das ganze über ne weitere for-schleife laufen zu lassen "Sertze i = 0; Bis 's' 8 Zeichen hat, durchlaufe diese schleife, dann setzte s in stringar[i]. Wenn i = 4 breche schliefe ab, und setzte
string SX := Stringar[0] + Stringar[1] + Stringar[2] + Stringar[3]"

was meisnt du, wär das gut? Oder gibts da was eleganteres?

Lieben Gruß

Smartie
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 11:22 
sry, aus Versehen "aktualisieren" gedrückt !

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 11:34 
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:
//globale variable  
RS232Active : Boolean;
tempBuffer     : String;   //als temporärer Buffer
        

 
//im OnCreate der Form  
RS232Active := False;  
//Einen Timer einfügen in dem nach 2 Sekunden (2000 im Interval eintragen)   
procedure TForm1.Timer1Timer(Sender: TObject);  
begin  
  RS232Active := False;  
  showmessage(tempBuffer); //einmal das empfangene ausgeben oder
                           //etwas Anderes damit machen
  tempBuffer      := '';   //und wieder Löschen, um den nächsten String 
                           //empfangen zu können
end;  

 

 
procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);    
  {Event OnTriggerAvail - Example how OnTriggerAvail works}    
var    
  I : Word;    
  C : Char;    
  S : String;    
begin    
  RS232Active := True;  
  Timer1.enabled := False; // Timer neustarten !!  
  Timer1.enabled := True;  
  S := '';    
  for I := 1 to Count do begin    
    C := ApdComPort1.GetChar;    
    case C of    
      #0..#31 : {Don't display} ;    
      else S := S + C;    
    end;    
  end;    
  Label1.Caption := S;    
  tempBuffer := tempBuffer + S; //empfangene Zeichen hinzufügen
//  ShowMessage('Got an OnTriggerAvail event for: ' + S + 'count= '+ Count);    
end;

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 12:23 
Ok, wir sind fast da *g*

also, ich hab zwar no n Bischen rumgespielt, mit String und buffer, aber hat nicht sooo viel genutzt. Also, bei dershowmessage zeigt er interessanter weise den tatsächlich übersendeten string komplett. nur im label zeigt ers nicht.

das mit meiner schleife hat übrigens nicht ganz so funktioniert wie es sollte, irgendwie hat er ein Problem damit, eine prozedur in der schleife zu haben.

Lieben Gruß

Smartie
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 13:06 
Hallo,

ich hab da noch ein wenig mit meienr Schleifenlösung gespielt, und hab da folgendes gemacht:

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:
interface

uses
  WinTypes, WinProcs, SysUtils, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, AdPort, OoMisc, ExtCtrls;


type
  TForm1 = class(TForm)
    ApdComPort1: TApdComPort;
    Test: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Timer1: TTimer;
    procedure TestClick(Sender: TObject);
    procedure ApdComPort1TriggerAvail(CP: TObject; Count: Word);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  var RS232Activate : Boolean;
      j: integer = 1;
      sar : Array[0..3] of String;
      XS: String;

implementation

{$R *.DFM}


procedure TForm1.TestClick(Sender: TObject);
  {Button Click - Send Output}
begin
  ApdComPort1.OutPut := ' Schick mir was';
end;

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
  {Event OnTriggerAvail - Example how OnTriggerAvail works}
var
  I : Word;
  C : Char;
  S : String;
begin

  RS232Activate := True;   
  Timer1.enabled := False; //Neustart des Timers!!
  Timer1.enabled := True;  // timer auf True setzten
  S := '';
 repeat// probieren wir das repeat hier
  repeat //for I := 1 to Count do begin //hab ich durch repeat ersetzt
    C := ApdComPort1.GetChar;
    case C of
      #0..#31 : {Don't display} ;
      else S := S + C;
    end; //of case

  until length(s) = 8; //end; {of for}
 sar[j] := s;
 j := j +1;
 ShowMessage('Got an OnTriggerAvail event for: ' + S); //hab ich probiert, hat keinen
                                                       //wirklichen einfluß
 until j = 4;    // repeat bis hier
 xs := sar[0] + sar[1] + sar[2] + sar[3];

  //Form1.Label5.Caption := InttoStr(d);
  Form1.Label1.Caption := xS;
  //interpret(S);
  ShowMessage('Got an OnTriggerAvail event for: ' + xS);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
 RS232Activate := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  RS232Activate := False;
end;

end.


Aber da brignt er richtig "schöne" Fehlermeldungen (Buffer ist empty)
Kann ich da was machen, oder ist diese Idde zur Problemlösung ohnehin Müll, und ich habs einfach nicht bemerkt?

Lieben Gruß und Danke

Smartie

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 13:16 
OK, den label hab ich bisher nicht betrachtet !


hier der code um das richtige in den Label zu bekommen:

ersetze "showmessage(tempBuffer)" durch "Label1.Caption := tempBuffer"

Jetzt sollte im Label das Richtige stehen !


Chris

(Vielen Dank für Deine PN :roll: )

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 13:22 
Hi,

hatte ich schon probiert, da kmmt NUr der letzte Block bei raus.

Fand ich auch seltsam, aber irgednwie scheint die showmessage irgendwie auf das programm zu wirken, frag mich nicht wie.

lieben Gruß

smartie
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 13:29 
Du musst natürlich die Zeile "Label1.Caption := S; " Löschen bzw. als
Remark (//) markieren, ansonsten wird es ja immer wieder überschrieben !

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
chrisw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 439
Erhaltene Danke: 3

W2K
D7
BeitragVerfasst: Di 19.04.05 13:31 
Grundsätzlich würde ich aber ein MemoFeld(TMemo) anstatt des Labels benutzen und dann immer nur die empfangenen Zeichen anhängen (Memo1.Text := Memo1.text +S).
Dann müssen aber die Steuerzeichen für Carriage return (#13) und Linefeed(#10) auch durchgelassen werden, ansonsten steht alles in einer Zeile

Chris

_________________
Man sollte keine Dummheit zweimal begehen, die Auswahl ist schließlich groß genug.
Smartie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 205



BeitragVerfasst: Di 19.04.05 13:37 
Ok, super, danke!
Ich mußte nur den befehl tempBuffer := ''; auch rauswerfen, denn sosnt gäbs den string immer nur für die voreingestellten 2 sekunden. der nachteil nur, ich kann keine zweidateinen hintereinander absenden, ist aber nicht so wild, da ich eh mit nur dieser einen datei arbeiten muß.
interpretieren von daten etc.

also nicht wundern, wenn ich bald mal auch fragen zu konvertierung und auslesen sowie erstellen vin ini-dateien stelle :D

Danke nochmal und lieben Gruß

Smartie