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 :
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
- Version compacte :
- Mode 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.