Modbus CRC checking using Arduino Uno


I have a power meter (Socomec Diris A20) knocking around that was spare from a job I did. Years ago I wrote a piece of code that communicated with it and pulled out the contents of a register (the line volts from memory). This was quite a strain for me but I got it to work after much trial and error. It was done in C# on a normal pc.

Not being happy with this (as it just read the value with no CRC checking to see if the value being read was ‘good’), I then asked a mate to modify some code I found on the internet that checked the CRC. This was also done (by my mate) and it worked fine. It was nothing fancy, it only read one register from one meter, but the basic groundwork was there.

Things then moved on and I never revisited this (I only did it for my own education, not for work), therefore it is not something I play with everyday.

I now have an Arduino Uno and want to attempt the same thing. I have ordered an RS485 converter but it has not yet arrived.

Here is the question :-

With the code below, which was obtained from the web again (and I’m pretty sure is the same code as my mate adapted years ago), can anyone convert this to run on an Arduino Uno. I don’t need any fancy functions to pass data back and forth. I just want to create a variable with hex data in it (or a string) with say ‘BE73D195A6’ and for the code to evaluate the CRC; in this case ‘A98C’.

Therefore something like this :-

void setup()


void loop()

TestHEX = BE73D195A6;

// Compute the MODBUS RTU CRC

for (int pos = 0; pos < len; pos++) {
crc ^= (UInt16)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)
Serial.print(calculated CRC) // i.e. A98C

If anyone is thinking ‘shouldn’t you be worrying about getting the data from the device into the Arduino through the RS485 adapter first, before worrying about checking the CRC’, then yes, you are no doubt correct. It’s just I never fully understood the CRC checking code in the first place when my mate originally did it, therefore whilst waiting for the RS485 converter to turn up (from China), I thought I would try to get my head around it more this time with just a short piece of code where I can put in static data to test. Once I understand that, I’ll then worry about how to strip the CRC off the incoming data and test it.

I’m not a complete novice, I have used RS232 and RS485 quite a lot, and understand that side of things well. It’s just the above lines such as ‘crc ^= (UInt16)buf[pos]’ that I’m not that good with, in fact I’m not that great with setting up arrays full stop. It would be nice to have this working so I can then strip it right back to understand what each and every piece is doing. I also understand how to calculate the CRC on paper, doing the looooong handwritten breakdown of bitwise operations, shifting and comparing. I just am not that great a C programmer to know how to actually code it. I can probably convert most of it (I’m ok with loops, if-thens, while’s, switch, etc. What I don’t fully understand is how to define things like (UInt16)buf[pos] (or split this up into Arduino C) so I’m not constantly stuck on compile errors that I have no understanding of how to correct.

Any help appreciated.

Kind regards


Thanks for the overwhelming amount of replies :slightly_frowning_face: but I've sorted it :slight_smile: . What I was lacking was a knowledge of how functions worked, particularly the passing of variables to and from.

So, rest easy :sleeping: , don't exert yourselves .