No worries, it was kinda fun to do that stuff again. I probably spent a couple of days massaging my first packet send/receive routines into shape the first time I did it, so if I've saved you a bit of that same time and heartache, then we're good.
I was mulling over that you might be about to enter the packet-receive swamp (if you're not already knee-deep with those alligators ;-) and the first thing I'd do is pull out the checksum calculation into its own sub so that you can use it for both generating outgoing checksums and checking incoming checksums, eg:
Sub CalculateChecksum(PacketBytes() As Byte, I1 As Int, I2 As Int) As Byte()
Dim ControlSum As Int = 0
For I = I1 To I2
ControlSum = ControlSum + SignedByteToUnsigned(PacketBytes(I))
Next
Dim ChecksumBytes(4) As Byte
'zero shift right left in because computer time is cheap and programmer time is not
ChecksumBytes(0) = 0x30 + Bit.And(Bit.ShiftRight(ControlSum, 12), 0x000F)
ChecksumBytes(1) = 0x30 + Bit.And(Bit.ShiftRight(ControlSum, 8), 0x000F)
ChecksumBytes(2) = 0x30 + Bit.And(Bit.ShiftRight(ControlSum, 4), 0x000F)
ChecksumBytes(3) = 0x30 + Bit.And(Bit.ShiftRight(ControlSum, 0), 0x000F)
Return ChecksumBytes
End Sub
and then the packet assembly bit collapses down to:
'Position 7 = BCC
Dim ChecksumBytes() As Byte = CalculateChecksum(PacketBytes, 1, PutPtr - 1) 'Position 2 to Position 6
For I = 0 To 3
PacketBytes(PutPtr) = ChecksumBytes(I)
PutPtr = PutPtr + 1
Next
and on the disassembly side you'd have something like:
'Position 7 = BCC
Dim ChecksumBytes() As Byte = CalculateChecksum(PacketBytes, 1, ChecksumPosition - 1) 'Position 2 to Position 6
Dim ChecksumOkFlag As Boolean = True 'optimism reigns supreme
For I = 0 To 3
If PacketBytes(ChecksumPosition + I) <> ChecksumBytes(I) Then
ChecksumOkFlag = False
Exit
End If
Next
BTW I did see you were using strings originally, which I can understand as a sin committed in the heat of the coding battle ;-) but the performance hit is like 100-fold or more. If you want to make it out of this low-level swamp alive, best avoid strings like the plague. Use bytes instead, or if the signed-vs-unsigned stuff gets too annoying, use shorts instead (still signed, but able to handle full "proper" 8-bit range 0..255) and convert them at handover to/from the serial stream. The maximum packet size was under 255 bytes, so worst-case is you waste maybe 500 bytes to have your packet assembly/disassembly buffers as easy-to-use shorts instead of pita bytes. Cheap insurance if you ask me, and you probably even reclaim some of that space through smaller/simpler code in that area.
What could possibly go wrong?!?!