Récupération de données d’un compteur Schneider A9MEM2050 via ESP et MQTT

Récupération de données d’un compteur Schneider A9MEM2050 via ESP et MQTT

8 juin 2022 1 Par FlorianT

Bonjour à tous,

Je m’appelle Florian Thiebaut et je suis actuellement en stage de fin d’études au G2Elab de Grenoble. Dans le cadre de ce stage, j’ai pu établir une communication pour transmettre des données à l’aide du protocole MQTT entre un compteur Schneider A9MEM2050 et un serveur MQTT via une Wemos D1 mini.

Aujourd’hui, je vous propose donc un tutoriel sur la mise en place de cette connexion.

I. Logiciels et composants utilisés pour ce dispositif

a. Outils et logiciels

Dans ce projet les logiciels suivants sont utilisés :

  • Arduino : IDE
  • Interface d’affichage pour les données : dans notre cas nous utilisons le logiciel OpenSource Jeedom.

b. Composants

Compteur Schneider A9MEM2050

Wemos d1 mini

Convertisseur RS485 TTL MAX485

II. Branchement du dispositif

Afin de pouvoir récupérer les données du compteur, nous allons utiliser le convertisseur RS485. Nous allons donc devoir le connecter à notre carte Wemos.

On connecte ensuite les bornes A et B du convertisseur (fils noir et rouge qui partent du bornier sur l’image) aux bornes A et B du compteur Schneider (fils noir et rouge).

III. Configuration Jeedom

En ce qui concerne la configuration de Jeedom, vous pouvez aller voir l’article suivant qui lui est consacré:

IV. Code Arduino

Notre code doit remplir plusieurs fonctions :

  • Connexion de la Wemos au réseau Wifi auquel est connecté le serveur(=broker) MQTT.
  • Connexion au serveur MQTT.
  • Récupération des données via le convertisseur RS485 TTL MAX485.
  • Envoi des données sous protocole MQTT au serveur MQTT.

a. Définitions

Pour réaliser ces tâches, nous allons utiliser la librairie « PubSubClient » et la librairie « EspMQTTClient ».

Tout d’abord, on définit les constantes que l’on va utiliser, à savoir l’IP du broker MQTT, les identifiants MQTT et les topics qui correspondent aux données que l’on recueille.

// MQTT
const char* mqtt_server = "XXX.XXX.XXX.XXX";  //IP of the MQTT Broker
const char* voltage_topic = "EB3/voltage";
const char* frequence_topic = "EB3/frequence";
const char* active_power_topic = "EB3/active_power";
const char* current_topic = "EB3/current";
const char* energy_topic = "EB3/energy";
const char* mqtt_username = "XXXX";    //MQTT username
const char* mqtt_password = "xxxxxxxxxx";    //MQTT password
const char* clientID = "client_local";         //MQTT client ID

Chaque topic est défini comme une sous partie de « EB3 », afin d’avoir un affichage plus clair sur la plateforme Jeedom.

On doit également définir les pins de communication associés entre la Wemos et le convertisseur. pour cela on utilise la numérotation fournie dans la documentation technique.

#define MAX485_DE      0    //D3=0
#define MAX485_RE_NEG  2    //D4=2

On peut ensuite déclarer le client MQTT.

// Initialise the WiFi and MQTT Client objects
WiFiClient wifiClient;
// 1883 is the listener port for the Broker
PubSubClient client(mqtt_server, 1883, wifiClient);

b. Fonctions

Tout d’abord on relève les données du compteur et on stocke ces valeurs dans un tableau. Ici, on a l’indice 0 pour la tension, l’indice 1 pour la fréquence, l’indice 2 pour la puissance active et l’indice 3 pour le courant.

