PLugwise CRC calculation in vbscript

Plugwise Forum about Plugwise devices and the Source software.
Post Reply
richard naninck
Member
Member
Posts: 123
Joined: Sun Nov 21, 2010 9:53 pm

PLugwise CRC calculation in vbscript

Post 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
Bwired
Administrator
Administrator
Posts: 4704
Joined: Sat Mar 25, 2006 1:07 am
Location: Netherlands
Contact:

Re: PLugwise CRC calculation in vbscript

Post 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
http://www.bwired.nl Online Home, Domotica, Home Automation. Weblog. http://blog.bwired.nl
richard naninck
Member
Member
Posts: 123
Joined: Sun Nov 21, 2010 9:53 pm

Re: PLugwise CRC calculation in vbscript

Post 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 :wink:
Bwired
Administrator
Administrator
Posts: 4704
Joined: Sat Mar 25, 2006 1:07 am
Location: Netherlands
Contact:

Re: PLugwise CRC calculation in vbscript

Post by Bwired »

Sorry :D
There is a lot about the protocol on this forum
Check also http://domoticaforum.eu/viewtopic.php?f ... 9&start=30
Tiz
Member
Member
Posts: 146
Joined: Tue May 19, 2009 12:21 pm
Location: Netherlands

Re: PLugwise CRC calculation in vbscript

Post 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;
        }
}
Mathijs
Post Reply

Return to “Plugwise Forum”