OsmoCarni : Puits ⁄ Osmoseur avec TDS et ATC + Jauges et autres joyeusetés

Bonjour,

Je vous présente mon projet de gestion de la pompe de puits et de l'osmoseur qui alimente en eau pure ma collection de plantes carnivores.

Historique :
Cela fait maintenant 20 ans que je collectionne les plantes carnivores,
principalement des Sarracenia.

Il y a 6 ans j'ai déménagé du nord de la France pour la région Occitanie et il était évident
que mes 3 cuves de recuperation d'eau de pluie de chacune 200l n'allaient pas
suffire pour cette région sèche en été !
Dans le nord j'utilisais déjà occasionnellement un osmoseur de 100gpd connecté au réseau d'eau de ville.

Il était évident que en Occitanie il fallait un puits dans ma futur maison afin d'alimenter l'osmoseur et abreuver les soiffardes !

Pour info je possède entre 250 et 300 pots de plantes carnivores reparties dans 12 bacs de 100l (1mx1m), 5 de 60l (1mx0.60m) et une multitude de bacs plus petit ... tous remplies d'eau osmosée.

J'ai de suite installé une pompe immergé afin d'alimenter l'osmoseur de 100gpd ...
autre évidence un osmoseur de 100gpd n'est pas suffisant à moins de laisser la pompe en
fonctionnement 24h/24 :frowning:

Changement de la membrane pour une 200gpd puis une 400gpd !

Au bout de 2 ans j'ai relié la pompe du puits à mon IPX800 V4 par un module enOcean afin de contrôler la mise en marche et arrêt de celle ci à distance.

Première étape mais un grand manque se faisait sentir et une lassitude de faire des allés retour au garage pour vérifier la pression en entré de l'osmoseur et vérifier la pureté de l'eau produite en consultant le TDS.

Il y a 2 ans (2021) j'ai décidé d'installer un ESP afin de contrôler le TDS en sortie de l'osmoseur.
J'ai aussi ajouté une 2eme membrane de 400gpd et changer les portes filtre qui étaient sous dimensionnés .

Voici l'usine à eau :

Projet OsmoCarni V1 (2021) :
Un simple ESP et un TDS Meter Gravity, lecture du résultat sur une page web au format texte ... bien-sur il fallait rafraîchir manuellement la page web :rofl:
Oui pas très sexy et pas très poussé comme projet, un peu en mode feignasse par manque cruel de temps.

Projet OsmoCarni V2.0 (2023) :
1er WE d'avril j'ai fait évoluer l'usine à eau :wink:
Carte Keyestudio Mega 2560 R3 Advanced + Keyestudio W5500 Ethernet Shield Ethernet Control + 2 TDS Meter Gravity + Sonde de température DS18B20
Toujours aussi sexy avec un affichage texte noir sur fond blanc et rafraîchissement manuel de la page web !

Projet OsmoCarni V2.1 (2023) :
2eme WE d'avril et raz le bol de cette page web toute moisie j'ai décidé d’améliorer l'aspect visuel en intégrant des Gauges et de dynamiser le rafraîchissement des données avec de l' Ajax !
Cerise sur le gâteau ... ajout d'une sonde Température / Humidité AM2320 :crazy_face:

Keyestudio Mega 2560 R3 Advanced :
Infos tech de la Carte

Keyestudio W5500 Ethernet Shield Ethernet Control :
Infos tech du Shield

TDS Meter Gravity :
Infos tech du module TDS
TDS-Meter-Gravity

Sonde de température DS18B20 :

Sonde Température / Humidité AM2320 :

Le Dashboard :

Si tu ne sais pas quoi faire ce soir regardes les aiguilles bouger ! :partying_face:
https://youtu.be/wixF8ooS9ZU

La Platine réunissant tous les composant :

Codes du projet :
Soyez indulgent sur le code ! :scream:
Le code et moi ne faisons pas bon ménage et sommes séparé par un abysse d'incompréhension.
J'ai appliqué la devise Shadok "En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche"

INO -> OSMOCARNIV2-1.ino (13,6 Ko)

