Différences entre les versions de « Niveau de liquide dans une cuve ou un forage »

De GCE Electronics
Aller à la navigation Aller à la recherche
Ligne 580 : Ligne 580 :
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn27"] == 1) * intervalle ; //capteur du haut
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn27"] == 1) * intervalle ; //capteur du haut
</source>
</source>
===Autres formes de cuve===
Il est tout à fait possible d'appliquer le principe des interrupteurs à flotteurs aux autres formes de cuves vues dans le chapitre précédent.
A vous de jouer.

Version du 7 octobre 2020 à 03:00

Niveau de liquide

Contribution.png
Nom Niveau de liquide
Famille Widget
Wiki créé le 04/10/2020
Wiki mis à jour le 04/10/2020
Auteur fgtoul


Présentation

Voici quelques widgets écrits en javascript et HTML. Vous pourrez les personnaliser et les utiliser sur les dashboards de votre IPX800 V4.

Attention, si vous mesurez le niveau d'un produit corrosif ou d'un hydrocarbure (fioul, ...) dans une cuve, il faudra utiliser un capteur spécifique (anti-corrosion, ATEX, ...).

Pour la construction des widgets ci-dessous, il vous sera demandé d'entrer des dimensions en cm.
Pensez à entrer les dimensions internes de la cuve (dimensions externes moins 2 fois l'épaisseur de l'enveloppe).

exemples avec un capteur analogique

Il existe différents types de capteurs permettant de mesurer un niveau.

Capteurs3.png


  • à laser, infrarouges ou ultrasons, ils mesurent la hauteur vide en haut de cuve grâce au temps pris par le signal pour parcourir la distance (d= v.t/2).
    Il est alors question de méthode dite ToF (Time of Flight) . La hauteur de liquide s'obtient par soustraction à partir de la hauteur totale de la cuve.
  • composés d'une sonde immergée, ils calculent la hauteur de liquide grâce à la pression lue en fond de cuve. La sonde à pression différentielle est plus précise car elle réajuste la mesure en fonction de la pression athmosphérique.

la hauteur de liquide est en lecture directe.

  • résistifs ou capacitifs, ils mesurent la hauteur de liquide en contact avec leur partie immergée (tige, fil conducteur, ...) grâce à la variation d'une caractéristique du circuit électrique.

Nous admettrons que vous avez correctement configuré votre entrée analogique afin d'obtenir une hauteur en centimètres. Pour cela, vous aurez adapté les formules de conversion dans la configuration de l'entrée analogique concernée, en fonction des caractéristiques du capteur.

Cas d'une cuve cylindrique horizontale

Fichier:CuveCylindrique.PNG NiveauCylindrique.png

usage :

  • Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
  • Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur est attendue en cm.
  • créez un widget de type HTML, hauteur 2 blocs.
  • insérez et ajustez ce code dans le widget :
 afficher le code
 
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);


var diametreCuve=86; //diametre en cm
var volumeCuve=2000; //volume cuve pleine en litres

var pourcentage=100 - (100*hauteurFuel/diametreCuve);

var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m

//calcul de la longueur de la cuve
var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2); 

//calcul volume Fuel
var vf=0;

if(h<=r && h>=0){// hauteur inférieure à rayon cuve
    vf=(Math.sqrt(r*r-(h-r)*(h-r))*(h-r)+r*r*Math.asin(Math.sqrt(r*r-(h-r)*(h-r))/r))*vc/(Math.PI*r*r);
}
else if (h>r && h<=2*r) {//  hauteur supérieure à rayon cuve
    vf=(Math.PI*r*r-Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))*(2*r-h-r)-r*r*Math.asin(Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))/r))*vc/(Math.PI*r*r);
}

vf=(vf*1000).toFixed(0);
return `
<style>
.box{ 
  height: 80px;
  width: 80px;
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:100%;
  overflow: hidden; 
}
   
 .fuel{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 80px;
    height: 80px;
transform:translate(0,${pourcentage}%);
    background:#76B558;
  } 
</style>
<div class="box"> 
  <div id="fuel" class="fuel"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> 
	<span >Contenance cuve: ${volumeCuve}</span> litres<br>
	<span >Longueur cuve: ${lc}</span> m<br>
	<span >Diamètre cuve : ${diametreCuve} </span> cm<br>
	<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
	<span style="font-weight:bold;">Volume Fioul : ${vf}  litres</span><br>
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> 
</div> 

`;

Cas d'une cuve cylindrique verticale

Fichier:CuveCylindriqueVerticale.jpg CuveCylindriqueVerticaleW.jpg

