libmodbuspp

Un wrapper C++ pour la librairie libmodbus

libmodbus est une librairie opensource pour envoyer/recevoir données selon le protocole MODBUS. Cette librairie est écrite en C et supporte Communications RTU(série) et TCP(Ethernet).

La librairie libmodbuspp fournit une surcouche C++ pour libmodbus, un wrapper n’ayant pas d’autre dépendance que libmodbus et libstdc++.

Cet article fait suite à celui présentant l’utilisation de MODBUS sur une carte Nano Pi.

Un bon exemple étant toujours meilleur qu’une longue explication, voilà un très exemple simple:


uint16_t values[2]; // array to store the values of the input registers
Master mb (Rtu, "COM1", "19200E1"); // new master on RTU
mb.open(); // open a connection
Slave & slv = mb.addSlave (33); // to the slave at address 33
slv.readInputRegisters (1, values, 2);
cout << values[0] << endl;
cout << values[1] << endl;

Cet exemple lit les registres d’entrée numéro 1 et 2 de l’esclave MODBUS (serveur) à l’adresse 33.

Guide de démarrage rapide

Installation

Le moyen le plus rapide et le plus sûr d’installer libmodbuspp sur Debian, Armbian, Raspbian… est d’utiliser le dépôt APT de piduino.org, voilà comment s’y prendre :

wget -O- http://www.piduino.org/piduino-key.asc | sudo apt-key add -
sudo add-apt-repository 'deb http://apt.piduino.org stretch piduino'
sudo apt update
sudo apt install libmodbuspp-dev libmodbuspp-doc 

Ce dépôt fournit les packages libmodbus pour les architectures i386,amd64, armhf et arm64. Dans les commandes ci-dessus, le dépôt est une distribution Debian Stretch, mais vous pouvez également choisir Ubuntu Trusty, Xenial ou Bionic en remplaçant stretch par trusty, xenial ou bionic.
Il peut être nécessaire d’installer le paquet software-properties-common si la commande add-apt-repository n’est pas disponible.

Pour Raspbian, vous devez faire un peu différent:

wget -O- http://www.piduino.org/piduino-key.asc | sudo apt-key add -
echo 'deb http://raspbian.piduino.org stretch piduino' | sudo tee /etc/apt/sources.list.d/piduino.list
sudo apt update
sudo apt install libmodbuspp-dev libmodbuspp-doc

Le dépôt Raspbian fournit des packages Piduino pour l’architecture armhf uniquement pour Stretch.

Si vous voulez construire à partir de sources, vous pouvez suivre le Wiki.

Exemple

Voici un exemple complet qui peut être compilé sans erreur :

#include <iostream>
#include <string>
#include <modbuspp.h>

using namespace std;
using namespace Modbus;

int main (int argc, char **argv) {
  string port ("/dev/ttyUSB0");

  if (argc > 1) {

    port = argv[1]; // the serial port can be provided as a parameter on the command line.
  }

  Master mb (Rtu, port , "38400E1"); // new master on RTU
  // if you have to handle the DE signal of the line driver with RTS,
  // you should uncomment the lines below...
  // mb.rtu().setRts(RtsDown);
  // mb.rtu().setSerialMode(Rs485);

  Slave slv (mb.addSlave (33)); // SolarPi Pressure meter

  cout << "Reads input registers of slave[" << slv.slave() << "] on " <<
       mb.backend().connection() << " (" << mb.backend().settings() << ")" << endl;

  if (mb.open ()) { // open a connection
    // success, do what you want here
    uint16_t values[2];

    if (slv.readInputRegisters (1, values, 2) == 2) {

      cout << "R0=" << values[0] << endl;
      cout << "R1=" << values[1] << endl;
    }
    else {
      cerr << "Unable to read input registers ! "  << mb.lastError() << endl;
      exit (EXIT_FAILURE);
    }
    mb.close();
  }
  else {
    cerr << "Unable to open MODBUS connection to " << port << " : " << mb.lastError() << endl;
    exit (EXIT_FAILURE);
  }

  return 0;
}

Entrez le texte de ce programme avec votre éditeur de texte préféré et enregistrez le fichier dans main.cpp

Pour construire, vous devez taper la commande:

g++ -o read-input-registers main.cpp $(pkg-config --cflags --libs libmodbuspp)

Vous pouvez ensuite l’exécuter:

./read-input-registers 
R0=9964
R1=10029

Vous trouverez plusieurs exemples dans le dossier /usr/share/doc/modbuspp/examples

Avec Codelite ce sera beaucoup plus facile et amusant car l’installation du paquet libmodbuspp-dev ajoute un modèle de projet modbuspp à Codelite.

Débogage avec Codelite

Pour créer un nouveau programme modbuspp dans Codelite, il faut, une fois votre workspace créé, utiliser le menu Workspace/New Project et sélectionner le modèle Simple Executable (C++ MODBUSPP) :

Documentation

Le paquet libmodbuspp-doc fournit de la documentation.

Les classes fournies par la librairie sont documentées par les pages de man:

  • La page Modbus_Master pour la classe Modbus::Master
  • La page Modbus_Data pour la classe Modbus::Data
  • La page Modbus_RtuLayer pour la classe Modbus::RtuLayer
  • La page Modbus_TcpLayer pour la classe Modbus::TcpLayer
  • La page Modbus_Timeout pour la classe Modbus::Timeout

L’API complète est documentée dans le dossier /usr/share/doc/modbuspp/api-manual/index.html

À propos de Modbus

MODBUS est un protocole de messagerie de la couche application, fournissant Communication maître/esclave entre appareils connectés entre eux par des bus ou des réseaux. Sur le modèle OSI, MODBUS est positionné au niveau 7. MODBUS est destiné à être un protocole de requête/réponse et fournit les services spécifiés par les codes de fonction. Les codes de fonction de MODBUS sont des éléments requête/réponse de MODBUS ou PDU (Unité de données de protocole).