pH metre DIY via ESPHome

Comme je vois pas mal de personnes intéressées par la mesure du pH et que je n’ai pas trouver de solutions probantes sur les divers forum, je vous livre ma solution et les divers points pour faire évoluer le projet. Je ne suis pas expert dans le domaine et ai des connaissance très limitées en électronique. Toutes expériences ou renseignements complémentaire sont les bien venus.

Pour ma part il s’agit d’une mesure en continue pour un aquarium d’eau de mer. Je précise ce point car ma calibration se fait entre pH 7 et 9. Il faudra adapter cette solution à votre usage et vos solutions de calibration.

Le principe :

J’utilise ESPHome pour faire remonter les valeurs de lecteur en mV et je gère la calibration depuis HA. J’envisageais au début de tout faire sur l’ESP mais cela implique de régénérer le code à chaque fois. Idem pour la formule de conversion, pour le moment à deux points mais qui pourrait se faire à pH 4, 7 et 10 simultanément.

Le matériel de base:

  • une carte pH metre acheté sur AE ref. PH-4502C


    Le connecteur possède 6 broches.
    To : Température pour un sonde externe au besoin (voir compensation ci-dessous)
    Do : sortie logique : si la valeur du pH est supérieure ou inférieure à un seuil réglé par le potentiomètre l’état est signalé par une LED. (port que je n’utilise pas)
    Po : La sortie analogique du PH
    G : Masse
    G : Masse (les deux sont à relier pour une meilleur lecture)
    V+ : 5V
    Ils existe des cartes plus évoluée avec isolement de la carte pour éviter les faux signaux si il y a des fuites de courant dans l’eau (du moins c’est que j’en ai compris). Chez moi le bac est relié à la terre ce qui doit limiter les problèmes.

  • Une sonde pH :
    Pour ma part une vielle sonde du commerce d’aquariophile de marque JBL. Le choix de cette dernière à son importance en fonction du milieu à mesurer et du temp d’immersion. Je ne vais pas faire de cours ici, mais préférez une double jonction à gel si vous la laisser constamment dans l’eau. Cette dernière s’usera plus rapidement dans des eaux à faible salinité de type eau du robinet qu’en eau de mer car la concentration en ions KCl qui la compose générera moins de pression osmotique et donc moins de perte. C’est aussi pour cela qu’il faut étalonner la sonde de manière régulière. Il me semble que les pH mètre les plus perfectionnés testent la sonde lors de la calibration pour ajuster cette dérive. Pour le moment je n’ai pas observé de problème de dérive dans le temps sur des solutions tampons.

  • Un ESP : dans mon cas un wemos d1 mini avec un carte ads115 pour l’acquisition analogique car le port A0 de la carte ne donne pas de mesure stable. Du coup la sortie analogique de la carte pH passe par l’entrée de la ads115 qui converti en I2C… si je dis pas de conneries. Pour le montage il faut se référer à la doc de la carte car le montage change en fonction de l’adressage de la carte. Là encore il faut il me semble qu’il faille relier les entrées analogiques non utilisées à la masse pour une meilleur lecture.

  • Une sonde de température : J’ai une sonde dallas extérieure qui est reliée directement à l’ESP avec la petite résistance qui va bien. Il me semble que la carte compense la température avec la une sonde qui lui est propre. Cette sonde mesure la température de la carte et non de l’échantillon et qui est possible de lui en adjoindre un externe via le connecteur To. Chez moi la sonde me sert à remonter la température de l’eau et non pas à compenser la valeur. Je crois que la compensation de température est superflue pour mon utilisation (cf les tableau ci joint). Si quelqu’un trouve un moyen de le faire je suis toute ouie à l’option pour l’intégrer dans mon projet.


    (http://www.crisoninstruments.com/site/pdfs_fr/01/crison_fr_1_1.pdf)

La mise en place:

SHEMA MONTAGE A FAIRE

Réglage de l’offset : Ph 7 est la moyenne des valeurs. Pour forcer la valeur il faut faire un cour-circuit au niveau de la connexion BNC à l’aide d’un trombone par exemple et mesurer la tension à l’aide d’un multimètre au niveau de la pin Po. Il faut ajuster la valeur à 2,5 V. On peut aussi faire varier la valeur de façon à ce que l’amplitude de mesures réelles soit équivalent à la moyenne de ce que l’on veut mesurer ( je sais pas ci c’est clair).

Le code ESPHome:

  name: phmeter2
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret wifissid
  password: !secret wifipassword
    
captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

i2c:
  sda: D2
  scl: D1
  scan: True

ads1115:
  - address: 0x48
  
dallas:
  - pin: D0
    update_interval: 10s
sensor:
  - platform: dallas
    address: 0xCA3C01B55648B728
    name: "Reef Temperature"
    filters:
      - median:
          window_size: 6
          send_every: 6
          send_first_at: 1
    unit_of_measurement: "°C"
    icon: "mdi:temperature-celsius"
    accuracy_decimals: 1
  - platform: ads1115
    multiplexer: 'A0_GND'
    gain: 6.144
    name: "Reef pH ads"
    id: ph_ads
    update_interval: 10s
    filters:
      - median:
          window_size: 6
          send_every: 6
          send_first_at: 1
    unit_of_measurement: "mV"
    icon: "mdi:water"
    accuracy_decimals: 3

On retrouve le port I2C et l’adresse de l’ads1115.
Le sensor de ma sonde dallas et de l’ads1115.
Le gain est de 6.144 car c’est avec lui que j’ai le plus d’aptitude et donc de précision de mesure. Je relève la mesure toutes les 10 secondes et envoie la valeur moyenne au bout 6 mesures soit toutes les minutes.

Remontée des valeurs dans MQTT


Comme expliqué plus haut je fais remonter la valeur en mV la conversion se fait dans HA.

Le package HA

Pour simplifier la gestion de mes projets je travaille avec un package pour chacun d’entre eux.
Les automatisations pour les notifications sont en cours de développement et ne devraient pas intéresser grand monde. Je mets le tout au cas où pour donner des idées ou avoir vos corrections éventuelles.

###################################################################################
#                                  device_tracker:                                #
###################################################################################
device_tracker:
  - platform: ping
    interval_seconds: 30
    hosts:
      ph_meter: 192.168.1.26
####################################################################################
##                               PH meter                          #
####################################################################################
input_boolean:
################################## 
  calib_ph:
    name: "Calib mode"

input_select:
################################## 
  c_calib_ph4:
    name: Calibration pH4
    icon: mdi:adjust
    options:
      - "4.00"
      - "4.01"
  c_calib_ph7:
    name: Calibration pH7
    icon: mdi:adjust
    options:
      - "6.86 "
      - "7.00"
      - "7.01"
  c_calib_ph9_10:
    name: Calibration pH9-10
    icon: mdi:adjust
    options:
      - "9.00"
      - "9.18"
      - "9.21"
      - "10.00"
      - "10.01"

input_number:
  v_calib_mv4:
    name: Calibration mV à 4 
    icon: mdi:gauge
 #   initial: 4.504
    min: 3.500
    max: 5.000
    step: 0.001
    mode: box
  v_calib_mv7:
    name: Calibration mV à 7 
    icon: mdi:gauge
 #   initial: 4.013
    min: 3.500
    max: 5.000
    step: 0.001
    mode: box
  v_calib_mv9:
    name: Calibration mV à 9
    icon: mdi:gauge
  #  initial: 3.703
    min: 3.500
    max: 5.000
    step: 0.001
    mode: box

sensor: 
  - platform: template
    sensors:
      reef_ph:   
        friendly_name: "Valeur PH"      
        value_template: '{{ (states.input_select.c_calib_ph9_10.state | float) - ( (((states.input_number.v_calib_mv9.state | float)-(states.sensor.reef_ph_ads.state | float))*((states.input_select.c_calib_ph7.state | float)-(states.input_select.c_calib_ph9_10.state | float))) / ((states.input_number.v_calib_mv7.state | float)-(states.input_number.v_calib_mv9.state | float)) ) | round(2) }}'
#      xc  (states.sensor.reef_ph_ads.state | float)
#          (states.input_select.c_calib_ph4.state | float)
#      ya  (states.input_select.c_calib_ph7.state | float)
#      yb  (states.input_select.c_calib_ph9_10.state | float)
#          (states.input_number.v_calib_mv4.state | float)
#      xa  (states.input_number.v_calib_mv7.state | float)
#      xb  (states.input_number.v_calib_mv9.state | float)
#########################################################ph_meter
# ph_meter ONLINE status sensors
      ph_meter:
        value_template: '{% if is_state("device_tracker.ph_meter", "home") %}Online{% else %}offline{% endif %}'
        friendly_name: 'État ph_meter'
        icon_template: >-
          {% if is_state('device_tracker.ph_meter', 'home') %}
            mdi:power-plug
          {% else %}
            mdi:power-plug-off
          {% endif %}

automation: 
# Notify offline     
  - alias: Notify ph_meter offline 
    trigger:
      platform: state
      entity_id: device_tracker.ph_meter
      to: 'not_home'
    action:
      service: notify.iosdevice
      data:
        title: "ph_meter offline"
        message: "le pH mètre est hors ligne !!! Mesures impossibles !!! "
        data:
          push:
            thread-id: "activité_reef-group"

  - alias: 'Notif Reef Temp'
    initial_state: 'on'
    trigger:
      - platform: time_pattern
        hours: "/1"
        seconds: "03"
    condition: 
      condition: and
      conditions:
        - condition: template
          value_template: >
            {% if ( states('sensor.time') > "08:00" ) and ( states('sensor.time') < "20:00" )%}
              True
            {% else %}
              False
            {% endif %}
        - condition: or
          conditions: 
            - condition: template
              value_template: "{{states('sensor.reef_temperature_2')| int > 26 | int}}"
            - condition: template
              value_template: "{{states('sensor.reef_temperature_2')| int < 23 | int}}"
    action:
      service: notify.iosdevice
      data_template:
        title: "Reef : Alerte Température"
        message: "La température d'eau est à {{states('sensor.reef_temperature_2')}} alors qu'elle devrait être comprise entre 23 et 26°C"
        data:
        push:
          thread-id: "activité_reef-group"
  • Je commence avec un device tracker qui me permet de me faire une alerte en cas de déconnexion

  • Un input_boolean qui permet d’accéder aux fonctions de calibration sur la carte Lovelace.

  • Ensuite, des inputs_select pour un faire le choix en fonction des solutions de calibration que je serai amené à utiliser sans avoir à modifier le code. Les PH de celle-ci varient en fonction de fabricants. Pour le moment la formule de calibration ne se base que sur deux valeurs (neutre et basique) mais pourrait se faire sur trois au besoin. Il faudrait par contre revoir la formule pour faire une régression linéaire à trois inconnues.

  • Les input_number sont là pour rentrer les valeurs en mV lors de la calibration pour chaque solution tampon directement depuis l’interface Lovelace.

  • les sensor :
    reef_ph convertit la valeur mV en PH en fonction du pH des 2 solutions de calibration choisies et de la valeur de la mesure réalisée pour chacune d’elle.
    ph_meter présente l’état connecté ou non du pH-mètre.

Intégration Lovelace

Le graphique : Capture d’écran 2020-10-11 à 17.21.12
Le pic bas de valeurs est dû à la vérification de la propreté de la sonde. Dommage que c’est bien plus beau d’ordinaire. Le graph présente 48h de valeurs et je suis en train de plancher à une échelle dynamique. Il me reste aussi a trouvé une icône pour le pH si quelqu’un a une piste je suis preneur.
Le code du graph:

entities:
  - entity: sensor.reef_ph
    index: 0
  - aggregate_func: min
    color: 'rgba(0,0,0,.25)'
    entity: sensor.nigh_time
    label: false
    show_line: false
    show_points: false
    show_state: false
    smoothing: false
    y_axis: secondary
font_size: 75
hours_to_show: 48
line_color: green
line_width: 2
points_per_hour: 4
show:
  extrema: true
  fill: true
  graph: line
  icon: true
  icon_adaptive_color: true
  labels: false
  legend: false
  name: true
  name_adaptive_color: true
  points: hover
  state: true
type: 'custom:mini-graph-card'

La Carte et Calibration

La carte est conditionnelle et affiche les inputs qu’en mode calibration pour éviter les fausses manipulations.

Le code de la carte

cards:
  - card:
      entities:
        - entity: sensor.reef_ph_ads
        - entity: sensor.reef_ph
        - entity: sensor.reef_temperature_2
        - entity: input_boolean.calib_ph
      show_header_toggle: false
      title: Reef pH  / Temp.
      type: entities
    conditions:
      - entity: input_boolean.calib_ph
        state: 'off'
    title: Reef pH  / Temp.
    type: conditional
  - card:
      entities:
        - entity: sensor.reef_ph_ads
        - entity: sensor.reef_ph
        - entity: sensor.reef_temperature_2
        - entity: input_boolean.calib_ph
        - entity: input_select.c_calib_ph4
        - entity: input_number.v_calib_mv4
        - entity: input_select.c_calib_ph7
        - entity: input_number.v_calib_mv7
        - entity: input_select.c_calib_ph9_10
        - entity: input_number.v_calib_mv9
      show_header_toggle: false
      title: Reef pH  / Temp. Calib mode
      type: entities
    conditions:
      - entity: input_boolean.calib_ph
        state: 'on'
    type: conditional
type: vertical-stack

Au final …

Voilà ! Bravo au courageux qui auront pris le temps de lire le post jusqu’au bout. Ça m’a pris une partie de l’après-midi rien que pour la rédaction du post en gérant les gamins à côté ;-). Raison pour laquelle j’ai du mal à partager de tels projets.