usage :

  • Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
  • Renseignez le volume total de la cuve en litres, le diamètre de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . La hauteur est attendue en cm.
  • créez un widget de type HTML, hauteur 2 blocs.
  • insérez et ajustez ce code dans le widget :
 afficher le code
 
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var diametreCuve=86; //diametre en cm
var volumeCuve=2000; //volume cuve pleine en litres

var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m

//calcul de la longueur de la cuve
var lc=(vc/Math.PI/Math.pow(r,2)).toFixed(2); 

var pourcentage=100 - (100*h/lc);

//calcul volume Fuel
var vf=0;
vf=Math.PI * Math.pow(r,2) * h;
vf=(vf*1000).toFixed(0); //conversion en litres
return `
<style>
.box{ 
  height: 80px;
  width: 40px;
  position: absolute;
  top: 50%;
  left: 20px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:15%;
  overflow: hidden; 
}
   
 .fuel{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 40px;
    height: 80px;
transform:translate(0,${pourcentage}%);
    background:#76B558;
  } 
</style>
<div class="box"> 
  <div id="fuel" class="fuel"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> 
	<span >Contenance cuve: ${volumeCuve}</span> litres<br>
	<span >Hauteur cuve: ${lc}</span> m<br>
	<span >Diamètre cuve : ${diametreCuve} </span> cm<br>
	<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
	<span style="font-weight:bold;">Volume Fioul : ${vf}  litres</span><br>
<span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> 
</div> 

`;

cas d'une cuve parallélépipédique

Fichier:CuveParallelepipedique.png NiveauCubique.png

usage :

  • Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
  • Renseignez le volume total de la cuve en litres, la hauteur et la longueur de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.
  • creez un widget de type HTML, hauteur 2 blocs.
  • insérez et ajustez ce code dans le widget :
 afficher le code
 
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);

var hauteurCuve=120; //hauteur cuve en cm
var largeurCuve=120; //largeur cuve en cm
var longueurCuve=209; //longueur cuve en cm
var volumeCuve=3000; //volume cuve pleine en litres

var pourcentage=100 - (100*hauteurFuel/hauteurCuve);

//calcul de la consommation à partir de la baisse du niveau
var consommation=((hauteurCuve-hauteurFuel)*largeurCuve*longueurCuve)/1000 //consommation en litres

//calcul volume Fuel
var vf=0;
vf=hauteurFuel*largeurCuve*longueurCuve;
vf=(vf/1000).toFixed(0);
return `
<style>

body { 
  background:$bgColor; 
  font: 14px/1 'Open Sans', helvetica, sans-serif; 
  -webkit-font-smoothing: antialiased; 
  color:#fff; 
} 
.box{ 
  height: 80px;
  width: 80px;
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:15%;
  overflow: hidden; 
}
   
 .fuel{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 80px;
    height: 80px;
transform:translate(0,${pourcentage}%);
    background:#76B558;
  } 
</style>
<div class="box"> 
  <div id="fuel" class="fuel"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> 
	<span >Contenance cuve: ${volumeCuve}</span> litres<br>
	<span >consommation : ${consommation} </span> litres<br>
	<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
	<span style="font-weight:bold;">Volume Fioul : ${vf}  litres</span><br>
    <span >Ratio volume : ${(vf/volumeCuve*100).toFixed(2)}</span> %<br> 
</div> 

`;

cas d'une citerne à bouts sphériques

Fichier:CiterneSh2.JPG CiterneW3.JPG

usage :

  • Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800.
  • Renseignez le diamètre de la citerne et sa longueur totale en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.
  • créez un widget de type HTML, hauteur 2 blocs.
  • insérez et ajustez ce code dans le widget :
 afficher le code
 
