Autor Beitrag
ibh_compucat
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win 2000, Win 8.1
D6, Ent. XE5 Ent.
BeitragVerfasst: Fr 04.01.08 16:33 
Hallo,

ich habe eine Kommunikation über RS232 mit AsyncPro aufgebaut (Com1) und frage einen Messwertgeber zyklisch ab, z.B. alle 100 ms. Und der antwortet auch mit einem Messwert.
Das funktioniert und ich habe einen (relativ) aktuellen Wert.
Nach wenigen Sekunden hört allerdings der Empfang auf, Messwertanforderung und Antwort kommen nach wie vor. Das habe ich mit einem Oszilloskop überprüft. Aber es wird kein Trigger Avail Ereignis mehr ausgelöst.
Ich knabbere nun schon seit einer Woche an dem Problem, deshalb meine herzliche Bitte: kann mir jemand weiterhelfen?

Gruß ibh_compucat

_________________
Was du nicht begreifst, kannst du nicht verlernen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 04.01.08 16:38 
Moin!

Zeig mal ein Stück Code, das läuft sonst auf Hellsehen hinaus... :?

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
ibh_compucat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win 2000, Win 8.1
D6, Ent. XE5 Ent.
BeitragVerfasst: Fr 04.01.08 16:59 
Hallo,

der Quellcode ist simpel:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
// 1. Messwertanforderung, der Timer steht z.B. auf 100 ms:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  ApdComPort1.OutPut := #2'0001'#3// Anforderungsstring = funktioniert immer, auch wenn keine Rückmeldung mehr kommt.
end;

// 2. Empfang der Daten:

procedure TForm1.ApdDataPacket1StringPacket(Sender: TObject; Data: String);
  var
  HS
      : String;
begin
  HS := Data;
  HS := copy(HS , 29);
  Form1.Label1.Caption := HS;
end;



wenn ich den Timer langsamer stelle, dann dauert es länger, bis der Messwert nicht mehr aktualisiert wird. Deshalb vermute ich, daß irgendein Buffer mit jedem empfangenen Packet gefüllt wird und irgendwann überläuft?

Gruß ibh_compucat

_________________
Was du nicht begreifst, kannst du nicht verlernen!


Zuletzt bearbeitet von ibh_compucat am Fr 04.01.08 17:11, insgesamt 1-mal bearbeitet
Mitmischer 1703
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 754
Erhaltene Danke: 19

Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
BeitragVerfasst: Fr 04.01.08 17:05 
Delphi-Tags einfügen :wink:!

_________________
Die Lösung ist nicht siebzehn.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 04.01.08 17:22 
Moin!

user profile iconibh_compucat hat folgendes geschrieben:
wenn ich den Timer langsamer stelle, dann dauert es länger, bis der Messwert nicht mehr aktualisiert wird.
Kommt denn im Fehlerfall eine Meldung oder sonstige Reaktion? Ist das Programm an sich noch bedienbar? Wenn du noch einen zusätzlichen Button auf´s Formular packst, der einfach nur ein ShowMessage() ausführt, und den anklickst, wenn keine Daten mehr von der Kompo kommen, wird dann die MessageBox angezeigt?

user profile iconibh_compucat hat folgendes geschrieben:
Deshalb vermute ich, daß irgendein Buffer mit jedem empfangenen Packet gefüllt wird und irgendwann überläuft?
Naja, 100ms sind nicht gerade lange, vielleicht läuft die MessageQueue über? :gruebel: Aber das zeigt der Test oben. :idea: Würde mich aber wundern, 100ms halte ich für machbar.

Schonmal drüber nachgedacht, das ganze in einen Thread auszulagern und nur die Anzeige zu synchronisieren? :nixweiss:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
ibh_compucat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win 2000, Win 8.1
D6, Ent. XE5 Ent.
BeitragVerfasst: Fr 04.01.08 17:39 
Hallo narses,

nein, es kommt keine Reaktion und das Programm ist weiterhin bedienbar. Ich habe mal so ein so ein APD.LOG File erzeugen lassen und da sieht man, wie zum Fehlerzeitpunkt nur noch Messwertanforderungen rausgehen, aber nichts mehr empfangen wird (obwohl die Telegramme ankommen).

Einen separaten Thread habe ich noch nie gemacht, ist das umfangreich?

Gruß ibh_compucat

_________________
Was du nicht begreifst, kannst du nicht verlernen!
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Fr 04.01.08 17:59 
Also, wenn ich Daten sende, und darauf eine Antwort erwarte, hab ich das meist so gemacht:

