Autor Beitrag
Rupert
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47
Erhaltene Danke: 1

Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
BeitragVerfasst: 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:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
    CommPortDriver1.CheckLineStatus:=true;
    CommPortDriver1.PacketMode:=pmDiscard; // default
    CommPortDriver1.InBufSize:=2048;
    CommPortDriver1.OutBufSize:=2048;
    CommPortDriver1.connect;
    CommPortDriver1.FlushBuffers( true,true);  // Beide SS-Speicher leeren
    if CommPortDriver1.connected then begin


Schritt 2:
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:
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);  // create new file
    while DataSize > 0 do begin
      Bytemenge_txt.caption:='   '+inttostr(datasize);
      Bytemenge_txt.refresh;
      sleep(20);
      CommPortDriver1.PausePolling; // Abfrage Stopp

      nToRead :=CommPortDriver1.CountRX;//Anzahl der zu empfangenen Bytes
      Setlength(msg,nToRead);//msg an die Bytelänge anpassen
      bytes_gelesen := CommPortDriver1.ReadData(pchar(msg),nToRead);//Daten nach msg kopieren

      CommPortDriver1.FlushBuffers( true,false);//Empfangsspeicher leeren
      CommPortDriver1.ContinuePolling;//Abfrage start

      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);  // close file

end;

_________________
Grüße Rupert
glotzer
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: So 14.11.10 20:55 
idee zur unschönen lösung:
64 byts müll senden, dann mit daten anfangen
Rupert Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47
Erhaltene Danke: 1

Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19341
Erhaltene Danke: 1752

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 47
Erhaltene Danke: 1

Netware, Linux, WIN A-Z, DOS
Delphi 2005- Delphi 2009
BeitragVerfasst: 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...

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:
{ ***********************************************************
                   Lies File - der Filename wird übergeben
  ***********************************************************}


procedure TFormMain.Readfile(AFileName: string);
var
  i    :integer;
  f    :file;
  pBuf :pointer;
  Buf  :array [0..65565of 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);  // create the file
      repeat
        sleep(64);   // warten bis sich der Buffer "erhohlt"
        CommPortDriver1.PausePolling;
        zulesen :=CommPortDriver1.CountRX;//Anzahl der zu empfangenen Bytes
        bytes_gelesen := CommPortDriver1.ReadData(pbuf,zulesen);//Daten nach msg kopieren

        BlockWrite(f,Buf,bytes_gelesen);  // write data
        memo1.SetSelTextBuf(pbuf);        // im Memo-Block anzeigen

        CommPortDriver1.FlushBuffers( true,false);//Empfangsspeicher leeren
        CommPortDriver1.ContinuePolling;//Wieder auf Empfang gehen
      until bytes_gelesen <= 0;
      CloseFile(f);  // close file
    end;
  end;
end;


...und damit der Thread komplett ist und andere auch was davon haben, hier auch das Senden eines Files

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:
{ ***********************************************************
                        Sende File
  ***********************************************************}


procedure TFormMain.SendFile(AFileName: string);
var
var
  i    :integer;
  f    :file;
  pBuf :pointer;
  Buf  :array [0..65565of 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// standardmenge

  while (not EOF(f)) do begin
    BlockRead(f,Buf,BytesSend,zusenden);  // zusenden ist die tats. Bytemenge
    CommPortDriver1. SendData (pBuf,zusenden); // zusenden, weil der letzte Block sicher nicht voll ist
    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