Je vous ai tout mis, car j’ai pas mal galéré dans mes débuts sur HA et ai du faire pas mal de recherche pour trouver l’inspiration pour réaliser des projets aboutis. J’espère que cela donnera envie aux nouveaux utilisateurs. J’ai un projet similaire en cours avec mesure de l’ORP et un gros projet à base de pompe doseuse (note à moi-même : trouver un WE entier pour la rédaction du post) que j’espère pouvoir vous partager.

Désolé pour les fautes de frappes, de grammaires ou d’orthographes…

Je compte sur vous pour les retours. Tout est bon à prendre. Avis aux amateurs pour compléter le projet, voir corriger des erreurs éventuelles.

6 « J'aime »

Merci du partage ! :+1:

Au top un bon début.

Yes merci pour le tuto

Tip top :slight_smile: :+1: :+1: :+1: :+1:

Beau boulot, je verrai pour l’adapter certainement pour l’été prochain pour la piscine…Merci du partage

Trés beau projet et bien expliqué merci

1 « J'aime »

Bonjour,

Super sujet!

Je me suis décidé à me lancer dans un projet de mesure de PH et Redox pour ma piscine hors sol…
C’est surement useless pour mon utilisation et ça va surement me coûter aussi cher que si je partais sur un produit tout fait mais bon, c’est surement aussi moins marrant et moins instructif…

