Un suivi de consommation sur Raspberry Pi vous indique exactement ce que consomme un circuit, à quel point une batterie se remplit et combien d'énergie un appareil utilise sur une journée. Dans ce tutoriel, vous allez mesurer la tension, le courant et la puissance en courant continu avec un INA219, les intégrer en wattheures, puis tout publier en JSON via MQTT pour qu'un tableau de bord ou une automatisation de votre maison connectée puisse les exploiter. Vous verrez aussi comment les HAT à pince ampèremétrique étendent ce principe aux circuits secteur en courant alternatif.
Choisir un capteur : INA219 ou pince ampèremétrique
| Module INA219 | HAT à pince ampèremétrique | |
|---|---|---|
| Mesure | Tension continue (jusqu'à 26 V), courant, puissance | Courant alternatif via une pince ; certaines cartes mesurent aussi la tension alternative |
| Raccordement | En série avec la charge, via une résistance shunt | Non invasif, la pince entoure un seul conducteur |
| Usage typique | Panneaux solaires, batteries 12 V, rubans LED, robots, le Pi lui-même | Circuits domestiques, électroménager, machines |
| Interface | I2C | Généralement un CAN SPI ou I2C sur le HAT |
| Sécurité | Basse tension uniquement | La pince est isolée, mais une installation près du secteur exige une personne qualifiée |
Ce tutoriel construit de bout en bout la version INA219, car elle est bon marché, précise en courant continu basse tension et sans danger pour expérimenter. Si vous avez besoin de mesurer de l'alternatif, un HAT à pince ampèremétrique est livré avec sa propre bibliothèque Python : lisez ses valeurs et réutilisez sans modification la partie MQTT du script. L'équivalent ESP32 pour le secteur est traité dans le guide capteur de courant SCT-013 avec ESP32.
Fonctionnement de l'INA219
L'INA219 mesure la faible chute de tension aux bornes d'une résistance shunt de 0,1 ohm placée en série avec votre charge, ainsi que la tension de bus côté charge. À partir de ces deux valeurs, il calcule en interne le courant et la puissance. Le module standard accepte jusqu'à 26 V sur le bus et, avec la calibration par défaut, environ 3,2 A. Comme le shunt est en série, tout le courant de la charge traverse le module : restez dans ses limites et utilisez des fils de section suffisante pour le courant.
Câblage
| Broche INA219 | Raccorder à |
|---|---|
| VCC | 3,3 V du Pi (broche physique 1) |
| GND | GND du Pi (broche physique 6) et masse de l'alimentation de la charge |
| SDA | GPIO2 (broche physique 3) |
| SCL | GPIO3 (broche physique 5) |
| VIN+ | Borne positive de la source d'alimentation |
| VIN- | Entrée positive de la charge |
La masse du circuit mesuré doit être commune avec celle du Pi, sinon la mesure de tension de bus n'a aucun sens. Activez l'I2C avec sudo raspi-config nonint do_i2c 0 et vérifiez que le capteur apparaît à l'adresse 0x40 avec i2cdetect -y 1.
Installer les logiciels
sudo apt update
sudo apt install -y python3-venv i2c-tools
mkdir -p ~/power-monitor && cd ~/power-monitor
python3 -m venv .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" adafruit-circuitpython-ina219
Topics et payload
| Topic | Contenu | Retained |
|---|---|---|
connectmq/demo/8d20f6/solar/power |
Tension, courant, puissance toutes les 5 s | Non |
connectmq/demo/8d20f6/solar/energy |
Wh cumulés, chaque minute | Oui |
connectmq/demo/8d20f6/solar/status |
online / offline |
Oui |
Un message de puissance ressemble à ceci :
{"voltage": 12.84, "current_ma": 412.6, "power_w": 5.3, "ts": 1792161000}
Le topic d'énergie est retained : un tableau de bord ouvert plus tard voit immédiatement le total du jour.
Le script de suivi de consommation pour Raspberry Pi
Le script effectue une mesure par seconde, calcule une moyenne sur l'intervalle de publication pour lisser le bruit et intègre la puissance dans le temps en wattheures. Il sauvegarde le compteur d'énergie sur disque toutes les dix minutes pour qu'un redémarrage ne le remette pas à zéro, sans écrire sur la carte SD à chaque mesure. Enregistrez-le sous power_monitor.py :
#!/usr/bin/env python3
"""INA219 power monitor publishing to MQTT."""
import json
import os
import time
import uuid
from pathlib import Path
import board
import paho.mqtt.client as mqtt
from adafruit_ina219 import INA219
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"power-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/8d20f6/solar")
PUBLISH_EVERY = 5 # secondes
ENERGY_EVERY = 60 # secondes
SAVE_EVERY = 600 # secondes
STATE_FILE = Path(os.getenv("STATE_FILE", "energy_wh.txt"))
ina = INA219(board.I2C()) # calibration par défaut : plage 32 V, 2 A
def load_energy():
try:
return float(STATE_FILE.read_text())
except (OSError, ValueError):
return 0.0
def save_energy(wh):
tmp = STATE_FILE.with_suffix(".tmp")
tmp.write_text(f"{wh:.4f}")
tmp.replace(STATE_FILE) # le renommage atomique évite les fichiers à moitié écrits
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print(f"Connection refused: {reason_code}")
return
print(f"Connected as {CLIENT_ID}")
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
client.connect(BROKER, PORT, keepalive=30)
client.loop_start()
energy_wh = load_energy()
samples = []
last_sample = time.monotonic()
last_publish = last_energy = last_save = last_sample
try:
while True:
time.sleep(1)
now = time.monotonic()
voltage = ina.bus_voltage + ina.shunt_voltage # tension côté alimentation
current_ma = ina.current
power_w = ina.power
if ina.overflow:
print("Warning: INA219 overflow, current exceeds calibrated range")
energy_wh += power_w * (now - last_sample) / 3600.0
last_sample = now
samples.append((voltage, current_ma, power_w))
if now - last_publish >= PUBLISH_EVERY:
n = len(samples)
payload = {
"voltage": round(sum(s[0] for s in samples) / n, 2),
"current_ma": round(sum(s[1] for s in samples) / n, 1),
"power_w": round(sum(s[2] for s in samples) / n, 2),
"ts": int(time.time()),
}
client.publish(f"{PREFIX}/power", json.dumps(payload), qos=0)
samples.clear()
last_publish = now
if now - last_energy >= ENERGY_EVERY:
energy = {"energy_wh": round(energy_wh, 3), "ts": int(time.time())}
client.publish(f"{PREFIX}/energy", json.dumps(energy), qos=1, retain=True)
last_energy = now
if now - last_save >= SAVE_EVERY:
save_energy(energy_wh)
last_save = now
except KeyboardInterrupt:
pass
finally:
save_energy(energy_wh)
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
client.loop_stop()
client.disconnect()
Lancez-le avec python power_monitor.py et abonnez-vous depuis une autre machine :
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-8d20f6 \
-t 'connectmq/demo/8d20f6/solar/#' -v
Allumez et éteignez la charge et observez current_ma et power_w réagir en moins de cinq secondes.
Calibration et précision
La calibration par défaut couvre 32 V et 2 A avec une résolution correcte. Si votre charge est faible, par exemple un microcontrôleur qui consomme quelques dizaines de milliampères, appelez ina.set_calibration_16V_400mA() après la création du capteur pour une résolution plus fine. Si vous dépassez la plage du module, remplacez le shunt par une valeur plus faible et écrivez votre propre calibration, ou passez à un capteur conçu pour des courants plus élevés.
Vérifiez avec un multimètre placé en série avec la charge. De petits décalages sont normaux ; une erreur constante en pourcentage provient généralement de la tolérance du shunt, que vous pouvez corriger par un facteur d'échelle logiciel. Un courant négatif signifie que VIN+ et VIN- sont inversés, ce qui peut d'ailleurs être utile : un moniteur de batterie peut se servir du signe pour distinguer charge et décharge.
Cas d'usage
Le même script convient à de nombreux projets moyennant un simple changement de préfixe de topic et de calibration. Comme les abonnés ne voient qu'un JSON avec des champs de tension, de courant, de puissance et d'énergie, vous pouvez changer de capteur plus tard, ou ajouter un second INA219 à l'adresse 0x41 pour un autre circuit, sans toucher au tableau de bord ni à l'automatisation qui consomment les données.
- Systèmes solaires et batteries : suivez la production des panneaux et la tension de la batterie, et publiez une alerte lorsque la batterie descend sous un niveau sûr.
- Mesure de vos propres projets Pi ou ESP32 : placez l'INA219 entre l'alimentation et un appareil pour voir la consommation réelle pendant les rafales Wi-Fi et la veille.
- Robots et véhicules : surveillez le courant des moteurs pour détecter les blocages.
- Éclairage et pompes 12 V : confirmez qu'une charge s'est réellement allumée, et pas seulement qu'un relais a cliqué.
Pour un suivi de toute la maison avec des pinces ampèremétriques et des graphiques sur le long terme, notre article compteur d'énergie domestique avec MQTT présente le côté abonné, et le guide Raspberry Pi avec Grafana et InfluxDB conserve les relevés pendant des mois. Avec un budget énergétique serré, le même script tourne très bien sur un nœud MQTT Raspberry Pi Zero 2 W.
Du banc d'essai à l'installation permanente
Sur le serveur MQTT public gratuit broker.connectmq.com, n'importe qui peut lire vos topics : c'est acceptable pour un essai sur table, mais cela révèle vos habitudes de consommation dans une vraie maison ou un atelier. Passez à un broker privé avec TLS avant d'installer le moniteur à demeure. Avec ConnectMQ, un broker MQTT managé, vous obtenez des identifiants générés pour chaque appareil ; définissez MQTT_PORT=8883 ainsi que MQTT_USERNAME=YOUR_USERNAME, MQTT_PASSWORD=YOUR_PASSWORD et MQTT_CLIENT_ID=YOUR_CLIENT_ID dans un fichier d'environnement systemd, puis redémarrez. Ajoutez ensuite une règle d'alerte à seuil dans le portail ConnectMQ, par exemple une tension inférieure à 11,8 V sur le topic de puissance, pour être averti avant qu'une batterie ne soit endommagée.
Si vous découvrez le rôle d'un broker MQTT ou la façon d'exécuter un script en tant que service, commencez par le tutoriel MQTT sur Raspberry Pi, puis revenez à ce montage.
Dépannage
ValueError: No I2C device at address: 0x40: vérifiez SDA et SCL, activez l'I2C et lancezi2cdetect -y 1.- La tension lue est proche de zéro : VIN+ ou VIN- n'est pas raccordé au circuit mesuré, ou les masses ne sont pas communes.
- Les mesures de courant sont bruitées : faites une moyenne sur l'intervalle de publication comme le script, et gardez les fils du shunt courts.
- Le total d'énergie repart à zéro après un redémarrage : le fichier d'état n'est pas accessible en écriture ou le script a été tué avant la sauvegarde ; vérifiez les permissions du répertoire de travail.
Démarrer avec ConnectMQ
Envoyez vos données de consommation vers un broker MQTT cloud que vos tableaux de bord et alertes peuvent joindre de partout. Créez votre broker ConnectMQ gratuit avec l'offre Serverless (Free), sans carte bancaire, et connectez-vous en TLS avec MQTT 3.1.1 ou 5.0. L'explorateur de topics en direct affiche chaque relevé dès son arrivée.
Questions fréquentes
Un INA219 peut-il mesurer la puissance du secteur en courant alternatif ?
Non. L'INA219 est un capteur pour courant continu jusqu'à 26 V. Utilisez un HAT à pince ampèremétrique ou un compteur d'énergie certifié pour les circuits en alternatif, et confiez les travaux sur le secteur à une personne qualifiée.
Quelle est la précision d'un suivi de consommation Raspberry Pi avec un INA219 ?
Suffisante pour la plupart des usages amateurs et de surveillance, une fois vérifiée avec un multimètre. La tolérance du shunt est la principale source d'erreur et peut être corrigée par un facteur d'échelle.
Pourquoi publier l'énergie sous forme de retained message ?
Pour que tout tableau de bord ou abonné qui se connecte plus tard reçoive immédiatement le total actuel, au lieu d'attendre jusqu'à une minute la prochaine mise à jour.
À quelle fréquence publier les relevés de puissance ?
Toutes les quelques secondes suffit pour des tableaux de bord. Mesurez plus vite en local, faites la moyenne et publiez cette moyenne pour limiter le trafic.



