Capteurs d’humidité du sol

Ce tutoriel explique comment mettre en oeuvre des capteurs analogiques d’humidité du sol en MicroPython. Deux technologies sont disponibles, par exemple chez Seed Studio :

  • Les capteurs résistifs : Module Grove - Moisture Sensor. Ce capteur se présente comme une fourche métallisée qui doit être plantée en terre. Plus le sol est humide, plus les fuites de courant entre les deux dents sont importantes. Le capteur mesure donc l’augmentation de tension due à la chute de résistivité.

  • Les capteurs capacitifs : Module Grove - Capacitive Moisture Sensor (Corrosion-Resistant). Ce capteur se présente comme un seul “piquet”. Son principal avantage sur les capteurs résistifs, c’est qu’il n’est pas métallisé ce qui le rend insensible à la corrosion et donc bien plus durable. Il fonctionne en mesurant la variation de capacité d’un condensatuer constitué par deux lignes de cuivre que vous pouvez observer sur sa surface, protégées par une pellicule de résine époxy voir ce site pour les explications, en anglais.

Ces deux capteurs s’utilisent de la même façon : il faut les planter en terre. Dans le cas de modules Grove, n’enfoncez pas les capteurs :

  • au-dessous de la partie métallisée des dents du PCB pour le module résistif
  • au-dessous de la ligne blanche sérigraphiée sur le PCB pour le module capacitif

Matériel requis

  1. Une carte d’extension de base Grove
  2. La carte NUCLEO-WB55
  3. Un module Grove - Moisture Sensor ou un module Grove - Capacitive Moisture Sensor (Corrosion-Resistant)

Les modules Grove capteurs d’humidité du sol :

Grove Capteurs d'humidité du sol

Crédit images : Seeed Studio

Calibrer les capteurs d’humidité du sol

Comme pour n’importe quels capteurs, ceux qui nous intéressent ici ne seront pas très utiles s’ils ne sont pas calibrés. Que signifie “mesurer l’humidité du sol” d’ailleurs ? Par référence à quelle humidité ? Nous posons là une des questions qui font de la science un outil efficace et sérieux : une mesure ne sert à rien si on n’a pas défini son intervalle de validité et, à forciori, si on ne sait pas ce qu’elle signifie précisément !

Le sujet de la mesure physique est complexe, celui de la calibration aussi. Par exemple, pour un capteur capacitif, la procédure décrite ici est assez subtile. Nous avons fait le choix (celui que l’on trouve sur de nombreux sites Inernet) de procéder comme suit :

  1. On active le capteur et on le laisse dans l’air. On peut considérer que l’air correspond à un sol infiniment sec. On mémorise la valeur renvoyée par le capteur dans cette situation dans une variable CAL_AIR.
  2. On active le capteur et on le plonge aux deux tiers dans un verre d’eau. On peut considérer que l’eau correspond à un sol infiniment humide. On mémorise la valeur renvoyée par le capteur dans cette situation dans une variable CAL_EAU. **ATTENTION ** : prenez garde à ne pas immerger les composants situés à la tête des capteurs (du côté de l’extrémité qui porte le connecteur au bus I2C) lors de cette opération !
  3. On remappe les valeurs remontées par le capteur de l’intervalle [Min(CAL_AIR, CAL_EAU) ; Max(CAL_AIR, CAL_EAU)] dans l’intervalle [0 ; 100] pour lire une humidité en pourcentage de l’inondation totale :laughing:.

Les scripts qui suivent explicitent cette procédure.

Le code MicroPython

Les scripts présentés ci-après sont disponibles dans la zone de téléchargement.

Nous aurons besoin de copier deux fichiers sur le disque PYBFLASH : le script principal, main.py et le pilote des capteurs, soil_moisture.py.

Pour commencer, voici le contenu de soil_moisture.py, relativement concis :

# Pilote pour les capteur analogiques d'humidité du sol de type :
# - Capacitifs, ex. : https://wiki.seeedstudio.com/Grove-Capacitive_Moisture_Sensor-Corrosion-Resistant/
# - Résistifs, ex. : https://wiki.seeedstudio.com/Grove-Moisture_Sensor/
# Après un premier relevé de mesures dans l'air (résultat : sig_air ) et dans l'eau (résultat : sig_eau )
# il est possible de calibrer le capteur en passant ces deux résultats dans la méthode d'intialisation.

