Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Bytes aus Comport lesen (https://www.delphipraxis.net/166671-bytes-aus-comport-lesen.html)

giantdwarf 24. Feb 2012 09:18

Bytes aus Comport lesen
 
Hallo zusammen,

mithilfe der ComPort Library versuche ich gerade einen Kommunikation per ccTALK Protokoll mit dem COM Port aufzubauen (delphi2009).
Dafür schreibe ich einen einfachen Poll Befehl. Im OnRxCharEvent lese ich die ankommenden Bytes. Aber die Antwort stimmt nicht mit der Erwarteten überein.
Ich habe inzwischen erfahren, dass das Gerät immer die gesendeten Bytes als Echo zurückschickt und dann erst die eigentliche Antwort.
Ich erhalte aber immer nur 5 Bytes zurück, und das sind meines Erachtens nicht die gesendeten.
Hat irgendjemand eine Idee was ich falsch mache oder übersehen haben??

Delphi-Quellcode:
unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, CPort, StdCtrls;

type
   TForm1 = class(TForm)
      Button1: TButton;
      Memo1: TMemo;
      ComPort1: TComPort;
      procedure Button1Click(Sender: TObject);
      procedure ComPort1RxChar(Sender: TObject; Count: Integer);
      procedure FormClose(Sender: TObject; var Action: TCloseAction);
   private
      { Private-Deklarationen }
   public
      { Public-Deklarationen }
   end;

const  
   Binaer: array[0..255] of string = ('#0', '#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', '#109',
      '#110', '#111', '#112', '#113', '#114', '#115', '#116', '#117', '#118', '#119',
      '#120', '#121', '#122', '#123', '#124', '#125', '#126', '#127', '#128', '#129',
      '#130', '#131', '#132', '#133', '#134', '#135', '#136', '#137', '#138', '#139',
      '#140', '#141', '#142', '#143', '#144', '#145', '#146', '#147', '#148', '#149',
      '#150', '#151', '#152', '#153', '#154', '#155', '#156', '#157', '#158', '#159',                   
      '#160', '#161', '#162', '#163', '#164', '#165', '#166', '#167', '#168', '#169',
      '#170', '#171', '#172', '#173', '#174', '#175', '#176', '#177', '#178', '#179',
      '#180', '#181', '#182', '#183', '#184', '#185', '#186', '#187', '#188', '#189',
      '#190', '#191', '#192', '#193', '#194', '#195', '#196', '#197', '#198', '#199',
      '#200', '#201', '#202', '#203', '#204', '#205', '#206', '#207', '#208', '#209',
      '#210', '#211', '#212', '#213', '#214', '#215', '#216', '#217', '#218', '#219',
      '#220', '#221', '#222', '#223', '#224', '#225', '#226', '#227', '#228', '#229',
      '#230', '#231', '#232', '#233', '#234', '#235', '#236', '#237', '#238', '#239',
      '#240', '#241', '#242', '#243', '#244', '#245', '#246', '#247', '#248', '#249',
      '#250', '#251', '#252', '#253', '#254', '#255');
     
var                          
   Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   Buff: array of Byte;
   i: Integer;
   sSend: String;

begin

   //ComPort initialisieren
   ComPort1.BaudRate := br9600;
   ComPort1.DataBits := dbEight;
   ComPort1.StopBits := sbOneStopBit;
   ComPort1.Parity.Bits := prNone;
   ComPort1.FlowControl.FlowControl := fcNone;
   ComPort1.Port := 'COM16';
   if not ComPort1.connected then
      ComPort1.Open;

   SetLength(Buff, 5);
   Buff[0] := 2;
   Buff[1] := 0;
   Buff[2] := 1;
   Buff[3] := 254;
   Buff[4] := 255;      //ccTalk Polling Befehl
   for i := 0 to 4 do
      sSend := sSend + Binaer[Buff[i]];
   Memo1.Lines.Clear;
   sSend := 'Sende: ' + sSend;
   Memo1.Lines.Add(sSend);

   //Befehl an Comport senden
   ComPort1.ClearBuffer(True, True); //sicherheitshalber
   ComPort1.Write(Buff, 5);

end;

procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
   Buff: array of Byte;
   ComStream: TComStream;
   sReceive: String;
   i: Integer;
begin
   if Count > 0 then
   begin

      ComStream := TComStream.Create(ComPort1);
      try
         SetLength(Buff, Count);
         //Ankommende Bytes lesen
         ComStream.Read(Buff[0], Count);
         for i := 0 to Count-1 do
            sReceive := sReceive + Binaer[Buff[i]];
         sReceive := 'Lese: ' + sReceive;  
         Memo1.Lines.Add(sReceive);  
      finally      
         ComStream.Free;
      end;
   end;
   
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   if ComPort1.Connected then
      ComPort1.Close;
end;

end.
Delphi-Quellcode:
  object ComPort1: TComPort
    BaudRate = br9600
    Port = 'COM1'
    Parity.Bits = prNone
    StopBits = sbOneStopBit
    DataBits = dbEight
    Events = [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full]
    FlowControl.OutCTSFlow = False
    FlowControl.OutDSRFlow = False
    FlowControl.ControlDTR = dtrDisable
    FlowControl.ControlRTS = rtsDisable
    FlowControl.XonXoffOut = False
    FlowControl.XonXoffIn = False
    StoredProps = [spBasic]
    TriggersOnRxChar = True
    OnRxChar = ComPort1RxChar
    Left = 72
    Top = 104
  end

Bummi 24. Feb 2012 09:36

AW: Bytes aus Comport lesen
 
Du kannst die Antwort auch per
Delphi-Quellcode:
    ReadStr(s,Count);
    FInBuffer := FInBuffer + s;
auslesen, wobei s und FInBuffer AnsiStrings sind, die Antwort kann in mehreren Portionen kommen daher FInBuffer
Wenn die Daten nicht passen solltest Du Baudrate, Databits, Stopbits und Baudrate überprüfen.

NickelM 24. Feb 2012 12:22

AW: Bytes aus Comport lesen
 
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   Buff: array of Byte;
   i: Integer;
   sSend: String;

begin
   //ComPort initialisieren
   ComPort1.BaudRate := br9600;
   ComPort1.DataBits := dbEight;
   ComPort1.StopBits := sbOneStopBit;
   ComPort1.Parity.Bits := prNone;
   ComPort1.FlowControl.FlowControl := fcNone;
   ComPort1.Port := 'COM16';
   if not ComPort1.connected then
      ComPort1.Open;

   SetLength(Buff, 5);
   Buff[0] := 2;
   Buff[1] := 0;
   Buff[2] := 1;
   Buff[3] := 254;
   Buff[4] := 255; //ccTalk Polling Befehl
   for i := 0 to 4 do
      sSend := sSend + Binaer[Buff[i]];
   Memo1.Lines.Clear;
   sSend := 'Sende: ' + sSend;
   Memo1.Lines.Add(sSend);

   //Befehl an Comport senden
   ComPort1.ClearBuffer(True, True); //sicherheitshalber
   ComPort1.Write(Buff[0], 5); //Du musst bei Array immer wie beim schreiben wie auch beim Lesen Array[0] sagen. Bei Dynamischen Arrays ist Buff ein Pointer, wo der dynamische Array im Speicher liegt, nicht die Daten.

end;

shmia 24. Feb 2012 13:03

AW: Bytes aus Comport lesen
 
Man kann und sollte auch direkt mit AnsiStrings arbeiten; dann entfällt dieses mühsehlige Rumgemache mit "buff" und "binaer".

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
   sSend: AnsiString;
begin
   if not ComPort1.connected then
   begin
     //ComPort initialisieren
     ComPort1.BaudRate := br9600;
     ComPort1.DataBits := dbEight;
     ComPort1.StopBits := sbOneStopBit;
     ComPort1.Parity.Bits := prNone;
     ComPort1.FlowControl.FlowControl := fcNone;
     ComPort1.Port := 'COM16';
     ComPort1.Open;
   end;


   sSend := #2#0#1#254#255; //ccTalk Polling Befehl
   // Hinweis: das letzte Byte ist die Prüfsummer bei ccTalk
   // eigentlich müsste diese berechnet werden

   Memo1.Lines.Clear;
   Memo1.Lines.Add('Sende: 'sSend);

   //Befehl an Comport senden
   ComPort1.ClearBuffer(True, True); //sicherheitshalber
   ComPort1.Write(sSend[1], Length(sSend));
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz