Here is how I am calculating crc16
Posted: Mon Aug 18, 2014 10:44 pm
After reading all the posts here, I thought I'd do a bit more research on the crc16 used by EKM.
The code that follows is a function that I wrote for the Xojo development environment http://www.xojo.com which I am using to create the applications for managing my meters - and eventually my home heating and pv solar power system.
I thought it might be of interest and maybe even of use to others here. I was initially baffled to discover that there are various versions of crc16 in existence, but fortunately I found a website (see notes in the code) that enabled me to quickly find out that EKM is using the MODBUS standard version. The only other wrinkle was dealing with the 7-bit issue. In that case I found that you need to first calculate the 8-bit MODBUS crc16 and then set the top bit of each of the two bytes in the crc checksum to zero. Thereafter - plain sailing!
jamesee
The code that follows is a function that I wrote for the Xojo development environment http://www.xojo.com which I am using to create the applications for managing my meters - and eventually my home heating and pv solar power system.
I thought it might be of interest and maybe even of use to others here. I was initially baffled to discover that there are various versions of crc16 in existence, but fortunately I found a website (see notes in the code) that enabled me to quickly find out that EKM is using the MODBUS standard version. The only other wrinkle was dealing with the 7-bit issue. In that case I found that you need to first calculate the 8-bit MODBUS crc16 and then set the top bit of each of the two bytes in the crc checksum to zero. Thereafter - plain sailing!
Code: Select all
'________________________________________________________________________________
' this function EKMcrc16 receives a string of bytes (s2) and returns EKM's 2-byte crc16
'_________________________________________________________________________________
'EKM's crc16 identified at MODBUS version of crc16 using
'http://www.lammertbies.nl/comm/info/crc-calculation.html
'coding algorithm was derived from a VB version here
'http://modbus.control.com/thread/1026164935
'and also from a Pascal version of the same algorithm on the same website
'___________________________________________________________________________________
dim i, j, k, crc1 as Uint16
dim b, b1, b2 as Uint8
crc1 = val("&hFFFF") ' FFFF is the initial value of crc for MODBUS crc16 calculation
for i = 1 to lenB(s2)
b = ascB(mid(s2, i, 1))
crc1 = crc1 xor b
for j = 1 to 8
k = crc1 and 1
crc1 =Bitwise.ShiftRight(crc1,1)
if k>0 then crc1 = Bitwise.BitXor(crc1, val("&hA001")) 'A001 is the divisor for MODBUS crc16 calculation
next j
next i
'crc1 is the MODBUS crc16 for the given string expressed as Uint16, a 16 bit positive integer
crc1 = crc1 and &h7F7F 'mask to make bit 8 of each byte zero for EKM metering data
'separate into two integers expressed as 2 x Unit8
b1 = crc1\256
b2 = crc1 mod 256
'function returns a two-byte string for matching with EKM's crc16
return chrB(b2) + chrB(b1) 'convert to bytes and reverse the order for matching with EKM meter string