
- La tension alternative est détectée avec des borniers dédiés.
- Le courant est détecté avec un transformateur de courant externe CT (pince) placé autour de la phase uniquement, permettant la mesure du courant par induction électromagnétique.
- L’échantillonnage des formes d’onde CA a lieu dans le circuit intégré de mesure interne pour calculer les paramètres électriques.
- Les données de mesure traitées sont communiquées à l’aide du protocole UART Modbus au microcontrôleur ESP32.
| S. Non | Composants | Quantité | Objectif du compteur d’énergie intelligent |
| 1 | ESP32 | 1 | Microcontrôleur principal utilisé pour ce projet |
| 2 | Module I2C | 1 | Utilisé pour interfacer l’écran LCD avec l’ESP32 |
| 3 | ACL 16×2 | 1 | Affiche le courant, la tension, le facteur de puissance, etc. |
| 4 | PZEM-004T(V4.0) | 1 | Mesure les paramètres électriques |
| 5 | TC externe | 1 | Nécessaire pour mesurer le courant avec PZEM |
| 6 | Planche à pain | 1 | Pour connecter tous les composants |
| 7 | Fils de liaison | Montant requis | Pour réaliser tous les branchements électriques nécessaires |
| 8 | IDE Arduino (logiciel) | – | Utilisé pour programmer le système de compteur d’énergie |

∗ Source d’alimentation : Prise de courant CA principale connectée via le module PZEM-004T.
∗ Détection de courant : CT externe pour mesurer le courant, avec détection de tension intégrée.
∗ Microcontrôleur : Utilisation de l’ESP32 pour le traitement et la transmission des données.
* Écran LCD : Surveillance locale sur un écran 16×2 à l’aide d’un module I2C.
∗ Surveillance à distance : WiFi connecté pour envoyer MQTT pour la surveillance à distance.
∗ Système d’alerte : Les alertes par SMS sont envoyées à l’aide de l’API Circuit Digest Cloud.