float Read_Meter_float(char addr , uint16_t  REG)
{
  float i = 0;
  uint8_t result,j;

  uint16_t data[2];
  uint32_t value = 0;
  node.begin(ID_slave,Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  result = node.readHoldingRegisters(REG,2); ///< Modbus function 0x03 Read Holding Registers
  delay(500);
  if (result == node.ku8MBSuccess) 
  {
    for (j = 0; j < 2; j++)
    {
      data[j] = (node.getResponseBuffer(j));
    }
    value = data[0];
    value = value << 16;
    value = value + data[1];
    i = HexTofloat(value);
    return i;
  } else
  {
    delay(1000);
    return 0;
  }
}

void GET_METER_FLOAT() 
{     // Update read all data
  delay(1000);                            
    for (char i = 0; i < Total_of_Reg_float ; i++)
    {
      DATA_METER_FLOAT [i] = Read_Meter_float(ID_slave, Reg_float_addr[i]);
    } 
}

Cette fonction va aller chercher les valeurs des registres déjà définis pour la tension, la fréquence, la puissance active et le courant. Ces valeurs de registres se trouvent dans la documentation technique du compteur dans la catégorie : communication Modbus. On y voit également que ces données sont de type float, d’où l’utilisation d’un convertisseur héxadécimal-float.

Cependant l’énergie est pré-définie comme étant un entier, c’est pourquoi il faudra adapter ces fonctions pour pouvoir correctement lire cette valeur.

Ci-dessous la documentation technique pour les registres:

Maintenant que l’on a accès aux variables qui nous intéresse, on peut les envoyer au serveur MQTT.

Pour cela il faut d’abord convertir ces variables en string, seul type de variables que peut transmettre le MQTT.

void loop() 
{  
  check_wifi();

  GET_METER_FLOAT();
  GET_METER_INT64();

  //MQTT can only transmit strings
  String voltage = String((float)DATA_METER_FLOAT[0]);
  String frequence = String((float)DATA_METER_FLOAT[1]);
  String active_power = String((float)DATA_METER_FLOAT[2]);
  String current = String((float)DATA_METER_FLOAT[3]);
  String energy = String((float)DATA_METER_INT64[0]);


  // Check if we publish to the MQTT Broker
  if (client.publish(voltage_topic, String(DATA_METER_FLOAT[0]).c_str())){
    Serial.println("Voltage sent!");
    Serial.println(DATA_METER_FLOAT[0]);
  }
  if (client.publish(frequence_topic, String(DATA_METER_FLOAT[1]).c_str())){
    Serial.println(DATA_METER_FLOAT[1]);
  }
  if (client.publish(active_power_topic, String(DATA_METER_FLOAT[2]).c_str())){
    Serial.println(DATA_METER_FLOAT[2]);
  }
  if (client.publish(current_topic, String(DATA_METER_FLOAT[3]).c_str())){
    Serial.println(DATA_METER_FLOAT[3]);
  }
  if (client.publish(energy_topic, String(DATA_METER_INT64[0]).c_str())){
    Serial.println(DATA_METER_INT64[0]);
  }

  delay(1);
}

! Attention !

Les pins RX et TX sont responsables de la communication série entre la carte Wemos et d’autres dispositifs. Lorsque l’on voudra uploader notre code sur notre ESP, il faudra donc débrancher ses fils du convertisseur le temps du téléchargement (clignotement de la LED) du code, pour éviter un conflit entre les différents flux de données.

V. Affichage des données

Comme expliqué précédemment, nous avons utilisé le logiciel Jeedom pour l’affichage de nos données.

Lorsque l’on télécharge notre code pour la première fois sur notre Wemos, il faut indiquer à Jeedom que l’on souhaite inclure un nouveau topic auquel il va souscrire. Pour se faire, on active l’inclusion via l’interface Jeedom.

Une fois l’inclusion activée, notre dossier EB3 apparaitra et on pourra ainsi retrouver les valeurs que l’on souhaite relever directement sur l’interface de l’application.

Vous pouvez maintenant utiliser la méthode habituelle pour historiser vos données.

Je vous souhaite une bonne journée,

Florian