🧪 Fabrication d'un capteur de turbidité pour piscine

Bonjour Ă  tous,

Une eau trouble dans une piscine (laiteuse, brunâtre, verdâtre, …) est toujours le signe d’un problème

  • dĂ©sĂ©quilibre de l’eau (PH, TAC, …)
  • chloration insuffisante,
  • prĂ©sence de minĂ©raux (calcaire, manganèse, …)
  • prĂ©sence de micro algues,
  • prĂ©sence de mĂ©taux (fer, cuivre, …),
  • filtration insuffisante,
  • filtre encrassĂ©,
  • etc.

Une eau turbide peut être impropre à la baignade, chaque particule en suspension peut en effet abriter germes et bactéries ou encore être irritante en cas de déséquilibre de l’eau.

Bref, il vaut mieux détecter l’émergence du problème le plus vite possible avant que cela ne s’aggrave et ne nécessite de trop gros efforts pour rétablir la situation.

Un turbidimètre est un capteur qui permet de mesurer la quantité de particules en suspension dans l’eau, le plus souvent grâce à un rayon lumineux (infrarouge).
J’ai décidé de fabriquer un capteur qui devra flotter dans le bassin.

Pour la fabrication de mon capteur, j’ai opté pour le matériel suivant :

  • capteur SEN0189 avec sa carte d’acquisition
  • 1 boule en plastique
  • câble blindĂ© type alarme
    imageimage

1. l’assemblage

Le capteur est fixé avec du mastic silicone qui permet le collage et l’étanchéité (il existe des colles spécifiques résistant au chlore). La carte du convertisseur analogique vers numérique est immobilisée avec de la colle à chaud.
Pensez à lester la demi-sphère du bas afin de permettre un bon positionnement du capteur lors de la mise à l’eau (le capteur doit être sous l’eau).
Pour ma part, j’ai lesté la demi-sphère avec du sable mélangé à de la résine époxy.
Cela permet de fixer le lest de manière permanente et optimale.
La boule en plastique est refermée et jointée avec de la colle photoactive (ultra-violets).

J’ai ajouté un petit sachet de gel de silice à l’intérieur du montage avant fermeture définitive afin d’éviter toute oxydation éventuelle des circuits électroniques et contacts.
En effet, la sphère a été refermée avec les conditions atmosphériques du moment, elle contient donc certainement un air humide (aujourd’hui l’hygrométrie de l’air est de 76%). Cette humidité formerait de la condensation néfaste aux composants électroniques. Le dioxyde de silicium évitera ce problème.

2. Connexion à l’ipx800
La carte du capteur permet de sélectionner le type de signal en sortie (analogique ou numérique).
En positionnant l’interrupteur à glissière en position D (numérique), nous avons la possibilité de configurer un seuil d’enclenchement grâce au potentiomètre (composant bleu). La sortie émet alors 4.5V au franchissement du seuil défini, sinon, la sortie est inerte (0 V).
Ce fonctionnement n’est pas celui qui nous intéresse. Nous positionnerons l’interrupteur en position A (analogique) pour avoir une tension en sortie proportionnelle à la turbidité de l’eau.
Le capteur doit être alimenté en 5V et possède une sortie analogique avec une tension allant de 0 à 4.5V à pleine échelle.
Par sécurité, il convient de mettre un pont diviseur en place. Nous utiliserons une résistance de 2.7 kΩ, que nous connecterons sur l’entrée analogique de l’IPX800.

Le schéma :

3. Configuration de base sur IPX800 V4

a. La formule

En théorie, la tension émise sur la sortie analogique est inversement proportionnelle à la turbidité de l’eau. Elle est de 4.5V pour une eau claire et diminue lorsque la turbidité de l’eau augmente.
Avec le pont diviseur en place, la tension variera donc de 0 Ă  3.3V.

