Search code examples
javadelphipascaldelphi-xe5modbus

Is "Word" from Delphi an equivalent variable to "Char" on Java?


In Delphi, a Word is a 16 bits unsigned variable (0..65535)

http://www.delphibasics.co.uk/RTL.asp?Name=Word

The char variable in Java is a 16 bit Unicode variable (0..65535)

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

I have the following code on Delphi

procedure TForm1.ReadHoldRegisters(var lst: TList<byte>; deviceaddr: byte;
  RegisterAddress, RegisterLength: word);
begin

  lst.Add(deviceaddr);
  lst.Add(3);
  lst.Add(RegisterAddress div 256);
  lst.Add(RegisterAddress mod 256);
  Add_CRC16(lst);
end;

procedure TForm1.Add_CRC16(var Data: TList<byte>);
var
  CRC16Lo, CRC16Hi, CL, CH, SaveHi, SaveLo: byte;
  Flag: Integer;
  b: byte;
begin
  CRC16Lo := $FF;
  CRC16Hi := $FF;
  CL := $1;
  CH := $A0;

  for b in Data do
  begin
    CRC16Lo := CRC16Lo Xor b;
    For Flag := 0 To 7 Do
    Begin
      SaveHi := CRC16Hi;
      SaveLo := CRC16Lo;
      CRC16Hi := CRC16Hi Div 2;
      CRC16Lo := CRC16Lo Div 2;

      If ((SaveLo And $1) = $1) Then
      Begin
        CRC16Hi := CRC16Hi Xor CH;
        CRC16Lo := CRC16Lo Xor CL;
      End;



    End;
  end;
  Data.Add(CRC16Lo);
  Data.Add(CRC16Hi);
end;

And it's equivalent on Java

    public void ReadHoldRegisters(List<Byte> lst, byte deviceaddr, char RegisterAddress, char RegisterLength)
        {

            lst.add(deviceaddr);
            lst.add((byte) 3);
            lst.add((byte) (RegisterAddress/256));
            lst.add((byte) (RegisterAddress%256));

            Add_CRC16(lst);

        }

    private void Add_CRC16(List<Byte> Data)
    {
        char  SaveLo, SaveHi;
        int flag;


        char CRC16Lo =  0xFF;
        char CRC16Hi =  0xFF;
        char CL      =  0x1;
        char CH      =  0xA0;


        // início do for in
        for (Byte b : Data)
        {
            CRC16Lo = (char) ((CRC16Lo) ^ b);
            for(flag=0;flag<7;flag++)
            {
                SaveHi = CRC16Hi;
                SaveLo = CRC16Lo;
                CRC16Hi = (char) (CRC16Hi/2);
                CRC16Lo = (char) (CRC16Lo/2);
/*
                if((SaveHi & 0x1) == 0x1 )
                {
                    CRC16Lo = ((char) (CRC16Lo|0x80));
                }
*/
                if((SaveLo & 0x1) == 0x1 )
                {
                    CRC16Hi = ((char) (CRC16Hi^CH));
                    CRC16Lo = ((char) (CRC16Lo^CL));

                }
            }
        }
        // fim do for in

        CRC16Hi = (char) (CRC16Hi & 0xffff);
        CRC16Lo = (char) (CRC16Lo & 0xffff);

        Data.add((byte) CRC16Lo);
        Data.add((byte) CRC16Hi);

    }

When I print the values by doing

for (Byte b : lst)
S = S + String.format("%1X ", b);

I get 01 03 00 20 F0 on Delphi and 1 3 0 D8 D9 on Java.

Assuming that char and word are equivalent variables, what's going wrong with RegisterAddress and RegisterLength my code?


Solution

  • As you said, a Delphi Word is an unsigned 16 bit type. The Java char likewise is an unsigned 16 bit type.

    However, you mention Word in the question, but it doesn't appear in the code. Well, you use Word in ReadHoldRegisters but nowhere in Add_CRC16 is the Word type used. So, you aren't using Word. You are using Byte. So, the two variants of Add_CRC16 differ significantly because of that.

    I've not looked at the rest of the code, but the mismatch between 8 bit Byte in Delphi and 16 bit char in Java is the most glaring issue. Start by fixing that problem, and see what comes next.

    As a final aside, I recommend that you avoid the Delphi Basics website, especially for reference material. You are much better served by the official documentation. The relevant documentation for this question is Delphi Data Types.