var Diametre = 120; //en cm
var Longueur = 350; //en cm
var HauteurFuel = (datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var volumeCuve=3900; //en litres

var R = Diametre /2;
var H=HauteurFuel;
pourcentage=100-100*H/Diametre;
if ( H >= R && H < Diametre)
{
H=(2*R)-H;
A = 0.25 * (Math.PI * Math.pow(R, 2)) - (Math.atan(((R - H) / R) / Math.sqrt(1-((R - H) / R)*((R - H) / R)))) * (Math.PI * Math.pow(R, 2)) /  (Math.PI * 2);
A = A - 0.5 * (R-H)* Math.sqrt(2*R*H-H*H);
A = 2 * A;
A = (Math.PI * Math.pow(R, 2)) - A;
}
else if( H==0 )
{
A = 0;
}
else if (H==Diametre )
{
A = Math.PI * Math.pow(R, 2);
}
else if (H > 0 && H < R )
{
A = 0.25 * (Math.PI * Math.pow(R, 2)) - (Math.atan(((R - H) / R) / Math.sqrt(1 - ((R - H) / R) * ((R - H) / R)))) * (Math.PI * Math.pow(R, 2)) / (Math.PI * 2);
A = A - 0.5 * (R - H) * Math.sqrt(2 * R * H - H * H);
A = 2 * A;
}
var volume = Math.round(A * Longueur / 1000);
if (volume>volumeCuve){volume=volumeCuve;}

return `
<style>
.box2{ 
  height: 40px;
  width: 80px;
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:20px;
  overflow: hidden; 
}
   
 .fuel2{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 80px;
    height: 40px;
transform:translate(0,${pourcentage}%);
    background:#76B558;
  } 
</style>
<div class="box2"> 
  <div id="fuel" class="fuel2"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> 
   <span >Contenance cuve: ${volumeCuve}</span> litres<br><br>
   <span >Hauteur Fioul: ${HauteurFuel}</span> cm<br>
   <span style="font-weight:bold;">Volume Fioul : ${volume}  litres</span><br>
   <br> 
   <span >volume idéal à commander : ${(volumeCuve-volume).toFixed(0)}</span> litres<br>
</div> 
`;

cas d'une cuve ellipsoïde

200px CuveEllipsoideW.JPG

usage :

Sur le dashboard, créez une source de données nommée STATUS vers le fichier Status.xml de l'ipx800. Renseignez le diamètre de la citerne, sa longueur totale et la profondeur de l'ellipsoïde en cm, son volume total en litres, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.

Remarques : 
* une citerne avec une profondeur d'ellipse à zéro est une cuve cylindrique,
* une citerne avec une profondeur d'ellipse égale à son rayon est une citerne à bouts sphériques

créez un widget de type HTML, hauteur 2 blocs.

insérez et ajustez ce code dans le widget :

 afficher le code
 
var hauteurFuel=(datasources["STATUS"]["response"]["analog0"] * 100).toFixed(2);
var diametreCuve=86; //diametre en cm
var longueurCuve=344; //longueur totale de la cuve en cm
var ellipse=43; //profondeur de l'ellipse en cm
var volumeCuve=1832; //volume cuve pleine en litres

var pourcentage=100 - (100*hauteurFuel/diametreCuve);
var vc=volumeCuve/1000; //conversion en m3
var d=diametreCuve/100; //conversion en m
var r=d/2;
var h=hauteurFuel/100; //conversion en m
var e=ellipse/100; //conversion en m
//e=2*e;
//calcul de la longueur de la cuve
var lc=(longueurCuve/100-2*e).toFixed(2); 

//calcul volume Fuel dans le cylindre
var vf1=0;
if(h<=r && h>=0){// hauteur inférieure à rayon cuve
    vf1=(Math.sqrt(r*r-(h-r)*(h-r))*(h-r)+r*r*Math.asin(Math.sqrt(r*r-(h-r)*(h-r))/r))*lc;
}
else if (h>r && h<=2*r) {//  hauteur supérieure à rayon cuve
    vf1=(Math.PI*r*r-Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))*(2*r-h-r)-r*r*Math.asin(Math.sqrt(r*r-(2*r-h-r)*(2*r-h-r))/r))*lc;
}
//calcul volume fuel dans ellipsoide
var a=e,b=r,c=r; 
var x=c-h;
var vf2=0;
vf2=Math.PI*a*b*(2*c/3 - x + (x*x*x)/(3*c*c));
//calcul volume total de fioul
var vf=((vf1+vf2)*1000).toFixed(0);
if (vf>volumeCuve){vf=volumeCuve;}
return `
<style>
.box4{ 
  height: 40px;
  width: 80px;
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:16px;
  overflow: hidden; 
}
   
 .fuel4{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 80px;
    height: 40px;
transform:translate(0,${pourcentage}%);
    background:#76B558;
  } 
</style>
<div class="box4"> 
  <div id="fuel" class="fuel4"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;"> 
	<span >Contenance cuve: ${volumeCuve}</span> litres<br>
	<span >Hauteur Fioul : ${hauteurFuel}</span> cm<br>
	<span style="font-weight:bold;"> Volume Fioul: ${vf}  litres</span><br>
    <span >Ratio volume : ${(100*vf/volumeCuve).toFixed(2)}</span> %<br> <br>
    <span >Volume Cmde idéale : ${(volumeCuve-vf).toFixed(0)}</span> litres<br> 
</div> 

`;

