Page 1 sur 1

Lecture flottant double

Posté : 02 juin 2021, 20:39
par dodev
Bonjour,

Je lis souvent des posts sur ce forum qui m'ont parfois bien aidé. Seulement aujourd'hui, j'ai un soucis sur une lecture de flottant double, des posts similaires ont déjà été postés et apparemment résolus, seulement pour moi cela ne fonctionne pas.

Voici le sujet:
Je suis sous Unity avec un M340 BMXP341000 et je lis en modbus série via le bloc Read_var sur un débitmètre KROHNE, son totalisateur.
Dans sa table de registre, il est mentionné flottant double (4 mots entiers).

J'ai fais cette programmation (trouvé auparavant dans des posts comme je l'ai stipulé) :
//
(*Conversion en 64 bits flottant*)
MOVE_BOOL_AREBOOL(0,table_ebools_FT2);
table_ebools_FT2:=COPY_ARINT_AREBOOL(Recept_total_deb_FT2, 0, 5, 0);
table_result_FT2:=COPY_AREBOOL_ARDINT(table_ebools_FT2, 10, 64, 0);

(*Calcul pour l'arrondi*)
retenue_FT2:=INT_TO_REAL(Recept_total_deb_FT2[0] and 16#03FF)/1024.0;
Totalisateur_FT2:=REAL_TO_UDINT((UDINT_TO_REAL(DINT_TO_UDINT(table_result_FT2[0]))+retenue_FT2)*1.024);
//

La valeur dans "Totalisateur_FT2" est ininterprétable (9 chiffres... :shock: ).

J'ai voulu tenter de découper deux parti en 32bits mais en vain...

Pour info, dans le "Recept_total_deb_FT2" j'obtiens les valeurs suivantes :
Recept_total_deb_FT2[0] = 22518
Recept_total_deb_FT2[1] = -19331
Recept_total_deb_FT2[2] = -7362
Recept_total_deb_FT2[3] = 16418

Avec ces infos, la variable totalisateur doit être à 9 m3.

Voila si quelqu'un ou Ita_soft à une idée. Grand merci !

Re: Lecture flottant double

Posté : 02 juin 2021, 21:06
par itasoft
slts
table_ebools_FT2:=COPY_ARINT_AREBOOL(Recept_total_deb_FT2, 0, 4, 0);

ceci dit, le totalisateur c"est exprimé en quelle unités physique ? ex: litres/heure

Re: Lecture flottant double

Posté : 04 juin 2021, 08:41
par dodev
Même avec le 4, ça ne fonctionne pas.
Le totalisateur est exprimé en m3.
Ne faut-il pas tourner le mot 0 avec 1 ou le 2 avec 3?

Re: Lecture flottant double

Posté : 04 juin 2021, 09:11
par itasoft
slts,
sinon le plus simple c'est de prendre les deux premiers mots pour en faire un UDINT , avant que le totalisateur arrive à 4 294 967 296 de M3 l'usine aura déjà coulée et toi tu sera déjà à la retraite et moi aussi, lol

UDINT_0:=DINT_TO_UDINT(INT_AS_DINT(Recept_total_deb_FT2[0], Recept_total_deb_FT2[1]));

Re: Lecture flottant double

Posté : 07 juin 2021, 07:21
par Bruce33
Bonjour,

Je n'ai pas bien compris la technique proposée par Itasoft (désolé :oops: ).

Du coup je propose une autre technique plus basique (bit à bit) pour la conversion de 4 mots représentant une valeur de type LREAL (64 bits), non prise en charge par Unity Pro/EcoStruxure Control Expert, en une valeur REAL (32 bits)

Composition des représentations selon la norme IEEE 754 concernant l'arithmétique à virgule flottante :
  • REAL, simple précision, 32 bits :
    1 bit de signe,
    8 bits d'exposant,
    23 bits de mantisse.
  • LREAL, double précision, 64 bits :
    1 bit de signe,
    11 bits d'exposant,
    52 bits de mantisse.
Le principe de la conversion est le suivant :
  • conservation du bit de signe,
  • conservation du bit de poids fort de l'exposant lié au biais
    et conservation des 7 bits de poids faible de l'exposant
    -> réduction de la plage des valeurs,
  • consersation des 23 bits de poids fort de la mantisse
    -> perte de précision.
J'ai repris la table de valeurs du débitmètre : Recept_total_deb_FT2 de type ARRAY[0..3] OF INT
Et j'ai déclaré :
- Calc_MotFort de type WORD
- Calc_MotFaible de type WORD
- Totalisateur_FT2 de type REAL

Code : Tout sélectionner

Calc_MotFort.15 := Recept_total_deb_FT2[3].15; (* bit de signe*)
Calc_MotFort.14 := Recept_total_deb_FT2[3].14; (* bit de poids fort de l'exposant conservé pour le biais*)
Calc_MotFort.13 := Recept_total_deb_FT2[3].10; (* 7 bits de poids faible de l'exposant *)
Calc_MotFort.12 := Recept_total_deb_FT2[3].9;
Calc_MotFort.11 := Recept_total_deb_FT2[3].8;
Calc_MotFort.10 := Recept_total_deb_FT2[3].7;
Calc_MotFort.9 := Recept_total_deb_FT2[3].6;
Calc_MotFort.8 := Recept_total_deb_FT2[3].5;
Calc_MotFort.7 := Recept_total_deb_FT2[3].4; (* fin exposant *)
Calc_MotFort.6 := Recept_total_deb_FT2[3].3; (* 23 bits de poids fort de la mantisse *)
Calc_MotFort.5 := Recept_total_deb_FT2[3].2;
Calc_MotFort.4 := Recept_total_deb_FT2[3].1;
Calc_MotFort.3 := Recept_total_deb_FT2[3].0;
Calc_MotFort.2 := Recept_total_deb_FT2[2].15;
Calc_MotFort.1 := Recept_total_deb_FT2[2].14;
Calc_MotFort.0 := Recept_total_deb_FT2[2].13;
Calc_MotFaible.15 := Recept_total_deb_FT2[2].12;
Calc_MotFaible.14 := Recept_total_deb_FT2[2].11;
Calc_MotFaible.13 := Recept_total_deb_FT2[2].10;
Calc_MotFaible.12 := Recept_total_deb_FT2[2].9;
Calc_MotFaible.11 := Recept_total_deb_FT2[2].8;
Calc_MotFaible.10 := Recept_total_deb_FT2[2].7;
Calc_MotFaible.9 := Recept_total_deb_FT2[2].6;
Calc_MotFaible.8 := Recept_total_deb_FT2[2].5;
Calc_MotFaible.7 := Recept_total_deb_FT2[2].4;
Calc_MotFaible.6 := Recept_total_deb_FT2[2].3;
Calc_MotFaible.5 := Recept_total_deb_FT2[2].2;
Calc_MotFaible.4 := Recept_total_deb_FT2[2].1;
Calc_MotFaible.3 := Recept_total_deb_FT2[2].0;
Calc_MotFaible.2 := Recept_total_deb_FT2[1].15;
Calc_MotFaible.1 := Recept_total_deb_FT2[1].14;
Calc_MotFaible.0 := Recept_total_deb_FT2[1].13; (* fin mantisse mantisse *)

Totalisateur_FT2 := WORD_AS_REAL (LOW := Calc_MotFaible, HIGH := Calc_MotFort);
Améliorations possibles :
  • vérifier si la valeur de l'exposant est dans la plage du type REAL (-126..+127)
    pour renvoyer une valeur de type -INF (16#FF80_0000) ou +INF (16#7F80_0000) ou zéro (16#0000_0000)
    et/ou un code d'erreur
  • arrondir la mantisse plutôt que la tronquer
:idea: A savoir également : Schneider Electric possède une bibliothèque de fonctions pour les calculs de valeurs réelles double précision (64 bits). C'est une librairie non officielle donc sans aucune garantie sur le bon fonctionnement.
Cette librairie définit un type de variable D_REAL équivalent à ARRAY[0..1] OF DWORD et possède entre autres une fonction DREAL_TO_REAL qui permet également la conversion 64 bits vers 32 bits.

Re: Lecture flottant double

Posté : 07 juin 2021, 10:56
par itasoft
slts,
Pour ce cas de figure ma combine qui consiste à diviser par 1000 la valeur pour la faire entrer dans 32 bits ne convient pas sinon la valeur 1 vaudrait 1000 M3
Prendre plutôt la solution à Bruce33 ou celle qui limite à 4 294 967 296 M3 à voir