Dans tous les projets DIY que j’ai pu voir sur le net, la quasi totalité ont comme interface entre la sonde et un ESP ou SONOFF une carte PH/ORP qui coûte (à mon sens) un bras:

J’ai bien vu la carte que tu as utilisé sur AE et j’ai hésité à partir sur celle-ci, mais compte tenu de la différence de prix, j’ai finalement pris une identique à celle ci-dessus pour faire un test dans un 1er temps me disant qu’avec un tarif comme celui d’AE ça cachait quelque chose…

Comme j’ai besoin de deux sondes (et donc deux adaptateurs), je partirais bien sur le modèle que tu as choisi pour la seconde.

Est-ce que tes mesures sont fiables / stables / cohérentes?
Il y a assez peu de retour sur cette carte quand on cherche sur le net, je pense que ça en aidera quelques uns à faire le bon choix en cas de doute…

Merci d’avance!

@Antoine1
Les mesures sont stables et fiables selon la sonde utilisée. Ma sonde d’aquarium m’a lâchée après quelques années en eau de mer (5 ans). Elles ne durent, en général pas plus d’un ou deux ans en eau douce du fait du différentiel osmotique / à la concentration en KCl contenu dans la sonde. Elle ne m’a jamais fait défaut et les mesures étaient stables. Il faut calibrer régulièrement ou du moins vérifier les valeurs mesurées avec les solutions tampons. La dernière sonde chinoise ce n’est pas la même chose. Les valeurs fluctuent plus, mais ça reste convenable. Je te conseille une sonde en gel à double jonction. Je n’ai pas encore trouvé mon bonheur sur les sites chinois. Je prends la JBL en animalerie.