exemple avec des capteurs tout ou rien (interrupteurs à flotteur)

FlotteurH.png

cas d'une cuve parallélépipédique

Fichier:CuveParallelepipedique.png FlotteursSch2.png NiveauCubiqueTOR.png

usage :

  • Montez les flotteurs à intervalle régulier sur la hauteur de la cuve.

Ici, nous allons supposer que le premier flotteur, situé à 20 cm du fond de la cuve, est connecté sur l'entrée digitale 21 ("btn20" dans le code).
Le deuxième flotteur est situé 14 cm plus haut, connecté à l'entrée digitale 22 (("btn21" dans le code),
Le troisième flotteur est situé 14 cm au dessus du 2ème, connecté à l'entrée digitale 23 (("btn22" dans le code),
et ainsi de suite jusqu'à 8 flotteurs.

  • Sur le dashboard, créez une source de données nommée STATUS_IPX vers le fichier Status.xml de l'ipx800.
  • Renseignez le volume total de la cuve en litres, la hauteur et la longueur de la cuve en cm, puis liez la variable hauteurFuel à la datasource, sur l’analogique de la sonde . la hauteur est attendue en cm.
  • créez un widget de type HTML, hauteur 2 blocs.
  • insérez et ajustez ce code dans le widget :
 afficher le code
 
var intervalle=14;  //intervalle entre 2 flotteurs en cm;
var basDeCuve=20;//hauteur sous le flotteur du bas
var hauteurEau=(datasources["STATUS_IPX"]["response"]["btn20"] == 0) * basDeCuve ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn21"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn22"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn23"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn24"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn25"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn26"] == 0) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn27"] == 0) * intervalle ;

var largeurCuve=104; //largeur cuve en cm
var hauteurCuve=117; //hauteur cuve en cm
var longueurCuve=250; //longueur cuve en cm
//calcul du ratio
var pourcentage=(hauteurEau/hauteurCuve)*100;
//calcul volume Eau et volume total
var ve=0; var vt=0;
ve=hauteurEau * largeurCuve * longueurCuve;
ve=(ve/1000).toFixed(0);
vt=hauteurCuve * largeurCuve * longueurCuve;
vt=(vt/1000).toFixed(0);

if (hauteurEau <= 20) {
couleurEau="#e25d6b";
} else {
couleurEau="#5dade2";
}

return `
<style>
body { 
  background:#0; 
  font: 14px/1 'Open Sans', helvetica, sans-serif; 
  -webkit-font-smoothing: antialiased; 
  color:#fff; 
} 

.box{ 
  height: 70px;
  width: 70px;
  position: absolute;
  top: 50%;
  left: 10px;
  transform: translate(0, -50%);
  background: #666666;
  border-radius:15%;
  overflow: hidden; 
}
 .eau{ 
    position: absolute;
    left: 0;
    top: 0;
    width: 70px;
    height: 70px;
transform:translate(0,${100-pourcentage}%);
    background: ${couleurEau} ;
  } 
</style>
<body>
<div class="box"> 
  <div id="eau" class="eau"></div> 
</div> 
<div style="float:left;margin-left:100px;margin-top:15px;font-size:12px;">
	<br>
	<span >Contenance cuve: ${vt}</span> litres<br>
	<span >Hauteur Eau : ${hauteurEau}</span> cm<br>
	<span style="font-weight:bold;">Volume Eau : ${ve}  litres</span><br>
    <span >Ratio volume : ${(ve/vt*100).toFixed(2)}</span> %<br> 
</div>

`;

remarque :


Il faudra ajuster le code en fonction des capteurs utilisés.

Pour l'exemple, nous avons utilisé des capteurs NF qui seront à l'état OFF lorsqu'ils seront immergés.

Pour des capteurs qui passent ON lorsqu'ils sont immergés, il faudra comparer l'état de l'entrée digitale à 1 au lieu de 0.

exemple :

var hauteurEau=(datasources["STATUS_IPX"]["response"]["btn20"] == 1) * basDeCuve ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn21"] == 1) * intervalle ; //capteur du bas
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn22"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn23"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn24"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn25"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn26"] == 1) * intervalle ;
hauteurEau=hauteurEau+(datasources["STATUS_IPX"]["response"]["btn27"] == 1) * intervalle ; //capteur du haut

Autres formes de cuve

Il est tout à fait possible d'appliquer le principe des interrupteurs à flotteurs aux autres formes de cuves vues dans le chapitre précédent.

A vous de jouer.