////////////////////////////////////////////////////////////////////
//                                                                //
//                           OSMOCARNI V2.1                       //
//                            (09-04-2023)                        //
//                                                                //
//                    OSMOSEUR PLANTES CARNIVORES                 //
//                                                                //
// - TDS In/Out                                                   //
// - Température Eau pour ATC du TDS                              //
// - Température / Humidité Garage                                //
// - Jauges des Valeurs                                           //
//                                                                //
////////////////////////////////////////////////////////////////////
//
// Activation Shield Ethernet
#include <SPI.h>
//
#include <Ethernet.h>
#include <SD.h>
//
// OneWire pour DS18B20
#include <OneWire.h>
//
// AM2320 sonde temperature/humiditée
#include <Adafruit_Sensor.h>
#include <Adafruit_AM2320.h>
//
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ 50
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0x7A, 0x22, 0x01, 0xA4, 0x86, 0x60 };
IPAddress ip(192, 168, 0, 110);  // IP address, may need to change depending on network
IPAddress gateway(192, 168, 0, 10);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(80);          // create a server at port 80
File webFile;                       // the web page file on the SD card
char HTTP_req[REQ_BUF_SZ] = { 0 };  // buffered HTTP request stored as null terminated string
char req_index = 0;                 // index into HTTP_req buffer
//
// AM2320 sonde temperature/humiditée
Adafruit_AM2320 AM2320 = Adafruit_AM2320();
//
// DS18B20
int DS18S20_Pin = 30;  //DS18S20 Signal pin on digital 30
//Temperature chip i/o
OneWire ds(DS18S20_Pin);  // on digital pin 2
//
//
// TDS
#define TdsSensorPinIN A0
#define TdsSensorPinOUT A1
#define VREF 5.0              // analog reference voltage(Volt) of the ADC
#define SCOUNT 30             // sum of sample point
int analogBufferIN[SCOUNT];   // store the analog value in the array, read from ADC
int analogBufferOUT[SCOUNT];  // store the analog value in the array, read from ADC
int analogBufferTempIN[SCOUNT];
int analogBufferTempOUT[SCOUNT];
int analogBufferIndexIN = 0, copyIndexIN = 0;
int analogBufferIndexOUT = 0, copyIndexOUT = 0;
float averageVoltageIN = 0, tdsValueIN = 0;
float averageVoltageOUT = 0, tdsValueOUT = 0;
//
//
void setup() {
  // AM2320 sonde Température/humiditée
  // Setup the sensor;
  AM2320.begin();
  // disable Ethernet chip
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  // initialize serial
  Serial.begin(9600);  // for debugging
  // initialize SD card
  Serial.println("Initializing SD card...");
  if (!SD.begin(4)) {
    Serial.println("ERROR - SD card initialization failed!");
    return;  // init failed
  }
  Serial.println("SUCCESS - SD card initialized.");
  // check for index.htm file
  if (!SD.exists("index.htm")) {
    Serial.println("ERROR - Can't find index.htm file!");
    return;  // can't find index file
  }
  Serial.println("SUCCESS - Found index.htm file.");
  //
  Ethernet.begin(mac, ip);  // initialize Ethernet device
  server.begin();           // start to listen for clients
}

