hi there
Im having a problem getting data from a power transducer, because it gives me 32bits of unsigned registers but i dont know how to read unsigned registers with the ModBusMaster function
can anyone help me.
Thanks
TacaPica
There are a couple options on how to handle unsigned 32bit integers. If the number never exceeds the range of a 32bit signed integer, then you can simply move the data into a Long data type. The Modbus manual for your device should show the maximum range it is using for those registers. Some devices don't go beyond 10,000,000 which fits in a Long just fine.
Below is a CRBasic program showing different ways to handle the full range of a 32bit unsigned integer.
'Examples of handling 32bit unsigned integers
'Declare Public Variables
Public Signed32 As Long
Public FloatValue As Float
Public StringValue As String * 16
Dim SourceData As Long = &h87654321 '2,271,560,481
Dim tempLong As Long,tempString As String * 16
Dim HighDigits As Long, LowDigits As Long
'Main Program
BeginProg
Scan (1,Sec,0,0)
'Signed32 will display incorrectly -2,023,406,815
'Can post process sampled data to convert to unsigned 'integer
'Math will give incorrect results
MoveBytes (Signed32,0,SourceData,0,4)
'Float has a large enough range, but does not have 'enough precision
' to store the exact number
'Can perform math with Float, giving correct result 'with lost precision
If SourceData < 0 Then
MovePrecise (FloatValue,0)
AddPrecise (FloatValue,Signed32)
AddPrecise (FloatValue,4294967296)
Else
FloatValue = SourceData
EndIf
'A string may be used to store and display correctly 'the 32bit unsigned number
'Math functions are not possible on strings
'Postprocessing is easier at the cost of storage space
If Signed32 < 0 Then
tempString = FormatLong(Signed32,"%d")
'This will split up the Signed32 digits
'perform addition in steps to not lose precision
If Len(tempString) > 6 Then
LowDigits = Mid(tempString,Len(tempString)-4,5)
LowDigits = 67296 - LowDigits 'Lowdigits shows 'positive, but is part of a negative number
HighDigits = Mid(tempString,1,Len(tempString)-5)
ElseIf Len(tempString) = 6
LowDigits = tempString
LowDigits = 67296 + LowDigits
HighDigits = 0
Else '5 or less characters
LowDigits = tempString
LowDigits = 67296 + LowDigits
HighDigits = 0
EndIf
HighDigits = HighDigits + 42949 + INT(LowDigits/100000)
LowDigits = LowDigits MOD 100000
StringValue = FormatLong(HighDigits,"%5u") & FormatLong(LowDigits,"%05u")
Else
StringValue = FormatLong (Signed32,"%d")
EndIf
NextScan
EndProg
thanks
i could try this code yet because i was pressured by my client to give him a quick answer and i made a simpler version of the code that u wrote here.
my code reads what i want, but seing your solution, i understud that i have a grave fault, that i have to correct in my next software update.
hi again
i wasnt pleased with my results so i digged a little more and discovered that the power transducer uses IEEE 754 codification (bit 31 to 24 are decade exponent(signed 8 bit) and 23 to 0 some are binary signed values others are binary unsigned values) to send data through modbus.
can anyone (again!!!) help me with the decoding of this registers?
thanks in advanced
TaCaPica
* Last updated by: TaCaPica on 9/7/2011 @ 9:31 AM *
I haven't followed the detail of this thread, but from your last post I think you may have a simple solution. This is because the datalogger uses the same IEEE 754 coding for its storage of float (real) variables. If you can get the value into a long integer, with the bytes in the right order, you may be able to do a simple conversion by using the Movebytes function to move the integer into a float variable.
See the help for Movebytes.