0
votes

I need help in calculating modbus CRC check for function code 1. I.e read coil register. I have sample code for CRC check for function code 3 i.e holding register for analog input.

# Read Coil Status (FC=01)

## Request

This command is requesting the ON/OFF status of discrete coils # 20 to 56 from the slave device with address 17.

11 01 0013 0025 0E84

  • 11: The Slave Address (17 = 11 hex)
  • 01: The Function Code (read Coil Status)
  • 0013: The Data Address of the first coil to read. (Coil 20 - 1 = 19 = 13 hex)
  • 0025: The total number of coils requested. (coils 20 to 56 = 37 = 25 hex)
  • 0E84: The CRC (cyclic redundancy check) for error checking.

Response

11 01 05 CD6BB20E1B 45E6

  • 11: The Slave Address (17 = 11 hex)
  • 01: The Function Code (read Coil Status)
  • 05: The number of data bytes to follow (37 Coils / 8 bits per byte = 5 bytes)
  • CD: Coils 27 - 20 (1100 1101)
  • 6B: Coils 35 - 28 (0110 1011)
  • B2: Coils 43 - 36 (1011 0010)
  • 0E: Coils 51 - 44 (0000 1110)
  • 1B: 3 space holders & Coils 56 - 52 (0001 1011)
  • 45E6: The CRC (cyclic redundancy check).

Read Holding Registers (FC=03)

Request

This command is requesting the content of analog output holding registers # 40108 to 40110 from the slave device with address 17.

11 03 006B 0003 7687

  • 11: The Slave Address (17 = 11 hex)
  • 03: The Function Code (read Analog Output Holding Registers)
  • 006B: The Data Address of the first register requested. (40108-40001 = 107 = 6B hex)
  • 0003: The total number of registers requested. (read 3 registers 40108 to 40110)
  • 7687: The CRC (cyclic redundancy check) for error checking.

Response

11 03 06 AE41 5652 4340 49AD

  • 11: The Slave Address (17 = 11 hex)
  • 03: The Function Code (read Analog Output Holding Registers)
  • 06: The number of data bytes to follow (3 registers x 2 bytes each = 6 bytes)
  • AE41: The contents of register 40108
  • 5652: The contents of register 40109
  • 4340: The contents of register 40110
  • 49AD: The CRC (cyclic redundancy check).

I am no issue for getting response for FC3. because i am sending properly the 2 byte address , but i dont know how can i send single byte and modify crc function for FC1 ->read coil register

Discription of read coil register

unsigned int crc_fn(unsigned char *dpacket,unsigned int len) { // CRC Function(Error calcualtion)
    unsigned int crc = 0xffff,poly = 0xa001;
    unsigned int i=0;

    for(i=0; i<len; i++) {
        crc^= dpacket[i];
        for(j=0; j<8; j++) {
            if(crc & 0x01) {
                crc >>= 1;
                crc ^= poly;
            } else
                crc >>= 1;
        }
    }
    return (crc);
}
1
"i dont know how can i send single byte and modify crc function for FC1" Please clarify what your problem is. Show your message construction code if necessary. The request CRC is calculated same way for FC1 as for FC3: just run crc function over the first 6 bytes of the message frame.user694733
I still can't find a question. What is your question? (Note that questions end with a question mark.) Please read about what an MVCE is. Provide an example that gives the wrong answer, what the right answer is supposed to be, and how you know that that is the right answer.Mark Adler
I have added msg construction for FC3. Now I would do modify for function code1. I don't know how CRC function run. The code I have taken from one of forum. where 50byte can used . unsigned int crc = 0xffff,poly = 0xa001; this value must be changed for function code1 what should be polynomial valueAMPS
There is still no question in this question.Mark Adler

1 Answers

0
votes

CRC is normally appended to a message most significant byte first. You need to swap two lines of code, sending the high order byte of the 16 bit crc before the low order byte. Try this change:

                Serial_1_Send_byte((unsigned char)(crc1>>8));
                Serial_1_Send_byte((unsigned char)crc1);