void loop() {
  // AM2320 sonde temperature/humiditée
  float tempC = AM2320.readTemperature();
  float humidity = AM2320.readHumidity();
  float digital_val;
  Serial.println("");
  Serial.print("Temperature: ");
  Serial.print(tempC);
  Serial.print(" \xC2\xB0");  // shows degree symbol
  Serial.print("C  |  ");
  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %RH");
  delay(2000);
  //
  // DS18B20
  float temperatureTDS = getTemp();
  //
  // TDS
  static unsigned long analogSampleTimepoint = millis();
  if (millis() - analogSampleTimepoint > 40U)  //every 40 milliseconds,read the analog value from the ADC
  {
    analogSampleTimepoint = millis();
    analogBufferIN[analogBufferIndexIN] = analogRead(TdsSensorPinIN);     //read the analog value and store into the buffer
    analogBufferOUT[analogBufferIndexOUT] = analogRead(TdsSensorPinOUT);  //read the analog value and store into the buffer
    analogBufferIndexIN++;
    if (analogBufferIndexIN == SCOUNT)
      analogBufferIndexIN = 0;
    analogBufferIndexOUT++;
    if (analogBufferIndexOUT == SCOUNT)
      analogBufferIndexOUT = 0;
  }
  static unsigned long printTimepoint = millis();
  if (millis() - printTimepoint > 800U) {
    printTimepoint = millis();
    for (copyIndexIN = 0; copyIndexIN < SCOUNT; copyIndexIN++)
      analogBufferTempIN[copyIndexIN] = analogBufferIN[copyIndexIN];
    averageVoltageIN = getMedianNum(analogBufferTempIN, SCOUNT) * (float)VREF / 1024.0;                                                                                                             // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    averageVoltageOUT = getMedianNum(analogBufferTempOUT, SCOUNT) * (float)VREF / 1024.0;                                                                                                           // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficientIN = 1.0 + 0.02 * (temperatureTDS - 25.0);                                                                                                                         //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatgeIN = averageVoltageIN / compensationCoefficientIN;                                                                                                                     //temperature compensation
    tdsValueIN = (133.42 * compensationVolatgeIN * compensationVolatgeIN * compensationVolatgeIN - 255.86 * compensationVolatgeIN * compensationVolatgeIN + 857.39 * compensationVolatgeIN) * 0.5;  //convert voltage value to tds value
    Serial.println("");
    Serial.print("TDS Temperature : ");
    Serial.println(temperatureTDS);
    Serial.print("TDS IN:");
    Serial.print(tdsValueIN, 0);
    Serial.print(" ppm ");
    Serial.println("");
    for (copyIndexOUT = 0; copyIndexOUT < SCOUNT; copyIndexOUT++)
      analogBufferTempOUT[copyIndexOUT] = analogBufferOUT[copyIndexOUT];
    averageVoltageIN = getMedianNum(analogBufferTempIN, SCOUNT) * (float)VREF / 1024.0;                                                                                                                    // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    averageVoltageOUT = getMedianNum(analogBufferTempOUT, SCOUNT) * (float)VREF / 1024.0;                                                                                                                  // read the analog value more stable by the median filtering algorithm, and convert to voltage value
    float compensationCoefficientOUT = 1.0 + 0.02 * (temperatureTDS - 25.0);                                                                                                                               //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.02*(fTP-25.0));
    float compensationVolatgeOUT = averageVoltageOUT / compensationCoefficientOUT;                                                                                                                         //temperature compensation
    tdsValueOUT = (133.42 * compensationVolatgeOUT * compensationVolatgeOUT * compensationVolatgeOUT - 255.86 * compensationVolatgeOUT * compensationVolatgeOUT + 857.39 * compensationVolatgeOUT) * 0.5;  //convert voltage value to tds value
    Serial.print("TDS Value OUT:");
    Serial.print(tdsValueOUT, 0);
    Serial.print(" ppm ");
    Serial.println("");
  }
  //
  EthernetClient client = server.available();  // try to get client
  if (client) {                                // got client?
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {  // client data available to read
        char c = client.read();  // read 1 byte (character) from client
        // buffer first part of HTTP request in HTTP_req array (string)
        // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
        if (req_index < (REQ_BUF_SZ - 1)) {
          HTTP_req[req_index] = c;  // save HTTP request character
          req_index++;
        }
        // last line of client request is blank and ends with \n
        // respond to client only after last line received
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          // remainder of header follows below, depending on if
          // web page or XML page is requested
          // Ajax request - send XML file
          if (StrContains(HTTP_req, "ajax_inputs")) {
            // send rest of HTTP header
            client.println("Content-Type: text/xml");
            client.println("Connection: keep-alive");
            client.println();
            // send XML file containing input states
            XML_response(client);
          } else {  // web page request
            // send rest of HTTP header
            client.println("Content-Type: text/html");
            client.println("Connection: keep-alive");
            client.println();
            // send web page
            webFile = SD.open("index.htm");  // open web page file
            if (webFile) {
              while (webFile.available()) {
                client.write(webFile.read());  // send web page to client
              }
              webFile.close();
            }
          }
          // display received HTTP request on serial port
          Serial.print(HTTP_req);
          // reset buffer index and all buffer elements to 0
          req_index = 0;
          StrClear(HTTP_req, REQ_BUF_SZ);
          break;
        }
        // every line of text received from the client ends with \r\n
        if (c == '\n') {
          // last character on line of received text
          // starting new line with next character read
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // a text character was received from client
          currentLineIsBlank = false;
        }
      }             // end if (client.available())
    }               // end while (client.connected())
    delay(1);       // give the web browser time to receive the data
    client.stop();  // close the connection
  }                 // end if (client)
}
// send the XML file containing all values
void XML_response(EthernetClient cl) {
  int analog_val;
  int analog_val1;
  float digital_val;
  float am2320_val;
  float am2320_valh;
  float temperatureTDS = getTemp();
  float am2320TC = AM2320.readTemperature();
  float am2320HR = AM2320.readHumidity();
  cl.print("<?xml version = \"1.0\" ?>");
  cl.print("<inputs>");
  analog_val = tdsValueIN, 0;
  analog_val1 = tdsValueOUT, 0;
  digital_val = temperatureTDS;
  am2320_val = am2320TC;
  am2320_valh = am2320HR;
  cl.print("<analog>");
  cl.print(analog_val);
  cl.print("</analog>");
  cl.print("<analog1>");
  cl.print(analog_val1);
  cl.print("</analog1>");
  cl.print("<digital>");
  cl.print(digital_val);
  cl.print("</digital>");
  cl.print("<am2320t>");
  cl.print(am2320_val);
  cl.print("</am2320t>");
  cl.print("<am2320h>");
  cl.print(am2320_valh);
  cl.print("</am2320h>");
  cl.print("</inputs>");
}
// sets every element of str to 0 (clears array)
void StrClear(char *str, char length) {
  for (int i = 0; i < length; i++) {
    str[i] = 0;
  }
}
// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind) {
  char found = 0;
  char index = 0;
  char len;

  len = strlen(str);

  if (strlen(sfind) > len) {
    return 0;
  }
  while (index < len) {
    if (str[index] == sfind[found]) {
      found++;
      if (strlen(sfind) == found) {
        return 1;
      }
    } else {
      found = 0;
    }
    index++;
  }

  return 0;
}
//
// DS18B20
float getTemp() {
  byte data[12];
  byte addr[8];
  if (!ds.search(addr)) {
    //no more sensors on chain, reset search
    Serial.println("no more sensors on chain, reset search!");
    ds.reset_search();
    return -1000;
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
    Serial.println("CRC is not valid!");
    return -1000;
  }
  if (addr[0] != 0x10 && addr[0] != 0x28) {
    Serial.print("Device is not recognized");
    return -1000;
  }
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);  // start conversion, with parasite power on at the end
  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);                // Read Scratchpad
  for (int i = 0; i < 9; i++) {  // we need 9 bytes
    data[i] = ds.read();
  }
  ds.reset_search();
  byte MSB = data[1];
  byte LSB = data[0];
  float tempRead = ((MSB << 8) | LSB);  //using two's compliment
  float TemperatureSum = tempRead / 16;
  return TemperatureSum;
}
//
// TDS
int getMedianNum(int bArray[], int iFilterLen) {
  int bTab[iFilterLen];
  for (byte i = 0; i < iFilterLen; i++)
    bTab[i] = bArray[i];
  int i, j, bTemp;
  for (j = 0; j < iFilterLen - 1; j++) {
    for (i = 0; i < iFilterLen - j - 1; i++) {
      if (bTab[i] > bTab[i + 1]) {
        bTemp = bTab[i];
        bTab[i] = bTab[i + 1];
        bTab[i + 1] = bTemp;
      }
    }
  }
  if ((iFilterLen & 1) > 0)
    bTemp = bTab[(iFilterLen - 1) / 2];
  else
    bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
  return bTemp;
}
//
//
// FIN min p'tit Quinquin

