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