| Autor |
Beitrag |
Rupert
      
Beiträge: 47
Erhaltene Danke: 1
Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
|
Verfasst: So 14.11.10 20:52
Hi Miteinander!
Nachdem ich mich nun den ganzen Sonntag ohne Erfolgserlebnis gequält habe und sogar den F1-Grand Prix ausgelassen habe, poste ich hier mein Problem.
Hardwaretest:
Die Datenverbindung zwischen Sender unf Empfänger habe ich mittels Hyperterminal getestet. Hier werden alle Datenbytes übertragen.
Die Einstellungen sind 19200,N,8,1 RTS/CTS.
Methode:
Über das Ereignis Onreceivedata wird die Routine CommPortDriver1ReceiveData abgespult. Zuvor wird über einen Startbutton das Programm auf die Daten vorbereitet. (Schritt 1)
Sobald das sendende Gerät Daten schickt wird Onreceivedata ausgelöst (Schritt 2)und die empfangenen Bytes im Memo-Feld aufgelistet.
Symthom:
Ich verliere die ersten 64 Bytes, als kämen Sie nicht an. Dabei ist es egal, ob ich zuerst Die Daten Sende und meine Software wartet, oder ich die Software warten lasse und dann zu senden beginne. Sende ich z.B. nur 15 Zeichen, dann kommt in der SW gar nichts an.
Es sieht so aus, als würden diese Daten "verschluckt"
Diese Daten versende ich
| Zitat: | no services pad
service timestamps debug uptime
service timestamps log uptime
no service password-encryption
!
hostname |
und diese kommen an
| Zitat: | s debug uptime
service timestamps log uptime
no service password-encryption
!
hostname |
Vielleicht hat jemand eine Ahnung, oder sieht den Fehler weshalb die Daten verloren gehen ....
lg
Rupert
Schritt 1:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| CommPortDriver1.CheckLineStatus:=true; CommPortDriver1.PacketMode:=pmDiscard; CommPortDriver1.InBufSize:=2048; CommPortDriver1.OutBufSize:=2048; CommPortDriver1.connect; CommPortDriver1.FlushBuffers( true,true); if CommPortDriver1.connected then begin |
Schritt 2:
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:
| procedure TFormMain.CommPortDriver1ReceiveData(Sender: TObject; DataPtr: Pointer; DataSize: Cardinal); var i,check : integer; Afilename:String; nToRead : UINT;
begin Afilename:=FileListBox1.Directory+'\'+Dateiname1.Text; AssignFile(f,Afilename);
Rewrite(f,1); while DataSize > 0 do begin Bytemenge_txt.caption:=' '+inttostr(datasize); Bytemenge_txt.refresh; sleep(20); CommPortDriver1.PausePolling; nToRead :=CommPortDriver1.CountRX; Setlength(msg,nToRead); bytes_gelesen := CommPortDriver1.ReadData(pchar(msg),nToRead); CommPortDriver1.FlushBuffers( true,false); CommPortDriver1.ContinuePolling; For i := 1 to bytes_gelesen do BlockWrite(f,msg[i],1); Memo1.Lines.Add(msg); if bytes_gelesen=0 then Datasize:=0; DataSize:=DataSize-bytes_gelesen; end;
CloseFile(f); end; |
_________________ Grüße Rupert
|
|
glotzer
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: So 14.11.10 20:55
idee zur unschönen lösung:
64 byts müll senden, dann mit daten anfangen
|
|
Rupert 
      
Beiträge: 47
Erhaltene Danke: 1
Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
|
Verfasst: So 14.11.10 20:57
Wenns so einfach wär...
Die Daten , die (wenns funktioniert) zu empfangen sind, sind CNC-Programme.
Wenn ich übrigens gleich nochmals sende, fehlen "nur" 22!
_________________ Grüße Rupert
|
|
jaenicke
      
Beiträge: 19341
Erhaltene Danke: 1752
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 14.11.10 21:12
Also wenn ich so den Quelltext von TCommPortDriver anschaue... Naja...
Nimm einfach einmal diese Komponente:
sourceforge.net/projects/comport/
Im Gegensatz zu der, die du benutzt, pollt die nicht nur (via Timer in diesem Fall), sondern benutzt die Warte-Routinen von Windows. Ich selbst benutze zum Zugriff auf den COM-Port auch WaitForMultipleObjects. Damit kannst du einmal auf ein COM-Event und andererseits auf einen Abbruch (beim Beenden des Programms bzw. des Lauschens) warten.
Ich habe jetzt nicht so viel Lust mir genauer anzuschauen was da passiert. Aber ich vermute das Problem innerhalb der Komponente, so dass es mit der neuen ohnehin erledigt sein dürfte.
|
|
Rupert 
      
Beiträge: 47
Erhaltene Danke: 1
Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
|
Verfasst: Mo 15.11.10 21:01
Wenn man auf das Ereignis OnReceiveData reagiert, dann fehlen tatsächlich immer einige Bytes.
Nachdem ich das Empfangen per Mausclick auslösen kann habe ich das Problem lösen können, indem ich auf das Ereignis verzichte.
Die Lösung ist eigentlcih ganz einfach...
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:
|
procedure TFormMain.Readfile(AFileName: string); var i :integer; f :file; pBuf :pointer; Buf :array [0..65565] of PAnsiChar; bytes_gelesen,zulesen :UINT;
begin CommPortDriver1.CheckLineStatus:=true; if not CommPortDriver1.Connected then begin messagebeep(MB_ICONEXCLAMATION); MessageDlg(CommPortDriver1.PortName+' ist offline',mtConfirmation,[mbOK],0) end; begin pBuf:=@Buf; begin; AssignFile(f,Afilename); Rewrite(f,1); repeat sleep(64); CommPortDriver1.PausePolling; zulesen :=CommPortDriver1.CountRX; bytes_gelesen := CommPortDriver1.ReadData(pbuf,zulesen); BlockWrite(f,Buf,bytes_gelesen); memo1.SetSelTextBuf(pbuf); CommPortDriver1.FlushBuffers( true,false); CommPortDriver1.ContinuePolling; until bytes_gelesen <= 0; CloseFile(f); end; end; end; |
...und damit der Thread komplett ist und andere auch was davon haben, hier auch das Senden eines Files
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:
|
procedure TFormMain.SendFile(AFileName: string); var var i :integer; f :file; pBuf :pointer; Buf :array [0..65565] of PAnsiChar; zusenden :UINT; BytesSend :Integer; begin CommPortDriver1.CheckLineStatus:=true; if not CommPortDriver1.Connected then begin messagebeep(MB_ICONEXCLAMATION); MessageDlg(CommPortDriver1.PortName+' ist offline',mtConfirmation,[mbOK],0) end; pBuf:=@Buf; AssignFile(f,AFileName); Reset(f,1); BytesSend := 2048; while (not EOF(f)) do begin BlockRead(f,Buf,BytesSend,zusenden); CommPortDriver1. SendData (pBuf,zusenden); CommPortDriver1.FlushBuffers( false,true); memo1.SetSelTextBuf(pbuf); memo1.Refresh; end; CloseFile(f); end; |
@jaenicke
Ich habe mir zwar den Cport Driver installiert, als ich aber sah, dass ich wieder alles umbauen muss (setup Dialog etc.) habe ich mich mit dieser Variante noch einmal auseinandergesetzt und das Problem lösen können - trotzdem vielen Dank...
_________________ Grüße Rupert
|
|
|