javadelphipascalmodbusdelphi-xe5

Is "Word" from Delphi an equivalent data type to "Char" in Java?


In Delphi, a Word is a 16 bits unsigned variable (0..65535).1 In Java, a char variable is a 16‐bit Unicode character (0..65535).2

I have the following code in 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 to 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;


        // beginning of 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));

                }
            }
        }
        // end of do for in

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

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

    }

Yet when I print the values by doing

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

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

Assuming that char and word are equivalent variables, what’s going wrong with RegisterAddress and RegisterLength in 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.