HTML ->
index.txt (14,8 Ko) (à renommer en index.htm :

<!DOCTYPE html>
<html>
    <head>
        <title>OsmoCarni</title>
        <link rel="icon" type="image/png" sizes="16x16"  href="favicon.png">
		<meta name="msapplication-TileColor" content="#ffffff">
		<meta name="theme-color" content="#ffffff">
	    <style>
          body {
            background-color: #2e2e2e;
            color: #ffffff;
               }
                     h1 {
             color: #ffffff;
      }
        </style>
        <script>
		var data_val = 0;
		eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('t W=v(f){W.2t.3T(A);A.B={Z:2u,19:1q,1h:1q,1J:U,1b:D,K:0,V:[\'0\',\'20\',\'40\',\'2A\',\'2B\',\'D\'],2r:10,2C:M,1E:U,2q:{2D:3,2E:2},2H:M,1c:{2j:10,2m:3y,2O:\'3v\'},J:{2P:\'#4h\',V:\'#31\',2r:\'#3k\',1J:\'#37\',1E:\'#37\',3e:\'#31\',1t:{2s:\'1e(3Y, 3d, 3d, 1)\',3c:\'1e(1Y, 5I, 5E, .9)\'}},1o:[{1n:20,1D:2A,1F:\'#3j\'},{1n:2A,1D:2B,1F:\'#36\'},{1n:2B,1D:D,1F:\'#5n\'}]};t g=0,1p=A,N=0,1S=0,1G=U;A.5d=v(a){N=f.1c?g:a;t b=(f.1b-f.K)/D;1S=a>f.1b?1S=f.1b+b:a<f.K?f.K-b:a;g=a;f.1c?3l():A.1g();C A};A.3m=v(a){N=g=a;A.1g();C A};A.4T=v(){g=N=1S=A.B.K;A.1g();C A};A.4R=v(){C g};A.13=v(){};v 2k(a,b){Q(t i 4P b){z(1H b[i]=="1W"&&!(4O.4y.2V.4p(b[i])===\'[1W 4n]\')&&i!=\'Z\'){z(1H a[i]!="1W"){a[i]={}}2k(a[i],b[i])}O{a[i]=b[i]}}};2k(A.B,f);A.B.K=1R(A.B.K);A.B.1b=1R(A.B.1b);f=A.B;N=g=f.K;z(!f.Z){4m 4j("4g 4d 4b 46 44 41 3Z 3W W 1W!");}t j=f.Z.5K?f.Z:2R.5v(f.Z),q=j.3u(\'2d\'),1i,1y,1A,14,17,u,1d;v 2M(){j.19=f.19;j.1h=f.1h;1i=j.4s(M);1d=1i.3u(\'2d\');1y=j.19;1A=j.1h;14=1y/2;17=1A/2;u=14<17?14:17;1i.2J=U;1d.3P(14,17);1d.G();q.3P(14,17);q.G()};2M();A.4Z=v(a){2k(A.B,a);2M();A.1g();C A};t k={4q:v(p){C p},4e:v(p){C E.1L(p,2)},4c:v(p){C E.1L(p,5)},3v:v(p){C 1-E.1O(E.5C(p))},5k:v(p){C 1-(v(p){Q(t a=0,b=1;1;a+=b,b/=2){z(p>=(7-4*a)/11){C-E.1L((11-6*a-11*p)/4,2)+E.1L(b,2)}}})(1-p)},4S:v(p){C 1-(v(p){t x=1.5;C E.1L(2,10*(p-1))*E.1T(20*E.1a*x/3*p)})(1-p)}};t l=2u;v 3S(d){t e=2v 3R;l=2x(v(){t a=2v 3R-e,1M=a/d.2m;z(1M>1){1M=1}t b=1H d.2g=="v"?d.2g:k[d.2g];t c=b(1M);d.3Q(c);z(1M==1){2b(l)}},d.2j||10)};v 3l(){l&&2b(l);t b=(1S-N),1n=N,29=f.1c;3S({2j:29.2j,2m:29.2m,2g:29.2O,3Q:v(a){N=1R(1n)+b*a;1p.1g()}})};q.5l="3O";A.1g=v(){z(!1i.2J){1d.3M(-14,-17,1y,1A);1d.G();t a=q;q=1d;3L();3K();3I();3H();3F();3D();3z();1i.2J=M;q=a;5G a}q.3M(-14,-17,1y,1A);q.G();q.4a(1i,-14,-17,1y,1A);z(!W.28){t b=2x(v(){z(!W.28){C}2b(b);2K();2L();z(!1G){1p.13&&1p.13();1G=M}},10)}O{2K();2L();z(!1G){1p.13&&1p.13();1G=M}}C A};v S(a){C a*E.1a/4J};v 1l(a,b,c){t d=q.4Y(0,0,0,c);d.1V(0,a);d.1V(1,b);C d};v 3L(){t a=u/D*5g,3x=u-a,2a=u/D*5q,5u=u-2a,1f=u/D*5z,5A=u-1f;3t=u/D*5F;q.G();z(f.2H){q.2o=3x;q.2n=\'1e(0, 0, 0, 0.5)\'}q.P();q.16(0,0,a,0,E.1a*2,M);q.L=1l(\'#42\',\'#43\',a);q.T();q.R();q.P();q.16(0,0,2a,0,E.1a*2,M);q.L=1l(\'#49\',\'#36\',2a);q.T();q.P();q.16(0,0,1f,0,E.1a*2,M);q.L=1l(\'#3j\',\'#3s\',1f);q.T();q.P();q.16(0,0,3t,0,E.1a*2,M);q.L=f.J.2P;q.T();q.G()};v 3H(){t r=u/D*2T;q.2e=2;q.2U=f.J.V;q.G();Q(t i=0;i<f.V.H;++i){t a=45+i*(1U/(f.V.H-1));q.1z(S(a));q.P();q.1K(0,r);q.F(0,r-u/D*15);q.1X();q.R();q.G()}z(f.2C){q.1z(S(2X));q.P();q.16(0,0,r,S(45),S(4N),U);q.1X();q.R();q.G()}};v 3I(){t r=u/D*2T;q.2e=1;q.2U=f.J.2r;q.G();t b=f.2r*(f.V.H-1);Q(t i=0;i<b;++i){t a=45+i*(1U/b);q.1z(S(a));q.P();q.1K(0,r);q.F(0,r-u/D*7.5);q.1X();q.R();q.G()}};v 3F(){t r=u/D*55;Q(t i=0;i<f.V.H;++i){t a=45+i*(1U/(f.V.H-1)),p=1w(r,S(a));q.1x=20*(u/1q)+"2i 2Y";q.L=f.J.3e;q.2e=0;q.2h="2f";q.27(f.V[i],p.x,p.y+3)}};v 3D(){z(!f.1J){C}q.G();q.1x=24*(u/1q)+"2i 2Y";q.L=f.J.1J;q.2h="2f";q.27(f.1J,0,-u/4.25);q.R()};v 3z(){z(!f.1E){C}q.G();q.1x=22*(u/1q)+"2i 2Y";q.L=f.J.1E;q.2h="2f";q.27(f.1E,0,u/3.25);q.R()};v 32(a){t b=f.2q.2E,34=f.2q.2D;a=1R(a);t n=(a<0);a=E.35(a);z(b>0){a=a.5t(b).2V().1j(\'.\');Q(t i=0,s=34-a[0].H;i<s;++i){a[0]=\'0\'+a[0]}a=(n?\'-\':\'\')+a[0]+\'.\'+a[1]}O{a=E.3O(a).2V();Q(t i=0,s=34-a.H;i<s;++i){a=\'0\'+a}a=(n?\'-\':\'\')+a}C a};v 1w(r,a){t x=0,y=r,1O=E.1O(a),1T=E.1T(a),X=x*1T-y*1O,Y=x*1O+y*1T;C{x:X,y:Y}};v 3K(){q.G();t a=u/D*2T;t b=a-u/D*15;Q(t i=0,s=f.1o.H;i<s;i++){t c=f.1o[i],39=(f.1b-f.K)/1U,1P=S(45+(c.1n-f.K)/39),1N=S(45+(c.1D-f.K)/39);q.P();q.1z(S(2X));q.16(0,0,a,1P,1N,U);q.R();q.G();t d=1w(b,1P),3a=1w(a,1P);q.1K(d.x,d.y);q.F(3a.x,3a.y);t e=1w(a,1N),3b=1w(b,1N);q.F(e.x,e.y);q.F(3b.x,3b.y);q.F(d.x,d.y);q.1C();q.L=c.1F;q.T();q.P();q.1z(S(2X));q.16(0,0,b,1P-0.2,1N+0.2,U);q.R();q.1C();q.L=f.J.2P;q.T();q.G()}};v 2L(){t a=u/D*12,1f=u/D*8,1u=u/D*3X,1r=u/D*20,2l=u/D*4,1B=u/D*2,38=v(){q.3f=2;q.3g=2;q.2o=10;q.2n=\'1e(5L, 3h, 3h, 0.45)\'};38();q.G();z(N<0){N=E.35(f.K-N)}O z(f.K>0){N-=f.K}O{N=E.35(f.K)+N}q.1z(S(45+N/((f.1b-f.K)/1U)));q.P();q.1K(-1B,-1r);q.F(-2l,0);q.F(-1,1u);q.F(1,1u);q.F(2l,0);q.F(1B,-1r);q.1C();q.L=1l(f.J.1t.2s,f.J.1t.3c,1u-1r);q.T();q.P();q.F(-0.5,1u);q.F(-1,1u);q.F(-2l,0);q.F(-1B,-1r);q.F(1B/2-2,-1r);q.1C();q.L=\'1e(1Y, 1Y, 1Y, 0.2)\';q.T();q.R();38();q.P();q.16(0,0,a,0,E.1a*2,M);q.L=1l(\'#3s\',\'#36\',a);q.T();q.R();q.P();q.16(0,0,1f,0,E.1a*2,M);q.L=1l("#47","#48",1f);q.T()};v 3i(x,y,w,h,r){q.P();q.1K(x+r,y);q.F(x+w-r,y);q.23(x+w,y,x+w,y+r);q.F(x+w,y+h-r);q.23(x+w,y+h,x+w-r,y+h);q.F(x+r,y+h);q.23(x,y+h,x,y+h-r);q.F(x,y+r);q.23(x,y,x+r,y);q.1C()};v 2K(){q.G();q.1x=40*(u/1q)+"2i 30";t a=32(g),2Z=q.4f(\'-\'+32(0)).19,y=u-u/D*33,x=0,2W=0.12*u;q.G();3i(-2Z/2-0.21*u,y-2W-0.4i*u,2Z+0.3n*u,2W+0.4k*u,0.21*u);t b=q.4l(x,y-0.12*u-0.21*u+(0.12*u+0.3o*u)/2,u/10,x,y-0.12*u-0.21*u+(0.12*u+0.3o*u)/2,u/5);b.1V(0,"#37");b.1V(1,"#3k");q.2U=b;q.2e=0.3n*u;q.1X();q.2o=0.3p*u;q.2n=\'1e(0, 0, 0, 1)\';q.L="#4o";q.T();q.R();q.3f=0.3q*u;q.3g=0.3q*u;q.2o=0.3p*u;q.2n=\'1e(0, 0, 0, 0.3)\';q.L="#31";q.2h="2f";q.27(a,-x,y);q.R()}};W.28=U;(v(){t d=2R,h=d.3r(\'4r\')[0],2S=4t.4u.4v().4w(\'4x\')!=-1,2Q=\'4z://4A-4B.4C/4D/4E/4F-7-4G.\'+(2S?\'4H\':\'4I\'),1I="@1x-4K {"+"1x-4L: \'30\';"+"4M: 2Q(\'"+2Q+"\');"+"}",1s,r=d.3w(\'1v\');r.2N=\'1I/4Q\';z(2S){h.2p(r);1s=r.2I;1s.3A=1I}O{4U{r.2p(d.4V(1I))}4W(e){r.3A=1I}h.2p(r);1s=r.2I?r.2I:(r.4X||d.3B[d.3B.H-1])}t b=2x(v(){z(!d.3C){C}2b(b);t a=d.3w(\'50\');a.1v.51=\'30\';a.1v.52=\'53\';a.1v.1h=a.1v.19=0;a.1v.54=\'56\';a.57=\'.\';d.3C.2p(a);58(v(){W.28=M;a.59.5a(a)},3y)},1)})();W.2t=[];W.2t.5b=v(a){z(1H(a)==\'5c\'){Q(t i=0,s=A.H;i<s;i++){z(A[i].B.Z.18(\'5e\')==a){C A[i]}}}O z(1H(a)==\'5f\'){C A[a]}O{C 2u}};v 3E(a){z(2G.3G){2G.3G(\'5h\',a,U)}O{2G.5i(\'5j\',a)}}3E(v(){v 2F(a){t b=a[0];Q(t i=1,s=a.H;i<s;i++){b+=a[i].1Z(0,1).5m()+a[i].1Z(1,a[i].H-1)}C b};v 3J(a){C a.5o(/^\\s+|\\s+$/g,\'\')};t c=2R.3r(\'5p\');Q(t i=0,s=c.H;i<s;i++){z(c[i].18(\'1k-2N\')==\'5r-5s\'){t d=c[i],B={},1m,w=2c(d.18(\'19\')),h=2c(d.18(\'1h\'));B.Z=d;z(w){B.19=w}z(h){B.1h=h}Q(t e=0,1s=d.3N.H;e<1s;e++){1m=d.3N.5w(e).5x;z(1m!=\'1k-2N\'&&1m.1Z(0,5)==\'1k-\'){t f=1m.1Z(5,1m.H-5).5y().1j(\'-\'),I=d.18(1m);z(!I){2z}5B(f[0]){2y\'J\':{z(f[1]){z(!B.J){B.J={}}z(f[1]==\'1t\'){t k=I.1j(/\\s+/);z(k[0]&&k[1]){B.J.1t={2s:k[0],3c:k[1]}}O{B.J.1t=I}}O{f.5D();B.J[2F(f)]=I}}26}2y\'1o\':{z(!B.1o){B.1o=[]}2w=I.1j(\',\');Q(t j=0,l=2w.H;j<l;j++){t m=3J(2w[j]).1j(/\\s+/),1Q={};z(m[0]&&m[0]!=\'\'){1Q.1n=m[0]}z(m[1]&&m[1]!=\'\'){1Q.1D=m[1]}z(m[2]&&m[2]!=\'\'){1Q.1F=m[2]}B.1o.3T(1Q)}26}2y\'1c\':{z(f[1]){z(!B.1c){B.1c={}}z(f[1]==\'2O\'&&/^\\s*v\\s*\\(/.5H(I)){I=3U(\'(\'+I+\')\')}B.1c[f[1]]=I}26}5J:{t n=2F(f);z(n==\'13\'){2z}z(n==\'V\'){I=I.1j(/\\s+/)}O z(n==\'2C\'||n==\'2H\'){I=I==\'M\'?M:U}O z(n==\'2q\'){t o=I.1j(\'.\');z(o.H==2){I={2D:2c(o[0]),2E:2c(o[1])}}O{2z}}B[n]=I;26}}}}t g=2v W(B);z(d.18(\'1k-3V\')){g.3m(1R(d.18(\'1k-3V\')))}z(d.18(\'1k-13\')){g.13=v(){3U(A.B.Z.18(\'1k-13\'))}}g.1g()}}});',62,358,'||||||||||||||||||||||||||ctx|||var|max|function||||if|this|config|return|100|Math|lineTo|save|length|attrValue|colors|minValue|fillStyle|true|fromValue|else|beginPath|for|restore|radians|fill|false|majorTicks|Gauge|||renderTo||||onready|CX||arc|CY|getAttribute|width|PI|maxValue|animation|cctx|rgba|r2|draw|height|cache|split|data|lgrad|prop|from|highlights|self|200|rOut|ss|needle|rIn|style|rpoint|font|CW|rotate|CH|pad2|closePath|to|units|color|imready|typeof|text|title|moveTo|pow|progress|ea|sin|sa|hlCfg|parseFloat|toValue|cos|270|addColorStop|object|stroke|255|substr||025||quadraticCurveTo|||break|fillText|initialized|cfg|r1|clearInterval|parseInt||lineWidth|center|delta|textAlign|px|delay|applyRecursive|pad1|duration|shadowColor|shadowBlur|appendChild|valueFormat|minorTicks|start|Collection|null|new|hls|setInterval|case|continue|60|80|strokeTicks|int|dec|toCamelCase|window|glow|styleSheet|i8d|drawValueBox|drawNeedle|baseInit|type|fn|plate|url|document|ie|81|strokeStyle|toString|th|90|Arial|tw|Led|444|padValue||cint|abs|ccc|888|shad|vd|pe|pe1|end|128|numbers|shadowOffsetX|shadowOffsetY|143|roundRect|eee|666|animate|setRawValue|05|045|012|004|getElementsByTagName|f0f0f0|r3|getContext|cycle|createElement|d0|250|drawUnits|cssText|styleSheets|body|drawTitle|domReady|drawNumbers|addEventListener|drawMajorTicks|drawMinorTicks|trim|drawHighlights|drawPlate|clearRect|attributes|round|translate|step|Date|_animate|push|eval|value|the|77|240|creating||when|ddd|aaa|specified||not|e8e8e8|f5f5f5|fafafa|drawImage|was|quint|element|quad|measureText|Canvas|fff|04|Error|07|createRadialGradient|throw|Array|babab2|call|linear|head|cloneNode|navigator|userAgent|toLocaleLowerCase|indexOf|msie|prototype|http|smart|ip|net|styles|fonts|digital|mono|eot|ttf|180|face|family|src|315|Object|in|css|getValue|elastic|clear|try|createTextNode|catch|sheet|createLinearGradient|updateConfig|div|fontFamily|position|absolute|overflow||hidden|innerHTML|setTimeout|parentNode|removeChild|get|string|setValue|id|number|93|DOMContentLoaded|attachEvent|onload|bounce|lineCap|toUpperCase|999|replace|canvas|91|canv|gauge|toFixed|d1|getElementById|item|nodeName|toLowerCase|88|d2|switch|acos|shift|122|85|delete|test|160|default|tagName|188'.split('|'),0,{}))
		function GetArduinoInputs()
		{
			nocache = "&nocache=" + Math.random() * 1000000;
			var request = new XMLHttpRequest();
			request.onreadystatechange = function()
			{
				if (this.readyState == 4) {
					if (this.status == 200) {
						if (this.responseXML != null) {
							document.getElementById("inputAN0").innerHTML =
								this.responseXML.getElementsByTagName('analog')[0].childNodes[0].nodeValue;
								data_valAN0 = this.responseXML.getElementsByTagName('analog')[0].childNodes[0].nodeValue;
							document.getElementById("inputAN1").innerHTML =
								this.responseXML.getElementsByTagName('analog1')[0].childNodes[0].nodeValue;
								data_valAN1 = this.responseXML.getElementsByTagName('analog1')[0].childNodes[0].nodeValue;
							document.getElementById("inputDIG2").innerHTML =
								this.responseXML.getElementsByTagName('digital')[0].childNodes[0].nodeValue;
								data_valDIG2 = this.responseXML.getElementsByTagName('digital')[0].childNodes[0].nodeValue;
							document.getElementById("inputAM2320T").innerHTML =
								this.responseXML.getElementsByTagName('am2320t')[0].childNodes[0].nodeValue;
								data_valAM2320TEMP = this.responseXML.getElementsByTagName('am2320t')[0].childNodes[0].nodeValue;
							document.getElementById("inputAM2320H").innerHTML =
								this.responseXML.getElementsByTagName('am2320h')[0].childNodes[0].nodeValue;
								data_valAM2320HUM = this.responseXML.getElementsByTagName('am2320h')[0].childNodes[0].nodeValue;
								}
					}
				}
			}
			request.open("GET", "ajax_inputs" + nocache, true);
			request.send(null);
			setTimeout('GetArduinoInputs()', 200);
			
		}
	</script>
    </head>
    <body onload="GetArduinoInputs()">
        <h1>
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
        <font color="#99ffff">O</font><font color="#93f9ff">s</font><font color="#8df3ff">m</font><font color="#87edff">o</font><font color="#81e7ff">s</font><font color="#7ce2ff">e</font><font color="#76dcff">u</font><font color="#70d6ff">r</font><font color="#6ad0ff"> </font><font color="#64caff">P</font><font color="#5ec4ff">l</font><font color="#58beff">a</font><font color="#52b8ff">n</font><font color="#4db3ff">t</font><font color="#47adff">e</font><font color="#41a7ff">s</font><font color="#3ba1ff"> </font><font color="#359bff">C</font><font color="#2f95ff">a</font><font color="#298fff">r</font><font color="#2389ff">n</font><font color="#1d83ff">i</font><font color="#187eff">v</font><font color="#1278ff">o</font><font color="#0c72ff">r</font><font color="#066cff">e</font><font color="#0066ff">s</font>
        </h1>
		<br>
        <canvas id="an_gauge_1" data-title="TDS IN" data-units="ppm" data-value-format="3.0" data-major-ticks="0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180" data-type="canv-gauge" data-min-value="0" data-max-value="180" data-onready="setInterval( function() { Gauge.Collection.get('an_gauge_1').setValue(data_valAN0);}, 200);"></canvas>
        <canvas id="an_gauge_2" data-title="TDS OUT" data-highlights="0 10 #82e0aa, 10 15 #d68910, 15 20 #cb4335" data-units="ppm" data-value-format="2.0" data-major-ticks="0  5 10 15 20" data-type="canv-gauge" data-min-value="0" data-max-value="20" data-onready="setInterval( function() { Gauge.Collection.get('an_gauge_2').setValue(data_valAN1);}, 200);"></canvas>
        <canvas id="dig_gauge_1" data-title="TEMP EAU" data-highlights="0 10 #d6eaf8, 10 20 #85c1e9, 20 30 #82e0aa, 30 40 #c0392b" data-value-format="2.2" data-units="&deg;C" data-major-ticks="0 10 20 30 40" data-type="canv-gauge" data-min-value="0" data-max-value="40" data-onready="setInterval( function() { Gauge.Collection.get('dig_gauge_1').setValue(data_valDIG2);}, 200);"></canvas>
        <br><br>
        <canvas id="dig_gauge_2" data-title="TEMP&Eacute;RATURE" data-highlights="0 10 #d6eaf8, 10 20 #85c1e9, 20 30 #82e0aa, 30 40 #d68910, 40 50 #cb4335" data-value-format="2.2" data-units="&deg;C" data-major-ticks="0 10 20 30 40 50" data-type="canv-gauge" data-min-value="0" data-max-value="50" data-onready="setInterval( function() { Gauge.Collection.get('dig_gauge_2').setValue(data_valAM2320TEMP);}, 200);"></canvas>&nbsp;&nbsp;&nbsp;
        <canvas id="dig_gauge_3" data-title="HUMIDIT&Eacute;" data-highlights="0 35 #cb4335, 35 45 #d68910, 45 60 #82e0aa, 60 70 #85c1e9, 70 80 #2e86c1" data-value-format="2.2" data-units="%" data-major-ticks="0 10 20 30 40 50 60 70 80" data-type="canv-gauge" data-min-value="0" data-max-value="80" data-onready="setInterval( function() { Gauge.Collection.get('dig_gauge_3').setValue(data_valAM2320HUM);}, 200);"></canvas>
		<br><br>
        <table style="width: 650px; float: left;margin-left:40px;" border="0">
			<tbody>
				<tr>
				<td>
					TDS IN : <span id="inputAN0">...</span> ppm<br>
					TDS OUT : <span id="inputAN1">...</span> ppm<br>
					Temp&eacute;rature eau : <span id="inputDIG2">...</span> &deg;C
				</td>
				<td style="vertical-align: top;">
					Temp&eacute;rature Garage : <span id="inputAM2320T">...</span> &deg;C<br>
					Humidit&eacute; Garage : <span id="inputAM2320H">...</span> %
				</td>
				</tr>
			</tbody>
		</table>
	</body>
</html>

Librairie TDS Meter Gravity :
https://github.com/DFRobot/GravityTDS

:face_with_monocle:

La suite au prochain épisode ! :wave:

On attend le code et les photos !

:wink:

Yeap c'est pour bientôt ! :rocket:

Petit mise à jour du message principal avec l'ajout des codes et librairies ! :see_no_evil:

Des axes d'améliorations ? Optimisations du code ? Corrections du code ? Je suis preneur !!!
:+1:

La suite au prochain épisode ! :wave:

ça se lit bien (j'ai regardé en diagonale) et ça a l'air propre
bravo

Étonné que le code soit propre :open_mouth:
Merci

Il y a le

Qui est dommage puisque ailleurs vous utilisez millis

Merci de ton retour, noté dans les taches de ma todolist ... éjecter le delay(2000); et bannir les delay à l'avenir ! :+1:
J'avais effectivement lu de ci de la qu'il était préférable de ne pas, plus utiliser delay.

Je travail actuellement sur les débitmètre :grimacing: , ensuite capteur de pression et je m'occupe du delay

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.