Raspberry Pi : un tableau de bord pour votre automate Modbus

Bonjour,

L’article précédent montrait la réalisation d’un tableau de bord pour un serveur Modbus TCP un peu particulier avec Node-RED.

Il est bien sûr possible d’appliquer ces mêmes technologies pour créer un tableau de bord quel que soit le serveur Modbus TCP ou l’esclave Modbus RTU.

En l’occurrence, j’ai à ma disposition un automate M340 de SCHNEIDER ELECTRIC, muni d’un coupleur NOC04101, et qui possède, entre autres, la fonctionnalité serveur Modbus TCP et le « flow » ci-après réalise les opérations suivantes :

D’une part, on lit et on affiche dans une jauge la valeur du %MW200.
On trouve donc les nœuds suivants :

  • un nœud qui effectue la lecture du %MW200, fonction FC3, lecture de registres internes,
  • un autre, l’extraction et la mise en forme de la donnée pour la jauge,
  • et la jauge elle-même.

D’autre part, un potentiomètre permet de régler la valeur du %MW210.
Il y a ainsi :

  • le nœud du potentiomètre,
  • et celui réalise l’écriture du %MW210, FC6, écriture d’un registre interne.

Le code de la fonction d’extraction est très simple, la requête FC3 remonte un tableau de données et l’on ne s’intéresse qu’à la première :

var msg_out = {payload:msg.payload[0]};
return msg_out;

Le programme automate se contente de recopier la valeur du %MW210 dans le %MW200 pour les besoins de ma démonstration.

[
    {
        "id": "43e491b2.0b35a8",
        "type": "tab",
        "label": "Modbus",
        "disabled": false,
        "info": ""
    },
    {
        "id": "6ca8bbe5.c10cfc",
        "type": "modbus-read",
        "z": "43e491b2.0b35a8",
        "name": "",
        "topic": "",
        "showStatusActivities": false,
        "showErrors": false,
        "unitid": "",
        "dataType": "HoldingRegister",
        "adr": "200",
        "quantity": "1",
        "rate": "1",
        "rateUnit": "s",
        "delayOnStart": false,
        "startDelayTime": "",
        "server": "43c0221.3e519dc",
        "x": 150,
        "y": 100,
        "wires": [
            [
                "d1453b66.31e57",
                "74b2d916.437c08"
            ],
            []
        ]
    },
    {
        "id": "d1453b66.31e57",
        "type": "debug",
        "z": "43e491b2.0b35a8",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 350,
        "y": 100,
        "wires": []
    },
    {
        "id": "35d64d2a.3a0dfa",
        "type": "ui_gauge",
        "z": "43e491b2.0b35a8",
        "name": "Modbus Gauge",
        "group": "338d75bf.8d7ca2",
        "order": 1,
        "width": 0,
        "height": 0,
        "gtype": "gage",
        "title": "MW200 Gauge",
        "label": "units",
        "format": "{{value}}",
        "min": 0,
        "max": "65535",
        "colors": [
            "#00b500",
            "#e6e600",
            "#ca3838"
        ],
        "seg1": "",
        "seg2": "",
        "x": 500,
        "y": 180,
        "wires": []
    },
    {
        "id": "74b2d916.437c08",
        "type": "function",
        "z": "43e491b2.0b35a8",
        "name": "",
        "func": "var msg_out = {payload:msg.payload[0]};\nreturn msg_out;",
        "outputs": 1,
        "noerr": 0,
        "x": 330,
        "y": 140,
        "wires": [
            [
                "35d64d2a.3a0dfa",
                "de0996f0.d1aef"
            ]
        ]
    },
    {
        "id": "de0996f0.d1aef",
        "type": "debug",
        "z": "43e491b2.0b35a8",
        "name": "",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "x": 490,
        "y": 140,
        "wires": []
    },
    {
        "id": "82cf117c.244d88",
        "type": "modbus-write",
        "z": "43e491b2.0b35a8",
        "name": "",
        "showStatusActivities": false,
        "showErrors": false,
        "unitid": "",
        "dataType": "HoldingRegister",
        "adr": "210",
        "quantity": "1",
        "server": "43c0221.3e519dc",
        "x": 500,
        "y": 320,
        "wires": [
            [],
            []
        ]
    },
    {
        "id": "7fad2d38.5ba184",
        "type": "ui_slider",
        "z": "43e491b2.0b35a8",
        "name": "Modbus MW210 Slider",
        "label": "MW210 Slider",
        "group": "338d75bf.8d7ca2",
        "order": 0,
        "width": 0,
        "height": 0,
        "passthru": true,
        "topic": "",
        "min": 0,
        "max": "65535",
        "step": 1,
        "x": 160,
        "y": 320,
        "wires": [
            [
                "82cf117c.244d88"
            ]
        ]
    },
    {
        "id": "43c0221.3e519dc",
        "type": "modbus-client",
        "z": "43e491b2.0b35a8",
        "name": "M340",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": false,
        "tcpHost": "192.168.1.100",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "unit_id": 1,
        "commandDelay": 1,
        "clientTimeout": 1000,
        "reconnectTimeout": 2000
    },
    {
        "id": "338d75bf.8d7ca2",
        "type": "ui_group",
        "z": "43e491b2.0b35a8",
        "name": "Modbus",
        "tab": "52e4f040.d2daf",
        "order": 1,
        "disp": true,
        "width": "6"
    },
    {
        "id": "52e4f040.d2daf",
        "type": "ui_tab",
        "z": "43e491b2.0b35a8",
        "name": "Modbus",
        "icon": "dashboard",
        "order": 3
    }
]

Le code du flow est disponible ici :
Node-RED-M340-OMB0

Et le tableau de bord résultant ressemble à ceci :

Je suis certain que vous voyez déjà toutes les opportunités qui s’offrent à vous pour un investissement somme toute modique.

Avec un œil sur votre automate depuis n’importe quel navigateur, de votre bureau ou sur votre mobile, vous pourrez vous consacrer à d’autres tâches comme apprendre Ada 😉 :
https://learn.adacore.com/index.html#

Bien sûr, lorsque vous vous serez fait la main sur votre Raspberry Pi, vous pourrez compter sur une version industrialisée de celui ci comme le netPI CORE 3 :
https://www.hilscher.com/products/product-groups/industrial-internet-industry-40/netiot-edge/niot-e-npi3-en/

Cordialement,
Stéphane