J’ai légèrement amélioré le programme (je ferai une mise à jour du post) on je passe par un inpu_text pour « sauvegarder » les valeurs et mis un rappel de calibration.

Les problèmes de mesures peuvent intervenir si tu as des fuites de courant dans l’eau. Les circuits doivent être isolés. Je ne me suis pas penché sur le problème. Si quelqu’un à des infos sur le sujet… tous conseils et explication sont les bienvenues.

Je planche sur une seconde version avec un autre carte avec l’ORP le montage est prêt depuis 3 mois, mais le temps me manque.

1 « J'aime »

Merci pour le retour!

Après avoir effectué mes tests de mesure Redox qui me semblent cohérentes, j’ai finalement décidé de prendre une seconde carte Phidget.

Je pense avoir exactement la même config que toi niveau matériel (Wemos D1 Mini + ADS1115 + DS18b20 + sondes PH et ORP via les cartes Phidgets).

J’attends toujours de recevoir la sonde PH de AE mais ça ne devrait plus tarder.
Ton code devrait m’être utile pour la partie calibrage je pense!

Tu aurais une photo de ton montage?
Je suis curieux de voir comment ta sonde PH et ta sonde de T° sont installées.
Je suis sur une piscine hors-sol, sans local technique du coup je cherche des idées pour poser les sondes.
Sais-tu si ces sondes peuvent être installées en extérieur ou si elles doivent être dans un milieu protégés.

