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 ![]()
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 ![]()
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 ![]()
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 ![]()
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

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 ! ![]()
https://youtu.be/wixF8ooS9ZU
La Platine réunissant tous les composant :
Codes du projet :
Soyez indulgent sur le code ! ![]()
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>
<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="°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É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="°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>
<canvas id="dig_gauge_3" data-title="HUMIDITÉ" 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érature eau : <span id="inputDIG2">...</span> °C
</td>
<td style="vertical-align: top;">
Température Garage : <span id="inputAM2320T">...</span> °C<br>
Humidité Garage : <span id="inputAM2320H">...</span> %
</td>
</tr>
</tbody>
</table>
</body>
</html>
Librairie TDS Meter Gravity :
https://github.com/DFRobot/GravityTDS
![]()
La suite au prochain épisode ! ![]()






