[Tuto] Utiliser le PZEM-004T-100A avec Arduino

Posté sur: mars 15, 2021

Catégories: Arduino

Auteur: Fabien

Tags: tuto , module , energétique , pzem , arduino , nano , 33 , iot , 100A , 004T

[Tuto] Utiliser le PZEM-004T-100A avec Arduino

Ce tutoriel est un exemple d'utilisation du module de compteur énergétique connecté sur un Arduino nano 33 iot pour réaliser de la collecte de mesure énergétique. Nous avons choisi de donner la forme d'une rallonge tout intégré à ce système. Il y aura une prise de raccordement secteur en entrée et une prise murale pour la sortie. L'arduino puisera son alimentation directement sur le 220V.

Choix du matériel

Il nous faudra pour le raccordement au 220V un câble avec fiche CE standard et une prise murale. Pour protéger le tout, nous choisissons de tout mettre dans une boite de dérivation. Il nous faut également un Arduino et son module énergétique. L'alimentation de l'Arduino sera géré par un transformateur 220Vac vers 5Vdc.



Assemblage électrique

Notre assemblage est très simple à mettre en oeuvre, nous fixons la prise sur le couvercle du boitier de dérivation puis raccordons le câble électrique en le faisant passer par un presse étoupe.

Librairies disponibles

Nous avons identifié 2 librairies disponibles sur Github (l'une étant l'évolution de l'autre):

Après plusieurs essais du module avec un Arduino Uno, nous avons choisi d'utiliser la seconde pour sa possibilité de jouer sur les adresses des modules. Ces 2 librairies ont 3 exemples:

  • Lecture de la data du module via un Hardware Serial
  • Lecture de la data du module via un Software Serial
  • Changement de l'adresse du module

Nos premiers essais ont été fait sur un Arduino Uno donc en Software Serial pour pouvoir utiliser le Hardware Serial pour échanger de la data via l'USB. Vous trouverez plus d'information sur les ports Serial hardware et software sur la page dédiée du site Arduino.

Usage de l'Arduino nano 33 iot pour remonter les mesures

Sur la base des exemples des librairies validés, nous avons testé ceux-ci sur un Arduino nano 33 iot. Plusieurs combinaisons ne fonctionnent pas:

  • Le software Serial ne fonctionne pas sur cette carte Arduino (Les cartes avec des microcontrôleurs SAMD21 ne les acceptent pas)
  • Les hardwares Serial de l'Arduino nano 33 iot sont le Serial (utilisé pour l'USB) et le Serial1 (Sur les pin 0 et 1)

L'Arduino nano 33 iot tout comme les autres cartes basées sur un SAMD21 permettent de faire ré-allouer des pins initialement prévues pour d'autres usages vers une utilisation en tant que port Serial. Ce principe est le principe des Sercoms, vous trouverez plus d'informations sur la page suivante.

Nous allons faire le choix d'utiliser le Sercom0, soit les pins 5 (Rx) et 6 (Tx) pour ce port COM. Sur la base de l'exemple "PZEMHardSerial" et les recommandations d'usage de Sercom du lien précédent, nous faisons le code suivant:

#include "Arduino.h"  #include "wiring_private.h"  #include "PZEM004Tv30.h"

Uart mySerial (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);

// Attach the interrupt handler to the SERCOM
void SERCOM0_Handler()
{
mySerial.IrqHandler();
}

/* Hardware Serial3 is only available on certain boards.
* For example the Arduino MEGA 2560
*/
PZEM004Tv30 pzem(&mySerial);

void setup() {
// Reassign pins 5 and 6 to SERCOM alt
pinPeripheral(5, PIO_SERCOM_ALT);
pinPeripheral(6, PIO_SERCOM_ALT);

Serial.begin(115200);
}

void loop() {
float voltage = pzem.voltage();
if(!isnan(voltage)){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}

float current = pzem.current();
if(!isnan(current)){
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}

float power = pzem.power();
if(!isnan(power)){
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}

float energy = pzem.energy();
if(!isnan(energy)){
Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}

float frequency = pzem.frequency();
if(!isnan(frequency)){
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}

float pf = pzem.pf();
if(!isnan(pf)){
Serial.print("PF: "); Serial.println(pf);
} else {
Serial.println("Error reading power factor");
}

Serial.println();
delay(2000);
}

Ce code fait bloquer l'Arduino nano 33 iot. Il disparait de la liste des dispositifs USB et le seul moyen de reprendre la main sur celui-ci est de le mettre en mode DFU par un double appuie rapide sur le bouton Reset.

Après des recherches dans la librairie pour comprendre le problème, nous avons identifié la chose suivante: Le constructeur de l'objet PZEM004Tv30 contient le begin du Serial, or lors de l'utilisation du Sercom il faut définir un état sur les pins utilisées (5 et 6) pour rendre utilisable ce port Série et ceci est fait lors du setup. L'objet PZEM004Tv30 ne peut donc pas être global.

Voici le code modifié pour compenser ce problème:

#include "Arduino.h"  #include "wiring_private.h"  #include "PZEM004Tv30.h"

Uart mySerial (&sercom0, 5, 6, SERCOM_RX_PAD_1, UART_TX_PAD_0);

boolean boot = true;

void SERCOM0_Handler()
{
mySerial.IrqHandler();
}

void setup() {
// Reassign pins 5 and 6 to SERCOM alt
pinPeripheral(5, PIO_SERCOM_ALT);
pinPeripheral(6, PIO_SERCOM_ALT);
Serial.begin(115200);
}

void loop() {
PZEM004Tv30 pzem(&mySerial);
if(boot == true) {
Serial.print("Current address:");
Serial.println(pzem.getAddress());
Serial.println();
boot = false;
} else {

float voltage = pzem.voltage();
if(!isnan(voltage)){
Serial.print("Voltage: "); Serial.print(voltage); Serial.println("V");
} else {
Serial.println("Error reading voltage");
}

float current = pzem.current();
if(!isnan(current)){
Serial.print("Current: "); Serial.print(current); Serial.println("A");
} else {
Serial.println("Error reading current");
}

float power = pzem.power();
if(!isnan(power)){
Serial.print("Power: "); Serial.print(power); Serial.println("W");
} else {
Serial.println("Error reading power");
}

float energy = pzem.energy();
if(!isnan(energy)){
Serial.print("Energy: "); Serial.print(energy,3); Serial.println("kWh");
} else {
Serial.println("Error reading energy");
}

float frequency = pzem.frequency();
if(!isnan(frequency)){
Serial.print("Frequency: "); Serial.print(frequency, 1); Serial.println("Hz");
} else {
Serial.println("Error reading frequency");
}

float pf = pzem.pf();
if(!isnan(pf)){
Serial.print("PF: "); Serial.println(pf);
} else {
Serial.println("Error reading power factor");
}

Serial.println();
delay(2000);
}
}

Assemblage final du projet

laissez un commentaire

Se connecter