Вопрос

I am connecting to a device using the modbus protocol. I need to obtain 3 values from the machine. The first value is of the data format int16 and when I send an example byte array:

static byte[] hz = new byte[] { (byte) 0x01, (byte) 0x03, (byte) 0x00,
        (byte) 0x33, (byte) 0x00, (byte) 0x01 };

and use a CRC calculation method I obtained from a previous question I asked on the subject.

    // Compute the MODBUS RTU CRC
private static int ModRTU_CRC(byte[] buf, int len)
{
  int crc = 0xFFFF;

  for (int pos = 0; pos < len; pos++) {
    crc ^= (int)buf[pos];          // XOR byte into least sig. byte of crc

    for (int i = 8; i != 0; i--) {    // Loop over each bit
      if ((crc & 0x0001) != 0) {      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
    }
  }

    // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
    return crc;  
    }

I can recieve a response. However, the other two values are of the int32 data format and do not return a reply when I use this method. To help troubleshoot I am using a program called Realterm. to fire off the commands as well. I use it to append a Modbus 16 CRC to the end of the byte stream and send it, this works for all three and returns the desired reply. Is this a case of the data format not working with this specific calculation formula? Whats the difference between CRC16 and Modbus16?

Это было полезно?

Решение

Modbus16 is a CRC16. CRC calculations have several parameters:

  • the bit width, in this case 16
  • the polynomial, in this case 0xA001
  • the initial value,in this case 0xFFFF
  • the bit order
  • whether the final CRC is inverted with an XOR.

There are quite a number of CRC16s defined, with different values for these parameters, and this appears to be one of them. See the Wikipedia article on Cyclic Redundancy Checks for more informaton.

Другие советы

class Obliczenia {

short POLYNOM = (short) 0x0A001;
short[] TAB = {2,3,8,0x13,0x88,1,0x90,0,0x3c,2,0};
short crc = (short) 0xffff;
short CRC_LByte,CRC_HByte;
  public Obliczenia() {
    for (short dana : TAB) {
        crc= CRC16( crc, dana);
    }
    System.out.println("KOD CRC="+Integer.toHexString(crc&0xffff));
    CRC_LByte=(short)(crc & 0x00ff);
    CRC_HByte=(short)((crc & 0xff00)/256);
     System.out.println(" W ramce CRC_LByte="+Integer.toHexString(CRC_LByte)+ "    CRC_HByte   "+Integer.toHexString(CRC_HByte));

}
short CRC16(short crct, short data) {
    crct = (short) (((crct ^ data) | 0xff00) & (crct | 0x00ff));
         for (int i = 0; i < 8; i++) {
        boolean LSB = ((short) (crct & 1)) == 1;
         crct=(short) ((crct >>> 1)&0x7fff);
        if (LSB) {
            crct = (short) (crct ^ POLYNOM);
        }
    }
    return crct;
}

}

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top