Board index » delphi » Newbie question about length

Newbie question about length


2004-09-02 08:38:38 PM
delphi254
Hi people,
I'm using TdTCPClient to implement some function of MODBUS TCP/IP protocol.
This is my code:
var
Cad,TX,RX: AnsiString; N: LongWord;
begin
try
clitCP.Connect;
TX := '';
TX := TX + Char($85); // Identificador del Mensaje
TX := TX + Char($87); // Identificador del mensaje
TX := TX + Char($00); // Tipo de protocolo
TX := TX + Char($00); // Tipo de protocolo
TX := TX + Char($00); // Longitud de la petición
TX := TX + Char($06); // Longitud de la petición
TX := TX + Char($01); // Dirección del esclavo
TX := TX + Char($03); // Codigo de función Modbus : Lectura de registros
TX := TX + Char($00);
TX := TX + Char($00);
TX := TX + Char($00);
TX := TX + Char($0A);
clitCP.Write(TX);
N := 0;
RX := '';
repeat
RX := RX +{*word*18}CP.ReadChar; Inc(N);
until N = 29;
Cad := '';
for N := 1 to Length(RX) do
begin
Cad := Cad+'$'+IntToHex(Ord(RX[N]),2);
end;
LBxRebudes.Items.Add(Cad);
finally
clitCP.Disconnect;
end;
Aftier Cli.Write how can i know the number of bytes received? I mean I'm
going to receive different lenght messages.
Thx
 
 

Re:Newbie question about length

"Carlos Sal" <XXXX@XXXXX.COM>writes
Quote
TX := '';
TX := TX + Char($85); // Identificador del Mensaje
TX := TX + Char($87); // Identificador del mensaje
TX := TX + Char($00); // Tipo de protocolo
TX := TX + Char($00); // Tipo de protocolo
TX := TX + Char($00); // Longitud de la petición
TX := TX + Char($06); // Longitud de la petición
TX := TX + Char($01); // Dirección del esclavo
TX := TX + Char($03); // Codigo de función Modbus : Lectura de
registros
TX := TX + Char($00);
TX := TX + Char($00);
TX := TX + Char($00);
TX := TX + Char($0A);
clitCP.Write(TX);
That is a very poor way to handle the data. It is not very efficient. You
should use records instead:
type
MBAPHeader = packed record
TransactionId: Word;
ProtocolId: Word;
DataLength: Word;
UnitId: Byte;
end;
var
Header: MBAPHeader;
begin
//...
Header.TransactionId := 34693;
Header.ProtocolId := 0;
Header.DataLength := 6;
Header.UnitID := 1;
clitCP.WriteBuffer(@Header, SizeOf(Header));
clitCP.WriteChar($03);
clitCP.WriteInteger($0A, False);
//...
end;
Quote
N := 0;
RX := '';
repeat
RX := RX +{*word*18}CP.ReadChar; Inc(N);
until N = 29;
That is a poor way to read the data back. You should use ReadString()
instead:
RX :={*word*18}CP.ReadString(29);
Better yet, you should use the same record as shown above.
Quote
Aftier Cli.Write how can i know the number of bytes received?
I'm going to receive different lenght messages.
That is not how Modbus works. You are supposed to read the fixed-sized
Header first, and then read how many remaining bytes it specifies. For
example:
var
Header: MBAPHeader;
Buffer: PByte;
begin
//...
clitCP.ReadBuffer(@Header, SizeOf(Header));
GetMem(Buffer, Header.DataLength-1);
clitCP.ReadBuffer(Buffer^, Header.DataLength-1);
// use Header and Buffer as needed...
FreeMem(Buffer);
end;
I suggest you go to www.modbus.org and download the ModBus spec if
you have not already done so.
Gambit
 

Re:Newbie question about length

Thx Remy..., Schneider guys didn't give me this useful information.
"Remy Lebeau (TeamB)" <XXXX@XXXXX.COM>escribi?en el mensaje
Quote

"Carlos Sal" <XXXX@XXXXX.COM>writes
news:41371437$XXXX@XXXXX.COM...

>TX := '';
>TX := TX + Char($85); // Identificador del Mensaje
>TX := TX + Char($87); // Identificador del mensaje
>TX := TX + Char($00); // Tipo de protocolo
>TX := TX + Char($00); // Tipo de protocolo
>TX := TX + Char($00); // Longitud de la petición
>TX := TX + Char($06); // Longitud de la petición
>TX := TX + Char($01); // Dirección del esclavo
>TX := TX + Char($03); // Codigo de función Modbus : Lectura de
registros
>TX := TX + Char($00);
>TX := TX + Char($00);
>TX := TX + Char($00);
>TX := TX + Char($0A);
>clitCP.Write(TX);

That is a very poor way to handle the data. It is not very efficient.
You
should use records instead:

type
MBAPHeader = packed record
TransactionId: Word;
ProtocolId: Word;
DataLength: Word;
UnitId: Byte;
end;

var
Header: MBAPHeader;
begin
//...
Header.TransactionId := 34693;
Header.ProtocolId := 0;
Header.DataLength := 6;
Header.UnitID := 1;
clitCP.WriteBuffer(@Header, SizeOf(Header));
clitCP.WriteChar($03);
clitCP.WriteInteger($0A, False);
//...
end;

>N := 0;
>RX := '';
>repeat
>RX := RX +{*word*18}CP.ReadChar; Inc(N);
>until N = 29;

That is a poor way to read the data back. You should use ReadString()
instead:

RX :={*word*18}CP.ReadString(29);

Better yet, you should use the same record as shown above.

>Aftier Cli.Write how can i know the number of bytes received?
>I'm going to receive different lenght messages.

That is not how Modbus works. You are supposed to read the fixed-sized
Header first, and then read how many remaining bytes it specifies. For
example:

var
Header: MBAPHeader;
Buffer: PByte;
begin
//...
clitCP.ReadBuffer(@Header, SizeOf(Header));
GetMem(Buffer, Header.DataLength-1);
clitCP.ReadBuffer(Buffer^, Header.DataLength-1);
// use Header and Buffer as needed...
FreeMem(Buffer);
end;

I suggest you go to www.modbus.org and download the ModBus spec if
you have not already done so.


Gambit