Chauffage SOLAIRE THERMIQUE à Aussillon (Tarn)



Sommaire rapide : mise en place des panneaux - schéma - ballon - vannes - fonctionnement chauffage - serpentin poêle - remplissage solaire - différents type de raccords - cout total - Automatisation - commandes circulateurs - programme complet - conclusion.

 

Début 2014, je tombe sur une annonce de chauffe-eau solaire par thermosiphon Giordano de 1980 à 100euros (à 10Km de chez nous). Après installation, je m'aperçois soudain - oh, miracle ! - que le soleil est capable de chauffer l'eau jusqu'à 80°C ! L’énergie du soleil est énorme !

Dès lors, je lis des livres (de l'Apper : "Installer un chauffage ou un chauffe-eau Solaire", "Installations solaires thermiques" de Peuser, Remmers, Schnauss, et d'autres livres comme "La Conception Bioclimatique" éditions Terre Vivante d'Olivier Oliva et de Samuel Courgey) et consulte les forums ( http://forum.apper-solaire.org/ , http://www.chaleurterre.com/forum/ , https://www.econologie.com/forums/ ) sur le web pour me former au solaire thermique.

Bilan :
La meilleure façon de récupérer la chaleur du soleil pour chauffer une maison est la maison bioclimatique : isolation extrême (mur terre-paille-chaux pour éviter l'étanchéité, car la chaux respire contrairement au ciment/béton), terrain en pente vers le sud, grande baie vitrée plein sud, gros mur Trombe (ici) ou mur capteur derrière la baie vitrée (à quelques mètres) qui va réguler la température de la maison (notion de "masse thermique" ou "inertie thermique"), et surtout une casquette (avancée de toit) bien calculée qui empêche le soleil de rentrer de fin avril à septembre, quand celui-ci est haut dans le ciel, afin d'éviter les surchauffes l'été. On voit même sur cet exemple, à l'ouest (gauche), la maison qui se referme un peu pour éviter l'entrée du coucher de soleil l'été :

 

Si pas possible de construire du neuf et pas possible de faire de grosses modifications au bâtiment, il reste les panneaux solaires thermiques :

Notre MAISON : près de Mazamet dans le Tarn (Occitanie). Maison de 1913 (rue Blériot à Aussillon), en pierres, 40m² au sol sur 3 étages : cave (non chauffée), rez-de-chaussée (salon/cuisine/WC), étage (1/3 mansardé).


Après travaux isolation ouest et toiture :

Historique des travaux d'isolation :

Aout 2011 : changement vieille chaudière gaz (foutue) par chaudière gaz à condensation (A SAVOIR : la condensation ne fonctionne qu'avec une eau de départ en dessous de 55°C, et plus c'est en dessous, plus la condensation se fait et le rendement de la chaudière augmente. L'idéale est donc de la coupler à un plancher chauffant ou à des murs chauffants).
Septembre 2012
: changement des menuiseries de toute la maison par du PVC ou bois (bois beaucoup plus performant) en double vitrage (cout d'env. 5000€).
Septembre 2015 : toiture refaite (nombreuses fuites) et isolée par l'extérieur avec 13cm de polyuréthane (matériel non écologique, car demande beaucoup d’énergie à sa fabrication... En laine de bois il fallait le double d'épaisseur et le prix doublait également : 20 000euros au lieu de 10 000 env.).
Décembre 2015 : isolation des murs extérieurs ouest, est et sud de l'étage, par 13cm de polystyrène (matériel non écologique, car demande beaucoup d’énergie à sa fabrication. Env. 15 000 euros).
Janvier 2016 : j'isole par l'intérieur les derniers murs non encore isolés (surtout au nord, car la présence du trottoir nous interdisait de le faire par l'extérieur) avec des plaques de placo/laine de roche récupérées. J'en profite pour faire des murs chauffants (modèle Pierre Amet, multicouche 16mm).

Maintenant isolé, on commençait à avoir plus chaud dans la maison, tout en chauffant beaucoup moins. La chaudière - passée en basse température grâce aux murs chauffants - consommait peu et lorsqu'on allumait le poêle le soir pendant seulement 1h, ça chauffait beaucoup plus vite : on ne devait plus chauffer les murs avant de se chauffer. Puis le lendemain, il ne faisait pas 13°C, mais 16-17°C.

Isoler le plafond de la cave ou pas ? (impossible d'isoler les murs, il faut les laisser respirer, car ils sont enterrés). Entre mai et septembre, la cave rafraichit la maison, ce qui est très intéressant avec les canicules. Entre septembre et fin décembre, la cave - à env. 17°C - chauffe un peu la maison. Mais l'hiver, entre fin décembre et avril, la cave (à 13-17°C) refroidit plus souvent la maison. Donc l'isolation du plafond de la cave ne serait intéressant qu'entre fin décembre et avril.


Les 2 modes de chauffage :

1 - Poêle fonte Jotul F3 : 1 à 2 stères de bois brulé/an (allumé - à feu très vif pour moins polluer - 1h le matin et 1h le soir lors des grands froids).
2 - Chaudière gaz à condensation (4 500KW/an) en basse T°C pour murs chauffants (modèle Pierre Amet, multicouche 16mm), et 4 radiateurs acier (2 dans chaque chambre qu'on chauffe à 15°C, 1 dans cuisine et 1 sèche serviette dans salle de bain)
La chaudière est réglée continuellement à 15°C sauf entre 6-7h et 18-21h à 17°C.

Mise en place des panneaux solaires :

La maison est petite, nous n'avons pas beaucoup de place : première idée, mettre les panneaux sur le gazon ?

---> On s'est dit que ce ne serait pas pratique pour passer la tondeuse hélicoïdale entre les panneaux...

Février 2018 :

Pas très esthétique, mais on ne peut pas tout avoir.
La toiture de la maison (pas très grande) est réservée, peut-être, aux futurs panneaux photovoltaïques (beaucoup plus légers).

Une partie des panneaux a été achetée d'occasion (ceux du garage à gauche, à 100€ pièce, des Roth) et les trois sur la façade de la maison sont des Tinox LM112 à 350€ pièce. L'avantage des Tinox est que ce sont des raccords à compression, sans joint et pratiquement sans fuite (avec le liquide anti-gel, il semble que le "sans fuite" n'existe pas...). Pour les 4 Roth du garage, les raccords à joins fuient facilement avec le glycol. Il faut utiliser des joints PTFE blanc (les joints gaz bleus fuient aussi).

Pour la fixation sur la façade de la maison, j'ai planté des cornières galvanisées dans le mur en pierre (le galvanisé coute un bras, mais ça évite d'avoir des trainées de rouille sur la façade). La difficulté avec les murs de pierres est de faire les trous là où on veut les faire. Les pierres derrière décident toujours par où passera le foret..., c'est à dire entre les pierres. Une fois le trou fait, on mouille bien au pulvérisateur de jardin (pas au tuyau d'arrosage quand même..., pour ne pas retrouver de l'eau dans la maison) et on remplit avec du ciment pâteux (j'utilise un vieux morceau de gouttière et un bâton de bois pour pousser le ciment). 3 ans après, ça n'a pas bougé.

Avec les panneaux horizontaux qui s'emboitent les uns dans les autres, il faut être très précis dans le parallélisme et l'horizontalité des supports. J'ai dû ajuster le tout avec des écrous de réhaussement.

(photo ecrous)

 

Pour fixer les panneaux du garage, j'ai mis une cornière au dessus et une cornière en dessous des panneaux (fixée sur la charpente du toit). Les jambes de maintien sont fixées par des tiges filetées qui traversent les poutres de la toiture :

 

PANNEAUX : 7 panneaux (ou "capteur plan") de 2m² à 85° par rapport à l'horizontale :

- 3 panneaux Tinox horizontaux LM112 (forme intérieure des tuyau = "échelle" ou "harpe") de Solaire Diffusion sur la facade avec des raccords à compression (efficacité garantie contre les fuites). Le seul problème de ces panneaux est que lorsqu'il faut démonter celui du milieu, il faut décaler aussi ceux des côtés. Il y a parfois un peu de buée, mais rien de grave.

- 4 panneaux Roth (serpentin à l'intérieur). J'en ai acheté 8 pour 800€. Ils avaient l'air en très bon état sur la photo, mais arrivée sur place, à 280Km de chez moi - vers Marseille -, ils étaient très oxydés, sauf un, celui qu'on m'avait montré en photo... Deux ans après, lorsque je les ai branchés, il y en avait 2 qui fuyaient ! Comme ils sont vraiment moches, on a préféré en acheter 3 neufs pour la façade. Ces panneaux, comme les LM112, se démontent facilement en détachant le cadre du devant (notice de l'apper).

Avec l'oxydation des panneaux Roth et l'isolation un peu plus faible des panneaux Tinox (au niveau des bouches d'aération qui diminuent la condensation), le rendement des 2 modèles est assez semblable. J'ai remarqué que lorsque le soleil monte (à partir d'avril), l'eau en sortie des Roth devient moins chaude que les Tinox. Mais entre sept et avril, les 4 panneaux du garage (ouest) sorte une eau 2 à 10°C plus chaude que les 3 panneaux en façade ; je pense que c'est dû à l'absorption différente de la vitre des panneaux. Aussi, en fonction des heures de la journée, P6 chauffe davantage, ou alors P7 (voir plus bas) : c'est à cause du reflet sur le toit de verre de la petite serre devant ces 2 panneaux.

Isolation circuit panneaux : bien protéger les manchons noirs d'isolation du soleil et de la pluie (avec par exemple une chute de bâche EPDM, de la goutière en zing, etc.). Le blanc est généralement plus voyant que le noir...

SCHEMA :

J'avais pris beaucoup de notes durant mes lectures/recherches de 2 ans, donc ça n'a pas été trop compliqué de faire ce schéma que j'avais quasi entièrement dans la tête ; le travail est en amont, pour se former et comprendre les choses :


(Ce schéma au format photoshop, si vous voulez le réutiliser)

La liaison ballon-panneaux solaires est en cuivre de 22mm, brasée (PAS d'étain sur le circuit solaire qui peut monter à 150°C !) . J'ai respecté l'égalité des distances en faisant la boucle de tickelman (l'eau prend toujours le chemin le plus court. Il faut que les distances depuis la station solaire soient les même pour chaque panneau, sinon, le panneau dont le chemin est plus court fonctionnera plus que les autres).

Bien réfléchir aux phénomènes de dilatation : en évitant de brancher un panneau (qui connait des changements de température de -10°C à +150°C) directement après plusieurs mètres de ligne droite. Mettre un coude juste avant, il pliera légèrement et encaissera les dilatations.

Afin de limiter les pertes de charge et moins fatiguer le circulateur, il faut éviter les coudes secs à 90°C. Prendre plutôt des coudes larges ou 2 coudes de 45° montés ensemble. De même, les liaisons rapides en inox créaient de la perte de charge (mais elles sont tellement pratiques...
).

BALLON :


Merci aux voisins qui m'ont aidé à le rentrer... (200Kg)

Commandée en Allemagne, 800 litres, 2 serpentins acier et un serpentin "hygiénique" en inox pour l'eau sanitaire (en jaune, au milieu sur le schéma ci-dessus). Ne jamais le déplacer à l'horizontale ou le coucher (à cause du poids des serpentins à l'intérieur, qui pourraient les plier et casser les soudures). Le ballon de 800L est à la cave et c'est le plus gros que je puisse rentrer dans la maison (j'ai dû "démonter" la fenêtre et son cadre...). Avec 7 panneaux, il me fallait normalement 1500L de réserve pour ne pas être en surchauffe l'été ; c'est pour cela que j'ai mis les panneaux très à la verticale (85° / horizontale). Pour l'hiver, avoir plus de réserve ne servirait à rien : en mars, lorsque j'ai vidé la cuve dans les radiateurs (jusqu'à température haut de cuve = 26°C), il faut env. 5h de super soleil (ciel non voilé) pour remonter la cuve à 50°C (que je revide aussitôt à 26°C pour être sûr de redémarrer rapidement le chauffage par le solaire le lendemain). Je n'ai pas vraiment d'excédant de chaleur et ma cuve de 800L suffit. Par contre, en octobre, comme le soleil commence à être bas, s'il y a un grand soleil et qu'il ne fait pas froid, je ne consomme pas les calories solaires, donc ma cuve monte jusqu'à 75°C (j'ai amélioré le programme en "cassant" le rendement à cette période. Et si le ballon dépasse les 75°C, j'envoie l'eau chaude dans les panneaux la nuit pour refroidir le système). Si j'avais eu 1500L, je n'aurais pas eu ces problèmes de surchauffe. Les maisons bioclimatiques ont souvent le même problème. Si la maison est bien conçue, ce n'est pas l'été qu'elle a des surchauffes (le soleil ne rentre pas), mais plutôt en octobre.

Isolation du ballon : Je conseille fortement de la faire avant tout branchement de tuyau (si vous la faites à la fin, c'est vraiment plus compliqué au niveau des raccords). Il vaut mieux aussi limiter les entrées-sorties au niveau du ballon pour limiter les pertes des chaleurs (si j'avais su, j'aurais enlevé V5 et V6 pour ne garder que V4, vu qu'avec les vannes V8-V7, je mixte et régle à la température que je veux).
Afin d'économiser, je n'ai pas acheté l'isolant du constructeur du ballon. J'ai isoler en 2 couches de laine de verre (récup), au total 30cm d'isolant, recouvert d'un film étirable en plastique pour éviter d'avoir la poussière de laine de verre dans la pièce.
Même très bien isolé, le ballon génère de la chaleur en été : pour nous, ça fait monter d'env. 2-3°C la partie de la cave où il est.
L'été (cave à 22°C), lorsque j'ai le haut du ballon à 75°C, 24h après, il est à env. 70°C (sans consommation de chaleur et sans apport). Si le haut de la cuve est à 55°C, je perds moins de 2°C/24h (et à 28°C haut cuve, je perds env. 1°C/24h, sans prélévement/apport). Plus le ballon est très chaud, plus il perd vite sa chaleur. On voit là qu'une réserve énorme d'eau très chaude ne sert à rien puisqu'on ne pourra pas la garder très longtemps. S'il n'y a pas de soleil, un système solaire ne fonctionne jamais très longtemps...


On peut coudre les morceaux d'isolant à l'aide d'une ficelle et d'une grosse aiguille.
Je conseille d'isoler AVANT de faire les branchements de plomberie.

J'ai aussi posé le ballon sur des plaques de polystyrène extrudé récupérées (enfermées dans un sac plastique) avec par dessus une plaque de plastique (panneau publicitaire) ; rien qui ne pourrit. Et je m'arrange pour avoir le minimum au sol afin de faciliter le ménage.

 

Raccords sur le serpentin d'eau sanitaire en inox : j'ai utilisé du multicouche qui est censé résister jusque 95°C (la température maxi autorisée pour le ballon est de 90°C).
Les manchons bleus isolent, mais servent surtout à évacuer l'eau d'éventuelles fuites vers l'extérieur de l'isolation du ballon (sans enlever l'isolant, je peux vérifier qu'il n'y a pas de fuite, puisque l'eau descendra dans ces manchons bleus).
Pour éviter la légionellose, il faut avoir, de temps en temps, une température supérieure à 55°C.
On peut voir le purgeur (gris, à placer dans tous les points hauts) qui permet d'évacuer l'air qui serait dans le ballon (et qui fait aussi rentrer l'air si on vide le ballon...). On remarque aussi les raccords diélectriques (plastique avec bague de cuivre) qui isolent électriquement le ballon du réseau d'eau de ville (mais le multicouche le fait déjà).


Sur le ballon, il est fortement conseillé de mettre des vannes partout pour pouvoir modifier ou démonter le circuit sans vider le ballon (sauf sur les serpentins qu'on peut vider facilement) :

Côté raccords circuit chauffage

Côté raccords circuit solaire

 

Mon ballon n'est pas recouvert d'émail à l'intérieur. Ce n'est pas nécessaire, car l'eau qu'il contient est de l'eau du circuit chauffage radiateur, donc de "l'eau morte" qui perd son oxygène avec le temps (il faut donc éviter de le vider ou de vider le circuit de chauffage trop souvent). D'après ce que j'ai lu, les revêtements émaillés ne sont d'ailleurs pas formidables : il y a toujours un endroit moins bien émaillé qui finit par s'oxyder. Les problèmes d'oxydation des ballons surviennent surtout avec l'eau sanitaire venant de la ville qui contient de l'oxygène. Dans mon ballon, cette eau passe uniquement dans le "serpentin sanitaire" en inox.

Composition des raccords pour la protection du ballon :

- circuit solaire : serpentins acier du ballon + raccord acier brut ou fer noir (PAS d'acier galvanisé avec glycol) + raccord diélectrique 3/4" + raccord laiton + tuyau cuivre 22mm

- circuit chauffage : ballon acier + raccord acier galvanisé + raccord diélectrique 3/4" + raccord laiton + tuyau cuivre 22mm + radiateurs (une vieille partie en acier, du multicouche dans les murs chauffants, quelques très petites longueurs en PER BAO)

- circuit EauChaudeSanitaire : serpentin inox + coude inox + raccord diélectrique 3/4" + raccord laiton + multicouche + tuyau cuivre 14mm (à l'arrivée d'eau de ville, je mets un petit filtre avec des aimants autour pour être sûr qu'il n'y ait pas de particules d'acier qui aillent dans le ballon inox)

- doigts de gant en inox et bouchons en inox ou acier galva.

Si vous achetez un ballon entièrement en inox, il faut prendre de l'inox austénique (21% de chrome et 7% de Nickel) et faire attention qu'aucune particule d'acier ne rentre dans le ballon (mettre des filtres aux l'entrées). Le ballon 100% inox n'est pas forcément la solution idéale et sans oxydation...

Sur le site de l'apper-solaire, il y a une excellente fiche sur les problèmes de corrosion galvanique : ici ou ici.

Normalement, sur mon ballon, il n'y a pas besoin d'anode magnésium, mais j'en ai quand même mis une pour apporter un peu de minéraux à mon eau. J'ai d'ailleurs lu qu'il ne fallait pas remplir son ballon avec de l'eau de pluie très peu minéralisée.

 

Il existe des systèmes électroniques d' "anode hydride" ou anode à courant permanent (ou imposé, AEP) type Correx. C'est une électrode en titane qui est entré dans le ballon et qui émet un courant pour contrer le courant d'électrolyse d'oxydation.

Pour vérifier l'état d'une anode magnésium : on débranche le fil de l'anode en y incérant un ampèremetre : l'anode est bonne si le courant > 0,3mA (en général, c'est à 0,8mA) entre le fil de l'anode et la terre. Une anode a une durée de vie de 10 ans.

Normalement il faut mettre le ballon sur la prise de terre, mais j'ai lu que cela pouvait augmenter l'oxydation du ballon (en créant un courant qui va à la terre...).

 

Les prises de température sur le ballon : il n'y en a que trois possibles et je regrette de ne pas avoir mis une ligne de 6-7 capteurs DS18B20 collés sur la tôle du ballon afin d'avoir plus de précision :

 

LES DIFFERENTES VANNES :


(Ce schéma au format photoshop, si vous voulez le réutiliser)

V1 : j'ai dû l'ajouter à cause d'un effet thermosiphon qui se mettait en marche, dans le sens normal du circulateur C1 : lorsque la cuve était bien chaude et que dehors il faisait assez froid, l'eau du ballon remonté naturellement. Les panneaux solaires sont en effet 4 à 5m plus haut que la cuve...
Dans la station solaire, il y a un clapet anti-thermosiphon au niveau du thermomètre rouge, mais celui-ci a déconné au bout d'un mois d'utilisation, donc je l'ai doublé avec celui en haut à gauche du ballon, appelé "Clapet anti-retour" sur le schéma (comme quoi les clapets c'est bien, mais rien de plus fiable qu'une vanne...). A savoir aussi, les clapets à battant ne sont pas très hermétiques, préférez des clapets à ressort.
Si comme pour moi, votre ballon est plus bas que les panneaux, l'idéal est de mettre des vannes partout pour bloquer tout phénomène de thermosiphon...

V2 : permet d'envoyer les calories de l'eau solaire au bon niveau dans le ballon (favorise la stratification). Si l'eau retour solaire est plus chaude que la sonde en milieu de cuve, alors je ferme V2 pour faire passer l'eau par le serpentin du haut. Sinon, j'ouvre V2 et l'eau prendra le chemin le plus court.

V3 : commandé directement par V1 (si V1 s'ouvre, V3 se ferme, et inversement). Plusieurs fonctions : 1- Si la température dans les panneaux est plus petite que -10°C, elle s'ouvre (V1 étant fermée), on met alors en route le circulateur C1 pour faire circuler dans le vide. C'est une protection de plus si le liquide anti-gel est défaillant (l'étape suivant est d'envoyer l'eau chaude du ballon dans les panneaux).
2- Lorsque les panneaux commencent à chauffer dans la journée, je mets en route C1, mais sans faire rentrer l'eau dans le ballon tout de suite (V1 fermée, V3 ouverte). Ce n'est que lorsque l'eau dans les tuyaux est bien chaude que j'ouvre V1 pour fermer V3, afin de faire rentrer l'eau chaude dans le ballon (ce n'est pas compliqué à faire, mais globalement, ce n'est pas indispensable ; le plus important est d'avoir du soleil...).

V4, V5, V6 : je prends ou bien je place, l'eau à la température souhaitée. Ces vannes permettent de respecter la stratification du ballon et d'éviter les remous dans le ballon (pour les flux entrant et sortant). En effet, si j'envoie une eau à 60°C en V6 alors que le haut du ballon est à 40°C, ce flux d'eau va créer beaucoup de remous en montant jusqu'en haut du ballon. Alors que si j'envoie cette eau de 60°C directement en V4, je n'aurais pas de remous et je ne créerais pas d'eau tiède.

V8 et V7 : forment une vanne de mélange 3 voies qui permet de maintenir une température de chauffage de 39°C max, lorsque c'est possible (voir aussi plus bas le chapitre chauffage).

V9 : fermée la plupart du temps, sauf quand C3 est en route.

V10 et V11 : s'ouvre lorsque la chaudière au gaz se met en route pour chauffer la maison (je ferme alors V4, V5, V6, V7, V8, V9).

V12 : vanne 3 voies qui permet le choix entre :
- Eau chaude sanitaire 100% par ballon solaire : si la température en haut du ballon solaire est supérieure à 43°C, je ne passe plus par la chaudière et j'éteins la chaudière au gaz (par un relais dans la prise).

- Eau chaude sanitaire venant du ballon solaire avec un complément de la chaudière au gaz pour être chauffée à au moins 55°C (pour tuer la légionellose).

Toutes les vannes motorisées sont en 12V (23€ pièce) : facilite l'installation, la commande, la sécurité. Inconvénient : elle font un peu de bruit (mais cela me permet de savoir ce qu'il se passe à l'oreille... elles ont toutes un bruit particulier, et un petit nom que je ne vous dirai pas)

FONCTIONNEMENT DU CHAUFFAGE MAISON :

Je veux avoir chaud dans la maison seulement lorsque c'est l'énergie solaire --> donc pas question de chauffer le ballon avec la chaudière au gaz (même si j'ai prévu cette possibilité avec un bouton dans mon programme Arduino).

J'utilise 2 thermostats : un pour la chaudière gaz (réglé à 18°C jour et 16°C nuit) et le deuxième pour le ballon solaire (réglé à 24°C jour et 19°C nuit). On voit donc que le ballon déclenche avant la chaudière.

L'idée est d'évacuer la chaleur du ballon le plus souvent possible pour permettre au circulateur solaire de démarrer même par temps peu ensoleillé (intérieur panneaux = 35°C env.).
Exemple : si j'ai le ballon à 45°C, il faut que l'eau dans les panneaux solaires soit à plus de 48°C pour démarrer la circulation solaire. Si j'ai le ballon à 25°C, il faut que l'eau des panneaux soit à 28°C pour démarrer la circulation --> donc le système démarre plus vite et je récupère plus de calories solaires. A savoir aussi, le transfert des calories de l'eau qui circulent dans les serpentins du ballon est plus efficace lorsqu'il y a une grosse différence de chaleur (ex.: eau à 55°C venant des panneaux avec un ballon à 30°C).

La maison est en pierre avec, principalement, une isolation extérieure, donc surchauffer la maison n'est pas perdu, cela chauffe les murs qui stockent la chaleur.
Tout l'hiver, j'ai le bouton "mode 0" enclenché (radiateurs sur chaudière gaz ou sur ballon solaire), et lorsque le haut du ballon dépasse les 28°C, je bloque la chaudière gaz et son circulateur (grâce à un relais en série), je place mes vannes correctement et j'active le circulateur chauffage solaire.

Gestion de la vanne 3 voies chauffage (V7-V8) :

Le mieux est de regarder dans le programme.
En gros, j'alimente mes 2 vannes (qui forment la 3 voies) par des impulsions plus ou moins longues.
Au démarrage, si la température de retour est < 18°C, la température de départ vers les radiateurs est fixée à 25°C pendant env. 3mn (j'ai vu que la chaudière au gaz fait comme ça. Je suppose que c'est pour éviter les chocs thermiques). Après, lorsque le retour est plus grand que 18°C, la température de départ vise 39°C. Au moment de faire cette partie du programme, j'ai essayé de la faire en PID, beaucoup trop compliqué pour moi, et je me suis aperçu qu'on pouvait faire beaucoup plus simple.
A savoir aussi : j'ai fixé un fusible thermique réarmable de 40°C sur le tuyau de départ qui coupe le circulateur chauffage (donc C2 ; avec un branchement en série sur l'alim 220V). Si jamais mon programme déconne ou qu'un relais reste collé, le circulateur s'éteindra. Ca m'a sauvé une fois, lors de la fabrication du programme. Ce jour-là, je me suis d'ailleurs rendu compte que même en arrêtant le circulateur C2, l'eau chaude continuée à monter dans les étages par thermosiphon... Il faut donc bien fermer systématiquement les vannes qui font le lien avec le ballon. Il est conseillé aussi de mettre la vanne 3 voies sur la partie chaude (ce que je n'ai pas fait au début), de manière à bien bloquer l'eau qui monterait par thermosiphon.

A l'usage, on a tendance à utiliser la télécommande/sonde solaire comme un bouton poussoir. C'est-à-dire que lorsqu'on voit que le lendemain il va y avoir du soleil, on met le chauffage solaire en route pour envoyer l'eau chaude dans les radiateurs afin de vider au maximum les calories du ballon solaire. Une fois sous 26°C, le chauffage solaire s'arrête (et la nuit aussi, pour éviter de faire du bruit). Le lendemain, comme la température du ballon est basse, le circulateur solaire démarrera plus vite et on récupérera plus tôt les calories solaires.

CIRCUIT POELE, serpentin :

J'en parle, mais sachez tout de suite que cela ne marche pas ! J'ai mis 10 mètres de tuyau de cuivre de 12mm de diamètre contre le tube de sortie des fumées du poêle (en le collant fortement). Mais essayer de récupérer des calories avec la chaleur des fumées, et même, en se rapprochant le plus possible du poêle, ne produit pas beaucoup d'eau chaude... Une meilleure solution serait le bouilleur, installé dans la chambre de combustion du poêle !
Dans mon programme Arduino, c
omme le serpentin chauffe très peu, je suis obligé d'arrêter le circulateur C3 toutes les minutes, le temps que l'eau chauffe suffisamment... (et même : je circule 30s, j'attends 3mn, je circule 30s, j'attends 3mn, etc. en fonction de la vivacité du feu)
En moyenne, sur une chauffe (3-4 buches), je gagne 1°C sur le ballon de 800L avec un départ à 15°C (retour à 25°C) ; et 0,5°C avec un départ à 23°C (retour à 32°C). Plus le ballon est froid, plus le rendement monte légèrement.
Lorsque le bas du ballon est à plus de 35°C, le rendement tombe énormément. Le delta devient même parfois négatif, donc il vaut mieux arrêter d'utiliser le serpentin du poêle plutôt que de refroidir l'eau du ballon...

Un jour, le circulateur n'a pas démarré (malgré le 220V à ses bornes), ça a chauffé très fort, le multicouche a fondu (il y a 2m de cuivre près du poêle, puis après du multicouche qui tient à 95°C), fuite, j'ai vidé le circuit rapidement sans danger (grâce aux robinets prévus à cet effet), puis j'ai laissé tombé cette partie du système. Je la laisse quand même dans mon programme Arduino, si ça peut aider quelqu'un. Puis peut-être que je la réutiliserai lorsque j'aurai un poêle bouilleur.

 

VASES D'EXPANSION :

Pour le vase d'expansion du chauffage, le gros rouge de 150L, il est dimensionné pour le cas où j'eusse installé 1500L de réserve. Avec mon ballon de 800L, un vase d'expansion de 80L aurait suffi. Je règle le circuit chauffage à 2 bars.

Pour le branchement du vase d'expansion solaire, on l'éloigne fortement avec un long tuyau (du 12mm, ca refroidit plus vite qu'un gros tuyau), ce qui le protègera des surchauffes (jusqu'à 95°C !). Le circuit solaire est à 2-3 bars.

Toujours monter les circulateurs avec l'axe à l'HORIZONTALE et en point bas (où il y a toujours de l'eau à pousser). Sur le circuit solaire, il faut les mettre sur la partie la moins chaude (donc en pousser vers les panneaux).

Au dessus du vase d'expansion solaire, on voit les vannes V7 et V8 qui forment la vanne 3 voies du chauffage, et son circulateur C2.
C3 et V9 sont pour le serpentin du poêle.

Sur la station solaire, le gros cylindre de laiton à gauche de C1, c'est un dégazeur qui récupère en continu l'air contenue dans l'eau ; il faut le purger de temps en temps.

En dessous de C1, il y a :

Un débitmètre (avec robinets de remplissage/vidage du circuit solaire)
Avec le temps, ce genre de débitmètre est illisible ou bloqué.

Juste en dessous, un autre débitmètre qu'utilise l'automate Arduino (jamais aucun problème, même lors de passage d'eau à 100°C) :

REMPLISSAGE du circuit solaire :

NE JAMAIS REMPLIR LES CAPTEURS LORSQU'ILS SONT CHAUDS (les chocs thermiques pourraient casser les soudures). Le faire en soirée (en jours très gris, on n'est pas à l'abri que le soleil apparaisse au moment du remplissage...).
Protocole : j
e ferme la vanne bleue (les thermomètres sont aussi des vannes) afin de faire passer l'eau par le bas du ballon en premier (et de chasser l'air des serpentins) ; V1 et V2 étant ouvertes. Au bout d'un moment, lorsque les serpentins solaires sont remplis, j'ouvre la vanne/thermomètre bleue, l'eau va monter dans les panneaux solaires.

Notice station solaire : 1 , 2.

J'utilise une pompe de camping car 12V (Shurflo), cela me permet de monter à 2-3 bars. Le vase d'expansion solaire est chargé à 2 bars (vide).

Mon circuit solaire fait 55L (pour des tubes de 22mm compter 0,314L /m + 2L par panneau) en théorie et 45L en pratique (j'ai vidé en mettant dans des bidons de 20L).
J'ai utilisé un mélange concentré (MB444E), donc à diluer avec de l'eau (c'est un peu moins cher 85euros/20L) plutôt que du mélange déjà prêt (67euros/20L, donc 134€ pour 40L).
Il faut utiliser du glycol dit "alimentaire" : Mono Propylène Glycol (MPG) = non toxique ; moins en tout cas.
(glycol
"standard" dans les voitures : Mono Ethylène Glycol (MEG) = toxique )

Le fluide anti-gel caramélise/durci au dessus de 180°C.

Rechargement : comme c'est souvent plus facile de mettre de l'eau du réseau de la ville (qui vous donne la pression) plutôt que de l'anti-gel avec une pompe, je conseille de mettre trop d'anti-gel au début. Au moins, si vous avez des fuites, vous n'aurez qu'à ajouter un peu d'eau.

Bien penser à mettre des petits robinets purgeurs (à pointeau ou avec joint EPDM) afin de chasser l'air lors du remplissage (donc aux points hauts) et aussi vider le circuit correctement lors du vidage (donc aux points bas).


Les petits sont plus facile à isoler correctement.

Différents types de RACCORDS :

- Filasse (chanvre) : jusqu'à 140°C , mais pas bon avec glycol (suinte) et pas pour fortes pressions. Il y a plein de vidéos sur le web qui vous expliqueront comment faire : abimer le filetage avec une pince ou une lame de scie à métaux pour que la filasse ne glisse pas au serrage. Bien tendre la filasse et mettre la pâte (argile) à la fin (si vous la mettez au debut, vous augmentez les risques de glissement au serrage). Lorsque vous voyez que la filasse est repoussée par le vissage, il vaut mieux refaire le raccord.

- Téflon PTFE : jusqu'à 260°C. Pour que cela fonctionne bien, il faut en mettre beaucoup (jusqu'à ce qu'on ne distingue plus le filetage) et le tendre fortement. Il existe du téflon très épais (ça va plus vite à poser, on ne fait pas 36 000 tours). Convient bien avec le circuit solaire au glycol.

- Colles : (Loctite 577-542-266, GEB, Tangit, etc.) jusqu'à 225°C. Le problème des colles est qu'au moindre mouvement (choc, resserrage d'un raccord à côté, dilatation), ça casse et ça fuit...

--> Donc pour le circuit solaire, qui à cause de l'antigel crée beaucoup de fuites, utilisez plutôt du téflon PTFE (et mettre du frein filet sur les filetages pour ne pas qu'ils se desserrent avec les dilatations).


Différents types de JOINTS : voir ici ou ici

Réseau eau potable

 

EPDM
120°C max

Spécial gaz. On me les avait conseillés pour le circuit solaire, mais ils finissent par fuir légèrement (le glycol les attaque).

Pour le circuit solaire avec glycol (les autres joints fuient).
PTFE, -50°C à 250°C, 100 bars

EVITER LES RACCORDS A JOINT le plus possible. J'en ai actuellement 2 sur le circuit chauffage qui fuient légèrement, à un endroit où je dois vider tous les radiateurs pour réparer... (c'est un branchement juste avant une vanne..., pas de chance). Préférez des raccords olive ou les soudures brasées.

Pour le circuit solaire : qui est soumis à de grosses différences de température (de -5°C à 150°C...), les raccords vissés (olive, à joints, etc.) ont tendance à se dévisser à la longue : il faut mettre du frein filet ou colle (loctite, GEB, etc. résistant à 200°C minimum) sur les 2 filetages. Pour démonter, si c'est trop collé, chauffer le raccord au chalumeau. Evitez autant que possible les raccords sur le circuit solaire et soudez à la brasure autodécapante de cuivre (à faire dans un endroit aéré). Si vous n'avez pas de chalumeau assez puissant, vous pouvez utiliser 2 petits chalumeaux ensemble.
J'ai beaucoup de petites fuites qui réapparaissent avec les grosses chaleurs notamment sur les raccords olive (pas trop ceux des panneaux Tinox LM...).

 

EFFET THERMOSIPHON :

Lorsque c'est possible, l'idéal est d'avoir les panneaux au sol (facile à installer, à réparer, à couvrir en cas de surchauffe) et le ballon un peu au dessus.
Moi j'ai dû faire l'inverse et cela m'a causé beaucoup de problèmes de thermosiphon. Grâce aux multiples sondes de température, je me suis aperçu que je n'arrive pas à récupérer toute la chaleur qui est au niveau haut des panneaux solaires. Souvent, j'ai env. 47°C en haut des panneaux et sur le conduit de retour chaud qui va vers le ballon, je n'ai que 41°C. (voir sur cet exemple)

En hiver, lorsque la cuve n'est pas très chaude (30°C), un jour de très beau soleil, il faut parfois que je maintienne un débit d'au moins 20L/mn pour réussir à descendre les calories (ce qui augmente la consommation du circulateur). Plus j'ai la cuve froide et les panneaux très chauds, plus l'effet thermosiphon se fait et plus j'ai du mal à descendre l'eau chaude des panneaux vers le ballon.

J'ai aussi eu de gros problèmes de thermosiphon avec le chauffage de la maison : lorsque le ballon était très chaud (au dessus de 60°C), à l'ouverture du circuit qui envoi l'eau chaude vers les radiateurs, l'eau montait extrêmement vite (bien plus vite que le circulateur) et mon système se mettait en sécurité (éteignant circulateur C2, fermant v7, v8 et v4,v5,v6). J'ai corrigé en déplaçant la vanne 8 sur la partie chaude (départ), avant elle était sur le retour (partie froide).

 

DIVERSES NOTES :

La consommation des circulateurs (15W par circulateur) est assez négligeable. Consommation des circulateurs du 11/10/2018 au 22/02/2019 = 31KW (6KW/mois = 1€/mois)

Pour augmenter de 1°C un litre d'eau, il faut 1000 calories = 1,16 Wh

COUT TOTAL :

PANNEAUX
4 panneaux solaires Roth d'occasion + frais pour aller les chercher
450
3 panneaux solaires TINOX LM112 (à 350€ pièce sur solaire-diffusion) + frais de port
1200
Visserie inox
80
Cornières galvanisées pour fixer les panneaux sur façade maison et toit garage (12m en 40/40mm)
500
7 raccords olive 18mm panneaux solaire-diffusion
30
Sous total = 
2260
 
CIRCULATEURS
Station solaire (avec circulateur WILO 25/6-3p) neuve, leboncoin
145
Circulateur pour circuit chauffage Grundfos UPS 25-60 180, occasion
60
Circulateur Salmson pour serpentin autour du conduit poêle
30
Sous total = 
235
 
BALLON
Ballon TWL hygiénique (5,8m², 29,1L), 2 serpentins acier (2,8m²+1,9m²), 800 L + frais de port
1560
Anode magnésium en 3/4"
22
Sous total = 
1582
 
VASES
Vase expansion pour circuit solaire 35L 
70
Vase d'expansion de 150L, pour stock chauffage (calculé pour 1500L)
187
Vase d'expansion sanitaire 11L
42
Sous total = 
299
 
VANNES
10 vannes 2 voies motorisées DN25 (23euros pièce)
230
3 vannes 2 voies motorisées DN15 (15euros pièce)
45
10 vannes classique 3/4" pour ballon, neuve
50
Sous total = 
325
 
TUYAUX CUIVRE
couronne de 20 mètres de cuivre recuit en 22mm pour liaison solaire, acheté d'occasion
80
10 mètres de cuivre en 22mm pour liaison solaire
65
10 mètres de cuivre de 22mm de récupération
0
10 mètres de cuivre en 12mm pour serpentin autour conduit du poele
36
10 mètres de cuivre de 18mm de récupération
0
Sous total = 
181
 
RACCORDS
65 raccords divers en 22mm (coudes, T, prolongateurs), occasion
27
Divers raccords cuivre, laiton, galva, inox, 2 purgeurs+vannes solaire, étain, téflon, joints, baguette soudure, soupape sécurité, raccords diélectriques, isolants, etc.
600
Liquide solaire
85
Sous total = 
712
 
ARDUINO
2 cartes Arduino Mega (à 8€ pièce, une de rechange), shields écran, ethernet, relais, 20 capteurs de température DS18x20, sonde K, sonde PT100 et sa carte ampli, débitmètre, etc. Le tout en double.
50
Sous total = 
50
 
TOTAL SOLAIRE =
5644€
 
 
MURS CHAUFFANTS
300m de multicouche en 16mm (pour radiateurs mur chauffant ; compter 70m par mur de 5m de large)
230
10 sacs de platre
80
Placo hydrofuge, sacs de joint, tasseaux bas de gamme, etc.
350
TOTAL MURS CHAUFFANTS (env. 200€ / mur) = 
660 €

Au niveau du temps, c'est surtout de se former qui m'en a pris beaucoup (lectures, forums, etc.). Compter 1 semaine pour la plomberie ? Pour la partie programmation à l'Arduino, si vous êtes comme moi débutant, ça prend plusieurs mois. Mais maintenant, je fais toutes sortes d'applications (porte automatique poulailler, mangeoire, suiveur solaire, etc.) beaucoup plus rapidement.

 


AUTOMATISATION avec carte ARDUINO :

 

J'ai mis beaucoup de notes dans le programme (voir plus bas) qui vous aideront à mieux comprendre.

Grâce à l'Arduino, je peux visualiser le fonctionnement de l'installation solaire de 3 manières :

- Le moniteur série du logiciel Arduino (il faut mettre un cable USB entre la carte Arduino et le PC) :

 

- Un afficheur dans le salon (c'est celui qu'on utilise le plus, très pratique de l'avoir à un endroit où l'on passe souvent):

 

- sur chaque ordinateur branché à la box ethernet, en tapant l'adresse 192.168.1.111 :


(A la période de l'impression d'écran, il fait 0°C la nuit et 18°C le jour)

Théoriquement, je pourrais aussi donner l'accès depuis internet, mais avec la livebox d'orange, ça ne marche pas (un jour, si je change... ).

 

Je n'ai pas fait de doigts de gant pour mettre les capteurs de température, je les ai fixés avec du fil de cuivre, comme ci-dessous. Une fois le tuyau bien isolé, la précision/réactivité me suffit, même au niveau des panneaux solaires. Sur le schéma ci-dessus, les températures sur les panneaux solaires ( "P6(cadre)" ) sont juste des capteurs vissés sur le cadre du panneau (sans isolation), mais contrairement à ce qu'on pourrait croire, cela fonctionne assez bien pour voir le panneau qui chauffe le plus. Le P6 et P7 sont toujours un peu plus chaud, car il y a une serre avec un toit en verre qui reflète le soleil.

 

Schéma de montage des capteurs de température sur le Arduino. Le DS18B20 permet d'avoir jusqu'à 128 petits capteurs en réseau avec 3 fils ! :


La résistance préconisée par le fabricant ne convient pas toujours. Essayez plusieurs résistances, vous finirez par avoir quelque chose de très fiable (beaucoup de problèmes au début, mais après, quand ça marche, ça marche bien !)
Il vaut mieux ne pas mettre tous les capteurs sur une seule entrée Arduino. Faites plusieurs lignes de capteurs afin de détecter plus facilement un problème (pour moi : D31 à l'intérieur et D30 pour les capteurs à extérieur).

 

Commande des vannes 12V (bleues, fermées/ouvertes par inversion de polarité) avec le Arduino :


Le schéma multiplié par 18 donne la grosse carte pleine de relais dans le centre du coffret Arduino (ci-dessous).

Branchement de la sonde de lumière qui me sert surtout pour le contrôle de l'arrosage goutte à goutte des jardinières de la rue :


Elle est dans une capsule de plastique près des panneaux solaires.

 

Le schéma de branchement de la sonde K avec son convertisseur qui mesure les températures du poêle (jusqu'à 1500°C !) . Puis, à droite, le schéma du RTC, horloge de l'arduino.

Valeurs des résistances à mettre pour les diodes témoins :

Ci-dessus, les boutons du panneau :

1 - ON/OFF du système général
2 - permet de choisir entre : "Chaudière gaz chauffe radiateurs" - "0" (position neutre, c'est l'arduino qui choisi) - "Chaudière gaz chauffe le ballon"
3 - bouton activation du "goutte à goutte" des jardinières de la rue (système géré par le Arduino en fonction de l'ensoleillement)
4 - bouton "sèche-serviette de la salle de bain", ce qui alimente en priorité le sèche-serviette (même l'été). C'est juste une vanne mise en parallèle sur le robinet d'équilibrage qui fait que l'eau chaude passe plus facilement par le sèche-serviette et donc moins sur le reste du réseau de chauffage.


Chaque cable est noté au feutre sur un petit bout de ruban adhésif PVC (très important si un cable ou une soudure casse).

En haut : la carte Arduino méga avec une carte ethernet par dessus.
Au milieu : la carte à relais de commande des vannes (on peut aussi utiliser des L293D, voir Terran sur forum)
A gauche : les boutons dont je parle ci-dessus.


Pour la carte ethernet : évitez le modèle qui chauffe et bug régulièrement, même en mettant un radiateur dessus : celle-ci

COMMANDES DES CIRCULATEURS

J'ai fait un boitier très pratique qui me permet de mettre chaque circulateur en marche forcée, en arrêt forcé ou en mode automatique (mode contrôlé par l'Arduino). En cas de problème, je peux ainsi éteindre ou allumer le circulateur facilement. Il y a aussi des voyants 220v qui m'indique si le circulateur tourne.


A gauche, on voit le radiateur du variateur que je vais démonter plus tard.

Voici le schéma (pour un circulateur) :

Côté Arduino, j'utilise un transistor BC548 qui commande un petit relais 5V.

Pour le circulateur solaire "C1", il y a en plus un variateur (ou "Dimmer", avec radiateur) comme celui-ci , que je vais finalement abandonner. La variation de vitesse apporte peu d'avantage (même si cela permet d'accélèrer régulièrement le circulateur pour éviter l'effet laminaire) et le variateur me faisait légèrement vibrer le circulateur en vitesse lente. En général, tous les circulateurs sont sur la plus faible vitesse (pour avoir une faible consommation). D'après mes observations, lorsque j'augmente la vitesse de C1, je perds beaucoup en efficacité (le transfert de chaleur dans le ballon et dans les panneaux se fait moins bien et le delta diminue beaucoup).
Le circulateur C1 est aussi protégé par le programme Arduino grâce au capteur de débit : si le circulateur est allumé et que le débit est nul, au bout de 5mn, le programme coupe le circulateur (et une petite alarme retentit dans la maison).

Pour chaque circulateur, il y a un voyant (éteint ou allumé), un fusible (1A) et pour C2 et C3 un fusible thermique pour le cas où le circulateur chauffe parcequ'il ne peut pas circuler à cause d'une vanne fermée (fusible th fixé avec un fil de cuivre contre le corps du circulateur):

Fusible thermique autoréarmable qui coupe le circuit électrique au dessus de 60°C.
Il devrait y en avoir obligatoirement dans tous les moteurs vendus dans le commerce pour les sauver d'une surchauffe.

Sur le circulateur de la chaudière au gaz, j'ai aussi mis un fusible thermique autoréarmable (comme ci-dessus) et un relais (12V, avec diode) en série pour couper le circulateur lorsque le chauffage solaire prend la main et que les vannes empêchent la chaudière gaz d'envoyer l'eau.

Bien laisser le caoutchouc transparent sur le fusible thermique, car sinon, ça disjoncte dans toute la maison.
(ça ne le fait pas si c'est un fusible thermique en plastique)

 

Un autre relais est positionné dans la prise 220V de la chaudière au gaz. Il permet d'arrêter la chaudière gaz lorsque le ballon solaire est assez chaud pour fournir l'eau chaude sanitaire sans complément (haut du ballon > 43°C). S'il n'est pas alimenté, le relais est passant ; cela peut aider si un jour le système arduino bug et qu'on veut quand même démarrer la chaudière pour se chauffer...

 

LE PROGRAMME COMPLET :

Je vous conseille de l'ouvrir dans le logiciel Arduino de votre PC, ce sera plus lisible (il fait 40 pages, 2400 lignes). Il y a une carte mémoire sur la carte ethernet de l'Arduino, que je n'utilise pas encore. Cela va permettre de réaliser un "datalogger" qui mémorisera toute l'activité du système (donc mémoriser la météo, l'ensoleillement, l'énergie produite, etc.).

// Programme de gestion installation solaire thermique (eau chaude pour chauffage maison + eau chaude sanitaire)
// Matthieu MONCEAUX, fevrier 2018
// Explications ici : http://mmonceaux.free.fr/solaire_thermique/
//
// Je vous conseille d'avancer pas à pas votre projet, car il y a beaucoup de possibilités de problèmes entre périphériques (ethernet,
// capteurs, etc.). Commencez très simple et ajouter petit à petit d'autres périphériques (en enregistrant sous un nouveau nom de
// fichier à chaque fois, pour pouvoir revenir à l'état stable)
//
// Eviter les "while" car il y a des risques de blocage en restant dans la boucle, préférer les "if"
//
// if (10 < difference_temperature < 20)  --> NE FONCTIONNE PAS
// PREFERER : if (10 < difference_temperature and difference_temperature < 20)  
// 
// NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage après 8s d'inactivité)
//
// Toujours essayer de réduire l'utilisation de la mémoire en mettant des variables appropriées (c'est mieux de le faire dès le début,
// plutot que de devoir tout refaire à la fin car plus assez de mémoire...)
// 
// ATTENTION, alimentation idéale de la carte ARDUINO = 6 à 7v (avec 12v, ça chauffe très fort)
// 
// Utiliser "Serial.print(F("Hello World")) " plutot que Serial.print("Hello World") permet d'économiser un peu de mémoire
//
// ********************
// corrigé : thermo couple bloquer à cause de l'écran LCD -> conflit avec sonde K du poele (utilise 4,5,6) "Data Out Port SPI sur 4-5-6"
// ********************

#include <SPI.h> // reseau communication SPI (ethernet, carte memoire SD, )
#include <Wire.h> // pour réseau I²C (horloge DS1307, capteur humiditee, etc.)
#include <OneWire.h> // reseau capteur temperature DS18B20
#include "max6675.h" // si " " = inclure fichier local au projet : librairie du MAX6675 pour la sonde K du poele, max 1000°C
#include <avr/wdt.h> // fonction WATCHDOG = reset du arduino s'il plante
//#include <MemoryFree.h> -> permet de voir la memoire disponible avec la commande Serial.print("freeMemory()reports"); Serial.println(freeMemory());
// 8k sur arduino Mega et 2K sur UNO


// Pour la sonde humidité (simple affichage, non indispensable dans le prog), j'ai eu de gros problèmes de conflit avec la carte Ethernet
// (qui ne fonctionnait plus) et l'affichage en I2C. J'ai résolu ces problèmes en changeant de bibliothèque
// Ne pas utiliser : "Adafruit_HTU21DF.h" et "HTU21D.h"
#include "SparkFunHTU21D.h" // cette bibliothèque m'a résolu les problèmes

//// Declaration capteur humidté HTU21 . ATTENTION : alimentation en 3,3V prise sur carte arduino
HTU21D myHumidity;
unsigned char humidite_cave;   //float ?
float temperature_cave;  //float ?


//// Declaration des variables, pour organiser la memoire de l'Arduino

boolean arrosee = false;
unsigned char dernier_arrosage = 0;
const unsigned char  broche_buzzer_cave = 29 ;  // Broche d29 = alarme (buzzer) Surchauffe ballon
const unsigned char  broche_buzzer_poele = 28 ;  // Broche d30 = alarme (buzzer) Surchauffe poele
const unsigned char  broche_ldr = 15 ; // Broche de mesure capteur lumiere LDR A15
// si 700< <800 --> nuageux.
// nuit = 15
//  Nuit de pleine lune = 0,5 lux
//  Rue de nuit bien éclairée = 20 à 70 luxl
//  Local de vie = 100 à 200 lux
//  Appartement bien éclairé = 200 à 400 lux
//  Local de travail = 200 à 3 000 lux
//  Stade de nuit = 150 à 1 500 lux
//  Extérieur par ciel couvert = 500 à 25 000 lux
//  Extérieur en plein soleil = 50 000 à 100 000 lux

boolean ete;
boolean alarm1; // probleme circulateur panneaux solaire qui ne tourne pas alors qu'allumé
boolean alarm2; // surchauffe ballon
boolean alarm3; // surchauffe poele
boolean alarm4; // erreur lecture des températures
boolean alarm5; // gel dans les panneaux solaires
unsigned char mois_demarrage, jour_demarrage, heure_demarrage, minute_demarrage;


//// SOLAIRE
const unsigned char consigne_solaire = 2; // C1 démarre si (température du panneau 2 > température bas ballon + consigne_solaire)
const char consigne_demarrage_circu_antigel = -7; // C1 démarre si température panneau 3 < consigne_demarrage_circu_antigel
unsigned int cycle_demarrage_solaire = 0;
boolean etatC1;
boolean etatC2;
boolean mode_gel = 0;
int delta_panneaux_ballon_milieu;
float delta_chd_frd_station;
float delta_stratification;
boolean serpentin_haut = 1;
boolean solaire_chauffe_ballon = 0;
float wh = 0; // puissance, débitmètre
float ballon_temp_moy; // somme des T°C ballon divisée par 3, donne la température totale du ballon sans stratification

unsigned int broche_sonde_pt100 = A11; // sonde pt100 qui se trouve dans le panneau n°2
unsigned int valeur_sonde_pt100; // valeur brut affichee sur l'arduino
unsigned int valeur_sonde_pt100_corrigee;
unsigned int valeur_sonde_pt100_precedente = 260; // valeur à env. 10°C pour éviter une alarme au reset de l'arduino
unsigned int valeur_sonde_pt100_precedente1 = 260; // valeur à env. 10°C pour éviter une alarme au reset de l'arduino
unsigned int temperature_sonde_pt100 = 0; // valeur calculee en °C

boolean v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12;

//// EAU CHAUDE
const unsigned char consigne_eau_chaude = 44; // valeur T°C haut du ballon en dessous de laquelle on démarre la chaudiere gaz pour 
// complémenter l'eau chaude sanitaire.

//// POELE
const unsigned char thermoDO = 34;  // Data Out Port SPI sur 4-5-6,  thermocouple SERPENTIN Peole ---> mais conflit avec shield LCD+boutons
const unsigned char thermoCS = 35;  //Chip Select,  thermocouple SERPENTIN Peole
const unsigned char thermoCLK = 33;  //Clock,  thermocouple SERPENTIN Peole
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); // Déclaration des pins utilisées pour thermocouple serpentin poele (communication SPI)
float delta_poele;
boolean c3_tourne = 0; // circulateur C3 allumer = 1 , éteint = 0
unsigned long duree_allumage_c3 = 250000;

/// CHAUFFAGE
const unsigned char heure_seche_serviette_matin = 7;
const unsigned char heure_seche_serviette_soir = 21;
boolean chauffer_sechoir = false;

const unsigned char broche_gaz_on_off = 25 ; // relais d'allumage chaudiere
const unsigned char broche_gaz_circulateur = 27 ; // relais pour bloquer le circulateur chaudiere
boolean relais_gaz; // lit l'etat du relais on/off chaudière gaz

unsigned char temperature_eau_visee_de_chauffe = 39; // VOIR DANS LA PARTIE CHAUFFAGE : on la change au démarrage du cycle de chauffe pour 
// éviter les chocs thermiques dans les murs chauffants.
boolean demarrage_seche_serviette;
unsigned int ldr; // capteur de lumiere, au sud
unsigned char mode = 0; //  mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, mode3=Poele, 
// mode4=BallonSolaire sur Radiateurs.
unsigned char etat_bouton_gaz_precedent = 5; // on oblige à relire l'intérieur des "if" des boutons
int j; // pour poele
boolean eau_par_gaz = 1; // = 1 si l'eau passe par la chaudiere au gaz, sinon = 0
unsigned int eau_par_gaz_compteur = 0;
boolean thermostat_chauffage_solaire;
unsigned int cycle_chauffage = 0;
boolean circulateur_C2_en_pause = 0;
float delta_chauffage;
float consigne_delta_chauffage;
float temperature_precedente;
float gain_temperature_chauffage;
int difference_consigne;
unsigned int temps_ouverture_vanne_v8v7;
int position_v8;
int position_v8_degre;

boolean mode_degommage = 0; // mode qui débloque les circulateurs 1 fois par jour

const unsigned char broche_vanne_goute_a_goutte = 39 ;


//// Commandes Circulateurs C1 et C3
const unsigned char broche_relais_C1 = 22 ;
const unsigned char broche_relais_C2 = 23 ;
const unsigned char broche_relais_C3 = 24 ;
unsigned char AC_LOAD_c1 = 17;  // PWM = Output to Opto Triac pin
unsigned char dimming_c1 = 25;  // 0=OFF ou entre 25(rapide) et 55(lent)

//// LECTURE DES BOUTONS/INTERRUPTEURS
int lecture_bouton_gaz; // entrée analogique A14
int lecture_bouton_goutte_a_goutte; // entrée analogique A13
int lecture_bouton_4; // entrée analogique A12
boolean bouton_gaz = 0; // etat du bouton "gaz"
boolean bouton_goutte_a_goutte = 0; // etat du bouton "goutte à  goutte"
boolean bouton_4; // état du "bouton 4" = seche serviette de la salle de bain (a chauffer meme en été)


//// DEBITMETRE
volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;
unsigned long currentMilis;
unsigned long lastMilis = 0;
float F;  float debit;
unsigned char temps = 2000 ;// durée de la mesure en ms


//// CAPTEURS TEMPERATURE DS18B20 (temp = -55 à  125°C, 128 capteurs max sur le réseau, alim=3v à 5,5v)(PT1000 = -50°C à 450°C)
// Prendre du cable blindé et éviter les cablages en étoile, cela crée des problèmes de lecture
// si ça ne fonctionne pas, essayer de changer la résistance (entre +5V et data) de 4,7KOhms (mettre par ex 2,2KO)
// bien récupérer les adresses des capteurs un à un avant de les brancher en réseau
// pour trouver facilement un capteur défaillant, faire plusieurs réseaux, plutot qu'un seul
const byte BROCHE_ONEWIRE_toit = 31; //broche du réseau de capteur DS18B20
const byte BROCHE_ONEWIRE_ballon = 30; //broche du réseau de capteur DS18B20
float temperature[29]; // nombre de float = 29 capteurs de température
int i;
const byte SENSOR_ADDRESS_0[] = {0x28, 0xFF, 0xF1, 0x01, 0x8B, 0x16, 0x03, 0xAB};// = en haut du serpentin solaire bas
const byte SENSOR_ADDRESS_1[] = {0x28, 0xFF, 0x06, 0x52, 0xA3, 0x16, 0x03, 0xBD};// = corps panneau 3
const byte SENSOR_ADDRESS_2[] = {0x28, 0xFF, 0x61, 0x95, 0x71, 0x17, 0x03, 0xD0};// = tuyau après panneau 1 et 2
const byte SENSOR_ADDRESS_3[] = {0x28, 0xFF, 0x8F, 0x2F, 0xA2, 0x16, 0x04, 0x98};// = corps panneau 2
const byte SENSOR_ADDRESS_4[] = {0x28, 0xFF, 0x80, 0xA9, 0xA2, 0x16, 0x05, 0x79};// = tuyau après panneau 1
const byte SENSOR_ADDRESS_5[] = {0x28, 0xFF, 0x61, 0x01, 0x71, 0x14, 0x04, 0xE9};// = corps panneau 1
const byte SENSOR_ADDRESS_6[] = {0x28, 0xFF, 0x3C, 0xC9, 0x70, 0x14, 0x04, 0x1E};// = tuyau panneau 4, 5, 6 et 7
const byte SENSOR_ADDRESS_7[] = {0x28, 0xFF, 0x05, 0x14, 0x71, 0x14, 0x04, 0x5E};// = corps panneau 4
const byte SENSOR_ADDRESS_8[] = {0x28, 0xFF, 0x5F, 0xC8, 0x70, 0x14, 0x04, 0xCE};// = corps panneau 5
const byte SENSOR_ADDRESS_9[] = {0x28, 0xFF, 0x69, 0x51, 0xA3, 0x16, 0x05, 0x96};// = corps panneau 6
const byte SENSOR_ADDRESS_10[] = {0x28, 0xFF, 0x66, 0x14, 0x71, 0x14, 0x04, 0x01};// = tuyau panneau 6 et 7
const byte SENSOR_ADDRESS_11[] = {0x28, 0xFF, 0x28, 0x70, 0x71, 0x14, 0x04, 0xD4};// = corps panneau 7
const byte SENSOR_ADDRESS_12[] = {0x28, 0xFF, 0x46, 0xC9, 0x6C, 0x14, 0x03, 0xBC};// = eau froide rue
const byte SENSOR_ADDRESS_13[] = {0x28, 0xFF, 0x5E, 0x88, 0x71, 0x14, 0x04, 0x48};// = départ bidon récup eau douche
const byte SENSOR_ADDRESS_14[] = {0x28, 0xFF, 0xB0, 0x13, 0x71, 0x14, 0x04, 0x45};//
const byte SENSOR_ADDRESS_15[] = {0x28, 0xFF, 0x91, 0x02, 0x71, 0x14, 0x04, 0xC7};//
const byte SENSOR_ADDRESS_16[] = {0x28, 0xFF, 0x4E, 0x02, 0x71, 0x14, 0x04, 0xF6};// = retour Chd panneaux facade
const byte SENSOR_ADDRESS_17[] = {0x28, 0xFF, 0x79, 0x13, 0x71, 0x14, 0x04, 0x94};// = retour Chd panneaux garage
const byte SENSOR_ADDRESS_18[] = {0x28, 0xFF, 0x30, 0x02, 0x71, 0x14, 0x04, 0x39};// = station arrivée chaud solaire
const byte SENSOR_ADDRESS_19[] = {0x28, 0xFF, 0xC6, 0xFB, 0x70, 0x14, 0x04, 0x4A};// = station depart froid solaire
const byte SENSOR_ADDRESS_20[] = {0x28, 0xFF, 0x24, 0x14, 0x71, 0x14, 0x04, 0x6B};// = C2 retour mur chauffant
const byte SENSOR_ADDRESS_21[] = {0x28, 0xFF, 0x1F, 0x8A, 0x71, 0x14, 0x04, 0x6B};// = puits
//const byte SENSOR_ADDRESS_21[] = {0x28, 0xFF, 0x60, 0x84, 0x71, 0x17, 0x03, 0xAA}; // ?
const byte SENSOR_ADDRESS_22[] = {0x28, 0xFF, 0x27, 0x80, 0x2D, 0x04, 0x00, 0x87};// = Salle Bain Etage
const byte SENSOR_ADDRESS_23[] = {0x28, 0xFF, 0x4C, 0xE1, 0x70, 0x14, 0x04, 0x1F};// = Milieu ballon
const byte SENSOR_ADDRESS_24[] = {0x28, 0xFF, 0x4B, 0x02, 0x71, 0x14, 0x04, 0x24};// = Haut ballon
const byte SENSOR_ADDRESS_25[] = {0x28, 0xFF, 0x1A, 0x95, 0x71, 0x17, 0x03, 0xCD};// = Bas ballon
const byte SENSOR_ADDRESS_26[] = {0x28, 0xFF, 0x9E, 0xC4, 0x71, 0x17, 0x03, 0x4E};// = arrivé/départ vannes de startification (et vers mur chauffant)
const byte SENSOR_ADDRESS_27[] = {0x28, 0xFF, 0xE4, 0x4D, 0x71, 0x17, 0x03, 0xD4};// = Salon (avec résistance de 33K, sinon, ne fonctionne pas)
const byte SENSOR_ADDRESS_28[] = {0x28, 0xFF, 0x60, 0x84, 0x71, 0x17, 0x03, 0xAA};// = depart chauffage solaire
OneWire ds(BROCHE_ONEWIRE_toit); // Création de l'objet OneWire pour manipuler le bus 1-Wire, pour capteur température en réseau
OneWire ds2(BROCHE_ONEWIRE_ballon); // Création de l'objet OneWire pour manipuler le bus 1-Wire, pour capteur température en réseau


///// HORLOGE avec DS3231, en I2C (broche SDA-20 et SCL-21 de arduino Mega) à l'adresse 0x68
// Mon horloge a tendance à perdre 1 à 2 mn par mois. Prenez-en une bonne...
#include <DS1307new.h>
int I2C_DS3232 = 0xD0 >> 1;
byte DS3232control = 0b00011100, DS3232status = 0b11001000 , DS3232aging , DS3232Msb , DS3232Lsb;
uint16_t startAddr = 0x0000;       // Adresse de démarrage Start dans  NV-RAM
uint16_t lastAddr;                 // Nelle addresse des stockage NV-RAM
uint16_t TimeIsSet = 0xaa55;       // Prévient qu'il n'y a pas de remise à  l'heure
#define DDS_LOAD  12  //FQ_UD  // DDS/Arduino Connections,  SCL= broche SCL21 (pour Mega) ou pin A5,  SD= broche SDA20 (pour Mega) ou pin A4
#define DDS_CLOCK 3
#define DDS_DATA  2
// int Select;
unsigned char Heure;
unsigned char Minute;
unsigned char Seconde;
unsigned char Jour;
unsigned char Mois;
unsigned int Annee;
///// HORLOGE avec DS3231


//// DECLARATION ETHERNET   Connecteur ICSP obligatoire;  broche D4(lecteurSD), D10(ethernet), D11,D12,D13,
// Sur arduino Mega : garder broche 50 à 53 libres pour carte ethernet
//#include <SPI.h> // déjà en debut de programme
#include <Ethernet.h>
//MAC addr of Ethernet Shield
byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//Linksys Router default IP address is 192.168.1.1
byte ip[] = { 192, 168, 1, 111 }; // P1 --> { 10, 1, 1, 5 };
EthernetServer server(80); // port 80 is default for HTTP. Can use 8080 or 8081 also
//EthernetServer server = EthernetServer(80);

// DECLARATION carte mémoire SD   utilise broche D4
#include <SD.h>  // pour carte SD
File monFichier;


//// DECLARATION LCD 20*4 HD44780 sur l'adresse 0x27 du I2C (broche SDA-20 et SCL-21 de arduino Mega)
#include <LiquidCrystal_I2C.h>
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address MOST use address 0x27, a FEW use 0x3F
//*** LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // pour le 2eme afficheur, souder les 3 bornes de config adresse



//--------------------------------  Fin Déclarations des variables  ---------------------------------------------------
//--------------------------------  Fin Déclarations des variables  ---------------------------------------------------


//// Fonction DEMARRER PRISE DE MESURE capteur température DS18B20.
void startTemperatureMeasure(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté
  ds.reset(); // Reset le bus 1-Wire et sélectionne le capteur
  ds.select(addr); // selection de l'adresse
  ds.write(0x44, 1);
} // commande 0x44 = Lance une prise de mesure et attend la fin de la mesure */

//// Fonction RECUPERATION VALEUR DE MESURE capteur température DS18B20.
float readTemperatureMeasure(const byte addr[]) {
  byte data[9]; // data[] : Données lues depuis le scratchpad   addr[] : Adresse du module 1-Wire détecté
  ds.reset();// Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad
  ds.select(addr);
  ds.write(0xBE);
  for (byte i = 0; i < 9; i++) {
    data[i] = ds.read(); // Lecture du scratchpad
  }
  return ((data[1] << 8) | data[0]) * 0.0625;
} // Calcul de la température en degré Celsius

//// Fonction DEMARRER PRISE DE MESURE capteur température DS18B20.
void startTemperatureMeasure2(const byte addr[]) {
  // addr[] : Adresse du module 1-Wire détecté
  ds2.reset(); // Reset le bus 1-Wire et sélectionne le capteur
  ds2.select(addr); // selection de l'adresse
  ds2.write(0x44, 1);
} // commande 0x44 = Lance une prise de mesure et attend la fin de la mesure */

//// Fonction RECUPERATION VALEUR DE MESURE capteur température DS18B20.
float readTemperatureMeasure2(const byte addr[]) {
  byte data[9]; // data[] : Données lues depuis le scratchpad   addr[] : Adresse du module 1-Wire détecté
  ds2.reset();// Reset le bus 1-Wire, sélectionne le capteur et envoie une demande de lecture du scratchpad
  ds2.select(addr);
  ds2.write(0xBE);
  for (byte i = 0; i < 9; i++) {
    data[i] = ds2.read(); // Lecture du scratchpad
  }
  return ((data[1] << 8) | data[0]) * 0.0625;
} // Calcul de la température en degré Celsius
//// FIN Fonction RECUPERATION VALEUR DE MESURE capteur température DS18B20.


//// Fonction ERREUR_LECTURE_ETEINDRE_CIRCULATEURS, seulement pour chauffage Circulateur C2
//// Eteint les circulateurs pour ne pas qu'ils chauffent s'il y a une erreur (large) de lecture des capteurs de température
void erreur_lecture_eteindre_circulateurs()
{
  etatC1 = digitalRead(broche_relais_C1);
  etatC2 = digitalRead(broche_relais_C2);
  if (temperature[25] < 5 and (etatC1 == 1 or etatC2 == 1)) //--> probleme, éteindre C1 et C2, + buzzer
  { digitalWrite(broche_relais_C2, LOW);
    // ne jamais eteindre C1 pour eviter les surchauffes solaires. Le poele se passe de sonde DS18B20
    // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
    alarm4 = true;
    for (j = 0; j <= 3; j++)
    { tone(broche_buzzer_cave, 700, 200);   //(pin, frequency, duration)
      delay(250);
      noTone(broche_buzzer_cave);
    }
  }
  else {
    alarm4 = false;
  }
}
//// FIN Fonction erreur_lecture_eteindre_circulateurs


//// Fonction SOLAIRE_ANTI-GEL
//// Faire tourner l'eau à haute vitesse pour éviter le gel dans les panneaux
void solaire_anti_gel()
{
  if (mode_gel == 0 and temperature[1] <= consigne_demarrage_circu_antigel) // consigne_demarrage_circu_antigel = -10 env.
  { mode_gel = 1;
    digitalWrite(32, LOW); // fermer V1 et ouvrir V3 pour circuler en dehors du ballon
    digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
  }
  if (mode_gel == 1 and temperature[2] < consigne_demarrage_circu_antigel - 5 and temperature[2] != -0.06)
  { // si T°C -5°C en dessous de la consigne antigel : sonner l'alarm et circuler avec eau du ballon
    digitalWrite(32, HIGH); // fermer V3 et ouvrir V1 pour faire rentrer l'eau dans la ballon et réchauffer l'eau des panneaux
    digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
    // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
    alarm5 = true;
    for (i = 0; i < 5; i++)
    { tone(broche_buzzer_cave, 800, 250);   //(pin, frequency, duration)
      delay(150);
      noTone(broche_buzzer_cave);
      tone(broche_buzzer_poele, 800, 250);
      delay(150);
      noTone(broche_buzzer_poele);
    }
  }
  else {
    alarm5 = false;
  }
  if (mode_gel == 1 and temperature[2] > consigne_demarrage_circu_antigel)
  { mode_gel = 0;
    digitalWrite(broche_relais_C1, LOW); // éteindre circulateur
    digitalWrite(32, LOW); // ouvrir V3 et fermer V1 pour ne pas faire rentrer l'eau dans le ballon
  }
}
//// FIN Fonction solaire_antigel

/*
  //// Fonction POELE : mesure et démarrage circulateur poele
  // Finalement, comme le serpentin chauffe tres peu, je suis obligé d'arreter le circulateur serpentin 1mn,
  // le temps que l'eau chauffe suffisamment, puis de le rallumer juste 30s, le temps de renouveler l'eau du serpentin.
  // J'ai essayé de ralentir le circulateur et limiter au maximum le débit, mais cela ne chauffait pas encore assez.
  // Puis j'ai l'impression qu'avec une circulation extrement lente en continu, on n'arrive plus à extraire les calories,
  // on a un régime laminaire.
  // Amélioration : prendre la température en direct dans le serpentin et démarrer le circulateur serpentin poele quand eau assez chaude ?
  // --> oblige à  avoir deux sondes (une "poele démarré" et une "eau" entre 13 et 70°C), n'apporte pas bcp plus de calorie.
  // Cela restera toujours un serpentin sur les fumées... Mais on peut améliorer en mettant une tole autour du serpentin
  // En moyenne, sur une chauffe (3-4 buches), je gagne 1°C sur le ballon de 800L avec un départ à 15°C (retour à 25°C),
  // et 0,5°C avec un départ à 23°C (retour à 32°C)...
  // Le problème est qu'il faut vider le circuit de tuyau à 13°C (dans la cave) avant d'avoir enfin le retour à 30°C...
  // Lorsque le bas du ballon est à plus de 35°C, le rendement tombe énormément, le delta devient négatif, voir = 1, donc il vaut mieux
  // arrêter d'utiliser le serpentin...
  // 28/2/18: le circulateur n'a pas démarré (malgré le 220V à ses bornes), ça chauffait très fort, le multicouche a fondu, fuite,
  // j'ai vidé le circuit rapidement sans danger
  void poele()
  {
  Serial.println("  ");
  Serial.print(F("POELE = "));
  Serial.print(thermocouple.readCelsius());
  delta_poele = temperature[26] - temperature[25];
  Serial.print(F("  C3=")); Serial.print(c3_tourne);
  Serial.print(F("  Retour_T26=")); Serial.print(temperature[26], 2);
  Serial.print(F("  D_T26-T25=")); Serial.print(delta_poele);
  Serial.print(F("  Duree_Allum=")); Serial.print(duree_allumage_c3); Serial.print(F("  "));

  // VITESSE CIRCULATEUR=3.  Bien pour ballon à 30°C, mais PROBLEME : si ballon est à 40°C ? retour négatif ?
  if (temperature[24] <= 35) // si haut du ballon solaire >= 35°C
  { if (thermocouple.readCelsius() >= 180)
    { duree_allumage_c3 = 120000 ; // 120000ms=120s/60=2min
    }

    if (thermocouple.readCelsius() < 180 and thermocouple.readCelsius() >= 160)
    { duree_allumage_c3 = 150000 ;
    }
    if (thermocouple.readCelsius() < 160 and thermocouple.readCelsius() >= 120)
    { duree_allumage_c3 = 250000 ;
    }
    if (thermocouple.readCelsius() < 120 and thermocouple.readCelsius() >= 60)
    { duree_allumage_c3 = 350000 ;
    }
  }
  else // temperature[24]> 35°C
  {
    if (thermocouple.readCelsius() >= 180)
    { duree_allumage_c3 = 250000 ;  // 120000ms=120s/60=2min
    }
    if (thermocouple.readCelsius() < 180 and thermocouple.readCelsius() >= 160)
    { duree_allumage_c3 = 350000 ;
    }
    if (thermocouple.readCelsius() < 160 and thermocouple.readCelsius() >= 120)
    { duree_allumage_c3 = 400000 ;
    }
    if (thermocouple.readCelsius() < 120 and thermocouple.readCelsius() >= 60)
    { duree_allumage_c3 = 999999999 ; // le retour devient négatif --> ne plus faire tourner le circulateur
    }
  }
  if (thermocouple.readCelsius() >= 70) // garder une valeur d'hystérésis, pour éviter que les vannes basculent sans arret durant
                                       // une prise de décision et une variation de la sonde.
  { mode = 3; // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, mode3=Poele, 
              // mode4=BallonSolaire sur Radiateurs.
    digitalWrite(broche_relais_C2, LOW); // éteindre circulateur chauffage solaire s'il était en marche.
    digitalWrite(45, HIGH); // alim vanne 7 et vanne 8
    digitalWrite(46, HIGH); // FERMER Vanne 7 si chaudière en marche
    digitalWrite(47, HIGH); // FERMER vanne 8 pour poele, et aussi si chaudière en marche
    digitalWrite(36, LOW); //ouvrir vanne9

    static unsigned long previousMillis2 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
    unsigned long currentMillis2 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
    if ((currentMillis2 - previousMillis2) >= duree_allumage_c3) // 120000-30000 = TEMPS ENTRE CHAQUE DEMARRAGE CIRCULATEUR
    { // il faut 60s au poele pour chauffer l'eau de 13°C à  45°C --> REDUIRE un peu le tps car si l'eau d'entrée est à  30°C...
      // à ballon haut=25,7, après 5 buches, ballon = 25,8°C ! 
      previousMillis2 = currentMillis2;
      digitalWrite(broche_relais_C3, HIGH); // allumer circulteur C3. Il y a une diode en parallèle positionnée sous le poele.
      c3_tourne = 1;
      digitalWrite(broche_buzzer_poele, HIGH); // faire un petit bruit dans le buzzer pour signaler la mise en marche
      digitalWrite(broche_buzzer_cave, HIGH); // faire un petit bruit dans le buzzer pour signaler la mise en marche
      delay(100);
      digitalWrite(broche_buzzer_poele, LOW);
      digitalWrite(broche_buzzer_cave, LOW);
    }
    if (c3_tourne == 1 and (currentMillis2 - 15000 >= previousMillis2)) // éteint circulateur x millisecondes apres
    { // il faut 30 secondes au circulateur pour vider le serpentin (vitesse 1 et robinet grand ouvert)
      // 15 secondes en vitesse 2, qui évite l'effet laminère et thermosiphon
      // 15 secondes en vitesse 3, qui évite l'effet laminère et thermosiphon
      c3_tourne = 0;
      digitalWrite(broche_relais_C3, LOW); // éteindre circulteur C3
      digitalWrite(broche_buzzer_poele, HIGH); // faire un petit bruit dans le buzzer pour signaler la mise à l'arret
      digitalWrite(broche_buzzer_cave, HIGH); // faire un petit bruit dans le buzzer pour signaler la mise à l'arret
      delay(200);
      digitalWrite(broche_buzzer_poele, LOW);
      digitalWrite(broche_buzzer_cave, LOW);
    }
    //****  A REMETTRE SI CIRCULATEUR NE BLOQUE PAS AU DEMARRAGE : stratification(); // envoi l'eau à la bonne hauteur dans le ballon.
  }

  if (thermocouple.readCelsius() < 60 and mode == 3) // Le "and mode==3" permet d'éviter le retour dans ce "if" par la suite
  { static unsigned long previousMillis4 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
    unsigned long currentMillis4 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
    if (currentMillis4 - previousMillis4 >= 300000) // lit la suite seulement toutes les x millisecondes
    { // délais de x millisecondes sans bloquer le programme et pour éviter les variations du capteur
      previousMillis4 = currentMillis4;
      digitalWrite(broche_relais_C3, LOW); // éteindre circulteur C3
      digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
      digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
      digitalWrite(48, HIGH); // Fermer Vanne 4
      digitalWrite(49, HIGH); // Fermer Vanne 5
      digitalWrite(38, HIGH); // Fermer Vanne 6
      digitalWrite(36, HIGH); // Fermer Vanne 9
      digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
      digitalWrite(46, HIGH); // vanne 7 fermee
      digitalWrite(47, HIGH); // Vanne 8 fermee
      //digitalWrite(broche_gaz_circulateur, LOW); // activer la circulation de la chaudière (un relais branché en série sur le circulateur)
      c3_tourne = 0;
      mode = 0; // mode=0 signifie qu'on rend la main à une autre fonction, comme les interrupteurs, qui sélectionnent un autre mode
    }
  }
  }
  //// Fin Fonction POELE
*/

//// Fonction DEBITMETRE
void isr()
{
  unsigned long now = micros(); // now = number of microseconds since the Arduino board began running the current program
  if (numPulses == 1) {
    firstPulseTime = now;
  }
  else {
    lastPulseTime = now;
  }
  ++numPulses;
}
//// Fin fonction DEBITMETRE


//// Fonction CIRCULATEUR solaire, variateur
void zero_crosss_int_c1()  // function to be fired at the zero crossing to dim the light
{ int dimtime_c1 = (100 * dimming_c1);  // For 60Hz =>65
  delayMicroseconds(dimtime_c1);    // Off cycle
  digitalWrite(AC_LOAD_c1, HIGH);   // triac firing
  delayMicroseconds(10);         // triac On propogation delay (for 60Hz use 8.33)
  digitalWrite(AC_LOAD_c1, LOW);    // triac Off
}
//// Fin fonction CIRCULATEUR solaire, variateur


//// Fonction DEGOMMAGE_CIRCULATEURS
// Allumer tous les circulateurs, à fond, 10 secondes pour les débloquer, de préférence le matin à 8h (fonction anti-gel)
// pas la peine d'ouvrir les vannes, en 10 secondes les circulateurs n'ont pas le temps de chauffer
void degommage_circulateurs_vannes()
{ if (Heure == 8 and Minute == 30 and Seconde < 15)
  { mode_degommage = 1;
    digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
    digitalWrite(broche_relais_C2, HIGH); // allumer circulateur
    digitalWrite(broche_relais_C3, HIGH); // allumer circulateur
  }
  else if (mode_degommage == 1) {
    mode_degommage = 0;
    digitalWrite(broche_relais_C1, LOW); // éteindre circulateur
    digitalWrite(broche_relais_C2, LOW); // éteindre circulateur
    digitalWrite(broche_relais_C3, LOW); // éteindre circulateur
  }
}
//// fin Fonction DEGOMMAGE_CIRCULATEURS


//// Fonction STRATIFICATION : envoi/prend l'eau au bon endroit dans le ballon en fonction du capteur de T°C n°26 positionné en sortie
void stratification() {
  static unsigned long previousMillis = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
  unsigned long currentMillis = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
  if (currentMillis - previousMillis >= 10000) // lit la suite seulement toutes les 10 secondes pour ne pas bouger sans arret les vannes
  { // délais de 5 secondes sans bloquer le programme
    previousMillis = currentMillis;
    if (temperature[26] > temperature[24]) // // Si T26 > T21 --> ouvrir V4-48, fermer V5-49, V6-38
    { digitalWrite(48, LOW); // toujours ouvrir avant de fermer, pour ne pas bloquer le circulateur
      digitalWrite(49, HIGH);
      digitalWrite(38, HIGH);
      Serial.print(F("  Vers Haut Ballon "));
    }
    if (temperature[26] <= temperature[24] and temperature[26] > temperature[23])
    { digitalWrite(49, LOW); // toujours ouvrir avant de fermer, pour ne pas bloquer le circulateur
      digitalWrite(48, HIGH);
      digitalWrite(38, HIGH);
      Serial.print(F("  Vers Milieu Ballon "));
    }
    if (temperature[26] <= temperature[23]) // "-0.06" = capteur déconnecté or (temperature[26] == -0.06)
    { digitalWrite(38, LOW); // toujours ouvrir avant de fermer, pour ne pas bloquer le circulateur
      digitalWrite(48, HIGH);
      digitalWrite(49, HIGH);
      Serial.print(F("  Vers Bas Ballon "));
    }
  }
}
//// Fin STRATIFICATION


//// Fonction ALARM surchauffe BALLON  (buzzer entre la masse et D29)   const int broche_buzzer_cave = 29 ;
void alarm_ballon() {
  // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
  if (temperature[25] > 80) // si température haut ballon > 85°C
  { Serial.print(F("  ALARM SURCHAUFFE BALLON")); Serial.print(temperature[25]); Serial.print(F("  "));
    alarm2 = true;
    for (j = 0; j <= 1; j++)
    { tone(broche_buzzer_cave, 500, 250);   //(pin, frequency, duration)
      delay(130);
      noTone(broche_buzzer_cave);
      tone(broche_buzzer_poele, 500, 250);   //(pin, frequency, duration)
      delay(130);
      noTone(broche_buzzer_poele);
    }
  }
  else {
    alarm2 = false;
  }
}
//// Fin Fonction ALARM BALLON

/*
  //// Fonction TEST ALARM
  void test_alarm()
  if () // si bouton test alarmes enfoncé
  {
  alarm1 = true; // probleme circulateur panneaux solaire qui ne tourne pas alors qu'allumé
  for (i = 0; i < 5; i++)
  { tone(broche_buzzer_cave, 800, 250);   //(pin, frequency, duration)
    delay(150);
    noTone(broche_buzzer_cave);
    tone(broche_buzzer_poele, 800, 250);
    delay(150);
    noTone(broche_buzzer_poele);
  }
  delay(4000); //wdt_disable();  wdt_enable(WDTO_8S);  si delay > 5 secondes
  alarm1 = false; // probleme circulateur panneaux solaire qui ne tourne pas alors qu'allumé

  alarm2 = true; // surchauffe ballon
  for (j = 0; j <= 1; j++)
  { tone(broche_buzzer_cave, 500, 250);   //(pin, frequency, duration)
    delay(130);
    noTone(broche_buzzer_cave);
    tone(broche_buzzer_poele, 500, 250);   //(pin, frequency, duration)
    delay(130);
    noTone(broche_buzzer_poele);
  }
   wdt_disable(); //wdt_enable(WDTO_8S);  ON ETEINT LE WATCHDOG POUR EVITER UN RESET
        delay(4000);
        wdt_enable(WDTO_8S); // on rallume le watchdog

  alarm2 = false; // surchauffe ballon

  alarm3 = true; // surchauffe poele
  for (j = 0; j < 3; j++)
  { tone(broche_buzzer_cave, 500, 250);   //(pin, frequency, duration)
    delay(130);
    noTone(broche_buzzer_cave);
    tone(broche_buzzer_poele, 500, 250);   //(pin, frequency, duration)
    delay(130);
    noTone(broche_buzzer_poele);
  }
  delay(4000);
  alarm3 = false; // surchauffe poele

  alarm4 = true; // erreur lecture des températures
  for (j = 0; j <= 3; j++)
  { tone(broche_buzzer_cave, 700, 200);   //(pin, frequency, duration)
    delay(250);
    noTone(broche_buzzer_cave);
  }
  delay(4000);
  alarm4 = false; // erreur lecture des températures

  alarm5 = true; // gel dans les panneaux solaires
  for (i = 0; i < 5; i++)
  { tone(broche_buzzer_cave, 800, 250);   //(pin, frequency, duration)
    delay(150);
    noTone(broche_buzzer_cave);
    tone(broche_buzzer_poele, 800, 250);
    delay(150);
    noTone(broche_buzzer_poele);
  }
  delay(4000);
  alarm5 = false; // gel dans les panneaux solaires
  }
  //// Fin Fonction TEST ALARM
*/

/*
  //// Fonction POSITION DES VANNES PAR DEFAUT : lorsque relais OFF (si arret carte arduino).
  /// Finalement, je n'utilise plus cette fonction : je positionne les fils des vannes en fonction de ce que je veux.
  void PositionVannesParDefaut()
  { digitalWrite(38, LOW); // Vanne 6, stratification basse : ouverte par défaut
  digitalWrite(39, LOW); // Vanne goutte à  goutte rue : fermée par défaut !
  digitalWrite(40, LOW); // Vanne 3 voies, +12v sur rouge = l'eau du ballon va à  la chaudiere par défaut
  digitalWrite(41, LOW); // Vanne 41 : ballon récupération eau douche : ouverte par défaut
  digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz par défaut
  digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz par défaut
  digitalWrite(44, LOW); // Vanne 13 : Radiateur Salle de Bain fermé par défaut (pour laisser l'eau circuler dans les autres radiateurs)
  digitalWrite(45, LOW); // ALIM Vanne7-8 : Chauffage, derriere Circulateur C2 :
  digitalWrite(46, LOW); // Vanne 7 : ouverte
  digitalWrite(47, LOW); // Vanne 8 : derriere Circulateur C2 : ouverte par défaut
  digitalWrite(36, LOW); // Vanne 9, derriere circulateur poele C3 (ouvert par défaut)
  digitalWrite(48, LOW); // Vanne 4, stratification haute : ouverte par défaut
  digitalWrite(49, LOW); // Vanne 5, stratification milieu : ouverte par défaut
  digitalWrite(32, LOW); // Vanne 3 et vanne 1, fonction anti-gel et thermosiphon : v3 ouverte par défaut, v1 fermée
  digitalWrite(26, LOW); // Vanne 2, circuit solaire plus court : fermée par défaut (l'eau passe dans les 2 serpentins)
  }
  //// Fin Fonction POSITION DES VANNES PAR DEFAUT
*/

//// Fonction LECTURE DES BOUTONS/INTERRUPTEURS  : GAZ, goutte à  goutte, et bouton 4
void lecture_boutons() {
  lecture_bouton_gaz = analogRead(14); // lecture de la valeur analogique en A14
  if (80 < lecture_bouton_gaz and lecture_bouton_gaz < 700) {
    bouton_gaz = 1;
  }
  if (lecture_bouton_gaz < 70) {
    bouton_gaz = 2;
  }
  if (lecture_bouton_gaz > 701) {
    bouton_gaz = 0;
  }

  lecture_bouton_goutte_a_goutte = analogRead(13); // lecture de la valeur analogique en A13
  if (lecture_bouton_goutte_a_goutte > 800) {
    bouton_goutte_a_goutte = 0;
  }
  if (lecture_bouton_goutte_a_goutte < 100) {
    bouton_goutte_a_goutte = 1;
  }

  lecture_bouton_4 = analogRead(12); // lecture de la valeur analogique en A12
  if (lecture_bouton_4 > 800) {
    bouton_4 = 0;
  }
  if (lecture_bouton_4 < 100) {
    bouton_4 = 1;
  }
}
//// Fin Fonction LECTURE DES BOUTONS/INTERRUPTEURS


//// Fonction EAU CHAUDE SANITAIRE
void eau_chaude_sanitaire() {
  if (temperature[24] >= consigne_eau_chaude + 1) // si T°C haut ballon > consigne+1 (env.43°C +1)--> ne pas passer sur chaudiere gaz
  { digitalWrite(40, HIGH); // vanne n°12 (3voies) vers réseau maison, sans passer par chaudiere
    digitalWrite(broche_gaz_on_off, HIGH); // on peut éteindre définitivement la chaudiere qui ne sert plus
    eau_par_gaz = 0;
    eau_par_gaz_compteur = 0;
  }
  else if (temperature[24] < consigne_eau_chaude) // si T°C haut ballon < consigne-1 (env.43°C)--> passer sur chaudiere gaz
  { digitalWrite(broche_gaz_on_off, LOW); // allumer chaudiere
    if (eau_par_gaz_compteur == 30) // basculer la vanne au 30eme tour (env. 30secondes), le temps que la chaudière chauffe son eau
    { digitalWrite(40, LOW);  // vanne n°12 (3voies) vers la chaudiere
      eau_par_gaz = 1;
    }
    if (eau_par_gaz_compteur < 30)
    { eau_par_gaz_compteur = eau_par_gaz_compteur + 1;  // on incremente le compteur, le temps d'arriver à 30s et que la chaudière ait chauffé son eau
    }
  }
}
//// Fin Fonction EAU CHAUDE SANITAIRE


/*
  //// Fonction RECUPERATION EAU DOUCHE
  // Bidon de 20L directement branché sur l'évacuation de la douche et qui se vide par une vanne motorisée (+ trop plein).
  // On fait passer dedans l'eau froide venant de la rue à l'intérieur d'un serpentin de PER diam. 12mm.
  // En Hiver : l'eau arrive à 8°C et sort à 15°C du bidon (qui est à 30°C). Donc l'échangeur en PER est très mauvais...
  // Finalement : je n'utilise plus ce système, mon évacuation n'était pas assez grosse et elle a fini par se boucher.
  void recup_eau_douche()
  {
  if (ete == false) // si entre octobre et mai
  { if ((Heure == 11 and Minute == 00) or (Heure == 16 and Minute == 0) )  // vider bidon à  11h et 16h
    { digitalWrite(41, LOW); // ouvrir vanne du bidon pour le vider
    }    else {
      digitalWrite(41, HIGH); // fermer vanne du bidon récup eau douche
    }
  }  else {
    digitalWrite(41, LOW); // ouvrir vanne du bidon récup eau douche si pas l'hiver (pas nécessaire de chauffer la cave et eau de ville pas tres froide)
  }
  }
  //// Fin RECUPERATION EAU DOUCHE
*/

//// Fonction GOUTTE à  GOUTTE
// Gere l'arrosage dans les jardinieres dehors
// Ayant eu des problemes avec les détecteurs d'humidité (s'oxyde en terre ; utiliser branche de lunettes en titane ?),
// j'ai préféré utiliser un capteur de lumiere et un capteur de température extérieur (celui du panneau 4)
// le système fonctionne maintenant assez bien, même si j'ai mis du micro à goutte goutte (tuyau de 4mm) qui entraine
// des difficultés à régler les débits. Je conseille plutot des tuyaux de 16mm (moins de problèmes si différences
// de longeur importantes). Eviter aussi les différences de hauteur des bacs... : car celui du haut videra ses tuyaux dans ceux du bas.
void goutte_a_goutte()
{
  if (bouton_goutte_a_goutte == 1) // si bouton goutte à goutte = ON
  { pinMode (broche_ldr, INPUT);
    ldr = analogRead(broche_ldr); // plus la valeur est petite, moins il y a de soleil
    RTC.getTime();
    Heure = RTC.hour;
    Minute = RTC.minute;
    if (Minute != 0) {
      arrosee = false;
    }
    wdt_disable();
    if (arrosee == false and Heure == 10 and Minute == 0 and ldr > 700 and temperature[7] > 20)
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 10;
    }
    if (arrosee == false and Heure == 12 and Minute == 0 and ldr > 850 and temperature[7] > 25) // température du cadre panneau 4
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 12;
    }
    if (arrosee == false and Heure == 14 and Minute == 0 and ldr > 850 and temperature[7] > 30)
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 14;
    }
    if (arrosee == false and (Heure == 16) and Minute == 0 and ldr > 880 and temperature[7] > 35)
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 16;
    }
    if (arrosee == false and Heure == 18 and Minute == 0 and ldr > 750 and temperature[7] > 35)
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 18;
    }
    if (arrosee == false and Heure == 20 and Minute == 0 and ldr > 680 and temperature[7] > 30)
    { digitalWrite(broche_vanne_goute_a_goutte, HIGH); // ouvrir arrosage
      delay(15000); // arroser 10s : NE PAS FAIRE DES "delay" > 7s A CAUSE DU WATCHDOG (reset automatique en cas de plantage)
      digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
      arrosee = true;
      dernier_arrosage = 20;
    }
    wdt_enable(WDTO_8S);
    digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
  }
  else {
    digitalWrite(broche_vanne_goute_a_goutte, LOW); // fermer arrosage
  }
}
//// Fin fonction GOUTTE à GOUTTE
/* fonction pour eviter les problemes du watchdog:
  void delaySeconds (int seconds) {// Function that feeds the puppy
  for (int i = 0; i <= seconds * 10; i ++) {
    delay (100);
    ESP.wdtFeed ();
  }
  }

  Example of use:
  delaySeconds (30); // delay 30 seconds


  ou alors :     wdt_disable();      wdt_enable(WDTO_8S);
*/




//-------------------------------- SETUP -------------------------------------------
//-------------------------------- SETUP -------------------------------------------
//-------------------------------- SETUP -------------------------------------------
void setup() {

  for (i = 22; i < 33; i++)  // ATTENTION : 33,34,35 utilisées pour sonde K du Poele
  { pinMode(i, OUTPUT);
  }
  for (i = 36; i < 54; i++) {  // ATTENTION : 33,34,35 utilisées pour sonde K du Poele
    pinMode(i, OUTPUT);  // definition des ports relais en sortie
  }

  // PositionVannesParDefaut(); // Positionne les vannes par défaut, toutes sur LOW.
  digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
  digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
  digitalWrite(48, HIGH); // Fermer Vanne 4
  digitalWrite(49, HIGH); // Fermer Vanne 5
  digitalWrite(38, HIGH); // Fermer Vanne 6
  digitalWrite(36, HIGH); // Fermer Vanne 9
  digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
  digitalWrite(46, HIGH); // vanne 7 fermee
  digitalWrite(47, HIGH); // Vanne 8 fermee
  digitalWrite(broche_gaz_circulateur, LOW); // autoriser la circulation de la chaudière (un relais branché en série sur le circulateur de la chaudière)

  pinMode(broche_sonde_pt100, INPUT); // sonde pt100 dans panneau n°2 et branchée sur un petit ampli puis sur arduino, mesure très instable
  pinMode(broche_ldr, INPUT); // sonde lumiere sur panneaux solaires

  //// Initialisation commandes Circulateur C1,C2,C3
  pinMode(broche_relais_C1, OUTPUT);
  pinMode(broche_relais_C2, OUTPUT);
  pinMode(broche_relais_C3, OUTPUT);
  digitalWrite(broche_relais_C1, LOW); // éteindre circulteur C1
  digitalWrite(broche_relais_C2, LOW); // éteindre circulteur C2
  digitalWrite(broche_relais_C3, LOW); // éteindre circulteur C3
  pinMode(AC_LOAD_c1, OUTPUT);// Set AC Load pin as output
  attachInterrupt(4, zero_crosss_int_c1, RISING);  // prépare les interruptions : sur Arduino MEGA: interruption n°4 = broche 19
  /*
     Pin    |  Interrrupt # | Arduino Platform
    ---------------------------------------
    2      |  0            |  All -But it is INT1 on the Leonardo
    3      |  1            |  All -But it is INT0 on the Leonardo
    18     |  5            |  Arduino Mega Only
    19     |  4            |  Arduino Mega Only
    20     |  3            |  Arduino Mega Only
    21     |  2            |  Arduino Mega Only
    0      |  0            |  Leonardo
    1      |  3            |  Leonardo
    7      |  4            |  Leonardo
    The Arduino Due has no standard interrupt pins as an iterrupt can be attached to almosty any pin.*/
  //// Fin Initialisation commandes Circulateur C1,C2,C3


  attachInterrupt(5, isr, CHANGE);  // interruption n°5 pour DEBITMETRE, broche 18


  pinMode(43, INPUT); // définir D43 comme une entrée, entrée de l'état du thermostat chauffage
  //digitalWrite(43, HIGH); //on active la résistance de pull-up en mettant la broche à l'état haut (mais cela reste toujours une entrée)

  pinMode(broche_buzzer_cave, OUTPUT); // si vous oubliez cette ligne, vous allez avoir des bruits parasites dans vos buzzers
  pinMode(broche_buzzer_poele, OUTPUT); // si vous oubliez cette ligne, vous allez avoir des bruits parasites dans vos buzzers
  digitalWrite(broche_buzzer_cave, LOW); // couper vraiment le son
  digitalWrite(broche_buzzer_poele, LOW); // couper vraiment le son
  // digitalWrite(broche_buzzer_cave, HIGH); //on active la résistance de pull-up en mettant la broche à l'état haut (mais cela reste toujours une entrée)
  // digitalWrite(broche_buzzer_poele, HIGH); //on active la résistance de pull-up en mettant la broche à l'état haut (mais cela reste toujours une entrée)

  Serial.begin(9600); // Initialisation du port série


  //// INITIALISATION HORLOGE DS3231
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Entree startAddr in NV-RAM address 0x08
  TimeIsSet = 0xffff;
  RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  RTC.ctrl = 0x00;     // 0x00=disable SQW pin, 0x10=1Hz, 0x11=4096Hz, 0x12=8192Hz, 0x13=32768Hz
  RTC.setCTRL();
  //// Fin INITIALISATION HORLOGE DS3231

  //// Enregistrement heure et date démarrage de l'arduino
  RTC.getTime();
  Heure = RTC.hour;
  Minute = RTC.minute;
  Seconde = RTC.second;
  Jour = RTC.day;
  Mois = RTC.month;
  Annee = RTC.year;
  mois_demarrage = Mois; jour_demarrage = Jour; heure_demarrage = Heure; minute_demarrage = Minute;



  //// ECRAN LCD 20*4
  lcd.begin(20, 4);  // initialize the lcd for 20 chars 4 lines, turn on backlight
  //// FIN ECRAN LCD 20*4


  //// Initialisation ETHERNET
  // NE PAS UTILISER LES BROCHES 50 à 53 pour autre chose (sur carte arduino Mega)
  pinMode(10, OUTPUT); // canbus and ethernet SPI CS.
  digitalWrite(10, HIGH);
  pinMode(53, OUTPUT);
  digitalWrite(53, HIGH); // ET NE PAS UTILISER la broche 53, pour que le port SPI fonctionne
  Ethernet.begin(mac, ip);  //Démarrer la connexion Ethernet et le serveur (version DHCP)
  server.begin();
  //// FIN Initialisation Ethernet


  //  Initialisation carte SD
  // SD.begin(4); //début de la communication avec la carte sur le pin 4 ou 10?

  //// FIN Initialisation carte SD


  myHumidity.begin(); // capteur d'humidité HTU 21D  en I2C

  wdt_enable(WDTO_8S); // Initialisation du WatchDog : reset de la carte en cas de plantage

}


//--------------------------------- LOOP -------------------------------------------
//--------------------------------- LOOP -------------------------------------------

void loop() {
  startTemperatureMeasure(SENSOR_ADDRESS_1);
  startTemperatureMeasure(SENSOR_ADDRESS_2);
  startTemperatureMeasure(SENSOR_ADDRESS_3);
  startTemperatureMeasure(SENSOR_ADDRESS_4);
  startTemperatureMeasure(SENSOR_ADDRESS_5);
  startTemperatureMeasure(SENSOR_ADDRESS_6);
  startTemperatureMeasure(SENSOR_ADDRESS_7);
  startTemperatureMeasure(SENSOR_ADDRESS_8);
  startTemperatureMeasure(SENSOR_ADDRESS_9);
  startTemperatureMeasure(SENSOR_ADDRESS_10);
  startTemperatureMeasure(SENSOR_ADDRESS_11);
  startTemperatureMeasure(SENSOR_ADDRESS_16);
  startTemperatureMeasure(SENSOR_ADDRESS_17);

  startTemperatureMeasure2(SENSOR_ADDRESS_0);
  startTemperatureMeasure2(SENSOR_ADDRESS_12);
  startTemperatureMeasure2(SENSOR_ADDRESS_13);
  startTemperatureMeasure2(SENSOR_ADDRESS_14);
  startTemperatureMeasure2(SENSOR_ADDRESS_15);
  startTemperatureMeasure2(SENSOR_ADDRESS_18);
  startTemperatureMeasure2(SENSOR_ADDRESS_19);
  startTemperatureMeasure2(SENSOR_ADDRESS_20);
  startTemperatureMeasure2(SENSOR_ADDRESS_21); // sonde puits
  startTemperatureMeasure2(SENSOR_ADDRESS_22); // salle de bain
  startTemperatureMeasure2(SENSOR_ADDRESS_23);
  startTemperatureMeasure2(SENSOR_ADDRESS_24); // ballon haut
  startTemperatureMeasure2(SENSOR_ADDRESS_25);
  startTemperatureMeasure2(SENSOR_ADDRESS_26);
  startTemperatureMeasure2(SENSOR_ADDRESS_27); // rez de chaussée
  startTemperatureMeasure2(SENSOR_ADDRESS_28);

  wdt_reset(); // Reset du watchDog (et de la carte arduino), si plantage


  // calcul ETE ou HIVER
  if (Mois > 6 and Mois < 9)
  { ete = true;
  }
  else {
    ete = false;
  }


  lecture_boutons(); // lecture des états des boutons
  solaire_anti_gel(); // active circulateur et alarm si on risque le gel dans les panneaux
  alarm_ballon(); // met en route une alarm si ballon solaire de 800L > 80°C
  //poele(); // met en route le circulateur serpentin poele si sonde K > 60°C
  // ALARM  Poele  : permet de savoir si le poele chauffe trop, surtout lorsqu'on est pas dans la pièce du poele
  if (thermocouple.readCelsius() >= 250) // si T°C poele > 250°C --> démarrer alarm
  { // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
    Serial.print(F(" POELE SURCHAUFFE="));
    Serial.print(thermocouple.readCelsius()); Serial.print(F("  "));
    alarm3 = true;
    for (j = 0; j < 3; j++)
    { tone(broche_buzzer_cave, 500, 250);   //(pin, frequency, duration)
      delay(130);
      noTone(broche_buzzer_cave);
      tone(broche_buzzer_poele, 500, 250);   //(pin, frequency, duration)
      delay(130);
      noTone(broche_buzzer_poele);
    }
  }
  else {
    alarm3 = false; // Fin ALARM
  }

  eau_chaude_sanitaire(); // si l'eau du ballon solaire de 800L < 43°C --> on complete la chauffe de l'eau sanitaire avec la chaudiere au gaz
  erreur_lecture_eteindre_circulateurs(); // eteint les circulateurs si erreur dans les sondes température DS18B20
  // ******   recup_eau_douche(); // gére le petit bidon de récup eau évacuation douche, abandonné car efficacité faible
  goutte_a_goutte(); // gére l'arrosage goutte à goutte si bouton goutte à goutte enclenché
  degommage_circulateurs_vannes(); // debloque les vannes une fois par jour 15 secondes


  humidite_cave = myHumidity.readHumidity();
  temperature_cave = myHumidity.readTemperature();

  Serial.println(""); Serial.print(F("Etag= ")); Serial.print(temperature[22], 2);
  Serial.print(F("  RdC= ")); Serial.print(temperature[27], 2); Serial.print(F("  Cav= ")); Serial.print(temperature_cave, 2);
  Serial.print(F(" (Hum=")); Serial.print(humidite_cave, 1); Serial.print(F("%)"));
  Serial.print(F("  Puits= ")); Serial.print(temperature[21], 2);

  // DEBUT HORLOGE
  Serial.println(F(" ")); Serial.println(" ");
  Serial.print(F("Last Start: ")); Serial.print(jour_demarrage); Serial.print(F("/")); Serial.print(mois_demarrage);
  Serial.print(F(", ")); Serial.print(heure_demarrage); Serial.print(F(":"));
  if (minute_demarrage < 10) {
    Serial.print(F("0"));
  }
  Serial.print(minute_demarrage);

  Serial.println(" ");
  RTC.getTime();
  Heure = RTC.hour;
  Minute = RTC.minute;
  Seconde = RTC.second;
  Jour = RTC.day;
  Mois = RTC.month;
  Annee = RTC.year;
  Serial.print(Heure);  Serial.print( ":");
  if (Minute < 10) {
    Serial.print(F("0"));
  }
  Serial.print( Minute );  Serial.print( ":" );
  if (Seconde < 10) {
    Serial.print("0");
  }
  Serial.print(Seconde);  Serial.print(F(", "));
  Serial.print(Jour); Serial.print(F("/")); Serial.print(Mois); Serial.print(F("/")); Serial.print(Annee); Serial.print(F(" "));
  /*
      if (ete == true) {
     Serial.print(F("ete");
    }
    else {
     Serial.print(F("hiver");
    }
  */
  // Fin HORLOGE


  // Affichage LDR
  ldr = analogRead(broche_ldr); // plus la valeur est petite, moins il y a de soleil
  Serial.print(F("  LDR = "));  //Serial.print(F("Hello World"))
  Serial.print(ldr);


  // Début DEBITMETRE
  /* G3/4" OD25.4mm  Débit: 1 ~ 30L/min     Impulsion de débit: F (Hz) = (6.6xQ) Q = L/min
     Max. Courant De Fonctionnement: 15mA (DC5 V)  Min. Tension De Fonctionnement: DC 5 V
     liquide Température: 80°C   précision: +-2% ~ 5%
     cable Connection: Rouge: Positif + ; Noir: Négative- ; jaune: signal D'impulsion. */
  attachInterrupt(5, isr, CHANGE);    // enable the interrupt
  delay (1000);   //Attendre 1  seconde.  Apparemment, lorsque j'utilise millis(), je perds des impulsions.
  detachInterrupt(5);
  F =  ((1000000.0 * (float)(numPulses - 2)) / (float)(lastPulseTime - firstPulseTime) / 2);
  numPulses = 0;
  attachInterrupt(5, isr, CHANGE);    // enable the interrupt
  debit = ((F) / 6.6) ;   //debit = ((F) / 6.6) * 60; // doc débimetre : Impulsion de débit: F (Hz) = (6.6xQ) Q = L/min = F/6.6
  if (debit > 50) {
    debit = 0; // si over flow ou si le débitmetre ne bouge plus
  }
  // Serial.print(F); Serial.print(F(" Hz  ");
  // Calcul de la puissance thermique: P(KW)=m(m3/h) * cp * dT * 1.16 (avec cp=1 pour l'eau). Un capteur solaire fourni jusqu'à 2000W (1KW/m2)
  wh = (debit * 60) * 1.0 * (temperature[18] - temperature[19]) * 1.16; // wh = flow() * 1.0 * (tempIn - tempOut) * 1.16;


  //Garder sur 11 lignes, permet de remonter avec une lecture facile (synchronisée)
  Serial.print(F("  Deb = ")); Serial.print(debit); Serial.print(F(" L/mn ")); Serial.print(F(" CycSol="));
  Serial.print(cycle_demarrage_solaire); Serial.print(F(" Delta_P2-BalBas=")); Serial.print(delta_panneaux_ballon_milieu); 
  Serial.print(F("(")); Serial.print(consigne_solaire); Serial.print(F(")"));
  Serial.print(F(" ChaufBal=")); Serial.print(solaire_chauffe_ballon);
  Serial.print(F(" SerpHaut=")); Serial.print(serpentin_haut); Serial.print(F("|")); Serial.print(temperature[0], 2); 
  Serial.print(F(" P="));
  Serial.print(wh, 0); Serial.print(F(" W")); Serial.println("  ");

  Serial.print(F("RetourChd = "));
  Serial.print(temperature[18], 2);
  Serial.print(F(" DepFrd = "));
  Serial.print(temperature[19], 2);
  delta_chd_frd_station = (temperature[18] - temperature[19]); // calcul du delta Chaud Froid au niveau de la station
  Serial.print(F(" (D = "));
  Serial.print(delta_chd_frd_station);
  Serial.println(") ");
  Serial.print(F("P1 = ")); Serial.print(temperature[1], 2); Serial.print(F(" (T2 = ")); Serial.print(temperature[2], 2);
  Serial.print(F(") ")); Serial.print(F("P2 = ")); Serial.print(temperature[3], 2); Serial.print(F(" (dedans=")); 
  Serial.print(temperature_sonde_pt100); 
  Serial.print(F(";")); Serial.print(valeur_sonde_pt100); Serial.print(F(") "));
  Serial.print(F("(T4 = ")); Serial.print(temperature[4], 2); Serial.print(F(") "));
  Serial.print(F("P3 = ")); Serial.print(temperature[5], 2); Serial.println(" ");
  Serial.print(F("P4 = ")); Serial.print(temperature[7], 2);
  Serial.print(F("  (T6 = ")); Serial.print(temperature[6], 2); Serial.print(F(") "));
  Serial.print(F(" P5 = ")); Serial.print(temperature[8], 2); Serial.println(" ");
  Serial.print(F("P6 = ")); Serial.print(temperature[9], 2);
  Serial.print(F("  (T10 = ")); Serial.print(temperature[10], 2); Serial.print(F(") "));
  Serial.print(F(" P7 = ")); Serial.print(temperature[11], 2); Serial.println("");
  Serial.print(F("  Ret Garg = ")); Serial.print(temperature[17], 2); Serial.print(F("  "));
  Serial.print(F("Ret Facad = ")); Serial.print(temperature[16], 2); Serial.print(F("  Moy = ")); 
  Serial.print((temperature[16] + temperature[17]) / 2);
  Serial.println("  ");

  Serial.print(F("BalHT = "));
  Serial.print(temperature[24], 2);
  Serial.print(F("  BalMIL = "));
  Serial.print(temperature[23], 2);
  Serial.print(F("  BalBAS = "));
  Serial.print(temperature[25], 2);
  delta_stratification = (temperature[24] - temperature[25]); // calcul du delta de stratification
  Serial.print(F(" (D="));
  Serial.print(delta_stratification);
  Serial.print(F(") TempTt = "));
  ballon_temp_moy = (temperature[24] + temperature[23] + temperature[25]) / 3;
  Serial.print(ballon_temp_moy);
  Serial.println(" ");

  relais_gaz = digitalRead(broche_gaz_on_off);
  if (eau_par_gaz == 1)
  {
    Serial.print(F("EAU GAZ(rel=")); Serial.print(relais_gaz); Serial.print(F(")"));
  }
  else {
    Serial.print(F("EAU SOL(rel=")); Serial.print(relais_gaz); Serial.print(F(")"));
  }
  Serial.print(F("  EauFrdRue="));
  Serial.print(temperature[12], 2);
  if (bouton_4 == 1)
  {
    Serial.print(F("  Sech Sal Bain ON (a "));
    Serial.print(heure_seche_serviette_matin); Serial.print(F("h et a ")); Serial.print(heure_seche_serviette_soir);
    Serial.print(F("h = "));
    Serial.print(chauffer_sechoir); Serial.print(F(")"));
  }
  Serial.println("");

  Serial.print(F("MODE="));
  Serial.print(mode);
  switch (mode) { // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, 
                  // mode3=Poele, mode4=BallonSolaire sur Radiateurs.
    case 0:
      Serial.print(F(" (BAL/GAZ->RAD)"));
      break;
    case 1:
      Serial.print(F(" (GAZ->RAD)"));
      break;
    case 2:
      Serial.print(F(" (GAZ->BAL)"));
      break;
    case 3:
      Serial.print(F(" (POEL->Bal)"));
      break;
    case 4:
      Serial.print(F(" (BAL->RAD)"));
      break;
  }
  Serial.print(F("  Bt_gaz="));
  Serial.print(bouton_gaz); Serial.print(F("|")); Serial.print(lecture_bouton_gaz);
  Serial.print(F("  Bt_g_a_g="));
  Serial.print(bouton_goutte_a_goutte);
  Serial.print(F("  Bt_Sech_Serv="));
  Serial.print(bouton_4);
  Serial.println(" ");



  // GESTION DES BOUTONS
  // GAZ sur RADIATEUR : seulement si le ballon solaire < 28°C avec thermostat_chauffage_solaire == 0
  if (bouton_gaz == 1 and mode != 3) // mettre la chaudiere gaz sur les radiateurs de la maison
  { mode = 1; // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, 
              // mode3=Poele, mode4=BallonSolaire sur Radiateurs.
    digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2 du chauffage solaire // au cas où...
    digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
    digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
    digitalWrite(48, HIGH); // Fermer Vanne 4
    digitalWrite(49, HIGH); // Fermer Vanne 5
    digitalWrite(38, HIGH); // Fermer Vanne 6
    digitalWrite(36, HIGH); // Fermer Vanne 9
    digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
    digitalWrite(46, HIGH); // vanne 7 fermee
    digitalWrite(47, HIGH); // Vanne 8 fermee
    digitalWrite(broche_gaz_on_off, LOW); // allumer la chaudiere
    digitalWrite(broche_gaz_circulateur, LOW); // activer la circulation de la chaudière
                                          // (un relais branché en série sur le circulateur de la chaudière)
    cycle_chauffage = 0;  // variable du chauffage par le ballon solaire
    etat_bouton_gaz_precedent = 1;
  }

  // GAZ sur BALLON
  if (bouton_gaz == 2 and mode != 3) // mettre la chaudiere gaz sur le chauffage du ballon
  { mode = 2; // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, mode3=Poele, 
              // mode4=BallonSolaire sur Radiateurs.
    digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2, au cas où...
    digitalWrite(42, LOW); // Vanne 10, ouverte
    digitalWrite(37, HIGH); // Vanne 11, fermée
    digitalWrite(36, HIGH); // Fermer Vanne 9
    digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
    digitalWrite(46, HIGH); // Vanne v7 fermée
    digitalWrite(47, LOW); // Vanne 8 ouverte
    digitalWrite(broche_gaz_on_off, LOW); // allumer la chaudiere
    // delay (20000); //attendre que la chaudiere s'allume, mais ne pas faire des delais > 7s à cause du watchdog
    // digitalWrite(broche_gaz_manuel,HIGH); // appui bref sur MANUEL pour chauffer le ballon
    // delay (2000);
    // digitalWrite(broche_gaz_manuel,LOW); // appui bref sur MANUEL pour chauffer le ballon
    digitalWrite(broche_gaz_circulateur, LOW); // activer la circulation de la chaudière 
                                             // (un relais branché en série sur le circulateur de la chaudière)
    stratification(); // envoi l'eau à  la bonne hauteur dans le ballon
    cycle_chauffage = 0; // variable du chauffage par le ballon solaire
    etat_bouton_gaz_precedent = 2;
  }

  // Retour à  etat 0
  if (bouton_gaz == 0 and mode != 3 and etat_bouton_gaz_precedent != 0)
  { // on laisse faire le chauffage solaire et son mode 4, qu'il quitte de temps à autre
    // if (eau_par_gaz == 0 and ete == true){digitalWrite(broche_gaz_on_off,HIGH);} // Eteindre la chaudiere
    digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2
    digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
    digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
    digitalWrite(48, HIGH); // Fermer Vanne 4
    digitalWrite(49, HIGH); // Fermer Vanne 5
    digitalWrite(38, HIGH); // Fermer Vanne 6
    digitalWrite(36, HIGH); // Fermer Vanne 9
    digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
    digitalWrite(46, HIGH); // vanne 7 fermee
    digitalWrite(47, HIGH); // Vanne 8 fermee
    position_v8 = 0; // 0 = fermee
    digitalWrite(broche_gaz_circulateur, LOW); // autoriser la circulation de la chaudière 
                                        // (un relais branché en série sur le circulateur de la chaudière)
    cycle_chauffage = 0;
    mode = 0;
    etat_bouton_gaz_precedent = 0;
  }




  //----------------------------------------------   SOLAIRE    ------------------------------------------------

  //// SONDE PT100 dans le panneau solaire, que je n'utilise finalement pas dans le fonctionnement du programme (juste en affichage),
  //// car ce système est très imprécis (variation en fonction de la longueur du cable, de l'alim, etc.)
  valeur_sonde_pt100 = analogRead(broche_sonde_pt100); // lecture port de la sonde PT100
  // Comme l'ampli n'est pas très proche de la sonde, j'avais des écarts de temperature jusqu'à +/-5°C, donc je fais une moyenne
  // avec les valeurs precedentes pour stabiliser :
  valeur_sonde_pt100_corrigee = (valeur_sonde_pt100 + valeur_sonde_pt100_precedente + valeur_sonde_pt100_precedente1) / 3;
  valeur_sonde_pt100_precedente1 = valeur_sonde_pt100_precedente;
  valeur_sonde_pt100_precedente = valeur_sonde_pt100;
  temperature_sonde_pt100 = 1.27 * valeur_sonde_pt100_corrigee - 290 ; // conversion en °C de la valeur ; voir ci-dessous :
  // 1.27 * valeur_sonde_pt100_corrigee - 320
  /* Formule à recalculer en fonction de votre capteur (évitez d'ajouter une longueur de cable au pt100, sinon instabilité).
    Fonction :  Y (temperature) = Pente (ou coef directionnel) * X (résistance) + b

    Après avoir fait quelques relevés de température / valeur donnée par le arduino (ou résistance),
    on prend deux points extrêmes du graphique (en X la résistance, en Y la température) :

    P1 (arduino 240 , Température de 10°C)       ou  P1(257,3)
    P2 (arduino 370 , Température de 260°C)      ou  P2(318,80) P=1.26 b=-320 (ça c'est qd j'ai allongé le cable de la PT100...)

    --> on calcule la pente (ou "coefficient directionel") P = y / x = (260-10)/(370-240) = 1,923
    De là, on en déduit "b" :
    10 (Y) = 1,923 (P) * 240 (X) + b --> b = 10-1,923*240 = -451.538

    Voir aussi site : http://edu.mrpigg.ca/termo.html

    A savoir aussi, dès que l'alimentation des circuits (arduino et ampli) varie, la valeur de PT100 varie... donc ce n'est pas un capteur prècis !
  */

  // finalement, je n'utilise pas la pt100, car trop instable


  // Notons qu'augmenter la vitesse du circulateur solaire est intéressant pour récupérer davantage d'énergie seulement lorsqu'il
  // y a beaucoup d'énergie, et que donc souvent, on en a déjà trop...
  // Donc je laisse le circulteur en vitesse 1, pour récupérer le maximum de calorie l'hiver, tout en en perdant lorsqu'il
  // y a beaucoup beaucoup de soleil et de chaleur (à ce moment là, il faudrait circuler plus vite pour déplacer toutes les
  // calories vers le ballon)


  delta_panneaux_ballon_milieu = temperature[2] - (temperature[23] + temperature[25]) / 2 ;


  //-- rendement maxi ------ si pas été et température bas ballon < 70 ;  VERSION RENDEMENT OPTIMAL -------
  if (Mois != 7 and Mois != 8 and Mois != 9 and temperature[25] < 70)
  { // hiver : Garder un delta solaire (panneau - bas cuve) élevé, mais pas forcément le plus élevé possible, car les panneaux
    // perdent en rendement à haute température.
    // Démarrer le circulateur rapidement (panneau déjà bien chaud)
    // Eviter les circulations trop lente(<5L/mn), car on entre en régime laminaire ("dans ce cas, tout se passe comme si une couche de
    // fluide adhérait à l'intérieur du tube et seul le centre du tube est utilisé par le courant de fluide")
    // Préférer allumer C1, éteindre C1 le temps que cela chauffe, rallumer, éteindre, etc. A chaque allumage du circulateur, cela créera
    // des remous qui amélioreront le rendement.
    // Utiliser V3 en bypass le temps que l'eau qui arrive sur le ballon soit chaude

    if (delta_panneaux_ballon_milieu > consigne_solaire and ldr > 700 and temperature[25] > 5) 
    // si (T°C dans panneau 2 - T°C ballon bas) > consigne (env. 8)
    // le temperature[25]>5 permet d'éviter le démarrage du circulateur à chaque reset (T°C=0 ou -0,06) de l'arduino ou 
    // lorsqu'il y a un problème de lecture des températures
    { digitalWrite(broche_relais_C1, HIGH); // allumer circulateur

      cycle_demarrage_solaire = cycle_demarrage_solaire + 1;

      if (temperature[18] > (temperature[23] + temperature[25]) / 2) // si T°C Chd station > T°C bas cuve
      { digitalWrite(32, HIGH); // HIGH = fermer V3 et ouvrir V1 pour faire rentrer l'eau dans le ballon
        solaire_chauffe_ballon = 1;
        static unsigned long previousMillis10 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
        unsigned long currentMillis10 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
        if (currentMillis10 - previousMillis10 >= 30000) // lit la suite seulement toutes les 30s pour ne pas bouger sans arret les vannes
        {
          if (temperature[18] < temperature[23])
          {
            previousMillis10 = currentMillis10;
            digitalWrite(26, HIGH); //ouvrir vanne 2 pour passer l'eau seulement dans le serpentin du bas
            serpentin_haut = 0;

          }  else if (temperature[18] >= temperature[23]) {
            digitalWrite(26, LOW); //fermer vanne 2 pour passer l'eau dans les deux serpentins
            serpentin_haut = 1;
          }
        }
        if (debit <= 0 and cycle_demarrage_solaire > 100) // si C1 tourne depuis plus de 5mn et pas de débit --> erreur
        { digitalWrite(broche_relais_C1, LOW); // éteindre C1, mais relais peut-être défectueux (collé ?)
          // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
          Serial.print(F("ALARM ERREUR DEBIT C1=0"));
          alarm1 = true;
          for (i = 0; i < 5; i++) {
            tone(broche_buzzer_cave, 800, 250); //(pin, frequency, duration)
            delay(500);
            noTone(broche_buzzer_cave);
            tone(broche_buzzer_poele, 800, 250);
            delay(500);
            noTone(broche_buzzer_poele);
          }
        }
        else {
          alarm1 = false;
        }
      }
      else {
        digitalWrite(32, LOW); // LOW = ouvrir v3, ne pas faire rentrer l'eau
        solaire_chauffe_ballon = 0;
      }
      // delta_chd_frd_station = (temperature[18] - temperature[19]); 
      // calcul du delta Chaud Froid au niveau de la station ; déjà calculé plus haut
    }
    else {
      static unsigned long previousMillis5 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis5 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis5 - previousMillis5 >= 30000) // lit la suite seulement toutes les 30 secondes pour ne pas bouger sans arret les vannes
      { // vider les dernière calorie dans le circuit
        previousMillis5 = currentMillis5;
        digitalWrite(broche_relais_C1, LOW); // éteindre circulateur
        digitalWrite(32, LOW); // LOW = ne pas faire rentrer l'eau dans la cuve et fermer vanne anti-thermosiphon V1
        digitalWrite(26, LOW); // fermer vanne 2 pour éviter thermosiphon de remonter vers panneaux
        cycle_demarrage_solaire = 0; solaire_chauffe_ballon = 0;
      }
    }
  }


  //-- été pas surchauffe ---------  si été, baisser la température de la cuve et moins chauffer la maison  ------------------
  // ne plus utiliser la vanne bypass V3 pour l'économiser et baisser légèrement l'efficacité
  // J'ajoute +10 à la consigne solaire --> il faut qu'il y ait 3+10°C d'écart entre panneau et bas milieu de cuve pour démarrer le Circu1

  if ((Mois == 7 or Mois == 8 or Mois == 9) and temperature[25] < 60)
  {
    if (delta_panneaux_ballon_milieu > consigne_solaire + 10 and ldr > 700 and temperature[25] > 5) 
    // si (T°C dans panneau 2 - T°C ballon bas) > consigne (env. 3)
    // temperature[25]>5 permet d'éviter le démarrage du circulateur à chaque reset (T°C=0 ou -0,06) de l'arduino ou lorsqu'il y a 
    // un problème de lecture des températures.
    {
      cycle_demarrage_solaire = cycle_demarrage_solaire + 1;
      digitalWrite(32, HIGH); // HIGH = fermer V3 et ouvrir V1 pour faire rentrer l'eau dans le ballon

      static unsigned long previousMillis10 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis10 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis10 - previousMillis10 >= 60000) // lit la suite seulement toutes les 60s pour ne pas bouger sans arret les vannes
      {
        if (temperature[18] < temperature[23])
        {
          previousMillis10 = currentMillis10;
          digitalWrite(26, HIGH); //ouvrir vanne 2 pour passer l'eau seulement dans le serpentin du bas
          serpentin_haut = 0;
        }  else {
          digitalWrite(26, LOW); //fermer vanne 2 pour passer l'eau dans les deux serpentins
          serpentin_haut = 1;
        }
      }
      digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
      solaire_chauffe_ballon = 1;

      if (debit <= 0 and cycle_demarrage_solaire > 100) // si C1 tourne depuis plus de 5mn et pas de débit --> erreur
      { digitalWrite(broche_relais_C1, LOW); // éteindre C1, mais relais peut-être défectueux (collé ?)
        // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
        Serial.print(F("ALARM ERREUR DEBIT C1=0"));
        alarm1 = true;
        for (i = 0; i < 5; i++) {
          tone(broche_buzzer_cave, 800, 250); //(pin, frequency, duration)
          delay(500);
          noTone(broche_buzzer_cave);
          tone(broche_buzzer_poele, 800, 250);
          delay(500);
          noTone(broche_buzzer_poele);
        }
      }
      else {
        alarm1 = false;
      }
    }
    else {
      static unsigned long previousMillis5 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis5 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis5 - previousMillis5 >= 120000) // lit la suite seulement toutes les 120 secondes pour ne pas bouger sans arret les vannes
      { previousMillis5 = currentMillis5;
        digitalWrite(broche_relais_C1, LOW); // éteindre circulateur
        digitalWrite(32, LOW); // LOW = ne pas faire rentrer l'eau dans le ballon et fermer vanne anti-thermosiphon
        digitalWrite(26, LOW); // fermer vanne 2 pour éviter thermosiphon
        cycle_demarrage_solaire = 0;
      }
    }
  }


  //-- été + surchauffe  ------  si été et  60°C <= Ballon Bas < 70°C => allumer circu 1 qu'à 120°C  -------------------------------------

  if ((Mois == 7 or Mois == 8 or Mois == 9) and temperature[25] >= 60 and temperature[25] < 70)  // bas ballon
  { // SURCHAUFFE --> casser le rendement des capteurs en les faisant fonctionner à haute T°
    // Garder la vitesse la plus lente pour chercher à monter le delta, garder les panneaux tres chauds (+ de °C, mais - de kWh, car - de débit)
    // Demarrer circulateur lorsque panneaux >= 120°C
    // l'eau glycolee peut tenir à 150°C env. à 2 bar, avant d'entrer en stagnation ("gazéification")
    // et le glycol s'abime fortement au dessus de 170°C env.

    if (temperature[2] >= 120) // si T°C dans panneau 2  > 120°C
    { cycle_demarrage_solaire = cycle_demarrage_solaire + 1;

      digitalWrite(26, LOW); // fermer vanne 2 pour passer l'eau dans les deux serpentins
      digitalWrite(32, HIGH); // fermer V3 et ouvrir V1 pour faire rentrer l'eau dans le ballon et la refroidir
      serpentin_haut = 1;
      digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
      solaire_chauffe_ballon = 1;
      if (debit <= 0 and cycle_demarrage_solaire > 100) // si C1 tourne depuis plus de 5mn et pas de débit --> erreur
      { digitalWrite(broche_relais_C1, LOW); // éteindre C1, mais relais peut-être défectueux (collé ?)
        // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
        Serial.print(F("ALARM ERREUR DEBIT C1=0"));
        alarm1 = true;
        for (i = 0; i < 5; i++) {
          tone(broche_buzzer_cave, 800, 250); //(pin, frequency, duration)
          delay(500);
          noTone(broche_buzzer_cave);
          tone(broche_buzzer_poele, 800, 250);
          delay(500);
          noTone(broche_buzzer_poele);
        }
      }
      else {
        alarm1 = false;
      }
    } else {
      static unsigned long previousMillis8 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis8 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis8 - previousMillis8 >= 120000) // lit la suite seulement toutes les 120 secondes pour ne pas bouger sans arret les vannes
      { previousMillis8 = currentMillis8;
        // digitalWrite(32, HIGH); // ouvrir V1 pour laisser l'eau remonter par thermosiphon dans les panneaux
        digitalWrite(broche_relais_C1, LOW); // éteindre circulateur solaire
        solaire_chauffe_ballon = 0;
        cycle_demarrage_solaire = 0;
      }
    }
  }


  //-- surchauffe 2 = décharge  ----------   si Ballon Bas > 70°C => allumer le circulateur à 120°C et DECHARGE LA NUIT  -----------
  if (temperature[25] >= 70)  // bas ballon, je n'utilise pas la temp BallonHaut pour avoir plus de fiabilité et n'avoir que temp 
                             // BallonBas qui est utile au programme
  { // SURCHAUFFE --> refroidir la nuit et casser le rendement des capteurs en les faisant fonctionner à haute T°
    // Garder la vitesse la plus lente pour chercher à monter le delta, garder les panneaux tres chauds (plus de °C, mais moins de kWh, car moins de débit)
    // Demarrer circulateur lorsque panneaux >= 120°C
    // l'eau glycolee peut tenir à 150°C env. à 2 bar, avant d'entrer en stagnation ("gazéification")
    // et le glycol s'abime fortement au dessus de 170°C env.

    if (ldr < 100 or Heure >= 22 or Heure <= 7) // si nuit, alors décharger le ballon dans les panneaux
    { static unsigned long previousMillis9 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis9 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis9 - previousMillis9 >= 120000) // lit la suite seulement toutes les 120 secondes pour ne pas bouger sans arret les vannes
      { previousMillis9 = currentMillis9;
        // REFROIDIR LA NUIT
        cycle_demarrage_solaire = cycle_demarrage_solaire + 1;

        digitalWrite(26, LOW); // fermer vanne 2 pour passer l'eau dans les deux serpentins
        serpentin_haut = 1;
        digitalWrite(32, HIGH); // fermer V3 et ouvrir V1 pour faire rentrer l'eau dans le ballon et le refroidir
        digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
        solaire_chauffe_ballon = 1;
      }
    } else if (temperature[2] >= 120) // si T°C dans panneau 2  > 120°C
    { cycle_demarrage_solaire = cycle_demarrage_solaire + 1;
      digitalWrite(26, LOW); // fermer vanne 2 pour passer l'eau dans les deux serpentins
      digitalWrite(32, HIGH); // fermer V3 et ouvrir V1 pour faire rentrer l'eau dans le ballon et la refroidir
      serpentin_haut = 1;
      digitalWrite(broche_relais_C1, HIGH); // allumer circulateur
      solaire_chauffe_ballon = 1;
      if (debit <= 0 and cycle_demarrage_solaire > 100) // si C1 tourne depuis plus de 5mn et pas de débit --> erreur
      { digitalWrite(broche_relais_C1, LOW); // éteindre C1, mais relais peut-être défectueux (collé ?)
        // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
        Serial.print(F("ALARM ERREUR DEBIT C1=0"));
        alarm1 = true;
        for (i = 0; i < 5; i++) {
          tone(broche_buzzer_cave, 800, 250); //(pin, frequency, duration)
          delay(500);
          noTone(broche_buzzer_cave);
          tone(broche_buzzer_poele, 800, 250);
          delay(500);
          noTone(broche_buzzer_poele);
        }
      }
      else {
        alarm1 = false;
      }
    } else {
      static unsigned long previousMillis8 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
      unsigned long currentMillis8 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
      if (currentMillis8 - previousMillis8 >= 120000) // lit la suite seulement toutes les 120 secondes pour ne pas bouger sans arret les vannes
      { previousMillis8 = currentMillis8;
        // digitalWrite(32, HIGH); // ouvrir V1 pour laisser l'eau remonter par thermosiphon dans les panneaux
        digitalWrite(broche_relais_C1, LOW); // éteindre circulateur solaire
        solaire_chauffe_ballon = 0;
        cycle_demarrage_solaire = 0;
      }
    }
  } // fin décharge dans panneaux





  //----------------------------------------------   CHAUFFAGE    ------------------------------------------------
  // Je veux avoir chaud seulement lorsque c'est l'énergie solaire --> donc pas question de chauffer le ballon avec la chaudière au gaz.
  // J'utilise 2 thermostats : un pour la chaudière gaz et le deuxième pour le ballon solaire.
  // La chaudière au gaz ne s'allume que lorsque la température de la maison descend sous 16-17°C
  // (c'est une chaudière qui fait aussi l'eau chaude sanitaire, donc tjrs chaude).
  // Le thermostat du circulateur du ballon solaire est lui règlé sur 18-22°C, il déclenche en priorité.
  // L'idée est d'évacuer la chaleur du ballon le plus souvent possible pour permettre au circulateur solaire de
  // démarrer même par temps peu ensoleillé le lendemain matin (intérieur panneaux = 35°C env.).
  // Exemple : si j'ai le ballon à 45°C, il faut que l'eau des panneaux soit à plus de 45°C pour démarrer la circulation.
  // Si j'ai le ballon à 25°C, il faut que l'eau des panneaux soit à plus de 30°C pour démarrer la circulation --> donc je récupére plus de calories
  // La maison est en pierre avec isolation extérieure, donc surchauffer la maison n'est pas perdu, cela chauffe les murs qui stockent.
  // Tout l'hiver, j'ai le bouton "mode 0" (gaz sur radiateur ou ballon solaire sur radiateur), mais lorsque le haut du ballon > 30°C,
  // je bloque le circulateur de la chaudière gaz avec un relais en série (+ placement des vannes), pour activer
  // le circulateur du chauffage solaire.


  thermostat_chauffage_solaire = digitalRead(43); // lecture thermostat télécommande chauffage
  Serial.print(F("CHAUF Therm = ")); Serial.print(thermostat_chauffage_solaire); Serial.print(F("  CycleChauff = ")); 
  Serial.print(cycle_chauffage); Serial.print(F("  C2Pause = ")); Serial.print(circulateur_C2_en_pause);
  Serial.print(F("  Aller_T28 = ")); Serial.print(temperature[28], 2); Serial.print(F("  Retour_T20 = ")); Serial.print(temperature[20], 2);
  Serial.print(F(" d(depart-retour)=")); Serial.print(delta_chauffage); Serial.print(F(" ")); Serial.print(gain_temperature_chauffage);


  static unsigned long previousMillis7 = 0; // Temps de la précédente mesure et actuel, LAISSER LE "static"
  unsigned long currentMillis7 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
  if (circulateur_C2_en_pause == 1 and (currentMillis7 - previousMillis7) >= 1800000) // lit la suite seulement toutes les 30mn=1800000ms
  { previousMillis7 = currentMillis7;
    circulateur_C2_en_pause = 0; // 30mn après, on peut redémarer le circulateur c2
  }

  if (bouton_4 == 1 and ((Heure == heure_seche_serviette_matin and Minute < 15) or (Heure == heure_seche_serviette_soir and Minute < 15)) )   
  // 9h et 21h, ne chauffer que le séche serviette salle de bain.
  { chauffer_sechoir = true;   //  7h et 22h
    digitalWrite(44, HIGH); // ouvrir bypass sèche serviette et l'eau prendra le parcours le plus court en alimentant que le sèche serviette
  } else {
    chauffer_sechoir = false;
    digitalWrite(44, LOW); // fermer vanne séchoir salle de bain bas et retrouver le robiner d'équilibrage
  }
  // BOUCLE PRINCIPALE
  // J'empêche le chauffage de fonctionner la nuit pour éviter le bruit des vannes
  if (Heure >= 8 and Heure <= 23 and circulateur_C2_en_pause == 0 and (thermostat_chauffage_solaire == 1 
  or chauffer_sechoir == true) and temperature[24] >= 28 and temperature[28] < 43 and temperature[28] > 0 
  and (mode == 0 or mode == 4) and mode != 1 and mode != 2 and mode != 3)
  // si ballon froid (T21), aucun intérêt d'envoyer l'eau dans les radiateurs. 
  // Temperature[28]>0 pour ne pas démarrer si les capteurs temperature déconnent.
  {
    delta_chauffage = temperature[28] - temperature[20]; // Temp de départ - Temp de retour du circuit chauffage
    mode = 4; // // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, mode3=Poele, 
    // mode4=BallonSolaire sur Radiateurs.
    digitalWrite(broche_gaz_circulateur, HIGH); // couper la circulation de la chaudière (un relais branché en série sur le circulateur)
    digitalWrite(42, HIGH); // Vanne 10, fermée
    digitalWrite(37, LOW); // Vanne 11, ouverte
    digitalWrite(36, HIGH); // Fermer Vanne 9
    if (cycle_chauffage == 0)
    {
      digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
      digitalWrite(46, LOW); // Vanne v7 ouverte
      digitalWrite(47, HIGH); // Vanne v8 fermee
      wdt_disable(); //wdt_enable(WDTO_8S);  ON ETEINT LE WATCHDOG POUR EVITER UN RESET
      delay(6000);// le temps que les vannes se ferment
      wdt_enable(WDTO_8S); // ON RALLUME LE WATCHDOG
      position_v8 = 0; // 0 = v8 fermee
    }

    // Si l'on vient de démarrer la chauffe, alors envoyer de l'eau à 25°C maxi pour éviter les chocs thermiques dans les murs chauffants
    if (cycle_chauffage < 150 and temperature[20] <= 18) // 150   et si le retour n'est pas déjà à plus de 20°C
    { temperature_eau_visee_de_chauffe = 25; // temperature de démarrage pour éviter les chocs thermiques
    } else {
      temperature_eau_visee_de_chauffe = 39; // après 150 cycle = 38-39 MAXIMUM ! Murs chauffants !
    }


    // gestion vanne 3 voies chauffage (qui sont en fait 2 vannes)
    static unsigned long previousMillis3 = 0; // Temps de la precedente mesure et actuel, LAISSER LE "static"
    unsigned long currentMillis3 = millis(); // millis() est une fonction qui donne le temps du Arduino depuis son démarrage
    if (cycle_chauffage == 0 or (currentMillis3 - previousMillis3) >= 10000) 
    // lit la suite seulement toutes les 10 secondes pour ne pas bouger sans arret les vannes
    { previousMillis3 = currentMillis3;
      digitalWrite(48, LOW); // ouvrir V4, toujours ouvrir avant de fermer, pour ne pas bloquer le circulateur
      digitalWrite(49, HIGH); // fermer V5
      digitalWrite(38, HIGH); // fermer V6
      difference_consigne = temperature_eau_visee_de_chauffe - temperature[28]; // température[28]= température de départ chauffage
      gain_temperature_chauffage = temperature[28] - temperature_precedente;
      // si gain_temperature_chauffage>0--> T°C départ monte.  Si gain_temperature_chauffage<0--> T°C depart descend
      if (difference_consigne >= 20)  {
        temps_ouverture_vanne_v8v7 = 600; //800
      }
      if (10 < difference_consigne and difference_consigne < 20)  {
        temps_ouverture_vanne_v8v7 = 300; //500
      }
      if (5 <= difference_consigne and difference_consigne <= 10)  {
        temps_ouverture_vanne_v8v7 = 100; //200
      }
      if (2 <= difference_consigne and difference_consigne < 5)  {
        temps_ouverture_vanne_v8v7 = 70; //100
      }
      if (1 <= difference_consigne and difference_consigne < 2)  {
        temps_ouverture_vanne_v8v7 = 30; //50
      }
      Serial.print(F(" ")); Serial.print(temps_ouverture_vanne_v8v7); Serial.print(F(" ")); Serial.print(difference_consigne); Serial.print(F(" "));
      if (temperature[28] < temperature_eau_visee_de_chauffe and gain_temperature_chauffage <= 0.25 and difference_consigne > 2 and position_v8 < 2600)
      // si petit ecart /à la consigne, arrêter de bouger
      { digitalWrite(45, HIGH); //  Alim des doubles vannes 7-8
        digitalWrite(46, HIGH); // fermer un peu V7
        digitalWrite(47, LOW); // ouvrir un peu V8
        wdt_disable(); //wdt_enable(WDTO_8S);  ON ETEINT LE WATCHDOG POUR EVITER UN RESET
        delay(temps_ouverture_vanne_v8v7);
        wdt_enable(WDTO_8S); // on rallume le watchdog
        digitalWrite(45, LOW); // couper Alim des doubles vannes 7-8
        position_v8 = position_v8 + temps_ouverture_vanne_v8v7; // 0 = fermee  2000 = ouverte au maxi
        Serial.print(F("OUVRE")); Serial.print(F(" (Posi V8=")); Serial.print(position_v8); Serial.print(F(")"));
      }


      // si T°C continue de monter --> arreter d'ouvrir (avec la variable gain_temperature_chauffage)
      if (temperature[28] > temperature_eau_visee_de_chauffe and gain_temperature_chauffage > 0)
      {
        digitalWrite(45, HIGH); //  Alim des doubles vannes 7-8
        digitalWrite(46, LOW); // ouvrir un peu V7
        digitalWrite(47, HIGH); // fermer un peu V8
        wdt_disable(); //wdt_enable(WDTO_8S);  ON ETEINT LE WATCHDOG POUR EVITER UN RESET
        delay(temps_ouverture_vanne_v8v7);
        wdt_enable(WDTO_8S); // on rallume le watchdog
        digitalWrite(45, LOW); // couper Alim des doubles vannes 7-8
        position_v8 = position_v8 - temps_ouverture_vanne_v8v7;  // 0 = fermee    2600 = ouverte au maxi
        Serial.print(F("FERME")); Serial.print(F(" (V8=")); Serial.print(position_v8); Serial.print(F(")"));
      }
      if (temperature[28] > temperature_eau_visee_de_chauffe + 2 or temperature[28] <= 0) // securite si sonde temperature deconne (-0.06)
      {
        digitalWrite(45, HIGH); //  Alim des doubles vannes 7-8
        digitalWrite(46, LOW); // ouvrir V7
        digitalWrite(47, HIGH); // fermer V8
        digitalWrite(48, HIGH); // fermer V4
        temps_ouverture_vanne_v8v7 = 1500;
        wdt_disable(); //wdt_enable(WDTO_8S);  ON ETEINT LE WATCHDOG POUR EVITER UN RESET
        delay(temps_ouverture_vanne_v8v7);
        wdt_enable(WDTO_8S); // on rallume le watchdog
        digitalWrite(45, LOW); // couper Alim des doubles vannes 7-8
        if (position_v8 < 800)
        {
          position_v8 = 0;
        }
        else {
          position_v8 = position_v8 - temps_ouverture_vanne_v8v7; // 0 = fermee    2600 = ouverte au maxi
        }
        Serial.print(F("FERME FORT")); Serial.print(F(" (V8=")); Serial.print(position_v8); Serial.print(F(")"));
      }
      temperature_precedente = temperature[28];
    }

    // transforme la valeur de la position_v8 de 0 à 2600 vers 0 à 90°
    position_v8_degre = map(position_v8, 0, 2000, 0, 90);

    cycle_chauffage = cycle_chauffage + 1;
    digitalWrite(broche_relais_C2, HIGH); // demarrer circulateur C2

    // si ballon très chaud, décharger dans l'inertie des murs et démarrer plus rapidement la récupération des calories solaires
    if (temperature[24] > 50) {
      consigne_delta_chauffage = 1.5; // le delta chauffage est la différence entre la temperature de depart et la temperature de retour
    } else {
      consigne_delta_chauffage = 3;
    }
    if (cycle_chauffage > 160 and delta_chauffage < consigne_delta_chauffage)
    { // si delta_chauffage très bas, la chaleur n'est plus diffusée dans les murs, faire une pause pour économiser l'électricité du circulateur
      // Garder un delta haut pour ne pas trop mélanger le ballon : en dessous de 4, on envoie beaucoup d'eau chaude en bas du ballon.
      // Mais aussi : lorsqu'on ne circule plus, la chaleur dans les radiateurs est seulement en haut et la diffusion se dégrade...
      circulateur_C2_en_pause = 1; // attendre mini 60mn que la chaleur se diffuse dans les murs avant de refaire tourner le circulateur
      digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2
      digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
      digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
      digitalWrite(48, HIGH); // Fermer Vanne 4
      digitalWrite(49, HIGH); // Fermer Vanne 5
      digitalWrite(38, HIGH); // Fermer Vanne 6
      digitalWrite(36, HIGH); // Fermer Vanne 9
      digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
      digitalWrite(46, HIGH); // vanne 7 fermee
      digitalWrite(47, HIGH); // Vanne 8 fermee
      position_v8 = 0; // 0 = fermee
      digitalWrite(broche_gaz_circulateur, LOW); // autoriser circulation de la chaudière (un relais branché en série sur le circulateur chaudière)
      mode = 0; cycle_chauffage = 0;
    }
  } else if (mode == 4 and (thermostat_chauffage_solaire == 0 or temperature[24] < 27) and chauffer_sechoir == false )
  { // sortir du mode chauffage si thermostat == 0
    digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2
    digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
    digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
    digitalWrite(48, HIGH); // Fermer Vanne 4
    digitalWrite(49, HIGH); // Fermer Vanne 5
    digitalWrite(38, HIGH); // Fermer Vanne 6
    digitalWrite(36, HIGH); // Fermer Vanne 9
    digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
    digitalWrite(46, HIGH); // vanne 7 fermee
    digitalWrite(47, HIGH); // Vanne 8 fermee
    position_v8 = 0; // 0 = fermee
    digitalWrite(broche_gaz_circulateur, LOW); // autoriser circulation de la chaudière (un relais branché en série sur le circulateur chaudière)
    mode = 0; cycle_chauffage = 0;
  }

  // PROTECTION des murs chauffants : garder cette partie du programme le plus facilement actif, donc hors d'autres boucles
  if (temperature[28] >= 43) // il y a aussi un fusible thermique de 40°C fixer sur tuyau départ qui coupe c2 (branchement série)
  {
    digitalWrite(broche_relais_C2, LOW); // arreter circulateur C2 du chauffage solaire
    digitalWrite(42, LOW); // Vanne 10, ouverte pour laisser la chaudiere gaz
    digitalWrite(37, LOW); // Vanne 11, ouverte pour laisser la chaudiere gaz
    digitalWrite(48, HIGH); // Fermer Vanne 4 pour éviter que l'eau monte par thermosiphon dans les radiateurs
    digitalWrite(49, HIGH); // Fermer Vanne 5 pour éviter que l'eau monte par thermosiphon dans les radiateurs
    digitalWrite(38, HIGH); // Fermer Vanne 6 pour éviter que l'eau monte par thermosiphon dans les radiateurs
    digitalWrite(36, HIGH); // Fermer Vanne 9
    digitalWrite(45, HIGH); // Alim des doubles vannes 7-8
    digitalWrite(46, HIGH); // vanne 7 fermee : pour éviter que l'eau monte par thermosiphon dans les radiateurs (si bas ballon>50°C)
    digitalWrite(47, HIGH); // Vanne 8 fermee
    position_v8 = 0; // 0 = fermee
    digitalWrite(broche_gaz_circulateur, LOW); // autoriser la circulation de la chaudière (un relais branché en série sur le circulateur)
    mode = 0; cycle_chauffage = 0;
    Serial.print(F(" SURCHAUFFE "));
    /*
        // ALARM : 1 bips= prob px solaire, 2 = surchauff ballon/murs chauffants, 3 = surchauff poele, 4 = prob temperature, 5 = gele Panneaux
        for (i = 0; i < 2; i++) {
          tone(broche_buzzer_cave, 500, 250);
          delay(130);
          noTone(broche_buzzer_cave);
          tone(broche_buzzer_poele, 500, 250); // (pin, frequency, duration)
          delay(130);
          noTone(broche_buzzer_poele);
        }
    */
  }

  //----------------------------------------------  FIN  CHAUFFAGE    ------------------------------------------------




  //--------------  AFFICHEUR  --------------------
  // mode , heure/mois, temperature : haut ballon, interieur panneau/bas ballon, poele, ou toutes (reset pour revenir à zéro)
  if ((Heure == 8 or Heure == 9 or Heure == 10 or Heure == 11 or Heure == 12 or Heure == 13 or Heure == 14 or 
  Heure == 15 or Heure == 16 or Heure == 17 or Heure == 18 or Heure == 19 or Heure == 20 or Heure == 21) and Minute == 0 and Seconde < 5)
  { lcd.begin(20, 4);  // initialize the lcd for 20 chars 4 lines, turn on backlight
  }
  //// HORLOGE ET ECRAN LCD avec DS3231 (conservation de la librairie DS1307)  site: http://f5mna.free.fr
  lcd.setCursor( 0, 0 );
  if (Jour < 10) {
    lcd.print ("0");
  }
  lcd.print(Jour );
  lcd.print("/");
  if (Mois < 10) {
    lcd.print ("0");
  }
  lcd.print(Mois);
  lcd.print (" ");
  if (Heure < 10) {
    lcd.print ("0");
  }
  lcd.print (Heure);
  lcd.print( ":");
  if (Minute < 10) {
    lcd.print ("0");
  }
  lcd.print( Minute );
  lcd.print( ":" );
  /* if (Seconde < 10) {
     lcd.print ("0");
    }*/
  lcd.print( Seconde );
  lcd.print(" MOD=");
  lcd.print(mode);

  //----------
  lcd.setCursor( 0, 1 );
  if (temperature[2] < 100)
  { lcd.print("Pan=");
    lcd.print(temperature[2], 0);
  }
  else
  { lcd.print("Pa=");
    lcd.print(temperature[2], 0);
  }
  lcd.print(" Rt=");
  lcd.print(temperature[18], 0);
  lcd.print(" C"); lcd.print(cycle_demarrage_solaire);

  if (cycle_demarrage_solaire < 10)
  { lcd.print("   ");
  }
  else if (cycle_demarrage_solaire < 1000 and cycle_demarrage_solaire > 9)
  { lcd.print(" ");
  }
  else if (cycle_demarrage_solaire > 999)
  { lcd.print("");
  }

  if ((Mois == 7 or Mois == 8 or Mois == 9) and temperature[25] >= 60 and temperature[25] < 70)
  {
    lcd.print("S");
  }
  else if (temperature[25] >= 70)
  { lcd.print("D");

  }
  else {
    lcd.print(" ");
  }

  //----------
  lcd.setCursor( 0, 2 );
  lcd.print("Bal=");
  lcd.print(temperature[24], 0);
  lcd.print(" T=");
  lcd.print(ballon_temp_moy, 0);
  lcd.print(" Poel=");
  lcd.print(thermocouple.readCelsius(), 0);
  if (thermocouple.readCelsius() < 100)
  {
    lcd.print(" ");
  }

  //----------
  lcd.setCursor( 0, 3 );
  lcd.print("DepChauf=");
  lcd.print(temperature[28], 1);
  lcd.print(" C"); lcd.print(cycle_chauffage);
  if (cycle_chauffage < 10)
  { lcd.print("   ");
  }
  else if (cycle_chauffage < 1000 and cycle_chauffage > 9)
  { lcd.print(" ");
  }
  else if (cycle_chauffage > 999)
  { lcd.print("");
  }


  /*  BOUTON POUR REGLAGE HORLOGE
    // RAZ valeur de la touche
    sensorValue = analogRead(sensorPin);  // lecture de la touche
    val_key = int(sensorValue / 100);     // valeur entière de la touche / 10
    if (val_key < 10)  {
      // Bouton();
    }

  */

  //// FIN HORLOGE ET ECRAN LCD avec DS3231





  //// ETHERNET
  // en utilisant "client.print(F(" j'ai gagné 5700 octets de RAM dynamique... J'avais 95% de libre et j'ai 25% de libre...
  // Inconveniant : ça ralenti un peu l'affichage
  //
  EthernetClient client = server.available();// Ecouter les clients entrants
  if (client) {
    // Une requète HTTP terminée par une ligne vide
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      //Serial.println("new client");
      // Serial.print(F("adresse IP: ");
      // Serial.println(Ethernet.localIP());

      if (client.available()) {

        // Envoyer un header de reponse standard http
        //client.print(F("HTTP/1.1 200 OK"));    //C'est OK
        //client.print(F("Content-Type: text/html"));
        //client.print(F("<html><head>"));    //---- debut de la page HTML ---
        //client.print(F("<meta content=\"utf-8\">"));
        //client.print(F("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=iso-8859-1\">"));
        //client.print(F("<META HTTP-EQUIV=\"Content-Language\" CONTENT=\"fr-FX\">"));
        client.println(F("<html><head><title>Solaire Aussillon</title></head><body>"));
        client.println(F("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"2\"><font face=\"Calibri\">"));   // METTRE un "\" devant " pour éviter problemes

        // METTRE un "\" devant " pour éviter problemes
        client.print("<div style=\"width:700px;height:695px;background-image:url('http://mmonceaux.free.fr/solaire_thermique/
             plan_solaire_matthieu_monceaux_31.jpg');position:relative;top:0;left:0\">"); // RECOLLER cette ligne à celle du dessus
        
        
        //masquage si poele froid
        if (thermocouple.readCelsius() < 40)
        {
          client.print("<div style=\"position:absolute;left:563px;top:595px\">");
          client.print("<img src=\"http://mmonceaux.free.fr/solaire_thermique/solaire_masque_poele.jpg\">");
          client.print("</div>");
        }
        

        client.print(Heure);  client.print(F(":"));
        if (Minute < 10) {
          client.print(F("0"));
        }
        client.print( Minute );  client.print(F(":" ));
        if (Seconde < 10) {
          client.print(F("0"));
        }
        client.print(Seconde);
        client.print(F(", "));
        client.print(Jour);
        client.print(F("/"));
        client.print(Mois);
        client.print(F("/"));
        client.print(Annee);
        client.print(F(" &nbsp <BR> &nbsp &nbsp Luminosité = "));
        client.print(ldr);
        client.print(F(" Lux"));

        // ajouter \ avant ", sinon probleme
        client.print(F("<div style=\"background:white;font-size:11px;position:absolute;left:365px;top:285px;\">"));
        client.print(debit); client.print(F(" L/mn "));
        if (cycle_demarrage_solaire > 0)
        {
          client.print(F("&nbsp CycSol = <mark>"));
          client.print(cycle_demarrage_solaire); client.print(F("</mark> <BR> &nbsp Delta_P2-BalBas = ")); 
          client.print(delta_panneaux_ballon_milieu);
          client.print(F("(seuil=")); client.print(consigne_solaire); client.print(F(")"));
          client.print(F("<BR>ChaufBal=")); client.print(solaire_chauffe_ballon);
          client.print(F(" &nbsp SerpHaut=")); client.print(serpentin_haut);
        }
        client.print(F("</div>"));

        if (etatC1 == 1)
        {
          client.print(F("<div style=\";position:absolute;left:346px;top:195px;\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/solaire_thermique_pompe_animee_06.gif\" height=\"30\" width=\"30\">"));
          client.print(F("</div>"));
        }

        client.print(F("<div style=\"background:white;font-size:14px;text-align:center;position:absolute;left:438px;top:129px;\">"));
        client.print(F("P = ")); client.print(wh, 0); client.print(F(" Watts"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:11px;text-align:center;position:absolute;left:178px;top:546px;\">"));
        client.print(temperature[0], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:365px;top:128px;\">"));
        client.print(temperature[19], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:265px;top:147px;\">"));
        client.print(temperature[18], 1); client.print((char)176); client.print(F("C"));
        client.print(F("<BR>(D=")); client.print(delta_chd_frd_station); client.print(F(")"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:324px;top:38px;padding:2px;\">"));
        client.print(F("P1(cadre)<BR>")); client.print(temperature[1], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:14px;text-align:center;position:absolute;left:398px;top:8px;\">"));
        client.print(F("<mark>")); client.print(temperature[2], 1);

        if ((Mois == 7 or Mois == 8 or Mois == 9) and temperature[25] >= 60 and temperature[25] < 70)
        {
          client.print(F("°C </mark>(dém 120°C)"));
        }
        else if (temperature[25] >= 70)
        { client.print(F("°C </mark>(décharg nuit)"));
        }
        else {
          client.print(F("°C</mark>"));
        }
        client.print(F("</div>"));
        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:431px;top:38px;padding:2px;\">"));
        client.print(F("P2(cadre)<BR>")); client.print(temperature[3], 1);
        client.print(F("°C (Dedans=")); client.print(temperature_sonde_pt100); client.print(F(")"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:532px;top:8px;\">"));
        client.print(temperature[4], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:592px;top:38px;padding:2px;\">"));
        client.print(F("P3(cadre)<BR>")); client.print(temperature[5], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:12px;text-align:center;position:absolute;left:252px;top:45px;\">"));
        client.print(temperature[16], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:12px;text-align:center;position:absolute;left:217px;top:60px;\">"));
        client.print(temperature[17], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:45px;top:108px;padding:2px;\">"));
        client.print(F("P4(cadre)<BR>")); client.print(temperature[7], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:10px;text-align:center;position:absolute;left:120px;top:99px;\">"));
        client.print(temperature[6], 0); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:175px;top:108px;padding:2px;\">"));
        client.print(F("P5(cadre)<BR>")); client.print(temperature[8], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:45px;top:209px;padding:2px;\">"));
        client.print(F("P6(cadre)<BR>")); client.print(temperature[9], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:10px;text-align:center;position:absolute;left:120px;top:213px;\">"));
        client.print(temperature[10], 0); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:175px;top:209px;padding:2px;\">"));
        client.print(F("P7(cadre)<BR>")); client.print(temperature[11], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:9px;text-align:center;position:absolute;left:278px;top:98px;\">"));
        client.print((temperature[16] + temperature[17]) / 2, 0);
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:13px;text-align:center;position:absolute;left:216px;top:443px;padding:1px;\">"));
        client.print(temperature[24], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:13px;text-align:center;position:absolute;left:216px;top:495px;padding:1px;\">"));
        client.print(temperature[23], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:13px;text-align:center;position:absolute;left:216px;top:584px;padding:1px;\">"));
        client.print(temperature[25], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"background:white;font-size:12px;text-align:center;position:absolute;left:210px;top:625px;\"><mark>Totale = "));
        client.print(ballon_temp_moy, 1); client.print((char)176); client.print(F("</mark><BR>Delta Strat = "));
        client.print(delta_stratification);
        client.print(F("</div>"));



        // CHAUFFAGE
        if (cycle_chauffage > 0)
        {
          client.print(F("<div style=\"font-size:11px;position:absolute;left:397px;top:622px;\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/solaire_thermique_pompe_animee_06.gif\" height=\"25\" width=\"25\">"));
          client.print(F("<BR>Thermostat = ")); client.print(thermostat_chauffage_solaire); client.print(F(" &nbsp CycleChauff = "));
          client.print(cycle_chauffage); client.print(F("<BR>Pause = ")); client.print(circulateur_C2_en_pause);
          client.print(F(" Delta = ")); client.print(delta_chauffage); client.print(F("&nbsp Gain = ")); client.print(gain_temperature_chauffage); 
          client.print(F("<BR>"));
          client.print(F("</div>"));
          //v7
          client.print(F("<div style=\"position:absolute;left:389px;top:597px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:381px;top:606px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
          //v8
          client.print(F("<div style=\"position:absolute;left:345px;top:573px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:353px;top:564px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
          // position_v8 |  position_v8_degre
          client.print(F("<div style=\"font-size:10px;position:absolute;left:322px;top:638px\"><CENTER><mark>V8="));
          client.print(position_v8); client.print(F("|"));
          client.print(position_v8_degre); client.print((char)176);
          client.print(F("</mark><BR>"));
          client.print(F("(90")); client.print((char)176); client.print(F("=ouvert max)</CENTER></div>"));
        }
        else {
          if (v7 == 0)
          { client.print(F("<div style=\"position:absolute;left:389px;top:597px\">"));
            client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
            client.print(F("</div>"));
          }
          else {
            client.print(F("<div style=\"position:absolute;left:379px;top:606px\">"));
            client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
            client.print(F("</div>"));
          }
          if (v8 == 0)
          { client.print(F("<div style=\"position:absolute;left:345px;top:573px\">"));
            client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
            client.print(F("</div>"));
          }
          else {
            client.print(F("<div style=\"position:absolute;left:353px;top:564px\">"));
            client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
            client.print(F("</div>"));
          }
          client.print(F("<div style=\"font-size:11px;position:absolute;left:397px;top:635px;\">"));
          client.print(F("<BR>Thermostat = ")); client.print(thermostat_chauffage_solaire); client.print(F("<BR>Pause = "));
          client.print(circulateur_C2_en_pause);
          client.print(F("</div>"));
        }

        client.print(F("<div style=\"font-size:11px;text-align:center;position:absolute;left:350px;top:488px;;\">"));
        client.print(temperature[28], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:11px;text-align:center;position:absolute;left:449px;top:618px;;\">"));
        client.print(temperature[20], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:11px;text-align:center;position:absolute;left:312px;top:567px;;\">"));
        client.print(temperature[26], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:11px;text-align:center;position:absolute;left:535px;top:560px;;\">"));
        client.print(thermocouple.readCelsius(), 1); client.print((char)176); client.print(F("C")); // poele
        client.print(F("</div>"));


        client.print(F("<div style=\"font-size:12px;position:absolute;left:462px;top:346px;\">"));
        if (eau_par_gaz == 1)
        { client.print(F("EAU sanitaire par GAZ ")); client.print(F(" (")); client.print(consigne_eau_chaude); client.print(F(")"));
        }
        else {
          client.print(F("EAU sanitaire par <mark>SOLEIL</mark>")); client.print(F(" (")); client.print(consigne_eau_chaude); client.print(F(") "));
        }
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:12px;position:absolute;left:590px;top:275px;\">"));
        client.print(temperature[12], 1); client.print((char)176); client.print(F("C")); // tempéarature arrivee eau rue
        client.print(F("</div>"));

        // chaudière ON / OFF
        client.print(F("<div style=\"color:#ff0000;font-size:14px;position:absolute;left:398px;top:391px;\"><B>"));
        if (relais_gaz == 0) // chaudière allumée
        { client.print(F("ON"));
        }
        else {
          client.print(F("OFF"));
        }
        client.print(F("</B></div>"));


        client.print(F("<div style=\"font-size:12px;text-align:center;position:absolute;left:530px;top:135px;\">"));
        client.print(F("<mark>MODE = "));
        client.print(mode);
        switch (mode) { // mode0=BallonSolaire ou Gaz sur Radiateurs, mode1=Gaz sur radiateurs, mode2=Gaz sur BallonSolaire, mode3=Poele, 
                        // mode4=BallonSolaire sur Radiateurs.
          case 0:
            client.print(F("</mark><BR>BALLON/GAZ sur RADIATEURS"));
            break;
          case 1:
            client.print(F("</mark><BR>GAZ sur RADIATEURS"));
            break;
          case 2:
            client.print(F("</mark><BR>GAZ sur BALLON"));
            break;
          case 3:
            client.print(F("</mark><BR>POELE sur BALLON"));
            break;
          case 4:
            client.print(F("</mark><BR>BALLON sur RADIATEURS"));
            break;
        }

        // ALARMES
        if (alarm1 == true)
        {
          client.print(F("<mark><BR>ALARME = Circu_1 NE TOURNE PAS</mark>"));
        }
        if (alarm2 == true)
        {
          client.print(F("<mark><BR>ALARME = SURCHAUFFE BALLON</mark>"));
        }
        if (alarm3 == true)
        {
          client.print(F("<mark><BR>ALARME = SURCHAUFFE POELE</mark>"));
        }
        if (alarm4 == true)
        {
          client.print(F("<mark><BR>ALARME = ERREUR LECTURE Températures</mark>"));
        }
        if (alarm5 == true)
        {
          client.print(F("<mark><BR>ALARME = GEL dans les panneaux solaires</mark>"));
        }

        /// bouton TEST alarm  :  client.print(F("<button onclick="TestAlarm();">TEST ALARM</button>"));

        client.print(F("</div>"));


        // temperature maison
        client.print(F("<div style=\"font-size:13px;position:absolute;left:54px;top:366px;\">"));
        client.print(temperature[22], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"font-size:13px;position:absolute;left:61px;top:405px;\">"));
        client.print(temperature[27], 1); client.print((char)176); client.print(F("C"));
        client.print(F("</div>"));

        client.print(F("<div style=\"text-align:center;background:white;font-size:13px;position:absolute;left:33px;top:442px;padding:1px\">"));
        client.print(temperature_cave, 1); client.print((char)176); client.print(F("C &nbsp"));
        client.print(humidite_cave); client.print(F("% <BR> Puits = "));
        client.print(temperature[21]);
        client.print(F("</div>"));

        //client.print(F(" (Mur= "); client.print(temperature[26]);client.print(F(") ");


        // Impression des barres sur les vannes
        v2 = digitalRead(26); v3 = digitalRead(32); v4 = digitalRead(48); v5 = digitalRead(49);
        v6 = digitalRead(38);    v7 = digitalRead(46); v8 = digitalRead(47);
        v9 = digitalRead(36); v10 = digitalRead(42); v11 = digitalRead(37); v12 = digitalRead(40);

        if (v2 == 1)
        { client.print(F("<div style=\"position:absolute;left:183px;top:517px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:175px;top:526px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }

        if (v3 == 0)
        { client.print(F("<div style=\"position:absolute;left:160px;top:569px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:184px;top:609px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:151px;top:578px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:174px;top:619px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }

        if (v4 == 0)
        { client.print(F("<div style=\"position:absolute;left:318px;top:424px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:328px;top:414px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        if (v5 == 0)
        { client.print(F("<div style=\"position:absolute;left:318px;top:476px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:328px;top:467px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        if (v6 == 0)
        { client.print(F("<div style=\"position:absolute;left:318px;top:541px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:328px;top:531px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        if (v9 == 1)
        { client.print(F("<div style=\"position:absolute;left:388px;top:496px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:378px;top:506px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        if (v10 == 0)
        { client.print(F("<div style=\"position:absolute;left:456px;top:471px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:466px;top:461px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        if (v11 == 0)
        { client.print(F("<div style=\"position:absolute;left:486px;top:471px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:496px;top:461px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }

        if (v12 == 0)
        { client.print(F("<div style=\"position:absolute;left:385px;top:350px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:406px;top:330px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_verticale.jpg\">"));
          client.print(F("</div>"));
        }
        else {
          client.print(F("<div style=\"position:absolute;left:375px;top:359px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
          client.print(F("<div style=\"position:absolute;left:397px;top:339px\">"));
          client.print(F("<img src=\"http://mmonceaux.free.fr/solaire_thermique/plan_solaire_matthieu_monceaux_barre_horizon.jpg\">"));
          client.print(F("</div>"));
        }



        client.print(F("</div>")); // de l'image de fond


        if (bouton_goutte_a_goutte == 1)
        {
          client.print(F("<BR>Arrosage jardinière ON (10h / 700Lux, 12 / 750, 14 / 850, 16 / 880, 18 / 750, 20 / 700, dernier = "));
          client.print(dernier_arrosage); client.print(F(")<BR>"));
        }

        if (bouton_4 == 1)
        {
          client.print(F("Séchoir Salle de Bain ON (à "));
          client.print(heure_seche_serviette_matin); client.print(F("h et à ")); client.print(heure_seche_serviette_soir);
          client.print(F("h = "));
          client.print(chauffer_sechoir); client.print(F(")"));
        }

        client.print(F("Bouton_gaz = "));
        client.print(bouton_gaz); client.print(F(" | ")); client.print(lecture_bouton_gaz);
        client.print(F(" &nbsp  Bouton_g_a_g = "));
        client.print(bouton_goutte_a_goutte);
        client.print(F(" &nbsp  Bouton_seche_serviette = "));
        client.print(bouton_4);
        client.print(F("&nbsp &nbsp Last Start: ")); client.print(jour_demarrage); client.print(F("/")); client.print(mois_demarrage);
        client.print(F(", ")); client.print(heure_demarrage); client.print(F(":"));
        if (minute_demarrage < 10) {
          client.print(F("0"));
        }
        client.print(minute_demarrage);
        client.print(F("<BR>"));

        /*client.print(F("POELE &nbsp = &nbsp "));
          client.print(thermocouple.readCelsius());
          delta_poele = temperature[26] - temperature[25];
          client.print(F(" &nbsp C3 = ")); client.print(c3_tourne);
          client.print(F(" &nbsp D_T26 - T25 = ")); client.print(delta_poele);
          client.print(F(" &nbsp Duree_Allum = ")); client.print(duree_allumage_c3);*/

        client.print(F("<BR>ALARMES : 1 bips = surchauffe Panneaux &nbsp 2 bips = surchauffe Ballon / Murs chauffants<BR>3 bips = surchauffe 
              Poêle &nbsp 4 bips = erreur température &nbsp 5 bips = gèle Panneaux")); // RECOLLER cette ligne à celle du dessus

        //client.println(F("<BR><h4 style = \"color: red\">Bienvenue sur le SOLAIRE arduino d'AUSSILLON !</h4>"));


        client.print(F("</font>"));

        client.print(F("</body></html>"));    //

        break;
      }
    }
  }
  delay(1);    // Laisser au navigateur web le temps de recevoir les données
  client.stop();     // Refermer la connexion:

  //// FIN ETHERNET



  // enregistrement carte SD : Panneaux (PT100, si surchauffe qui entraine mauvaise lecture des DS18B20),P watts,alarm,chauffage, 
  // eau gaz/solaire, conso KW maison



  // Enegistrement des températures ( -0.06 = erreur )
  temperature[1] = readTemperatureMeasure(SENSOR_ADDRESS_1);
  temperature[2] = readTemperatureMeasure(SENSOR_ADDRESS_2);
  temperature[3] = readTemperatureMeasure(SENSOR_ADDRESS_3);
  temperature[4] = readTemperatureMeasure(SENSOR_ADDRESS_4);
  temperature[5] = readTemperatureMeasure(SENSOR_ADDRESS_5);
  temperature[6] = readTemperatureMeasure(SENSOR_ADDRESS_6);
  temperature[7] = readTemperatureMeasure(SENSOR_ADDRESS_7);
  temperature[8] = readTemperatureMeasure(SENSOR_ADDRESS_8);
  temperature[9] = readTemperatureMeasure(SENSOR_ADDRESS_9);
  temperature[10] = readTemperatureMeasure(SENSOR_ADDRESS_10);
  temperature[11] = readTemperatureMeasure(SENSOR_ADDRESS_11);
  temperature[16] = readTemperatureMeasure(SENSOR_ADDRESS_16);// retour chaud panneaux facade
  temperature[17] = readTemperatureMeasure(SENSOR_ADDRESS_17);// retour chaud panneaux garage

  temperature[0] = readTemperatureMeasure2(SENSOR_ADDRESS_0);
  temperature[12] = readTemperatureMeasure2(SENSOR_ADDRESS_12);
  temperature[13] = readTemperatureMeasure2(SENSOR_ADDRESS_13);
  temperature[14] = readTemperatureMeasure2(SENSOR_ADDRESS_14);
  temperature[15] = readTemperatureMeasure2(SENSOR_ADDRESS_15);
  temperature[18] = readTemperatureMeasure2(SENSOR_ADDRESS_18);
  temperature[19] = readTemperatureMeasure2(SENSOR_ADDRESS_19);
  temperature[20] = readTemperatureMeasure2(SENSOR_ADDRESS_20);
  temperature[21] = readTemperatureMeasure2(SENSOR_ADDRESS_21); // puits
  temperature[22] = readTemperatureMeasure2(SENSOR_ADDRESS_22); //salle de bain
  temperature[23] = readTemperatureMeasure2(SENSOR_ADDRESS_23);
  temperature[24] = readTemperatureMeasure2(SENSOR_ADDRESS_24); // haut ballon
  temperature[25] = readTemperatureMeasure2(SENSOR_ADDRESS_25); // SI = -0.06 --> erreur
  temperature[26] = readTemperatureMeasure2(SENSOR_ADDRESS_26);
  temperature[27] = readTemperatureMeasure2(SENSOR_ADDRESS_27); // Rez de Chaussée
  temperature[28] = readTemperatureMeasure2(SENSOR_ADDRESS_28);


  // Serial.print(F("freeMemory() reports "));  Serial.println( freeMemory() ); // 8k sur arduino Mega et 2K sur UNO



}

 

ZIP de ce programme : avec les librairies associées et des petits programmes complémentaires (comme le réglage de l'heure depuis le PC, les essais des relais, la recherche des adresses des DS18B20, etc.) : solaire_thermique_arduino_mmonceaux.free.fr.zip (4,8Mo)

 

 


CONCLUSIONS :

Bilan bien sûr très positif, surtout pour l'écologie et tout ce que j'ai appris en faisant cette installation.
En plus de se chauffer gratuitement et écologiquement à volonté lorsqu'il y a du soleil, cette installation a permis de réduire de 60% à 70% notre consommation de gaz : de 4500KW/an avant (en chauffant peu) à 2000KW/an aujourd'hui (en chauffant davantage si soleil), soit 250€ de gagné par an. Vu que cela nous a couté 5650€, on remboursera l'investissement dans 20ans. A court terme, le bilan financier n'est pas fameux. Vu son très faible prix, on aurait donc pu se contenter de continuer à bruler le gaz que les générations n'auront pas... Mais faut-il réfléchir de manière financière ? N'est-ce pas ce mode de pensée "financier" que nous a inculqué l'usage de l'argent, qui cause la perte de tant de vies sur Terre (disparition d'espèces végétales, animales, humaines, etc. causées par la destruction de l'environnement, le réchauffement climatique, etc.) ?

Cette installation va éviter le rejet d'environ 650Kg de CO2 par an (le calcul ici ou ici. Mais il faudrait aussi prendre en compte ce que j'ai acheté pour faire cette installation solaire..., pas évident). C'est env. 5000Km/an en voiture d'économisé.
Le gaz n'étant pas une énergie renouvelable, en consommer moins, c'est en laisser aux générations futures (et c'est pareils pour toutes les autres énergies - même dites "renouvelables" - qui reposent souvent en grande partie sur une grosse consommation de pétrole : la meilleure énergie est celle que l'on ne consomme pas !).

Courbes des consommations totales de la maison : ici

Merci bien-sûr aux créateurs, administrateurs et participants bénévoles de l'APPER , à ceux qui prennent le temps departager leurs expériences et aux contributeurs des forums.

 


Aller plus loin :


Site de l'Apper : http://www.apper-solaire.org/

Forum de l'Apper : http://forum.apper-solaire.org/

Solari-home, solaire thermique & économie d'énergie : http://solari-home.wifeo.com/economie-dlectricit.php

Des présentations sur des systèmes solaires : http://slideplayer.fr/search/solaire/

Connaitre le nombre d'heures d'ensoleillement dans votre région : http://www.linternaute.com/voyage/climat/mazamet/ville-81163

ARDUINO :
http://www.mon-club-elec.fr
Mesure de puissance thermique & data logging : http://domoenergytics.com/domo.energy/Puissance-thermique-data-logging

 

 

 

 

MattMonc, (page commencée en janv 2018)

MattMonc's Web, ACCUEIL