Page 1 of 1
PLugwise CRC calculation in vbscript
Posted: Wed Dec 22, 2010 8:24 pm
by richard naninck
If anybody is interested in a CRC calculation for use in vbscript you can use the code below. Just copy it and run it and you will get the correct CRC for the data sent. The ascii string can be anything you want and a correct CCITT X-Modem CRC16 will returned. Have fun.
Code: Select all
Option Explicit
'On Error Resume Next
MsgBox Calc_CRC("0012000D6F00002366BB") '338B
'-------------------------------------------------------
'- Calc CRC 16 CCITT (X-Modem) -------------------------
'-------------------------------------------------------
Function Calc_CRC(Data)
Dim crc
Dim nit
Dim bit
Dim tempcrc1
Dim tempcrc2
crc = 0
For nit = 1 To Len(Data)
tempcrc1 = 0
tempcrc2 = (((crc \ 256) Xor Asc(Mid(Data, nit, 1))) And 255) * 256
For bit = 0 To 7
If (tempcrc1 Xor tempcrc2) And 32768 Then
tempcrc1 = (tempcrc1 * 2) Xor &H1021
Else
tempcrc1 = tempcrc1 * 2
End If
tempcrc2 = tempcrc2 * 2
Next
crc = ((crc * 256) Xor tempcrc1) And 65535
Next
Calc_CRC = Hex(crc)
End Function
Re: PLugwise CRC calculation in vbscript
Posted: Wed Dec 22, 2010 9:58 pm
by Bwired
Hihi
this is mine
Code: Select all
Private Function GetCRC16(inputStr As String) As Long
Dim i As Integer, j As Integer
Dim curVal As Long
Dim CRC As Long
Dim Poly As Long
' Poly: X16+X12+X5+1
Poly = 4129
' Init CRC value
CRC = 0
' For each value
For i = 1 To Len(inputStr)
' Get Value from the char
curVal = Asc(Mid(inputStr, i, 1))
' XOR it
CRC = CRC Xor ((curVal And 255) * 256)
' Run trough each bit
For j = 0 To 7
If (CRC And 32768) = 32768 Then
CRC = (CRC * 2) And 65535 ' Shift left
CRC = (CRC Xor Poly) ' Sum Poly
Else
CRC = (CRC * 2) And 65535 ' Shift left
End If
Next j
Next i
' Return value
GetCRC16 = CRC
End Function
Re: PLugwise CRC calculation in vbscript
Posted: Wed Dec 22, 2010 10:13 pm
by richard naninck
Looks about the same. Biggest problem in vbscript was the lack of type casting. I needed an unsigned short so I had to And it with 255. In vbscript everything greater than &H7FFF gets signed negative. Took me a while to notice that. It just didn't work using the Hex notations but it did using decimal. In C this one is really simple and way better to follow. Anyways, the basis of my HouseBot setup is vbscript since that is native to HouseBot and I couldn't find a working example so here is one to save some time.
I ordered a plugwise home basic kit yesterday and am going to write my own interface for HouseBot. I needed this CRC because I don't want to loose time over something like this after receiving the kit.
EDIT: Just tested your code in vbscript (so without the type casting) and it works as well. I dumped my code for your since your code is a few lines shorter and cleaner. Where was this example a few hours before I searched for it and decided to go my own way

Re: PLugwise CRC calculation in vbscript
Posted: Wed Dec 22, 2010 10:51 pm
by Bwired
Sorry
There is a lot about the protocol on this forum
Check also
http://domoticaforum.eu/viewtopic.php?f ... 9&start=30
Re: PLugwise CRC calculation in vbscript
Posted: Wed Dec 22, 2010 11:14 pm
by Tiz
I am also working on this and am able to switch my plugwise plugs. But since I do everything in Java, it might add value to post my implementation for this checksum I have implementations both for byte arrays and string parameters and return values since I prefer to work with byte[].
Code: Select all
public class Checksum {
//scrambler lookup table for fast computation.
private static int poly = 0x1021; // x16 + x12 + x5 + 1 generator polynomial
public static String getCRC16_String(String contents) {
int[] crcTable = getScramblerTable();
// loop, calculating CRC for each byte of the string
int work = 0x0000;
byte[] bytes = contents.getBytes();
for ( byte b : bytes )
{
// xor the next data byte with the high byte of what we have so far to
// look up the scrambler.
// xor that with the low byte of what we have so far.
// Mask back to 16 bits.
work = ( crcTable[ ( b ^ ( work >>> 8 ) ) & 0xff ] ^ ( work << 8 ) ) &
0xffff;
}
byte[] crc16 = new byte[] { (byte)(work >> 24),
(byte)(work >> 16),
(byte)(work >> 8),
(byte)work };
return Integer.toHexString(work); // crc16;
}
public static byte[] getCRC16_bytes(byte[] contents) {
int[] crcTable = getScramblerTable();
// loop, calculating CRC for each byte of the string
int work = 0x0000;
for ( byte b : contents)
{
// xor the next data byte with the high byte of what we have so far to
// look up the scrambler.
// xor that with the low byte of what we have so far.
// Mask back to 16 bits.
work = ( crcTable[ ( b ^ ( work >>> 8 ) ) & 0xff ] ^ ( work << 8 ) ) &
0xffff;
}
String crc16 = Integer.toHexString(work);
return crc16.getBytes();
}
private static int[] getScramblerTable() {
// initialise scrambler table
int[] crcTable = new int[256];
for ( int i = 0; i < 256; i++ )
{
int fcs = 0;
int d = i << 8;
for ( int k = 0; k < 8; k++ )
{
if ( ( ( fcs ^ d ) & 0x8000 ) != 0 )
{
fcs = ( fcs << 1 ) ^ poly;
}
else
{
fcs = ( fcs << 1 );
}
d <<= 1;
fcs &= 0xffff;
}
crcTable[ i ] = fcs;
}
return crcTable;
}
}