Il est possible de configurer l’entrée analogique de l’ipx800 (V4 ou V5) en voltmètre.
Pour l’utilisation dans un scénario, il conviendra alors de définir le seuil analogique en fonction de la turbidité à ne pas dépasser.
Mélangez du sucre dans de l’eau jusqu’à obtenir une eau trouble, correspondant à la limite à ne pas dépasser selon vous (aspect visuel). Relevez la tension lue par l’IPX et définissez un seuil analogique que vous pourrez utiliser dans les scénarios.
Pour une eau propre, la tension devrait être supérieure à 2666 mV.
Une eau peu trouble : de 2663mV Ă  2666 mV,
l’eau sera dite trouble lorsque la tension sera inférieure à 2663 mV.

b. le Widget
L’entrée analogique étant configurée en voltmètre, la mesure est affichable directement dans un widget de type Jauge (IPX800 V4 ou V5)
image image

4. Les unités néphélométriques de turbidité (UNT)
L’ UNT est l’unité de mesure de la turbidité proportionnelle à la quantité de particules en suspension qui troublent le liquide. Il est alors possible de faire le lien entre le nombre d’unités UNT et l’aspect du liquide.
plage de l’unité : de 0 à 4000

Une turbidité à 0 UNT signifie que le liquide est clair (dépourvu de particules en suspension), à 4000 UNT le liquide est opaque .

exemple pour l’eau :
UNT <5 : eau claire
5 < UNT < 30 : eau légèrement trouble
UNT > 50 : eau trouble

Pour information, l’ARS préconise généralement une turbidité inférieure à 2 UNT dans les piscines publiques, une turbidité plus élevée pouvant conduire à une dégradation de la qualité
microbiologique de l’eau.

a. La formule du fabricant
Le datasheet du capteur nous donne la formule de conversion en UNT Ă  partir de la tension lue sur la sortie analogique :
image

TurbiditéUNT=(-1120.4 * Volts²) + (5742.3 * Volts) - 4352.9

Cette formule est donnée pour une sortie à 4.5V maxi, il est nécessaire de l’adapter suite à la mise en place du pont diviseur (la tension maximale est de 3.3V)
image

DĂ©tails des calculs

Revoyons la formule du pont diviseur pour déterminer un lien entre la tension entre la sortie du capteur et la tension côté IPX800 :

Vs=(R1 / (R1+R2)) * Ve

Nous savons que R1=4700Ω et R2=2700 Ω
donc Vs=0,63513 * Ve
Ve représente la tension émise à la sortie du capteur, Vs représente la tension lue par l’IPX800.

La formule du fabricant Ă©tait

f(X)=(-1120.4 * X²) + (5742.3 * X) - 4352.9

Nous savons que la tension en sortie sera telle que Volts=X*0.63513
Il suffit donc d’opérer au remplacement de X dans la formule
f(Volts)=(-1120.4 * (Volts/0.63513)²) + (5742.3 * (Volts/0.63513)) - 4352.9
<=> f(Volts)=(-2777.45734 * Volts² )+ 9041.1365 *Volts - 4352.9

La formule d’origine devient donc

f(Volts)=(-2777.45734 * Volts² )+ 9041.1365 *Volts - 4352.9

b. La formule adaptée à notre IPX800
Il ne faut pas oublier que l’ipx ne lit pas une tension à proprement parler, mais lit une valeur X en sortie d’un Convertisseur Analogique vers Numérique (CAN).

DĂ©tails des calculs

La détermination d’une tension appliquée sur une entrée analogique de l’IPX en fonction de la valeur numérique retournée par le CAN se fait par la formule suivante

V(x)=0,000050354 * n

