Lecture flottant double

Forum traitant des automates industriels de marque Schneider - Telemecanique
Répondre
dodev
Asservi son premier moteur
Asservi son premier moteur
Messages : 29
Enregistré le : 26 sept. 2016, 20:26

Lecture flottant double

Message 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 !
Avatar du membre
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7806
Enregistré le : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Lecture flottant double

Message 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
Automaticien privé (de tout)
itasoft@free.fr
dodev
Asservi son premier moteur
Asservi son premier moteur
Messages : 29
Enregistré le : 26 sept. 2016, 20:26

Re: Lecture flottant double

Message 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?
Avatar du membre
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7806
Enregistré le : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Lecture flottant double

Message 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]));
Automaticien privé (de tout)
itasoft@free.fr
Avatar du membre
Bruce33
Dieu du process
Dieu du process
Messages : 931
Enregistré le : 28 oct. 2015, 06:54
Localisation : Pas-de-Calais

Re: Lecture flottant double

Message 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.
Avatar du membre
itasoft
Mi homme - Mi automate
Mi homme - Mi automate
Messages : 7806
Enregistré le : 20 oct. 2015, 10:15
Localisation : Lyon
Contact :

Re: Lecture flottant double

Message 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
Automaticien privé (de tout)
itasoft@free.fr
Répondre