Pour ma part j’ai pris ces deux sondes:

Mes mesures d’ORP sont stables et tiennent la route (j’attends encore de recevoir la solution de calibrage pour en être 100% certain)

Je vais tenter un montage alimenté avec deux accus en 18650, le tout dans un boitier étanche…

@antoine Pour mes sondes elles trempent dans l’aquarium avec se genre de support.


Je rencontre un soucis de valeur avec les deux brancher ORP/pH. Je pense qu’il faille isoler les circuits mais j’ignore tout pour savoir comment faire. Si quelque as des connaissance en électronique et peux m’aiguiller je suis preneur.

" Si l’échantillon à mesurer est raccordé à la masse (à travers une canalisation ou un agitateur magnétique métallique…), le circuit électronique du pH-mètre doit être isolé de la masse et la connexion du pH-mètre à d’autres appareils (par exemple un enregistreur ou une imprimante) doit être effectuée avec une isolation galvanique. Si ce n’est pas le cas, il y a un risque de passage du courant dans l’électrode de référence, ce qui perturbera la mesure"

Ok, ça veut dire qu’elles sont immergées en totalité et donc waterproof?

Pour ton problème, j’ai vu sur le forum de Domoticz quelqu’un qui avait le même souci avec une installation destinée à une piscine. Je crois que ça a un rapport avec la « pool terre ».
[PROJET] Gestion de piscine - Page 7 - Forum Domoticz en français.
De mémoire, en ayant les deux sondes branchées, le mec a des interférences / variations dans ses mesures.

Je ne me suis pas arrêté dessus n’ayant (pas encore?) le problème mais si je dis pas de bêtises, il y a une reprise à la masse à faire.

