'MODBUS (RTU mode) CRC calculation... what's wrong? it's a misprint of the DPS5020 user manual?

I am analyzing the MODBUS protocol (rs232 com port) used in the DPS5020 power supply module and I cannot understand the CRC calculation method in RTU mode (page 3) https://cloud.kyme32.ro/ftp_backup/DPS5020%20PC%20Software(2017.11.04)/DPS5020%20CNC%20Communication%20%20Protocol%20V1.2.pdf. In the first example on page 4 for sending bytes 1, 3,0,2,0,2 the value CRC = 65CB (Hex) is indicated (2 byte swapped). I've also tried several CRC calculators online but can't find the right value. I also did a step-by-step diagram of the calculation and the right rotation of the bits, but the values ​​do not return to me. Is it necessary to use all the bytes of the frame (6) for the calculation or only the data values ​​(4)? I have tried both without success... Could you kindly put a little diagram of how the calculation is done and the return values ​​step by step (16 bit xor with A001 value, rotate right yes / no ... etc)? I know that in the end you have to swap the 2 bytes between them but the single values ​​do not come back to me anyway. Or is it simply a misprint of the manual?



Solution 1:[1]

All bytes in the frame are used in the CRC calculation.

Here is a C implementation of the CRC, which should answer your question about exactly what to shift and exclusive-or when:

#include <stddef.h>
#include <stdint.h>

uint16_t crc16modbus_bit(uint16_t crc, void const *mem, size_t len) {
    unsigned char const *data = mem;
    if (data == NULL)
        return 0xffff;
    for (size_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (unsigned k = 0; k < 8; k++) {
            crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
        }
    }
    return crc;
}

(The initial CRC value is returned when called with mem equal to NULL.)

Solution 2:[2]

If it is a large loop, you probably want to use a queue system where you use timeouts to do the loop. Basic idea below with hard coded array.

function batchDeleteA() {
  //var batchSize = 100;
  var batchSize = 3;

  // var threads = GmailApp.search('label:inbox older_than:2d');
  var threads = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  var removeBatch = function() {
    var batch = threads.splice(0, Math.min(batchSize, threads.length));
    // GmailApp.moveThreadsToTrash(batch);

    if (threads.length) {
      console.log("remaining: ", threads.length);
      window.setTimeout(removeBatch, 1);
    } else {
      console.log("complete");
    }
  };

  removeBatch();

}

batchDeleteA()

If you are getting throttled, you can increase the timeout from 1 to a larger number of milliseconds.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mark Adler
Solution 2 epascarello