La surveillance de la tension électrique est essentielle dans de nombreux projets d'électronique et de domotique. Que vous souhaitiez analyser la qualité de votre réseau électrique, créer un système d'alerte en cas de surtension ou simplement intégrer des mesures de tension dans votre projet IoT, le capteur ZMPT101B couplé à un ESP32 offre une solution fiable et économique. Dans cet article, nous explorerons comment configurer et programmer ce système en MicroPython.
Le capteur ZMPT101B
Le ZMPT101B est un transformateur de tension de précision conçu pour mesurer les tensions alternatives (AC). Contrairement à d'autres capteurs, il offre:
- Une isolation galvanique entre le circuit de mesure et la tension mesurée
- Une précision élevée grâce à son design spécifique
- Une bonne linéarité sur une large plage de tension
- Une compatibilité avec les tensions standard du réseau électrique (110V-240V)
Ce capteur fonctionne en réduisant la tension alternative à un niveau sécuritaire et mesurable par les microcontrôleurs. Sa sortie analogique peut être facilement connectée aux entrées ADC (Analog-to-Digital Converter) d'un ESP32.
Matériel requis
Pour réaliser ce projet, vous aurez besoin de:
- Un ESP32 (DevKit, NodeMCU ou autre variante)
- Un module capteur ZMPT101B
- Des fils de connexion Dupont (mâle-femelle)
- Un câble micro-USB pour programmer l'ESP32
- Un ordinateur avec Thonny IDE ou autre environnement MicroPython
- Une alimentation stable pour l'ESP32
- Des composants de sécurité optionnels (fusible, boîtier isolant)
- Multimètre pour étalonnage.
Câblage
La connexion entre l'ESP32 et le ZMPT101B est relativement simple, mais doit être effectuée avec précaution étant donné que nous travaillons avec des tensions potentiellement dangereuses.
- Alimentez le module ZMPT101B:
- VCC du module vers 3.3V de l'ESP32
-
GND du module vers GND de l'ESP32
-
Connectez la sortie analogique:
- Sortie analogique du ZMPT101B vers la broche GPIO32 de l'ESP32 (configurable dans le code)
⚠️ ATTENTION: La partie mesure du ZMPT101B doit être manipulée avec une extrême prudence. Ne touchez jamais les bornes d'entrée lorsqu'elles sont connectées à une source de tension. Idéalement, utilisez un boîtier isolé pour votre projet final.
L'architecture du code MicroPython
Le code que nous avons développé suit une architecture orientée objet, avec une classe ZMPT101B
qui encapsule toutes les fonctionnalités nécessaires pour effectuer des mesures précises. Analysons sa structure:
- Initialisation: Configuration de l'ADC avec les paramètres appropriés et définition des points de caractérisation
- Calcul d'équation linéaire: Permet de convertir les valeurs ADC brutes en tension réelle
- Mesure ADC: Échantillonnage et traitement statistique pour obtenir des valeurs RMS précises
- Mesure effective: Conversion des valeurs ADC en tension effective
Points Forts du Code :
- Calcul RMS pour une précision optimale sur les signaux AC.
- Gestion de la mémoire avec array
et gc
pour éviter les débordements.
Cette approche modulaire facilite la réutilisation du code et son adaptation à différents scénarios.
Code complet
Voici le code MicroPython corrigé pour mesurer la tension avec le capteur ZMPT101B:
python
import math
from machine import ADC, Pin
from time import sleep
import utime
import array
import gc
class ZMPT101B:
def __init__(self, p_adc):
self.pt_carac = [(0, 0), (717, 235.0)] # Points de calibration (ADC, Volts)
self.adc = ADC(Pin(p_adc)) # Configuration de l'ADC sur la broche spécifiée
self.adc.atten(ADC.ATTN_11DB) # Configuration pour la plage 0-3.3V
self.adc.width(ADC.WIDTH_12BIT) # Résolution 12 bits (0-4095)
def equa_droite(self, pt1, pt2):
# Calcule l'équation de la droite entre deux points
x1, y1 = pt1
x2, y2 = pt2
a = (y2 - y1) / (x2 - x1) # Pente
b = y1 - a * x1 # Ordonnée à l'origine
return a, b
def mes_adc(self, etalon=False):
# Mesure et calcule la valeur RMS du signal
nb_per = 3 # Nombre de périodes à mesurer
T = 20 # Période du signal en ms (pour 50Hz)
nb1 = 380 * nb_per # Nombre d'échantillons initial
tabg = array.array('h', [0] * nb1)
# Mesure à haute vitesse
debut = utime.ticks_us()
for i in range(nb1):
tabg[i] = self.adc.read()
fin = utime.ticks_diff(utime.ticks_us(), debut)
# Ajustement du nombre d'échantillons en fonction du temps réel d'acquisition
nb = int(nb1 * nb_per * 20000 / fin)
tabg = tabg[:nb]
if etalon:
gmin = min(tabg)
gmax = max(tabg)
# Calcul de la valeur moyenne
gmean = sum(tabg) // nb
# Soustraction de la composante continue
for i in range(nb):
tabg[i] -= gmean
# Calcul RMS (Root Mean Square)
gsquare = sum(g**2 for g in tabg)
grms = math.sqrt(gsquare / nb)
grms = round(grms, 2)
if etalon:
print(f"x={grms} max={gmax} min={gmin}")
# Libération de la mémoire
tabg = None
gc.collect()
return grms
def mes_eff(self, etalon=False):
# Conversion de la valeur RMS en tension effective
pt_carac = self.pt_carac
nb = len(pt_carac) - 1
i = 1
a = -1
grms = self.mes_adc(etalon)
while a == -1 and i < nb:
A = pt_carac[i-1]
B = pt_carac[i]
if grms <= B[0] + 4: # Tolérance de 4 unités
a, b = self.equa_droite(A, B)
i += 1
if a == -1:
A = pt_carac[i-1]
B = pt_carac[i]
a, b = self.equa_droite(A, B)
g_eff = a * grms + b
if g_eff < 0:
return 0.0
return round(g_eff, 1)
def main():
mueff = ZMPT101B(p_adc=32) # Initialisation du capteur sur GPIO32
while True:
ueff = mueff.mes_eff(True) # Mesure avec affichage des détails
print(f"Tension efficace: {ueff}V")
print("-" * 20)
gc.collect() # Nettoyage de la mémoire
sleep(2) # Attente entre les mesures
if __name__ == "__main__":
main()
Pourquoi cette approche est efficace
Notre implémentation présente plusieurs avantages qui la rendent particulièrement efficace:
-
Échantillonnage à haute vitesse: La collecte des données est optimisée pour capturer un nombre suffisant de points par cycle sinusoïdal.
-
Calcul RMS précis: Contrairement à une simple moyenne, la valeur RMS (Root Mean Square) reflète correctement l'énergie du signal alternatif.
-
Calibration par points: Le système utilise des points de référence pour convertir les valeurs ADC en tensions réelles, permettant une calibration précise.
-
Gestion de la mémoire: L'utilisation de
gc.collect()
et la libération des tableaux temporaires évitent les problèmes de mémoire sur l'ESP32. -
Suppression de la composante continue: En soustrayant la valeur moyenne du signal, nous obtenons une mesure plus précise de la composante alternative.
Applications pratiques
Ce système de mesure de tension peut être utilisé dans diverses applications:
- Monitoring énergétique domestique: Surveillez la qualité de votre réseau électrique
- Systèmes d'alerte: Créez des notifications en cas de surtension ou sous-tension
- Domotique: Intégrez les mesures à votre système domotique pour automatiser certaines actions
- Projets IoT: Envoyez les données de tension à une plateforme cloud pour analyse
Comment améliorer ce système
Plusieurs améliorations peuvent être apportées à notre système de base:
-
Calibration automatique: Implémentez une routine d'auto-calibration avec une tension de référence connue
-
Filtrage numérique: Ajoutez des algorithmes de filtrage pour réduire le bruit et améliorer la précision
-
Interface web: Créez une interface web hébergée par l'ESP32 pour visualiser les données en temps réel
-
Stockage des données: Ajoutez une carte SD ou utilisez la mémoire flash pour enregistrer l'historique des mesures
-
Connectivité avancée: Intégrez MQTT ou d'autres protocoles pour transmettre les données à d'autres systèmes
-
Calcul de puissance: Combinez avec un capteur de courant comme le SCT-013 pour calculer la puissance consommée
Mise en œuvre pratique
Pour mettre en œuvre ce système dans un projet réel, suivez ces étapes:
-
Calibration: Utilisez un multimètre de référence pour ajuster les points de calibration dans le code
-
Sécurisation: Placez tous les composants dans un boîtier isolant pour éviter tout risque électrique
-
Alimentation stable: Utilisez une alimentation stabilisée pour l'ESP32 afin d'éviter des mesures erronées
-
Intégration: Connectez votre système à d'autres projets via Wi-Fi, Bluetooth ou stockage de données
FAQ : Réponses aux Questions Courantes
Q: Quelle est la précision typique de ce système? R: Avec une bonne calibration, on peut atteindre une précision de ±1% à ±3% sur la plage 100-250V AC.
Q: Le système peut-il mesurer des tensions continues (DC)? R: Non, le ZMPT101B est spécifiquement conçu pour les tensions alternatives. Pour les tensions continues, d'autres capteurs comme des diviseurs de tension seraient plus appropriés.
Q: Comment calibrer correctement le capteur? R: Utilisez un multimètre de référence pour mesurer la tension réelle et ajustez les points de calibration (pt_carac
) dans le code en conséquence.
Q: Peut-on utiliser ce code avec d'autres microcontrôleurs? R: Oui, avec quelques adaptations pour les fonctions ADC spécifiques à chaque plateforme, ce code peut être porté sur Arduino, STM32 ou Raspberry Pi Pico.
Q: Quelle est la consommation électrique du système? R: Le système complet (ESP32 + ZMPT101B) consomme environ 80-150mA, selon les fonctionnalités activées (Wi-Fi, Bluetooth, etc.).
Conclusion
Le ZMPT101B associé à un ESP32 constitue une solution polyvalente et précise pour mesurer la tension alternative. Grâce à MicroPython, nous avons pu développer un code modulaire et efficace qui peut servir de base à de nombreux projets. La mesure de tension est souvent le premier pas vers des applications plus complexes comme le monitoring énergétique, les systèmes de sécurité électrique ou l'optimisation de la consommation.
N'hésitez pas à adapter ce code à vos besoins spécifiques et à l'intégrer dans vos propres projets IoT. La flexibilité de la plateforme ESP32 et la simplicité de MicroPython vous permettront d'explorer de nombreuses possibilités à partir de cette base solide.