Crc16

parky

Member
Join Date
Oct 2004
Location
Midlands
Posts
5,758
As it's the holidays, I'm a little bored, so looking back on something I did a while back thought I would post it just incase someone may be interested.
An ex collegue of mine had an FX3U Mitsi PLC with a standard 232-BD coms board, what he really needed was the 232-ADP-MB for modbus communications, this has the required firmware to generate the required modbus RTU message including the CRC 16 checksum, the BD board does not.
So the attached is a CRC generator function in ST.
a typical modbus master message is for example [01,03,00,00,00,02,C4,0B]
i.e. Read holding registers [Addr,Function,start addr hi,start addr lo,number regs hi,num regs lo,crc hi,crc lo] so a total of 8 bytes. this reads registers 0000-0001 (4001-4002) due to the offset.
The crc function takes the 6 bytes (not the crc) & calculates & returns the checksum. You then build the whole message as the above example. bearing in mind in Mitsubishi all registers are 16 bit so a little fiddly, i.e. the first send array[0] will be reversed i.e. 0301 as will all others, the checksum does not as it is already reversed in the CRC function.
This could be ported into other platforms, however, the WTOB (word to byte) function may not be availlable so either do a byte swap or move the upper & lower bytes of the 16 bit registers into seperate 16 bit registers, this would be extra or incorporate the byte swap within the loop with another loop but could get messy.
EDIT: I did this not realising that the FX3U IDE has a crc function but did not see it, however, I don't think the other processors have that (just before someone comments that there is a standard function for the FX3U). Have a Happy new year

CRC 16 generator.png
 
Last edited:
The problem I faced was some functions like bit test or word to bits are not in the FX but are in the Q series, so had to use standard functions to extract the lsb for the test for true or false, this way it will work in both the Q & FX platform. It would have been easier if he had got the proper card but supply being what it was like it was not an option.

Replaced the if/endif with
IsTrue := Temp_word > 0;
 
Last edited:
It's a compare for greater than 0, outputs a true or false.
I get that. It's just that with binary AND and XOR operators, which I would expect to be foundational parts of any language (even Logix has them;)) we could do this:
Code:
CRC_1 := ((CRC_1 AND HFFFE)/2) AND H7FFF) XOR ((CRC_1 AND 1) * HA001);
Although to be fair, that's just me playing code golf, and your ST-ish code is much clearer.
 
Nope, will not compile CRC_1 := ((CRC_1 AND HFFFE)/2) AND H7FFF) XOR ((CRC_1 AND 1) * HA001);, parse errors plus others.
Hindsite is a great thing, when I did this, the guy was on-site, I only had a Q series PLC so originally built it on that, forgot that the FX did not have certain functions, did a quick re-hash & sent it to him.
Also, de-bugging needed to split it up, originally had to have a few temps in to see what was going on.
 
Yes, I thought about using tables, however, this was a small PLC so retentive memory is not that big, There is some extra file memory but again to use that reduces the total memory, also a little slower. In actual fact, it did not increase the scan time much even when it was used as a continuous scan rather than on demand. the MB messages are pretty short i.e. only about 8-10 bytes & only reading a few registers.
As for ST, I'm not that up to speed as I do not use it much, also, I wrote the original in FBD, just thought giving some code in ST means it can be used on other platforms.
In my ide, it is far easier to drag & drop the in-built functions into the block rather ythan spend time writing them using the keyboard, by the time you have got the syntax right you can drag & drop a number of functions onto your code so integrating into a large bracketed formular takes time to get it right, some functions do not seem to like such an integrated formular & I did not want to spend time trying to reduce code that worked anyway.
So even if the code is long I know from seeing the compiled code that condensing it does not really reduce the number of instructions.
Also, many of the functions have EN/ENO there are also the same functions without EN/ENO, some are not supported in ST, this is probably due to the different platforms it is supposed to support.
Again, this platform does not have access to 8 bit bytes directly, all registers are 16 bit (2 are used for 32, floats or 4 for precision floats), when getting this code to correctly generate the CRC, all this plus byte reversal etc. had to be tested, originally, the documentation for that PLC suggested that once the CRC had been generated to swap the bytes, this turned out to be false, however, the bytes for the rest of the message does have to be as lo byte is sent before hi byte.
So in this case, being under pressure to get something going, make it easy for others to understand it & the limitations of a small PLC made it a little challenging, as I posted, I did not have that particular PLC I had to use the Q series, this had a function to test bit in a word, the platform used does not have that or be able to use a bit level in a word register. so a quick change had to be done.
 
Never thought about it, the problem as stated earlier was a collegue of mine was on site, the platform was an FX 3U PLC with a 232-BD coms board fitted, the other instrument was some form of sensor with MB protocol, the 232-BD coms board does not directly support Modbus, there is a 232-ADP-MB which does, apparently the add on com port was ordered wrongly, no time to get the correct one. so yes it needed to be CRC.
I had to download a MB slave test program & start reading (I did have some memory of CRC from many years ago).
One thing I did miss was that the FX 3U series actually has a function to generate the CRC, as there are probably 250 plus instructions I did not see it & I was using a Q series at the time & that function is not availlable in that platform.
 

Similar Topics

Hello, I'm running on an AB ControlLogix and need to generate a 16-bit CRC, to ensure data integrity when transferring to another system. I have...
Replies
4
Views
7,045
ALL TEAM I'm working on a project using connected component workbench (CCW) from Allan Bradley PLC and I have tried to implement CRC16 but my...
Replies
0
Views
1,486
Hello guyzz, I have a problem that sounds something like this: I need to read from Citect a energy meter (Type Algodue UPT210) over RS-485 and...
Replies
9
Views
5,272
Hi all, like the title of the thread, I'm looking some sample code for realize the CRC16 routine using S7 STL or SCL language for Modubs RTU...
Replies
8
Views
7,931
Has anyone implemented a CRC16 routine in RSLogix5000? I need to do this to check a large data download. Thanks, Rich
Replies
0
Views
1,425
Back
Top Bottom