Page 1 sur 1

[R] Hex to Float - Mid-Little Endian (CDAB)

Posté : mer. 21 oct. 2020 20:53
par Laulo7
Bonsoir,

je dialogue en Modbus TCIP et j'ai réussi à récupérer la plupart des informations dont j'avais besoin mais pas à les mettre toutes en formes.

Mon PB:
convertir de l'Hex (DD8E443B) en Décimal (751.4).
J'ai parcouru le net et tester plusieurs solutions mais je n'y arrive pas.

A l'aide du site : https://www.scadacore.com/tools/progra ... onverter/ j'ai vue qu'il me fallait faire la conversion de l'Hex en "Float - Mid-Little Endian".

Pourriez vous m'aider SVP.
Merci.

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 22 oct. 2020 16:36
par jcaspar
B :D onne nouvelle Autoit dispose des fonctions nécessaires
elles sont présentes dans la documentation

En souhaitant que les exemples ci dessous répondent à votre demande



Converti un nombre decimal en hexadecimal

Code : Tout sélectionner


 #include <MsgBoxConstants.au3>

; Assign a Local variable the hex number representation of 1033.
Local $sHex1 = Hex(10, 4)

; Display the result.
MsgBox($MB_SYSTEMMODAL, "", $sHex1)


Converti un nombre hexadecimal en decimal

Code : Tout sélectionner

#include <MsgBoxConstants.au3>
#include <AutoItConstants.au3>

_Example()
Func _Example()
	Local $iDec = Dec("000A", $NUMBER_AUTO)
	MsgBox($MB_SYSTEMMODAL, "", $iDec) ; Displays the number 4095.
EndFunc   ;==>_Example


Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 22 oct. 2020 17:42
par jchd
Il y a un certain mélange des "boutismes" là !

Code : Tout sélectionner

Local $tb = DllStructCreate("byte[4]")
Local $tf = DllStructCreate("float", DllStructGetPtr($tb))

; show actual memory layout
DllStructSetData($tf, 1, 751.461791992188)
ConsoleWrite(DllStructGetData($tb, 1) & @LF & @LF)

; reset so things are clear
DllStructSetData($tb, 1, Binary("0x0"))

; now the real opposite conversion
DllStructSetData($tb, 1, Binary("0xDD8E443B"))

Local $n1 = DllStructGetData($tb, 1, 1)
Local $n2 = DllStructGetData($tb, 1, 2)
Local $n3 = DllStructGetData($tb, 1, 3)
Local $n4 = DllStructGetData($tb, 1, 4)
DllStructSetData($tb, 1, $n2, 1)
DllStructSetData($tb, 1, $n1, 2)
DllStructSetData($tb, 1, $n4, 3)
DllStructSetData($tb, 1, $n3, 4)
ConsoleWrite(DllStructGetData($tb, 1) & @LF)
ConsoleWrite(DllStructGetData($tf, 1) & @LF & @LF)

; Another way:
Local $s = "DD8E443B"
Local $h = StringRegExpReplace($s, "([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})([[:xdigit:]]{2})", "0x$2$1$4$3")
DllStructSetData($tb, 1, Binary($h))
ConsoleWrite(DllStructGetData($tb, 1) & @LF)
ConsoleWrite(DllStructGetData($tf, 1) & @LF)

Re: Hex to Float - Mid-Little Endian (CDAB)  

Posté : jeu. 22 oct. 2020 18:09
par mikell
Pas compris grand chose :mrgreen: mais je l'avais fait comme ça (raw, moins propre évidemment)

#include <WinAPIConv.au3>

$n = "DD8E443B"
$i = StringRegExpReplace($n, '(....)(....)', "$2$1")
MsgBox(0, "", _WinAPI_IntToFloat(Int("0x" & $i)))

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 22 oct. 2020 18:59
par jchd
Ah oui, c'est vrai qu'il y a aussi ces conversions en WinAPI.
D'un autre côté c'est bien aussi de s'habituer aux DllStruct quand on travaille avec un protocole non trivial, car on peut ainsi traiter assez facilement des trames complexes entières, à condition de s'y mettre.
ModBus est big-endian.

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 22 oct. 2020 19:11
par Laulo7
Bonsoir,
merci à tous.

Avec les valeurs de tests cela fonctionne.

Test en 'dynamique' demain.

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 22 oct. 2020 19:14
par mikell
jchd a écrit : jeu. 22 oct. 2020 18:59ModBus est big-endian.
ModBus ? koi tesse ? ça se mange ? :mrgreen:

Sinon oui évidemment tu as raison sauf que quand tu connais pas, ébin c'est pas de la tarte
Je suis allé voir les entrailles de _WinAPI_IntToFloat, j'en sors ça qui est (un peu) plus clean

$xn = "DD8E443B"
$iInt = Int("0x" & StringRegExpReplace($xn, '([[:xdigit:]]{4})([[:xdigit:]]{4})', "$2$1"))
$tInt = DllStructCreate("int")
DllStructSetData($tInt, 1, $iInt)
$tFloat = DllStructCreate("float", DllStructGetPtr($tInt))
MsgBox(0, "", DllStructGetData($tFloat, 1) )

Edit
Bon j'ai à peu près compris les Dll de ton code. Pour les maths ce sera pour plus tard :?

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : ven. 23 oct. 2020 01:53
par jchd
OP :
je dialogue en Modbus TCIP et j'ai réussi à récupérer la plupart des informations dont j'avais besoin mais pas à les mettre toutes en formes.

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : ven. 23 oct. 2020 13:21
par mikell
Je déconnais :roll:
Mais si Modbus est big-endian pourquoi les données obtenues par l'OP sont d'un format différent ?

Re: Hex to Float - Mid-Little Endian (CDAB)

Posté : ven. 23 oct. 2020 14:30
par jchd
J'sais point ! Il va peut-être nous dire.

Re: * Résolu* Hex to Float - Mid-Little Endian (CDAB)

Posté : jeu. 12 mai 2022 19:27
par Laulo7
Bonjour,

Voici le bout de code que j'ai utilisé:
Func _HexToLittleEndian($hHex)
   Local $i , $ii
   $i = StringRegExpReplace($hHex, '(....)(....)', "$2$1")
   $ii =  _WinAPI_IntToFloat(Int("0x" & $i))
   return StringFormat("%.2i", $ii) ;formate en entier arrondi 2 chiffres apres virgule
EndFunc