class SOILMOIST:

	# Initialisation
	# sig_air : retour analogique du capteur lorsqu'il est dans l'air
	# sig_eau : retour analogique du capteur lorqu'il est plongé dans l'eau
	def __init__(self, adc, sig_air = 0, sig_water = 4095):
		self._adc = adc
		self._min = sig_air
		self._max = sig_water

	# Mesure analogique "brute"
	def raw(self):
		return self._adc.read()

	# Mesure recentrée dans l'intervalle calibré, en %
	# 0% : capteur dans l'air
	# 100% : capteur baignant dans l'eau
	def measure(self):
		return self._map(self._adc.read(), self._min, self._max, 0, 100 )

	# Fonction map de l'API Arduino
	# https://www.arduino.cc/reference/en/language/functions/math/map/
	def _map(self, x, in_min, in_max, out_min, out_max):
		return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

Editez maintenant le script main.py et collez-y le code ci-dessous :

# Objet du script :
# Mise en oeuvre des capteurs d'humidité du sol de type résistifs et capacitifs.
# Si vous utilisez un capteur résistif, choisir CAP = False. 
# Si vous utilisez un capteur capacitif, choisir CAP = True.
#
# Procédure de calibrage :
# 1. Mettre CALIB = False
# 2. Laisser le capteur dans l'air et remonter les valeurs brutes de l'ADC. 
#    Mémoriser le résultat : CAL_AIR = ...
# 3. Plonger le capteur aux 2/3 dans l'eau (sans mouiller ses composants
#    électroniques !) et remonter les valeurs brutes de l'ADC. 
#    Mémoriser le résultat : CAL_EAU = ... 
# 3. Mettre CALIB = True
# 4. Relancez les mesures pour obvserver des valeurs d'humlidité en pourcentage.

from time import sleep # Pour temporiser
from pyb import Pin, ADC # Pour gérer les broches et l'ADC 
import soil_moisture # pilote du capteur d'humidité du sol

# Est-ce qu'on a déjà calibré ?
CALIB = True

# Est-ce que le capteur est capacitif ?
# (si non, il est pris pour résistif)
CAP = True

NB_MES = 255 
INV_NB_MES = 1 / NB_MES

# Capteur sur A0 (analogique)
adc = ADC(Pin('A0'))

if CALIB: # Si on a déjà déterminé les constantes de calibration
	
	if CAP: # S'il s'agit d'un capteur capacitif
		
		# Retour de la mesure "raw" pour ...
		CAL_AIR = 2535 # Mon capteur capacitif plongé dans l'air
		CAL_EAU = 1535 # Mon capteur capacitif plongé dans l'eau
	
	else: # S'il s'agit d'un capteur résistif
		
		# Retour de la mesure "raw" pour ...
		CAL_AIR = 0    # Mon capteur résistif plongé dans l'air
		CAL_EAU = 2365 # Mon capteur résistif plongé dans l'eau

	#instance de la classe du capteur avec les constantes de calibrage spécifiées
	capteur = soil_moisture.SOILMOIST(adc, sig_air = CAL_AIR, sig_water = CAL_EAU)

else: # Si on n'a pas encore calibré

	#instance de la classe du capteur
	capteur = soil_moisture.SOILMOIST(adc)

while True:

	if not CALIB: # Si on est en phase de calibrage

		# Renvoie les mesure "raw" pour pouvoir les constantes
		# obtenir les constantes CAL_AIR et CAL_EAU
		sum = 0
		for i in range(NB_MES):
			# Mesure brute (en quanta de l'ADC)
			sum = sum + capteur.raw()

		# Moyenne de NB_MES mesures
		avg = sum * INV_NB_MES
				
		print("Valeur brute de l'ADC : " %avg) 

	else: # Si on a déjà calibré le capteur

		print("Humidité %1d %%" %capteur.measure()) 
	
	sleep(10) # Temporisation de dix secondes

Affichage sur le terminal série de l’USB User

Une fois le script lancé avec CTRL-D et observez les valeurs remontées :


Sortie capteurs d'humidité du sol


On utilise ici un capteur capacitif planté dans le pot d’une plante grasse.