| Autor |
Beitrag |
ibh_compucat
      
Beiträge: 130
Win 2000, Win 8.1
D6, Ent. XE5 Ent.
|
Verfasst: 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
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: 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 
      
Beiträge: 130
Win 2000, Win 8.1
D6, Ent. XE5 Ent.
|
Verfasst: Fr 04.01.08 16:59
Hallo,
der Quellcode ist simpel:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Timer1Timer(Sender: TObject); begin ApdComPort1.OutPut := #2'0001'#3; end;
procedure TForm1.ApdDataPacket1StringPacket(Sender: TObject; Data: String); var HS : String; begin HS := Data; HS := copy(HS , 2, 9); 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
      
Beiträge: 754
Erhaltene Danke: 19
Win 7, Debian
Delphi Prism, Delphi 7, RAD Studio 2009 Academic, C#, C++, Java, HTML, PHP
|
Verfasst: Fr 04.01.08 17:05
Delphi-Tags einfügen  !
_________________ Die Lösung ist nicht siebzehn.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 04.01.08 17:22
Moin!
ibh_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?
ibh_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?  Aber das zeigt der Test oben.  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?
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
ibh_compucat 
      
Beiträge: 130
Win 2000, Win 8.1
D6, Ent. XE5 Ent.
|
Verfasst: 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
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: 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:
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 
      
Beiträge: 130
Win 2000, Win 8.1
D6, Ent. XE5 Ent.
|
Verfasst: 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
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: Fr 04.01.08 19:40
Was du noch ausprobieren könntest:
Bau mal in dem Timer, vor dem Senden der Anfrage folgendes
Delphi-Quelltext 1: 2:
| ApdComPort.FlushInBuffer; ApdComPort.FlushOutBuffer; |
Damit sollten die Puffer der Schnittstelle geleert werden, vllt. hilft es ja.
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: 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:
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 public ApdComPort1: TApdComPort; ComListener: TComListener; end;
var Form1: TForm1;
implementation
{$R *.dfm}
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); end; end;
procedure TComListener.DoNotify; begin FOnReceive(Self); end;
function TApdComPort.CharReady: Boolean; begin Result := False; end;
function TApdComPort.GetChar: Char; begin Result := #0; end;
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.
|
|
|