none
Calculating BCC (Block Check Character) using two's complement

    Question

  • I have serial port captures of a device that uses the two's complement to calculate BCC (Block Check Character).

    The book for the device describes how to calculate the BCC and gives an example which I understand and can calculate.

    The problem is that I cannot calculate the BCC for any of the strings that I captured and get the same answer.

    The book details the steps to calculate the BCC.
    1) Add all the hexadecimal values in the DF1 data field, and discard any overflow (if the sum requires more than eight bits, use only the eight least significant bits).
    (Note: Do not include embedded responses, if any [DLE ACK or DLE NAK]. If a value of 10hex is used twice in succession, only the first is counted.
    2) Convert the hexadecimal sum in step 1 to an equivalent eight-bit binary code.
    3) Change the eight-bit binary value in step 2 to its twos complement as follows:
      a) Change each zero bit to a one, and each one to a zero.
      b) Add one to the eight-bit value in step 3a.  The result is the twos complement value required for the BCC.

    The example for the book is as follows:
      10 02 08 09 06 00 02 04 03 10 03 ??
    so ignore 10 02 and 10 03 and sum up 08 09 06 00 02 04 03 = 20hex
    0010 0000 (20hex)
    1101 1111 complemented
         + 1  add one
    1110 0000 2's Complement (E0hex)...I can use the steps and get the same answer.

    --------------------------------------------------------------
    From the data I have captured I have
    10 02 20 20 48 20 26 5 10 03 8D  
    ignore 10 02 and 10 03 and 8D(BCC character) and add the rest
     20 20 48 20 26 5 = D3
    11010011  binary for D3 hex
    00101100  complemented
          +1  add 1
    00101101  2's complement which is 2D hex The answer is supposed to be 8D hex
    -------------------------------------------------------------
    From the data I have captured I have
    10 02 20 20 48 20 5C 05 10 03 57
    ignore the 10 02 and 10 03 and BCC of 57
    20 20 48 20 5C 05 = 109 hex
    Keep the 8 least significant bits = 09 hex
    0000 1001  09 hex
    1111 0110  complemented
         +  1  add 1
    1111 0111  2's complement which is F7 and the answer is supposed to be 57
    -------------------------------------------------------------
    From the data I have captured I have
    10 02 20 20 48 20 5E 05 10 03 55
    ignore 10 02 and 10 03 and BCC of 55
    20 20 48 20 5E 05 = 10B
    Keep the 8 least significant bits = 0B hex
    0000 1011
    1111 0100
         + 1
    1111 0101  F5 answer is 55.

     

     

     


    FordIT

    Wednesday, August 22, 2012 3:32 PM

Answers

  • If you get the correct result for the example from the documentation then your code is OK and the problem is with the data.  There should be plenty of examples available from other documentation for compatible devices to eliminate any doubt about the calculation or the accuracy of the description or how you have interpreted it - that's one benefit of a standard.

    However, that code is for testing your calculation - it isn't the actual code you are using for the data that is being transmitted by the device.  Therefore it is possible that the data is being corrupted before it gets to the calculation.  

    Are the values in the data stream sensible in terms of the current configuration of the device?  How have you confirmed that the data you are reading is the same as the data that the device is transmitting?   If you disable checksum checking does the device communication work correctly and does the display show values that correspond to the device input conditions?

    Thursday, August 30, 2012 9:49 PM