- Daten senden
- warten, bis die Gegenstelle die Daten verarbeitet hat (also x ms, muss man ausprobieren)
- Daten empfangen:
ausblenden Delphi-Quelltext
1:
2:
while ApdComPort1.CharReady do
  Buffer := Buffer + ApdComPort1.Getchar;

d.h. ich verlass mich gar nicht auf irgendwelche Trigger o.ä.
Jedenfalls hat mich diese Methode noch nie im Stich gelassen ;)
Die Timeout Bedingung in der While-Schleife hab ich nun der Einfachheit halber mal weggelassen, kann ich bei Bedarf nachreichen.

Edit: Hier das Tool (Portmon) könnte für dich vielleicht interessant sein - ist ein Sniffer für die serielle Schnittstelle, zeigt also genau an, was auf der Schnittstelle passiert:
technet.microsoft.co...bb896644(en-us).aspx

Edit2: Argh, hier das Forum stört sich an den Klammern in der URL, deswegen geht kein Link, sorry :( Musst du wohl per Hand kopieren.
ibh_compucat Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 130

Win 2000, Win 8.1
D6, Ent. XE5 Ent.
BeitragVerfasst: Fr 04.01.08 19:25 
Hallo Xentar,

danke für die Tipps, ich habe mir den Portemon heruntergeladen und der sagt mir, daß ein Fehler mit Stoppbit vorliegt. Stand auf 2 und habe ich nun auf 1 reduziert, dann hat Portemon nicht mehr gemeckert aber das Ergebnis ist das gleiche. Ich habe auch Deinen Code testweise bei mir eingebaut: nach wenigen Sekunden reißt die Kommunikation ab bzw. es wird empfangseitig nichts mehr erkannt oder entgegengenommen, so wie zuvor.
Das verrückte ist, daß die ersten 2 - 3 Sekunden alles wunderbar läuft.

Gruß ibh_compucat

_________________
Was du nicht begreifst, kannst du nicht verlernen!
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Fr 04.01.08 19:40 
Was du noch ausprobieren könntest:
Bau mal in dem Timer, vor dem Senden der Anfrage folgendes
ausblenden Delphi-Quelltext
1:
2:
ApdComPort.FlushInBuffer;
ApdComPort.FlushOutBuffer;

Damit sollten die Puffer der Schnittstelle geleert werden, vllt. hilft es ja.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 04.01.08 19:53 
Moin!

Hm, lass das mal mit dem ereignisgesteuerten Empfang. Probier das mal mit einem Thread. Ich habe dir mal hier ein Beispiel gebastelt (es kompiliert und "läuft" bei mir, ich habe eben nur nicht AsyncPro installiert :?). Das Prinzip sollte damit aber klar sein: :idea:
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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  TApdComPort = class(TObject)
  public
    function CharReady: Boolean;
    function GetChar: Char;
  end;

  TComListener = class(TThread)
  private
    FApdComPort: TApdComPort;
    FBuffer: String;
    FOnReceive: TNotifyEvent;
  protected
    procedure DoNotify;
  public
    constructor Create(AApdComPort: TApdComPort; const AOnReceive: TNotifyEvent = NIL);
    procedure Execute; override;
    property OnReceive: TNotifyEvent read FOnReceive write FOnReceive;
    property Buffer: String read FBuffer;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure ComReceive(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    ApdComPort1: TApdComPort;
    ComListener: TComListener;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TComListener }

constructor TComListener.Create;
begin
  inherited Create(FALSE);
  FreeOnTerminate := TRUE;
  FApdComPort := AApdComPort;
  FOnReceive := AOnReceive;
end;

procedure TComListener.Execute;
begin
  while NOT Terminated do begin
    FBuffer := '';
    while FApdComPort.CharReady do
      FBuffer := FBuffer + FApdComPort.Getchar;
    if (FBuffer <> ''then begin
      if Assigned(FOnReceive) then
        Synchronize(DoNotify);
    end
    else
      Sleep(10); // 10ms Pause
  end;
end;

procedure TComListener.DoNotify;
begin
  FOnReceive(Self);
end;

{ TApdComPort }

function TApdComPort.CharReady: Boolean;
begin
  Result := False;
end;

function TApdComPort.GetChar: Char;
begin
  Result := #0;
end;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  ApdComPort1 := TApdComPort.Create;
  ComListener := TComListener.Create(ApdComPort1,ComReceive);
end;

procedure TForm1.ComReceive(Sender: TObject);
begin
  ShowMessage((Sender as TComListener).Buffer);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ComListener.Terminate;
  ApdComPort1.Free;
end;

end.

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.