Dans la formule du capteur déterminée précédemment, il convient donc de remplacer la variable Volts par son expression n * 0.000050354
f(Volts)=(-2777.45734 * Volts² )+ 9041.1365 *Volts - 4352.9
<=> f(n) = (-2777.45734 * (n * 0.000050354)² + (9041.1365 * n * 0.000050354) - 4352.9
<=> f(n) = (-0.00000704231339968002 * n²) + (0.455257387 * n) - 4352.9
<=> f(n) =(-1/141998.7926 * n²) + (0.455257387 * n) - 4352.9

Sur l’ipx, nous écrirons la formule comme suit :

Valeur → Analog : ( -1/141998.7926 * x * x) + (0.455257387 * x ) - 4352.9

Nous utiliserons notre tableur préféré pour déterminer la réciproque (méthode dans cet article).

UNT V
0 2.6667
1000 2.4771
3000 1.5862

image

Sur l’IPX800, nous écrirons la formule comme suit

Analog → Valeur : (x * x * 0.000000085283)+ (0.000104316667 * x) + 2.6667

Les formules à mettre en place sur l’entrée analogique de l’IPX800 sont donc :

Valeur → Analog : ( -1/141998.7926 * x * x) + (0.455257387 * x ) - 4352.9
Analog → Valeur : (x * x * 0.000000085283)+ (0.000104316667 * x) + 2.6667

c. Le widget

La valeur de turbidité peut être affichée dans un widget de type jauge (IPX800 V4 ou V5)
image image

.L’eau est réputée propre avec une turbidité inférieure à 5 et peu trouble jusqu’à 30 UNT. Personnellement, j’ai donc opté pour un seuil à 10 UNT.

Je serai alerté chaque fois que la turbidité dépassera 10 UNT. Visuellement c’est très peu perceptible dans le bassin, le capteur me permettra donc d’intervenir plus tôt par rapport aux saisons passées sans capteur.

En seconde partie de ce tuto, je ferai un retour d’expérience.

Annexe :
En utilisant du câble 3 paires, il serait possible d’ajouter une sonde de température plongeant dans le bassin grâce à un doigt de gant (merci @grocrabe pour cette suggestion).
Il y aurait peut-être assez de place dans le capteur pour un LM35 ou TMP36 (boitier TO92) sans avoir à ajouter de puits de mesure, à voir … ou bien à défaut le noyer dans la résine formant le lestage afin de réduire la latence …

Have Fun

12 « J'aime »

Super bonne idée
Une autre solution, serait de l intégrer dans un T en aval de la filtration?

Ce capteur ne peut pas être monté en ligne, il ne résisterait pas à la pression.
Les capteurs industriels prévus à cet effet sont assez onéreux :wink:

Bonjour @fgtoul,

Super tuto, cela va ĂŞtre utile pour le printemps :+1: !!! A quand une version made by GCE ? :thinking:

Ou peut-être de réaliser une derivation en tube transparent qui passerait entre les 2 parties du capteur ? (Quel est l’espace disponible ?)

le wiki dont le lien est donné plus haut fournit les dimensions.
Pour une mesure en ligne, il faut des capteurs plus performants.

Effectivement on y trouve les plans du capteur. L’espace disponible pour placer un tube est de 5,6 mm, ce qui est insuffisant pour réaliser ma suggestion.

sans oublier que le tube transparent va fausser les mesures en déviant encore plus le faisceau lumineux par réfraction :wink:

par contre as tu réfléchi à l’automatisation avec une durée de filtration calculée sur la température et le résultat de la turbidité?
On connait tous la loi classique durée de filtration = la Temp/2 qu’on pourrait moduler +/- 2 heures en fonction de la turbidité?
Et si insuffisant notification pour vérifier le chlore?
Intéressant comme sujet

la filtration selon moi doit rester programmée en fonction de la température, soit avec la formule T/2, soit par le nombre de cycles en fonction du débit de la pompe, cette dernière méthode étant, je le rappelle, beaucoup plus économique. N’oublions pas les asservissements ( PàC, traitrements automatiques, …). Mais à mon sens, il ne faut pas créer de règle liée à la turbidité :wink:

Le capteur de turbidité enverra une notification mais n’agira pas sur la filtration.
Une eau trouble pouvant avoir plusieurs origines possibles, forcer la filtration n’est pas toujours suffisant, ni même souhaitable. Il faut d’abord analyser la situation (ph, chlore, tac, …) et surtout la couleur de l’eau car ce sont peut-être des algues mais aussi du métal ou tout simplement un débris collé au capteur.
Bref, la solution ne passe pas toujours par la filtration, il faudra souvent faire un traitement auparavant (algicide, séquestrant à métaux, réglage PH, Chlore choc, …), pour un réajustement du TAC il est même conseillé d’arrêter la filtration jusqu’à dissolution du produit, idem pour une floculation.

Donc par souci d’économie et d’efficacité par le respect des process, pas d’action en cas de turbidité, l’homme doit garder la main, à moins d’ajouter un capteur de couleur (photomètre électronique) et développer une véritable IA :slight_smile:

J’ai déjà analysé ce que m’apporterait un capteur de couleur (par analyse d’image avec caméra immergée ou autre capteur RGB sur Arduino), mais à l’échelle de l’ipx, le développement serait beaucoup trop complexe pour une valeur ajoutée plutôt faible.
Heureusement, lorsque l’équilibre de l’eau est stable (voir usage de la balance de Taylor), l’eau est rarement turbide.

1 « J'aime »

Hello…
Super concept… fallait y penser, effectivement la turbiditĂ© renvoie une info sur la « qualitĂ© Â» de l’eau.
Pour l’hivernage, c’est top, c’est une période ou on se soucis moins de la piscine, qui plus est, elle est généralement bâchée.
Bravo pour cette réalisation, de la réalisation du capteur jusqu’a l’intégration a l’IPX.

1 « J'aime »

Bonjour Ă  tous,
voici un widget développé spécialement pour le capteur de turbidité.
Dans un premier temps, il est développé pour IPX800 V4

Widget HTML pour IPX800 V4

image

image

image

image

voici le code :

var x=datasources["IPX800"]["response"]["analogV0"];
var SEUIL=10;

var UNT=(( -1/141998.7926 * x * x) + (0.455257387 * x ) - 4352.9).toFixed(0);
var Volts=(x * 0.050354).toFixed(1);

var color = `color: #${ UNT > SEUIL ? 'f00' : '0f0' };`;
//UNT=40;
    	var turbide,pcolor;
        var im=document.getElementById("pointeurNTU");
        var offset=0;
        if (UNT<15){offset=0;turbide="CLAIRE";}
		else if(UNT >=15 && UNT<30){offset=1;turbide="TRES PEU TROUBLE";}
		else if(UNT >=30 && UNT<75){offset=2;turbide="PEU TROUBLE";}
		else if(UNT >=75 && UNT<250){offset=3;turbide="TROUBLE";}
		else if(UNT >=250){offset=4;turbide="TRES TROUBLE";}
		
return `
<img style="margin-left:10px;margin-top:25px;height:140px;width:250px;display:block;" src="https://zupimages.net/up/22/40/aimn.png"/>
<div id="pointeurNTU" style="position:absolute;top:130px;left:${25 + offset*50}px;width:30px;font-size:32px;${color}">&#8682;</div>
<div style="margin-left:10px;margin-top:10px">
    <div >UNT : ${UNT}</div>
    <div >U : ${Volts} mV</div>
    <div >SEUIL : ${SEUIL}</div>
</div>
<div id="turbid" style="position:absolute;left:110px;top:180px;color:#0ff;font-size:14px;">${turbide}</div>

`;
  • CrĂ©ez une source de donnĂ©es nommĂ©e IPX800 sur le dashboard de la V4

  • DĂ©finissez la turbiditĂ© Ă  ne pas dĂ©passer en UNT (seuil)

  • prĂ©cisez le nom de l’entrĂ©e analogique dans le code (analog0 pour l’entrĂ©e analogique N°1)

Le dépassement du seuil est indiqué par le changement de couleur du pointeur.

voici l’image utilisée :


c’est de la création perso, libre de droit. Vous pouvez l’héberger sur votre réseau local, pensez à ajuster l’URL dans le code.

Scénarisation
Pour la scénarisation sur la V4, il suffit d’écrire une scène émettant un push lors du dépassement du seuil.
Vu que je ne veux pas être averti plusieurs fois dans la journée en cas de yoyo des mesures proches de l’hystérésis, j’ai ajouté une plage horaire.


Il était possible également de gérer une sortie virtuelle, plusieurs méthodes sont possibles.

La scène est alors :
PLAGE HORAIREETANALOG (seuil bas =9.9; seuil haut=10)ON<PUSH

Rappel : 10 est la valeur de mon seuil de turbidité. Je serai averti lorsque la turbidité dépassera 10 NTU

2 « J'aime »

bonsoir Ă  tous,
comme convenu, voici le widget HTML pour ipx800 V5

en taille 2x2
image

en taille 2x1
image

L’image utilisée est la même que plus haut pour la version V4.
Vous pouvez l’héberger sur votre réseau local, vous devrez alors adapter l’url.

Le dépassement du seuil est indiqué par le changement de couleur du pointeur.

vous devrez définir la valeur des paramètres API et SEUIL ainsi que l’id de la variable analogique correspondant à l’entrée connectée au capteur. Pas besoin de créer un objet fonction car nous récupérons la valeur brute puis appliquons les formules nécessaires dans le code.

<img style="position:absolute;left:0px;top:0px;height:90px;width:220px;display:block;" src="https://zupimages.net/up/22/40/aimn.png"/>
<div id="pointeurNTU" style="position:absolute;top:50px;left:0px;width:30px;font-size:32px;">&#8682;</div>
<span id="turbid" style="position:absolute;left:10px;top:95px;color:#0ff;font-size:14px;">TROUBLE</span>
<div style="position:absolute;left:10px;top:120px;">
    <div id="txtUNT"></div>
    <div id="txtmV"></div>
    <div id="txtSeuil"></div>
</div>

<script type="text/javascript">
   var server="",//vide pour local, sinon format http://ip
   api="mon_APIkey", //renseigner clé API
   uriAna="/api/core/ana/",
   id="327698",
   brute,
   SEUIL=10;
  
function init(){
   var Volts=0;
   var turbide="";
   var offset=0;
   var analog=0;
   var color;
 /* recup analogique */

    //NTU : récup valeur brute sur IPX
          getIPX((ipx) => {brute = ipx.value;});
    //NTU : calcul formule du capteur
          analog=(( -1/141998.7926 * brute * brute) + (0.455257387 * brute ) - 4352.9).toFixed(0);
    //NTU : couleur si dépassement de seuil
        color = analog > SEUIL ? '#f00' : '#0f0';
    //NTU : déplacement du pointeur graphique
        if (analog<SEUIL){offset=0;turbide="CLAIRE";}
		else if(analog >=SEUIL && analog<30){offset=1;turbide="TRES PEU TROUBLE";}
		else if(analog >=30 && analog<75){offset=2;turbide="PEU TROUBLE";}
		else if(analog >=75 && analog<250){offset=3;turbide="TROUBLE";}
		else if(analog >=250){offset=4;turbide="TRES TROUBLE";}
    //mVolts
		Volts=(brute * 0.050354).toFixed(1);
               document.getElementById("txtUNT").innerHTML="UNT : " + analog;   
               document.getElementById("txtmV").innerHTML="U : " + Volts + " mV";
               document.getElementById("txtSeuil").innerHTML="Seuil : " + SEUIL;
               document.getElementById("turbid").innerHTML=turbide;
               document.getElementById("pointeurNTU").style.left = 12+offset*44 + "px";
               document.getElementById("pointeurNTU").style.color=color
        
}
/* Get data from API */
function getIPX(cb) {
 fetch(uriAna+id+"?ApiKey="+api, {method: "GET"}).then((ret) => { // Get IPX object
 ret.json().then((ipx) => {
 cb(ipx); // Return IPX state from API
 });
 });
}

function autoRefresh() {
setInterval(() => {
init();
}, 1000); // 1 sec
}

setTimeout(() => {
  init();
}, 50)
autoRefresh();
</script>
2 « J'aime »

Bonjour
Voila des photos du montage.

DĂ©coupe de la boule plastique avec une mĂŞche de 22mm

Mise en place du capteur avec du mastic silicone pour étanchéité

Mise en place du lest époxy et de la carte d’acquisition

Montage du câble , noeud de retenue, gaine thermo et silicone pour étanchéité dans le haut de la sphère.

Bonne journée

5 « J'aime »

bonjour Ă  tous,
voici une amélioration du widget pour IPX800 V5 avec l’API HTML Widget :

image

image

<img id="sepia" style="position:absolute;left:2px;top:0px;width:98%;display:block;" src="https://zupimages.net/up/23/15/j0p1.png"/>
<div id="pointeurNTU1" style="position:absolute;top:50px;left:0px;width:30px;font-size:32px;">&#8682;</div>
<span id="turbid1" style="position:absolute;top:80px;color:#666666;left:10px;font-size:14px;font-weight:bolder;">TROUBLE</span>
<div style="position:absolute;left:10px;top:120px;">
    <div id="txtUNT1"></div>
    <div id="txtmV1"></div>
    <div id="txtSeuil1"></div>
</div>

<script>
window.GCE_Refresh.push(function(data) {
    switch (data['_id'])
    {
        case 262144:
            turbidity(data.value); 
            break;
    }
  })
  
  
function init() {
    GCE_API.getANA(262144).then((ret) => {
    turbidity(ret.value);
    })
  }
   
   
function turbidity(brute){
   var Volts=0,
       offset=0,
       color,
       SEUIL=10,
       screenWidth = screen.width,
       windowWidth = window.innerWidth;
       
    //formule du capteur:
       var analog=(( -1/141998.7926 * brute * brute) + (0.455257387 * brute ) - 4352.9).toFixed(0);

    //NTU : couleur si dépassement de seuil
        color = analog > SEUIL ? '#ff0' : '#0f0';
    //NTU : déplacement du pointeur graphique
        if (analog<SEUIL){offset=0;turbide="CLAIRE";}
		else if(analog >=SEUIL && analog<30){offset=1;turbide="TRES PEU TROUBLE";}
		else if(analog >=30 && analog<75){offset=2;turbide="PEU TROUBLE";}
		else if(analog >=75 && analog<250){offset=3;turbide="TROUBLE";}
		else if(analog >=250){offset=4;turbide="TRES TROUBLE";}
    //mVolts
		Volts=(brute * 0.050354).toFixed(1);
		var zoom=( screenWidth / windowWidth).toFixed(2);
        var sepia= document.getElementById("sepia");
        document.getElementById("pointeurNTU1").style.left = -4+(sepia.offsetWidth/10)+offset*(sepia.offsetWidth/5)+"px";
        document.getElementById("pointeurNTU1").style.top = (sepia.offsetHeight*0.7)+ "px";
        document.getElementById("pointeurNTU1").style.color=color;
        document.getElementById("pointeurNTU1").style.height=32*zoom;
        document.getElementById("turbid1").style.top=sepia.offsetHeight +16*zoom +"px" ;
        
        document.getElementById("txtUNT1").innerHTML="UNT : " + analog;   
        document.getElementById("txtmV1").innerHTML="U : " + Volts + " mV";
        document.getElementById("txtSeuil1").innerHTML="Seuil : " + SEUIL;
        document.getElementById("turbid1").innerHTML="EAU " + turbide;
    }

  init();

</script>

l’id 262144 est celui de l’entrée analogique liée au capteur (voir plus haut).

Bonne journée

2 « J'aime »