All replies

  • I get the same results as you. Perhaps your device is later (or earlier) than the book - is there an update or erratum available, either for the book or the firmware?

    --
    Andrew

    Wednesday, August 22, 2012 6:17 PM
  • I think there are a few different ways to calculate a BCC

    A few sources I have read say this :

    BCC is XOR of all the bytes in a given byte stream excluding the first SOH[chr(1)] or STX[chr(2)] till first ETX[chr(3)] or EOT[chr(4)]. ETX is included in the BCC.

    Another says this:

    The BCC consists of 2 bytes of characters.
    The BCC is the result of exclusive OR operation (XOR) on the BCC calculation range from the first character to the character immediately before the BCC. The character string of the XOR result is inserted as a BCC before the terminator.

    Allen-Bradley Home Automation agrees with your formula. I think Andrew's post is the answer.

    Wednesday, August 22, 2012 10:45 PM
  • I think you have to consider whether you are reading the data correctly, or looking at the correct field.  I note that this string:

      10 02 08 09 06 00 02 04 03 10 03

    seems to use very different values than this string:

      10 02 20 20 48 20 5C 05 10 03

    Of course, it's possible that the values in the example are arbitrary.  Does your data match what you expect (apart from the checksum), and can you get sensible results from that data if you ignore the checksum issue?  For instance, 08,09 is usually source,destination - 20,20 would actually be invalid data in this case.

    Are you sure that there is no conversion happening between the data being received at the port and being processed in your calculation?  A conversion can happen if any portion of the data is converted to type String at any point in the process.

    Does your device have an option for BCC/CRC?  If so, are you sure it is configured for BCC?

    Wednesday, August 22, 2012 11:22 PM
  • I haven't been able to find any other documentation on the device.  So it is possible that there was an updated version and I don't have the matching documentation.

    FordIT

    Wednesday, August 29, 2012 5:12 PM
  • I tried the XOR and couldn't get the answer to match the data.  I found some source code online for BCC calculation for another Allen-Bradley device and I could not get the data to match the calculation. 

    FordIT

    Wednesday, August 29, 2012 5:15 PM
  • I didn't find any settings or mention of CRC in the book.

    FordIT

    Wednesday, August 29, 2012 5:17 PM
  • The method you quote from the book appears to be the ISO 1155 method (en.wikipedia.org/wiki/Longitudinal_redundancy_check), so that seems to be in order. Could there be an error with the serial port settings?

    --
    Andrew

    Wednesday, August 29, 2012 5:35 PM
  • What device are you using ? Perhaps the manufacturer has documentation or support to help find the exact method for the device.

    Wednesday, August 29, 2012 7:48 PM
  • What device are you using ? Perhaps the manufacturer has documentation or support to help find the exact method for the device.

    The BCC calculation provided is the standard for the protocol - the device has to integrate with many others from a variety of suppliers and it has to function with off-the-shelf software, so the manufacturer's specifications cannot include any differences. The descriptions of the calculation are all exactly the same.  For instance:
    "BCC     Add all bytes between DLE STX (start of message) and DLE ETX (end of message) using modulo 256. Then perform a two’s complement. If DLE stuffing was used in the message data only one of the two DLE’s should be included in the BCC."

    They are all the same.   Of course, it's possible that the instructions refer to a different device, the manufacturer has not implemented the calculation correctly (the device is actually faulty or non-compliant), the device has not been configured correctly or the communication is not working correctly.

    Wednesday, August 29, 2012 10:10 PM
  • Are the values in the data stream sensible in terms of the current configuration of the device?  How have you confirmed that the data you are reading is the same as the data that the device is transmitting?
    Wednesday, August 29, 2012 10:11 PM
  • Here are some examples of conflicting algorithms for BCC

    http://www.lammertbies.nl/forum/viewtopic.php?t=71

    The rules according to ISO/IEC 1155-1978 are:

    http://automationwiki.com/index.php?title=BCC

    BCC calculation is done in following way:

    Each bit is modulo-2 sum of all bits in corresponding column.

    Odd or even parity can be used for either row or columns

    1’s compliment sum is used for BCC instead of modulo 2

    Bytes in a block are treated as unsigned integers and added using 1’s compliment.

    The resulting sum is inverted and used as BCC.

    At receiver, 1’s compliment sum of all characters, including BCC is computed.

    No errors, if the result = 0 (0 in 1’s compliment represented by ‘000…’ or ‘111…’)

    http://stackoverflow.com/questions/1406974/function-to-calculate-block-check-characterbcc-in-c-sharp

    Block Check Character(BCC) I need a function to calculate Block Check Character(BCC) in C#. 01 30 02 4D 21 20 20 03

    This is the string, how do I calculate "Block Check Character" for this string.

    BCC = Exclusive OR from SOH to ETX SOH ID STX CODE ETX BCC 0x01 0x30 0x02 0x40 0x03

    http://zone.ni.com/devzone/cda/epd/p/id/956

    This example illustrates how to programmatically create a block check (BCC) character, also known as a frame check character.

    In many serial and network communications, an error checking character is appended to the end of the string you want to send.

    The first VI creates and appends a block check character to a string by performing consecutive exclusive OR (XOR) operations

    on the characters you want to send. This operation can be repeated on the receiver end and the computed BCC can be compared

    to the BCC included in the string in order to check for errors in data transmission, as illustrated in the second VI.

    http://en.wikipedia.org/wiki/Block_check_character -=> http://en.wikipedia.org/wiki/Longitudinal_redundancy_check

           Set LRC = 0

           For each byte b in the buffer

           do

               Set LRC = (LRC + b) AND 0xFF

           end do

           Set LRC = (((LRC XOR 0xFF) + 1) AND 0xFF)

    http://www.rakurs.su/files/ControlComponents/H158-E1-01+E5_N+CommManual.pdf

    Page 25/130 This is the Block Check Character.

    The BCC result is found by calculating the exclusive OR of the bytes from the node

    number up to ETX.

    http://www1.amalnet.k12.il/holtz/profession/asherRoom/Documents/MICRO3and3CProtocolManual.pdf

    The BCC consists of 2 bytes of characters.

    The BCC is the result of exclusive OR operation (XOR) on the BCC calculation range from the first character to the character

    immediately before the BCC. The character string of the XOR result is inserted as a BCC before the terminator.

    http://www.ab.com/support/abdrives/1203/serial_communication/3301.pdf

    BCC Add all bytes between DLE STX (start of message) and DLE ETX (end of message) using modulo

    256. Then perform a two’s complement. If DLE stuffing was used in the message data only one

    of the two DLE’s should be included in the BCC.

    http://www.google.com/search?tbm=bks&hl=en&q=allen+bradley+block+check+character+calculation&btnG=

    entry marked "Home automation basics: practical applications using Visual Basic 6 - Page 107"

    Thursday, August 30, 2012 5:19 AM
  • http://www.google.com/search?tbm=bks&hl=en&q=allen+bradley+block+check+character+calculation&btnG=

    entry marked "Home automation basics: practical applications using Visual Basic 6 - Page 107"

    Thursday, August 30, 2012 5:34 AM
  • Most of those are used in protocols other than the one that OP is using, and so are not relevant.   The one for the Allen-Bradley 1203- series devices is the one I quoted and does correspond to the protocol that OP is using.  The descriptions from the compatible devices are almost word-for-word copies of each other (as they should be if the devices are going to communicate correctly).
    Thursday, August 30, 2012 8:41 AM
  • Here are some examples of conflicting algorithms for BCC

    http://www.lammertbies.nl/forum/viewtopic.php?t=71

    The rules according to ISO/IEC 1155-1978 are:

    http://automationwiki.com/index.php?title=BCC

    BCC calculation is done in following way:

    Each bit is modulo-2 sum of all bits in corresponding column.

    Odd or even parity can be used for either row or columns

    1’s compliment sum is used for BCC instead of modulo 2

    Bytes in a block are treated as unsigned integers and added using 1’s compliment.

    The resulting sum is inverted and used as BCC.

    At receiver, 1’s compliment sum of all characters, including BCC is computed.

    No errors, if the result = 0 (0 in 1’s compliment represented by ‘000…’ or ‘111…’)

    http://stackoverflow.com/questions/1406974/function-to-calculate-block-check-characterbcc-in-c-sharp

    Block Check Character(BCC) I need a function to calculate Block Check Character(BCC) in C#. 01 30 02 4D 21 20 20 03

    This is the string, how do I calculate "Block Check Character" for this string.

    BCC = Exclusive OR from SOH to ETX SOH ID STX CODE ETX BCC 0x01 0x30 0x02 0x40 0x03

    http://zone.ni.com/devzone/cda/epd/p/id/956

    This example illustrates how to programmatically create a block check (BCC) character, also known as a frame check character.

    In many serial and network communications, an error checking character is appended to the end of the string you want to send.

    The first VI creates and appends a block check character to a string by performing consecutive exclusive OR (XOR) operations

    on the characters you want to send. This operation can be repeated on the receiver end and the computed BCC can be compared

    to the BCC included in the string in order to check for errors in data transmission, as illustrated in the second VI.

    http://en.wikipedia.org/wiki/Block_check_character -=> http://en.wikipedia.org/wiki/Longitudinal_redundancy_check

           Set LRC = 0

           For each byte b in the buffer

           do

               Set LRC = (LRC + b) AND 0xFF

           end do

           Set LRC = (((LRC XOR 0xFF) + 1) AND 0xFF)

    http://www.rakurs.su/files/ControlComponents/H158-E1-01+E5_N+CommManual.pdf

    Page 25/130 This is the Block Check Character.

    The BCC result is found by calculating the exclusive OR of the bytes from the node

    number up to ETX.

    http://www1.amalnet.k12.il/holtz/profession/asherRoom/Documents/MICRO3and3CProtocolManual.pdf

    The BCC consists of 2 bytes of characters.

    The BCC is the result of exclusive OR operation (XOR) on the BCC calculation range from the first character to the character

    immediately before the BCC. The character string of the XOR result is inserted as a BCC before the terminator.

    http://www.ab.com/support/abdrives/1203/serial_communication/3301.pdf

    BCC Add all bytes between DLE STX (start of message) and DLE ETX (end of message) using modulo

    256. Then perform a two’s complement. If DLE stuffing was used in the message data only one

    of the two DLE’s should be included in the BCC.

    http://www.google.com/search?tbm=bks&hl=en&q=allen+bradley+block+check+character+calculation&btnG=

    entry marked "Home automation basics: practical applications using Visual Basic 6 - Page 107"

    Thanks for posting.  I tried the example from the that book and I get the same answer.   I still cannot get the answer from the existing serial string capture.  I am going try recapturing the data transactions and see if I am getting faulty data.

    I need to read all the replies because I see there is alot to be learned.

    If any one is interested this is what I got so far. 

        Sub CalculateBCC()
            Dim sInput As String = InputBox("Enter Decimal Strings separted by commas""Calculate BCC")
            sInput = sInput.Replace(" """)
            Dim aString() As String = sInput.Split(",")
            Dim x As Integer = 0
            Dim s As Integer = 0
            Dim sHex As String = ""
            Dim aBytes() As Byte
            Dim iAnswer As Integer = 0
            For x = 0 To UBound(aString)
                If IsNothing(aString(x)) Then Exit For
                ReDim Preserve aBytes(x)
                s = (CInt(aString(x)))
                iAnswer = iAnswer + s
                sHex = Hex(s)
                If sHex.Length > 2 Then
                    sHex = Strings.Right(sHex, 2)
                End If
                s = ConvertByteToInteger(sHex)
                aBytes(x) = s
            Next
            Debug.WriteLine("CalculateBCC1=" & iAnswer.ToString & " Hex(" & Hex(iAnswer) & ") " & Now)
            iAnswer = iAnswer Xor 255
            iAnswer = iAnswer + 1
            sHex = Hex(iAnswer)
            sHex = Strings.Right(sHex, 2)
            Debug.WriteLine("CalculateBCC1=" & iAnswer.ToString & " Hex(" & sHex & ") " & Now)
     
     
        End Sub

    FordIT

    Thursday, August 30, 2012 5:17 PM
  • If you get the correct result for the example from the documentation then your code is OK and the problem is with the data.  There should be plenty of examples available from other documentation for compatible devices to eliminate any doubt about the calculation or the accuracy of the description or how you have interpreted it - that's one benefit of a standard.

    However, that code is for testing your calculation - it isn't the actual code you are using for the data that is being transmitted by the device.  Therefore it is possible that the data is being corrupted before it gets to the calculation.  

    Are the values in the data stream sensible in terms of the current configuration of the device?  How have you confirmed that the data you are reading is the same as the data that the device is transmitting?   If you disable checksum checking does the device communication work correctly and does the display show values that correspond to the device input conditions?

    Thursday, August 30, 2012 9:49 PM
  • I use Eurotherm Controllers, the BCC is calculated like that in them: Excluding and starting from STX and including and ending to ETX.

    • while calculating block checksum (BCC) do the following (it's not clearly
      described in their documentation):
      • 0xFF XOR (1st byte of block)
      • (previous result) XOR (2nd byte of block)
      • .
      • .
      • .
      • (previous result) XOR (last byte of block)
      • (previous result) XOR 0xFF
      • the result of last operation is (BCC)

    I would not ever figured that out without googling XOR and EuroTherm.

    Thursday, January 09, 2014 12:49 PM