Modbus Float value - Printable Version +- Ewon Technical Forum (https://techforum.ewon.biz) +-- Forum: Development (https://techforum.ewon.biz/forum-50.html) +--- Forum: BASIC Script (https://techforum.ewon.biz/forum-52.html) +--- Thread: Modbus Float value (/thread-1903.html) |
Modbus Float value - spessi - 24-12-2021 Dear All, I'm following a customer that is reading a float value thorugh Modbus Tcp IO server, but the modifier F and H embedded aren't able to read the correct value. Checking the two registers with wireshark the raw value is: 3a b4 b8 41 >>> format ABCD The correct reading must be 23.08 that it seems the format Little-Endian (DCBA) >>> I checked with Modbus Poll (see picture in attach) and with an online HEX converter ( https://www.scadacore.com/tools/programming-calculators/online-hex-converter/ ). Ewon seems to be able to read float ABCD sequence ( 0.00137878221 ) or CDAB sequence ( -0.0000460694573 ). Reading separately the two registers (called for example WL and WH), I'm able with a simple basic script to unpack each byte: BA%=WL@ DC%=WH@ A%=(BA% / 256) MOD 255 B%=(BA% - (A%*256)) MOD 255 C%=(DC% / 256) MOD 255 D%=(DC% - (C%*256)) MOD 255 PRINT A% PRINT B% PRINT C% PRINT D% A >>> 58 >>> hex 3A B >>> 180 >>> hex B4 C >>> 184 >>> hex B8 D >>> 65 >>> hex 41 At this stage I'm not able to rebuild the right value 23.08 with the format DCBA. I didn't find any way with the command embededd into the basic scripting. Do someone have any suggestion to do that? Thank you Marco RE: Modbus Float value - spessi - 28-12-2021 Here below a FUNCTION to convert two register (Low and Hgh) into a type FLOAT, passing the Modbus tags (WL@,WH@): example of function call >>> floatDCBA@ = @DINT_TO_FLOAT(WL@,WH@) //////////////////////////////////////////////////////////////// FUNCTION DINT_TO_FLOAT($regL,$regH) CLS // SINGLE BYTE ABCD $BA%=$regL $DC%=$regH $A%=($BA% / 256) MOD 255 $B%=($BA% - ($A%*256)) MOD 255 $C%=($DC% / 256) MOD 255 $D%=($DC% - ($C%*256)) MOD 255 // DINT VALUE DCBA $DCBA% = $D%*16777216 + $C%*65536 + $B%*256 + $A% // CONVERSION DINT_TO_FLOAT // EXPONENT $espx% = (($DCBA% AND 2139095040) MOD 8388607) - 127 Print $espx% // MANTISSA $bitMantx% = $DCBA% AND 8388607 $mantx = ($bitMantx%#22)*(2^-1) + ($bitMantx%#21)*(2^-2) + ($bitMantx%#21)*(2^-3) + ($bitMantx%#19)*(2^-4) + ($bitMantx%#18)*(2^-5) + ($bitMantx%#17)*(2^-6) + ($bitMantx%#16)*(2^-7) + ($bitMantx%#15)*(2^-8) $mantx = $mantx + ($bitMantx%#14)*(2^-9) + ($bitMantx%#13)*(2^-10) + ($bitMantx%#12)*(2^-11) + ($bitMantx%#11)*(2^-12) + ($bitMantx%#10)*(2^-13) + ($bitMantx%#9)*(2^-14) + ($bitMantx%#8)*(2^-15) + ($bitMantx%#7)*(2^-16) $mantx = $mantx + ($bitMantx%#6)*(2^-17) + ($bitMantx%#5)*(2^-18) + ($bitMantx%#4)*(2^-19) + ($bitMantx%#3)*(2^-20) + ($bitMantx%#2)*(2^-21) + ($bitMantx%#1)*(2^-22) + ($bitMantx%#0)*(2^-23) $mantx = 1.0 + $mantx // SIGN AND FLAOT VALUE PRINT $bitMantx%#31 $signBit%=$bitMantx%#31 IF $signBit% = 0 THEN $DINT_TO_FLOAT = $mantx*2^$espx% ELSE $DINT_TO_FLOAT = -($mantx*2^$espx%) ENDIF ENDFN //////////////////////////////////////////////////////////////// Ciao Marco RE: Modbus Float value - simon - 29-12-2021 Hello Marco, Sorry for the late reply and thank you for your feedback :-) I think the function FCNV could have been used as well : ieee = 0.0 a$ = "1234" a$(1) = Chr$(140) a$(2) = Chr$(186) a$(3) = Chr$(9) a$(4) = Chr$(194) ieee = FCNV a$,2 PRINT ieee // This will print -34.432176 Just in case your hand made function does not work in all cases... Simon |