How to interpret two word (32-bit) data from a serial device?

Hi everyone,

I'm trying to figure how how to correctly display a two word (32 bit) parameter value from a serial device. The problem is that this register is sent by the device using the following order:  higher value word: first 16 bit, lower value: second 16 bit.

I've created a 32 bit unsigned data type dataset, as the device memory map establishes for the data type of the register. I'm reading the register this way and I've found out that what I'm displaying isn't the actual value of the register but an inverted value: because of the order that the device uses to send the data (16 bit with highest value first), I'm receiving the two words inverted!

To make thing more easy to understand I'm going to make some numbers: 

Say that actual register value is 227,149.... this in binary is interpreted as 0000 0000 0000 0011 0111 0111 0100 1101.... being the first 16 bits one word (0000 0000 0000 0011), and of course the other 16 bits the second word (0111 0111 0100 1101). Now, what the devices is doing is comparing both words (both 16 bit halves) and sending the second one first, as it has a higher value compared to the first word. This way, what I'm receiving is 0111 0111 0100 1101 0000 0000 0000 0011... that converted to decimal corresponds to the number 2,001,534,979!

Has anyone experience solving anything like this? I would appreciate any help.

Thanks in advance!.

  • Hi

    How the data field arrives to the "serial device" ?

    Because this kind of inverting order is not "programmaticaly" normal.

    If you cannot correct the data source format, you will have to proceed with bit inversion :

    - in a CALC block (using 2^^ and &), if the meaning of this value have to be used in a controller

    Example :

    The fifth bit of an Integer or Long value can be isolated like that : True If (Value & (2^^4)) = (2^^4)

    and you will have to create a While/End_While structure to enumerate bits 0 to 31

    - in a VBA, you can use this 'rotation' of bits :

    Private Function LongLeftRotate(ByVal value As Long) As Long

       Dim lngSign As Long, lngI As Long

       Dim Bits As Long

       Bits = 16

       For lngI = 1 To Bits

           lngSign = value And &HC0000000

           value = (value And &H3FFFFFFF) * 2

           value = value Or ((lngSign < 0) And 1) Or (CBool(lngSign And &H40000000) And &H80000000)

       Next

       LongLeftRotate = value

    End Function

    and use it like that :

       Dim LongInitial     As Long

       Dim LongModified    As Long

       LongInitial = 2001534979             ' 0111 0111 0100 1101 0000 0000 0000 0011

       LongModified = LongLeftRotate(LongInitial)

       MsgBox LongModified    ' give 227149 = 0000 0000 0000 0011 0111 0111 0100 1101

    Hope that will help