'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 |