@Antoine1 de ce que j’ai compris il faut utiliser un Photocoupleur sur la masse.
J’ai commander deux carte pour fait un essai.
Les sonde doivent dépasser de l’eau. Prévois leur un par pluie.

Au contraire, la problématique vient du fait que les sondes sont à la même masse (via le fluide).
Il faut au contraire totalement isoler les sondes et/ou les interfaces. Ce qui n’est pas si simple.
J’avais rencontré le problème lorsque j’avais développé mes propres interfaces https://www.cap-recifal.com/forums/topic/668-ph-mètre-diy/?do=findComment&comment=100230
J’avais isolé galvaniquement les interfaces afin que les tensions deviennent flottantes. Cela passait par des convertisseurs CC et un optocoupleur analogique indépendants pour chaque interface. Voir le schéma que j’ai donné en lien.
Mais c’était de l’analogique (0 / 5V) et le but était d’entrer sur une carte Arduino avec une tension variable. Je pensais que les interfaces numériques avaient contourné cette problématique (je n’ai jamais creusé et essayé puisque mes interfaces analogiques fonctionnaient).
Je vois que le passage au numérique ne résout pas le problème…
Il faudrait regarder si il existe des interfaces totalement isolées.
J’avais également bricolé un truc fonctionnel mais peu fiable dans le temps. C’était d’isoler la mesure : Faites un test en trempant la sonde dans un verre rempli du liquide à mesurer. La mesure devrait être stable. Mettez un fil électrique entre l’eau de votre piscine/aquarium et le liquide dans le verre, et vous verrez que les variations reprennent.
La solution est donc d’isoler la sonde de mesure (Ph, ORP) du volume d’eau. J’avais fabriqué un petit récipient dans lequel était positionné une sonde. Le récipient alimenté en goutte à goutte par un circuit de pompe.

Une carte d’isolement analogique devrait faire l’affaire non ? Entre l’ADS et la carte d’acquisition de la sonde.

Il faut que toute les liaisons soient isolées. L’alimentation ET le retour mesure.
La seule liaison qui malheureusement ne peut être évitée (et c’est elle qui pose soucis) c’est celle entre les sondes via le liquide.
Si tes cartes isolent l’alim et le signal de sortie, c’est gagné.
Tiens nous au jus :wink:

Je viens de percuter…
@Antoine1
Si vous utilisez des cartes Wemos, c’est que votre liaison est hertzienne. Donc si vous avez une alimentation 240AC/5VDC isolée (0V non raccordé à une masse = tension flottante), ou une batterie, la sonde dispose alors d’un potentiel flottant. :+1:
Il vous suffit d’avoir une seconde alimentation identique pour alimenter la seconde carte.
(Avec un Wemos par carte également. Çà va de soit).
Les deux sondes auraient ainsi deux potentiels flottants et ne se perturberaient pas (et ne seraient pas non plus sensibles aux parasites contenus dans l’eau, si tant est que celle-ci ne soit pas reliée à la terre. )

Bonjour à tous, je découvre ce topic et je suis très intéressé pour implémenter ça sur mon spa (intex gonflable). Quelqu’un a t il déjà tenté sur un spa? Je me demande surtout comment intégrer les sondes en étant « caché ». Les valeurs qui m’intéressent sont comme vous : le ph, le redox et la température de l’eau.
Je me demande aussi l’utilité du module ads1115 ? Vous parlez d’une instabilité sur l’entrée A0 du wemos, pouvez vous m’en dire plus ?
Merci d’avance

@Zobi
La mesure analogique sur le wemos n’est pas précise. Si on utilise l’ADS c’est pour ça précision. Le wemos est en 10bit l’ads en 16bits. Ça paraît pas comme ça mais l’augmentation de la précision est importante. Presque 60 fois plus précise et ça compte lorsque on mesure une différence infime de voltage.

si cela peut vous aider, je vais utiliser le tuto de gammatronic : UN ANALYSEUR d’eau de PISCINE CONNECTÉ - YouTube
et integrable à HA