#include
#include
#include
#include
#include
#include
LiquidCrystal_I2C lcd(0x27, 16, 2);
HardwareSerial PZEMSerial(2);
PZEM004Tv30 pzem(PZEMSerial, 17, 16);
float V = pzem.voltage();
float I = pzem.current();
float P = pzem.power();
float E = pzem.energy();
float F = pzem.frequency();
float PF = pzem.pf();
String payload =
"{\"mobiles\":\"" + String(mobileNumber) +
"\",\"var1\":\"Energy meter\"" +
",\"var2\":\"High Voltage\"}";
if (V > 255) {
if (millis() - lastSMS > smsCooldown) {
sendSMS();
lastSMS = millis();
}
}
void sendSMS() {
WiFiClientSecure secureClient;
secureClient.setInsecure();
HTTPClient http;
String apiUrl = "https://www.raspberryme.cloud/send_sms?ID=" + String(templateID);
http.begin(secureClient, apiUrl);
http.addHeader("Authorization", apiKey);
http.addHeader("Content-Type", "application/json");
lcd.clear();
lcd.print("Volt:"); lcd.print(V,1);
delay(2000);
--
V
client.subscribe("unique/energy/voltage");
client.on("message",(topic,message)=>{
voltage.innerText = message.toString();
});
client.on("error",(err)=>{
showAlert(err.message);
});
– Le modèle de publication-abonnement fonctionne mieux pour la diffusion en temps réel des données des capteurs vers de nombreux appareils de réception.
– La faible exigence de bande passante signifie une utilisation de données bien moindre que la publication (polling) avec HTTP.
– Une faible latence signifie que les mises à jour se produisent presque instantanément ; il n’y a donc aucun décalage entre les demandes et les réponses.
– Avoir une connexion persistante vous permet de surveiller votre environnement sans perdre la connectivité.
– La qualité de service permet de créer des garanties de livraison en fonction de l’importance des données.



Référentiel GitHub et fichiers sources
Accédez au code source complet, aux schémas de circuit et à la documentation de ce compteur d’énergie intelligent basé sur l’IoT avec alerte SMS.
Vidéo de travail : compteur d’énergie intelligent utilisant l’IoT
Démonstration montrant la surveillance de l’énergie en temps réel avec affichage des données à distance et notifications d’alerte en cas de conditions électriques anormales.
⇥ 7. Sera-t-il possible d’ajouter ce compteur d’énergie intelligent aux systèmes domotiques existants ?
Oui, c’est possible. Le protocole MQTT permet une intégration facile avec Home Assistant, OpenHAB, Node-RED ou d’autres systèmes d’automatisation personnalisés. Pour ajouter des données énergétiques aux règles d’automatisation, au tableau de bord et/ou à la logique de contrôle de votre système domotique, il vous suffit de vous abonner aux rubriques publiées par ce compteur d’énergie intelligent.
Ce tutoriel a été créé par le Équipe d’ingénierie de CircuitDigest. Nos experts se concentrent sur la création de didacticiels pratiques et concrets pour aider les créateurs et les ingénieurs à apprendre les projets Raspberry Pi, les projets Arduino, les projets de développement IoT et bien plus encore.
J’espère que vous avez aimé cet article et appris quelque chose de nouveau en construisant un compteur d’énergie intelligent utilisant l’IoT. Si vous avez des doutes, vous pouvez les poser dans les commentaires ci-dessous ou utiliser notre forum CircuitDigest pour une discussion détaillée.
Projets de caméra ESP32 associés


Sonnette vidéo intelligente utilisant la caméra ESP32
Cette sonnette vidéo Wi-Fi intelligente utilisant ESP32-CAM peut être alimentée par une prise secteur, et chaque fois que quelqu’un à la porte appuie sur le bouton de la sonnette, elle jouera une chanson spécifique sur votre téléphone et enverra un message texte avec un lien vers une page de streaming vidéo où vous pourrez voir la personne à la porte de n’importe où dans le monde.

Code de projet complet
Copier le code
#include
#include
#include
#include
#include
#include
#include
#include
void sendSMS();
// --------------------------------------
// LCD
// --------------------------------------
LiquidCrystal_I2C lcd(0x27, 16, 2);
// --------------------------------------
// PZEM
// --------------------------------------
HardwareSerial PZEMSerial(2);
PZEM004Tv30 pzem(PZEMSerial, 17, 16);
// --------------------------------------
// WiFi + MQTT
// --------------------------------------
const char* ssid = "Yourssid";
const char* password = "Password";
unsigned long lastSMS = 0; // timestamp of last SMS sent
const unsigned long smsCooldown = 60000; // 1 minute in milliseconds
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;
const char* apiKey = "yourapikey";
const char* deviceID = "ESP-32_Tracker";
const char* templateID = "101";
const char* mobileNumber = "Yourphonenumber";
WiFiClient espClient;
PubSubClient client(espClient);
// MQTT topics
const char* tV = "unique/energy/voltage";
const char* tI = "unique/energy/current";
const char* tP = "unique/energy/power";
const char* tE = "unique/energy/energy";
const char* tF = "unique/energy/frequency";
const char* tPF = "unique/energy/pf";
const char* tJSON = "unique/energy/data";
// --------------------------------------
// WiFi connect
// --------------------------------------
void setup_wifi() {
Serial.print("[WiFi] Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
int retry = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
retry++;
if (retry > 40) {
Serial.println("\n[WiFi] Failed.");
return;
}
}
Serial.println("\n[WiFi] Connected!");
Serial.print("[WiFi] IP: ");
Serial.println(WiFi.localIP());
}
// --------------------------------------
// MQTT reconnect
// --------------------------------------
void reconnect() {
while (!client.connected()) {
Serial.print("[MQTT] Connecting...");
String cid = "ESP32-" + String(random(1000, 9999));
if (client.connect(cid.c_str())) {
Serial.println("OK");
} else {
Serial.print("Fail rc=");
Serial.println(client.state());
delay(2000);
}
}
}
// --------------------------------------
// SEND SMS FUNCTION
// --------------------------------------
void sendSMS() {
Serial.println("SMS FUNCTION CALLED");
WiFiClientSecure secureClient; // FIXED
secureClient.setInsecure();
HTTPClient http;
String apiUrl = "https://www.raspberryme.cloud/send_sms?ID=" + String(templateID);
http.begin(secureClient, apiUrl);
http.addHeader("Authorization", apiKey);
http.addHeader("Content-Type", "application/json");
String payload =
"{\"mobiles\":\"" + String(mobileNumber) +
"\",\"var1\":\"Energy meter\"" +
",\"var2\":\"High Voltage\"}";
Serial.println(payload);
int code = http.POST(payload);
Serial.print("HTTP Response Code: ");
Serial.println(code);
String response = http.getString();
Serial.println(response);
http.end();
}
// --------------------------------------
// SETUP
// --------------------------------------
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0); lcd.print("Energy Monitor");
lcd.setCursor(0, 1); lcd.print("Starting...");
delay(2000);
PZEMSerial.begin(9600);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
}
// --------------------------------------
// LOOP
// --------------------------------------
void loop() {
if (!client.connected()) reconnect();
client.loop();
float V = pzem.voltage();
float I = pzem.current();
float P = pzem.power();
float E = pzem.energy();
float F = pzem.frequency();
float PF = pzem.pf();
// =====================================================
// High Voltage(FIXED)
// =====================================================
// === ZERO CURRENT ALERT ===
if (V > 255) {
if (millis() - lastSMS > smsCooldown) {
Serial.println(" High Voltage Detected");
sendSMS();
lastSMS = millis(); // update timestamp
}
}
if (isnan(V) || V < 10.0) {
Serial.println("Mains appears OFF -> forcing zeros");
I = 0.0;
P = 0.0;
E = 0.0;
F=0.0;
PF=0.00;
// Optionally: publish zeros to MQTT and update LCD here
} else {
// Normal publishing and LCD display
}
Serial.printf("[Data] V: %.1f I: %.3f P: %.1f E: %.3f F: %.1f PF: %.2f\n",
V, I, P, E, F, PF);
// -------- MQTT PUBLISH ----------
client.publish(tV, String(V, 1).c_str(), true);
client.publish(tI, String(I, 3).c_str(), true);
client.publish(tP, String(P, 1).c_str(), true);
client.publish(tE, String(E, 3).c_str(), true);
client.publish(tF, String(F, 1).c_str(), true);
client.publish(tPF, String(PF, 2).c_str(), true);
String json = "{";
json += "\"V\":" + String(V, 1) + ",";
json += "\"I\":" + String(I, 3) + ",";
json += "\"P\":" + String(P, 1) + ",";
json += "\"E\":" + String(E, 3) + ",";
json += "\"F\":" + String(F, 1) + ",";
json += "\"PF\":" + String(PF, 2);
json += "}";
client.publish(tJSON, json.c_str(), true);
// -------- LCD DISPLAY ----------
lcd.clear(); lcd.setCursor(0,0);
lcd.print("Volt:"); lcd.print(V,1); lcd.print("V");
delay(2000);
lcd.clear(); lcd.setCursor(0,0);
lcd.print("Curr:"); lcd.print(I,3); lcd.print("A");
delay(2000);
lcd.clear(); lcd.setCursor(0,0);
lcd.print("Power:"); lcd.print(P,1); lcd.print("W");
delay(2000);
lcd.clear(); lcd.setCursor(0,0);
lcd.print("Energy:"); lcd.print(E,3); lcd.print("kWh");
delay(2000);
lcd.clear(); lcd.setCursor(0,0);
lcd.print("Freq:"); lcd.print(F,1); lcd.print("Hz");
delay(2000);
lcd.clear(); lcd.setCursor(0,0);
lcd.print("PF:"); lcd.print(PF,2);
delay(2000);
}
Retrouvez l’histoire de Raspberry Pi dans cette vidéo :

