Open-Source - Modbus-Stack - Auswahlrichtlinie: Sieben tiefe Vergleiche

kostenlosKostenloses technisches Material

Dieser Inhalt ist direkt lesbar und eignet sich für das Grundlagenlernen und die Suche.

Warum sollten Sie diesen Artikel lesen

Diese Frage wurde tausende Male auf Stack Overflow, control.com, CSDN gestellt - "Welche Open-Source - Modbus-Bibliothek sollte ich verwenden?" Jede Antwort ist ein paar Sätze, niemand hat sie systematisch verglichen. Die chinesische Community ist noch schlechter, die Hälfte der Posts, die sie durchsucht haben, haben vor zehn Jahren Code für NModbus4 gepostet, und sie wissen nicht einmal, dass das NModbus-Main - Warehouse auf 3.0.x migriert ist.

Ich habe drei Tage damit verbracht, das Lager für diese sieben Protokollstacks zu durchsuchen, die kleinsten Exemplare jedes einzelnen auszuführen und den Wartungsstatus zu überprüfen. Unten ist das Ergebnis. Wenn Sie es eilig haben, springen Sie direkt zu dem Abschnitt "Empfohlene Pfade für Anfänger", wählen Sie die Bibliothek, die Ihrer Plattform entspricht und beginnen.

Gesamtübersicht Vergleichstabelle

ProtokollstackSpracheLizenzAnzahl der SterneWartungsstatusMasterSlaveRTUTCPFür wen geeignet
FreeModbusCBSD~ 1.5kLow ActivePay✅✅✅STM32 Bare Metal / RTOS
libmodbusCLGPL v2.1 +~ 3.5kAktiv✅✅✅✅Linux-Computer / Gateway
pymodbusPythonBSD~ 2.2kSehr aktiv✅✅✅✅Host / Test-Skript
NModbusC #MIT~ 700Aktive✅✅✅✅. NET / WinForm Host
jamodJavaApache 2.0~ 300Stagnation✅✅✅✅Java Legacy System
modbus-tkPythonLGPL~ 500Low Active✅✅✅✅Rapid Prototyping
QtModbusC + +LGPL/GPLQt Built-inActive✅✅❌✅Qt Cross-Plattform - App

Die Star-Zahl ist eine Zahl, die ich im Juni 2026 erfasst habe, ungefähr in der Größenordnung, die genauen Zahlen, die Sie auf GitHub sehen können.

FreeModbus - Standard-Antwort für Embedded Bare Metal

Git Hub :https://github.com/cwalter-at/freemodbus

FreeModbus wurde von Christian Walter geschrieben, einem österreichischen Embedded-Ingenieur. Das Ding ist in der STM32 - Kreise gleichbedeutend mit ext4 im Linux-Kernel - man kann nichts anderes verwenden, aber es ist am wenigsten fehlerfrei.

* * Codevolumen * *: ca. 6 - 12 KB ROM, je nachdem, welche Funktionscodes und Übertragungsmodus Sie aktivieren. Die RAM-Overhead kostet mehrere hundert Bytes, hauptsächlich die Datenpuffer und Ereigniswarteschlüssen. Ein Cortex-M0 kann im Grunde läuft.

* * Funktionscode-Unterstützung * *: 03 (Lese-Halt - Register), 04 (Lese-Eingangs - Register), 06 (Einzel-Register - Schreiben), 16 (Schreiben mehrerer Register), 01 (Lese-Spule), 02 (Lese-diskreter Eingang), 05 (Einzel-Spule - Schreiben), 15 (Schreiben mehrerer Spule). Es gibt auch 17 (Berichte von der Station-ID). Beachten Sie, dass es keine 22 (Maske Schreibregister) und 23 (Lesen und Schreiben mehrerer Register) gibt, die Sie selbst hinzufügen müssen.

* * Übertragungsmodus * *: RTU, ASCII, TCP werden unterstützt, durch kompilierte Makroschalter.

* * Master / Slave Station * *: Dies ist der Ort, an dem FreeModbus am häufigsten missverstanden wird. Das offizielle Lager ist nur Open Source für Slave-Codes, die Master-Stationen werden bezahlt. Es gibt eine Reihe von Community-Magic - Modifikationen auf GitHub, die Master-Funktionen hinzugefügt haben, wie z. B. FreeModbus_Slave-Master - RTT-STM32 von armink, Open-Source, gute Qualität, aber nicht offizielle Wartung. Beachten Sie bei der Verwendung dieser Versionen von Drittanbietern: Die Zeitüberschreitungs - und Wiederversuchlogik ist sehr grob implementiert, nicht direkt in die Produktion.

* * Codebeispiel * * - - Initialisierung eines RTU-Slaven auf STM32, Adresse 1, Baudrate 9600, keine Überprüfung:

#include "mb.h"

int main(void) {
    eMBInit(MB_RTU, 0x01, 0, 9600, MB_PAR_NONE);
    eMBEnable();
    while (1) {
        eMBPoll();
    }
}

Nur diese drei Zeilen. " eMBPoll () `läuft die Zustandsmaschine des gesamten Protokollstacks, nicht blockiert, und Sie müssen es mit einem 3,5 T-Timeout - Signal in einem Timerinterrupt speisen. Dieser 3,5 T-Timer ist die Nummer eins der FreeModbus-Transportation, die im Folgenden beschrieben wird.

* * Bekannte Probleme * *: - Das offizielle Repository-Update ist sehr langsam, die letzte große Version v1.6 ist seit einigen Jahren nicht mehr bewegt, die Bug-Fix ist nicht behoben, um das Schicksal zu sehen. - Unterstützt nur einen einzelnen seriellen Port, eine Protokollstack-Instanz kann nur einen UART binden, mehrere serielle Port-Szenarien müssen den Code ändern - Der TCP-Modus verwendet lwIP-raw - API, nicht Socket, was bedeutet, dass es unter FreeRTOS + LWIP funktioniert, aber unter Linux kann der TCP-Modus nicht ausgeführt werden. - Keine Gleitkomma-Verarbeitung Hilfsfunktionen, Größe-End - Umwandlung selbst schreiben

* * Dokumentation * *: Nur ein API-Dokument, im HTML-Format, reicht, aber nicht gut. Es gibt viele chinesische Community-Tutorials, CSDN sucht ein paar.

libmodbus - die richtige Wahl für Linux-Computer

Git Hub :https://github.com/stephane/libmodbus

Stéphane Raimbault, Französisch. libmodbus ist eine der bewährtesten Modbus-Bibliotheken, die in der Sprache C geschrieben wurden. 3.5k Star ist nicht weiß.

Das Design dieser Bibliothek ist völlig anders als das von FreeModbus. FreeModbus ist für MCUs mit begrenzten Ressourcen konzipiert, mit Rückruffunktionen und Zustandsmaschinen. libmodbus ist POSIX-Stil, blockiert API, `modbus _ read _ registers ()` Aufruf wartet, bis die Daten zurückgegeben werden oder Zeitüberschreiten. Menschen, die industrielle Computerprogramme schreiben, mögen diesen Stil - einfach und direkt, unabhängig von der Zustandmaschine.

* * Funktionscode-Unterstützung * *: Fast alle. 01/02/03/04/05/06/07/0F/10/11/16/17, unterstützt auch 22 (Maske-Schreiben) und 23 (Multiple-Lesen - Schreiben). Modbus _ set _ float () / modbus _ get _ float () können Fließkommazahlen direkt nach IEEE 754 verarbeiten und unterstützen ABCD / DCBA / BADC / CDAB vier Bytefolge.

* * Übertragungsmodus * *: RTU + TCP vollständig unterstützt. Die gleiche API-Sammlung, `modbus_new_rtu()` erzeugt den seriellen Port-Kontext, `modbus_new_tcp()` erzeugt den TCP-Kontext, und danach ist die Leserschnittstelle genau die gleiche.

* Der TCP-Sklaven verwendet `modbus _ TCP _ listen ()` + `modbus _ TCP _ accept ()` und schreibt eine Routine am Linux-Socket - Server.

* * Codebeispiel * * - Lesen Sie das Hold-Register 0x0000 von Station 1 und gibt einen 16 - Bit-Wert zurück:

#include <modbus.h>
#include <stdio.h>

int main() {
    modbus_t *ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1);
    modbus_set_slave(ctx, 1);
    modbus_connect(ctx);
    uint16_t val;
    modbus_read_registers(ctx, 0, 1, &val);
    printf("Register 0 = %dn", val);
    modbus_close(ctx);
    modbus_free(ctx);
}

* * Bekannte Probleme * *: - Die Semantik von `modbus _ connect()` ist leicht zu treten. Im RTU-Modus wird `open()` geöffnet, während im TCP-Modus `connect()` mit dem Server verbunden ist. Der TCP-Slave - Modus benötigt weder modbus _ connect () noch kann es sein, stattdessen modbus _ TCP _ listen () zu benutzen. Verwirrt, ich weiß nicht, warum. - Der Zeiger wird nach `modbus _ free ()` nicht automatisch leer. Wenn Sie in einer Schleife wiederverknüpfen, zuerst free und dann new, ohne manuell `ctx = NULL`, wird es gelegentlich auf freigegebenen Speicher verweisen, was sich als zufälliger Absturz oder verrückte Wiederverknüpfung manifestiert. Das habe ich verloren. - Die Linie ist unsicher. Ein `modbus _ t *` Kontext kann nicht von zwei Threads gleichzeitig verarbeitet werden, muss selbst gesperrt werden. - Unter Windows ist der Name „\.". COM10 `Dieses Format, Linux ist` / dev / ttyUSB0`, Plattformübergreifende Kompilierung zu beachten

* * Dokument ation * * : Of fizi elle Web se itelibmodbus.orgEs gibt eine Reihe von Dokument ationen im Stil der Manu al page , plus die Online - Ver sion von mk do cs . Klar , aber keine Beisp iele für Projek te , nur die unter dem Ver zeich nis ` t ests /` .

pymodbus - Der faktische Standard für Python-Ökologie

Git Hub :https://github.com/pymodbus-dev/pymodbus

Pymodbus ist derzeit eine der aktivsten Modbus-Bibliotheken, die nicht gepflegt werden. Nachdem die pymodbus-dev - Organisation die Übernahme übernahm, wurde die asynchrone Architektur von 3.x umgeschrieben, unterstützte asyncio und wurde weiterhin veröffentlicht. Die neueste stabile Version für Ende 2024 ist v3.6.x.

* * Funktionscode * *: Vollständige Unterstützung. 01/02/03/04/05/06/15/16/22/23, auch 43 (Lesegerät Identifikation)

* * Übertragungsmodus * *: RTU + TCP + TLS Die TLS-Unterstützung wurde in pymodbus 3.x hinzugefügt, und es kann direkt mit modbus + tls:// ausgeführt werden. Das ASCII-Modus wird ebenfalls unterstützt, aber in 3.x als veraltet markiert.

* Master / Slave * *: Beide werden unterstützt und sowohl synchron als auch asynchron APIs werden unterstützt. Die Slave-Station kann einen vollständigen Simulator ausführen - `pymodbus.simulator` kann ein virtuelles Gerät mit mehreren Registers aus der JSON-Konfigurationsdatei starten, das für die Entwicklung des Host-Computers sehr nützlich ist.

* Codebeispiel * -

from pymodbus.client import ModbusSerialClient

client = ModbusSerialClient(port="/dev/ttyUSB0", baudrate=9600)
client.connect()
rr = client.read_holding_registers(address=0, count=1, slave=1)
print(rr.registers[0])
client.close()

Die asynchrone Version ist ein wenig mehr Zeilen und verwendet den `async with` Kontextmanager, der mit asyncio ausgeführt wird.

* Bekannte Probleme * *: - Die API von 2.x auf 3.x hat sich enorm geändert. ` pymodbus. client. sync. ModbusSerialClient wurde zu pymodbus. client. ModbusSerialClient, und der Rückgabewert read _ holding _ registers wurde von ReadHoldingRegistersResponse zu ModbusResponse. Wenn Sie den Beispielcode `from pymodbus. client. sync import ...` im Internet suchen, Das ist ja auch 2x, nicht einfach. - Synchroner und asynchroner Modus können nicht vermischt werden. Wenn eine asynchronische Event-Loop bereits im gleichen Prozess ausgeführt wurde, blockiert der Synchronisierungsclient die Ereignis-Loop und verursacht einen Timeout. - Im RTU-Modus ist die Konfiguration des seriellen Port-Timeout empfindlich. Der Standard-Timeout von 3 Sekunden reicht für geringe Geräte (4800 bps) möglicherweise nicht aus und muss auf 5 - 10 Sekunden selbst eingestellt werden. - Installieren Sie pip mit `pip install pymodbus`, nicht mit `pymodbus3` oder `pymodbus2`. Installieren Sie nicht falsch

* * Dokumentation * *: Die vollständige Dokumentation befindet sich unter readthedocs und Dutzende von Beispielscripts im Verzeichnis `examples /`. Es gibt keine chinesischen Dokumente, aber die englische Sprache ist sehr klar.

NModbus - die einzige ernsthafte Wahl für die. NET-Plattform

Git Hub :https://github.com/NModbus/NModbus

Die Geschichte von NModbus ist ein bisschen rund. Das erste NModbus war ein Projekt auf Google Code (ja, das ist Google Code), das später auf GitHub als NModbus4 migriert wurde, und dann auch NModbus4 eingestellt wurde. NModbus / NModbus ist der Nachfolger von NModbus4, von rquackenbush verwaltet, aktiv in Entwicklung, mit dem Paketnamen `NModbus`, neueste Version 3.0.x, Unterstützung für. NET 6 +.

* * Funktionscode * *: 01/02/03/04/05/06/15/16 Vollunterstützung. 22 und 23 erfordern eine benutzerdefinierte Funktionscode-Verarbeitung.

* * Übertragungsmodus * *: RTU, ASCII, TCP, UDP vollständig unterstützt. Serieller Anschluss unterstützt Windows / Linux über das Paket `NModbus.Serial`.

* Slave-Stationen unterstützen benutzerdefinierte Datenspeicher und können Register in Speicher, Datenbanken und sogar SPS zugeordnet werden.

* * Codebeispiel * * - - - TCP Masterstation liest ein Register:

using NModbus;

var client = new TcpClient("192.168.1.100", 502);
var factory = new ModbusFactory();
var master = factory.CreateMaster(client);
ushort[] result = master.ReadHoldingRegisters(1, 0, 1);
Console.WriteLine(result[0]);

* * Bekannte Probleme * *: - Support für serielle Ports ist abhängig von System.IO.Ports, zusätzliche Konfigurationsrechte unter Linux erforderlich - `SlaveDataStore` ist unter Multithreading nicht threadsicher und muss beim Lese - und Schreiben mit hoher Gleichzeitigkeit selbst gesperrt werden. - Die asynchrone API (`ReadHoldingRegistersAsync`) gibt `Task` zurück, aber die zugrunde liegenden E / A sind tatsächlich synchron, es gibt keine asynchronen E / A.

* * Dokumentation * *: README genügt, das Verzeichnis `Samples /` enthält mehrere Beispiele. Das ist vor allem auf Stack Overflow basiert.

jamod - "Vorfahren" der Java - Ökosysteme, aber ich empfehle Ihnen, nicht zu verwenden

Source For ge :https://sourceforge.net/projects/jamod/ Git Hub (Open HA B - F ork):https://github.com/openhab/jamod

jamod wurde von Dieter Wimberger im Jahr 2002 geschrieben, und er arbeitet länger als viele der Ingenieure hier. Das letzte substanzielle Update war 2010 und seitdem ist es weitgehend nicht mehr. Die openHAB-Community hat eine Fork-Version mit mehreren Bugs für sich selbst behoben, aber diese Fork ist nur passiv gehalten.

Wenn Sie gerade ein neues Java-Projekt mit Modbus eröffnen möchten, überspringen Sie einfach jamod und schauen Sie sich j2mod an (GitHub: steveohara / j2mod). j2mod ist eine umgeschriebene Version von jamod, Apache 2.0 lizenziert, Java 8 +, immer noch in Aktualisierung (letzte Übermittlung im Juli 2024), RTU + TCP vollständig unterstützt, sowohl Master als auch Slave.

Aber da dieser Artikel Jamod abdecken soll, schreibe ich es trotzdem. Unterstützte Funktionscodes von jamod: 01/02/03/04/05/06/15/16.Übertragungsmodus: RTU + ASCII + TCP. Die serielle Kommunikation hängt von `javax.comm` ab (die alte API, das JDK ist nicht mehr verfügbar), die Alternative ist RXTX oder jSerialComm.

Beispiel Code:

import net.wimpi.modbus.Modbus;
import net.wimpi.modbus.io.ModbusTCPTransaction;
import net.wimpi.modbus.msg.ReadInputRegistersRequest;
import net.wimpi.modbus.msg.ReadInputRegistersResponse;
import net.wimpi.modbus.net.TCPMasterConnection;
import java.net.InetAddress;

TCPMasterConnection conn = new TCPMasterConnection(
    InetAddress.getByName("192.168.1.100"));
conn.connect();
ReadInputRegistersRequest req = new ReadInputRegistersRequest(0, 1);
ModbusTCPTransaction trans = new ModbusTCPTransaction(conn);
trans.setRequest(req);
trans.execute();
ReadInputRegistersResponse res = (ReadInputRegistersResponse) trans.getResponse();
System.out.println(res.getRegisterValue(0));
conn.close();

Der Begriff „bekanntes Problem" ist für Jamod zu leicht, denn es ist ein Problem an sich. Aber wenn Sie ein altes System aus dem Jahr 2012 pflegen und es verwenden müssen, ist die openHAB-Fork viel besser als das Original.

modbus-tk - ein guter Helfer für schnelle Prototypen

Git Hub :https://github.com/ljean/modbus-tk

Der Franzose Luc Jean hat das Wort „tk" im Namen für TestKit geschrieben - es ist sehr klar, dass es sich um Testwerkzeuge handelt. Nicht für die Produktionsumgebung. Viele Leute haben es tatsächlich hergestellt, weil es wirklich einfach ist.

* * Funktionscode * *: 01/02/03/04/05/06/15/16. 22 / 23 nicht unterstützt.

* * Übertragungsmodus * *: RTU + TCP. ASCII ist nicht unterstützt.

* Slaves können bequem mit `add _ slave` + `add _ block` ein simuliertes Gerät erstellen. Eingebaut ist ein Hook-Funktionsmechanismus, der benutzerdefinierte Logik einfügt, wenn Sie eine Lese - und Schreibanforderung erhalten - das ist ein cleveres Design, das Sie beim Schreiben von Testscripts direkt in den Hook einfügen können.

* * Codebeispiel * * - - RTU Master-Lesenregister:

import serial
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu

master = modbus_rtu.RtuMaster(
    serial.Serial(port="/dev/ttyUSB0", baudrate=9600))
val = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 1)
print(val[0])

* * Bekannte Probleme * *: - Letztes Update um 2020, Bugfix hängt im Grunde von Community PR ab. Kompatibilitätsprobleme mit Python 3.12 können auftreten - Keine asynchrone Unterstützung, alle Operationen sind synchron blockiert. - Es gibt keine eingebaute Hilfe für Fließkommazahlen, du musst `struct.pack/unpack` selbst benutzen. - Das Timeout-Verhalten der Master-Methode `execute()` ist nicht sehr kontrollierbar, die unteren Abhängigkeit von einem Pyserial-Timeout, kann eine nicht reagierende Slave-Station lange stecken.

* * Dokumentation * *: `examples/` ist ein paar Beispiele im Verzeichnis, die das ganze Dokument sind. Der Code ist klein und dauert nur 10 Minuten.

QtModbus - Native Schema für Qt-Entwickler

Dies ist keine „Bibliothek", sondern Teil des offiziellen Qt-Moduls „qtserialbus". Qt 5.8 wurde eingeführt und ist jetzt ein Standardmodul für Qt6.

Da es sich um Qt handelt, ist das API-Design vollständig im Qt-Stil: Signal-Slot, Ereignis-Schleife, QModbusReply. Natürliche Plattformübergreifende Unterstützung - dasselbe Code läuft unter Windows, Linux, macOS und Embedded Linux (Boot2Qt).

* * Funktionscode * *: Unterstützt alle Standardtypen über die Aufzählung `QModbusDataUnit:: RegisterType`: Coils, DiscreteInputs, InputRegisters, HoldingRegisters. Unten kann man den Funktionscode definieren.

* * Übertragungsmodus * *: Nur TCP (`QModbusTcpClient` / `QModbusTcpServer`). * * Kein RTU * * Dies ist eine wichtige Einschränkung - Qt offiziell hat keine integrierte Modbus-RTU - Unterstützung, und Sie müssen RTU-Frame - Resolutionen mit `QSerialPort` selbst in der Anwendungsebene schreiben oder eine Implementierung von Drittanbietern suchen. Einige Entwickler verwenden `QModbusRtuSerialMaster` (ein Gemeinschaftsprojekt), um diese Lücke zu füllen.

* Master / Slave Station *: Alle unterstützt. TCP-Slaven können über `QModbusTcpServer` implementiert werden, um die Daten in die Registrierung von `QModbusServer` anzupassen.

* * Codebeispiel * * - - - TCP-Client liest ein Register:

#include <QModbusTcpClient>
#include <QModbusDataUnit>

auto client = new QModbusTcpClient(this);
client->setConnectionParameter(
    QModbusDevice::NetworkAddressParameter, "192.168.1.100");
client->setConnectionParameter(
    QModbusDevice::NetworkPortParameter, 502);
client->connectDevice();

QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 0, 1);
auto *reply = client->sendReadRequest(unit, 1);
connect(reply, &QModbusReply::finished, this, [reply]() {
    qDebug() << reply->result().values().at(0);
});

Asynchron, verbinden Ergebnisse mit Signal-Slot. Beachten Sie, dass der von `sendReadRequest` zurückgegebene `QModbusReply *` Lebenszyklus von Qt verwaltet wird, nicht manuell löschen.

* * Bekannt * *: - Keine RTU, das ist die größte. Sie haben richtig gelesen, das offizielle Modbus-Modul von Qt hat keine RTU - Die Verbindung wird nicht automatisch wiederverbindet, wenn sie getrennt wird, Sie müssen die Logik für die Wiederverbindung selbst in das `stateChanged` - Signal schreiben. - Die Anzahl der TCP-Verbindungen für `QModbusTcpServer` ist maximal begrenzt und ist standardmäßig 1. SetMaxClients () ändern - Lizenzprobleme: Qt ist LGPL / GPL-Doppellizenz, kommerzielle Closed-Source - Projekte benötigen eine Qt Commercial License

* * Dokumentation * *: Offizielle Qt-Dokumentation. Beispielprojekte finden Sie auf der Begrüßungsseite von Qt Creator.

Neue empfehlen den Weg

Nicht verwickeln, wählen Sie nach Ihrem Technikstack:

- ** STM32 Bare Metal / FreeRTOS ** → FreeModbus. Sie haben keine andere Wahl, das ist die Standard-Antwort. Die Transplantation dauert einen halben Tag, schaltet den 3,5 T-Timer einen halben Tag, danach braucht es nicht mehr. - * * Linux-Computer / Gateway (C) * * → libmodbus. Wenn ein Raspberry Pi mit Debian Modbus-Gateway läuft, ist die libmodbus + MQTT-Brücke die klassische Lösung. ` libmodbus `s Sammlung, `mosquitto` auf der Wolke - * * Python Host / Testscript * * → pymodbus. pymodbus. simulator Simulation + pymodbus Client Lesen und Schreiben, ein Skript erledigt das Debugging des Geräts. Mit Pytest können Modbus-Automatisierungstests durchgeführt werden. - * * C # WinForm / WPF-Host * * → NModbus. NuGet ist installiert und der drei Zeilen Code beginnt das Lesen des Registers. Echtzeitkurven mit ScottPlot, der häufigsten Kombination von Technikstacks in der Fabrik - * * Qt Cross-Plattform - Desktop-Anwendung * * → QtModbus. Wenn Ihre Anwendung bereits Qt verwendet, sollten Sie keine zusätzlichen C-Bibliothek - Abhängigkeiten einführen, sondern direkt die offizielle Qt-Lösung verwenden. - * * Java Enterprise System (Neues Projekt) * * → Verwenden Sie Jamod nicht. Mit j2mod (GitHub: steveohara / j2mod), ist es eine moderne Umschreibung von jamod, die API viel klarer ist - * * Schnelle Verifizierung von Ideen * * → modbus-tk. Drei Minuten mit einem Slave-Station - Simulator, überprüfen Sie, ob die Register-Zuordnung richtig ist, und dann schalten Sie auf pymodbus offizielle

klassische Kombination Schema

* * "FreeModbus Slave + pymodbus-Host - Test" * *: Embedded-Gerät läuft FreeModbus als Slave-Station, die Entwicklungsphase mit Python schreiben pymodbus-Skript lesen und schreiben Register für die Funktionsverifizierung. Flexibilität als Modbus Poll - Sie können Datenprüfung, Grenztests und Stresstests in Ihr Skript hinzufügen. Nach dem Umschalten wechseln Sie dann auf einen echten Host (C # oder Qt).

* * "libmodbus-Gateway + pymodbus-Konfigurationswerkzeug" * *: Die industrielle Steuerung läuft libmodbus-Docking Dutzende von Modbus-RTU - Geräten, die Daten sammeln nach der MQTT-Cloud. Der Web-Hintergrund verwendet pymodbus für das Lesen und Schreiben von Geräteparametern - keine Echtzeit erforderlich, die Entwicklungseffizienz von Python überwältigt alles.

* * „QtModbus macht die Schnittstelle + libmodbus macht die Grundlagen" * *: Qt schreibt Cross-Plattform - Desktop SCADA, Mensch-Maschine - Interaktion und Diagramme mit Qt Charts, aber Modbus Kommunikation nicht direkt mit QtModbus (da es keine RTU gibt), sondern über libmodbus C-API die Grundlagenerfassung, Qt ist nur für die Anzeige verantwortlich. Diese Kombination ist üblich in Betriebsüberwachungssystem.

Die Fluchtliste

* * Erste Pit: 3,5 T Timer von FreeModbus * *

Das Modbus-RTU - Protokoll schreibt mindestens 3,5 Zeichen Zeit zwischen Frames vor. Bei einer Baudrate von 9600 beträgt ein Zeichen etwa 1ms, 3.5T ≈ 3.5ms. Viele Menschen setzen den Timer direkt auf 3,5 ms Zyklus-Interruption. Irrtum. Der 3.5T-Timer von FreeModbus wird verwendet: Der Timer wird bei jedem Empfang eines Bytes zurückgesetzt, und wenn der Timer überflutet wird (es bedeutet, dass es keine neuen Bytes innerhalb von 3.5T gibt), wird ein Frame als beendet angesehen. Daher sollte der Timer auf einen einmaligen Modus eingestellt werden, nicht auf einen zyklischen Modus. Wählen Sie `vMBPortTimersEnable()` in einem Interrupt, das das Bytes empfängt, um den Timer neu zu starten.

Bei unterschiedlichen Baud-Raten entspricht die Zeit von 3,5 T: 9600bps → ~ 3.65ms, 19200bps → ~ 1.83ms, 115200bps → ~ 304 μ s. Bei 115200 3,5 T ist es nur etwa 300 Mikrosekunden, wenn Ihr Timer die minimale Partikelgröße von 1 ms ist, kann die Kalibrierung nicht so fein sein, wird die Framesintervallerkennung fehlerhaft sein. Zu diesem Zeitpunkt wird entweder die Baudrate auf 38.400 reduziert oder der High-Genauigkeit - Modus des Hardware-Timer verwendet.

* * Zweiter Pit: Connect vs new _ TCP vs listen Semantik von libmodbus * *

Mod bus _ new _ t c p ()192.168.1.100", 50 2) " Kon text er stellt , aber noch nicht verb unden . ` mod bus _ connect (ct x) ` Ö ff net den seri ellen Port im R TU - M odus und verbind et den Server im TCP - M aster - Mod us . Im TCP - S kla ven mod us wird nicht ` mod bus _ connect () ` ges etzt , sondern ` mod bus _ TCP _ listen (ct x , 1) ` + ` mod bus _ TCP _ accept (ct x , & so cket) ` .

Der häufigste Fehler: Wenn man beim Schreiben von TCP-Slaven `modbus _ connect()` verwendet, dann stellt man fest, dass man keine Anfrage vom Master empfängt. Denn „connect ()" bedeutet, sich mit jemandem zu verbinden, nicht darauf zu warten, dass jemand dich verbindet.

Ein weiterer Pit: Der `ctx` - Zeiger ist nach `modbus _ free (ctx)` noch da. Wenn Sie die Verbindung in einer Schleife wiederherstellen möchten (z.B. wenn das Netzwerk unterbrochen ist und wiederhergestellt wird), müssen Sie zuerst `ctx = NULL` und dann `modbus _ new _ tcp ()` verwenden, sonst kann es möglich sein, auf freigegebenen Speicher zuzugreifen. Wireshark-Paket - Grab sieht, dass TCP SYN zehntausendmal verrückt nachgeschickt wird - das ist `modbus _ connect ()`, der auf einen wilden Zeiger zugreifen wird.

* * Dritte Grube: pymodbus Synchron vs. Asynchron Mixing * *

pymodbus 3.x hat zwei Client-APIs: synchronisierte `ModbusSerialClient` / `ModbusTcpClient` und asynchrone `AsyncModbusSerialClient` / `AsyncModbusTcpClient`.

Wenn Sie einen Synchronisierungsclient in einem Prozess verwenden, der bereits eine asynchrone Ereignis-Schleife hat, blockiert die zugrunde liegende Socket-E / A die Ereignis-Schleife und führt dazu, dass alle asynchronen Aufgaben angehalten werden. Umgekehrt wird bei asynchronen Clients in reinen synchronen Skripten die `wait` - Syntax Fehlermeldungen geben.

Die Regel ist einfach: entweder voll synchron oder voll asynchron. Für Testskripte reicht in der Regel eine Synchronisierung aus. Wenn ein Prozess mehrere Dutzende Geräte gleichzeitig verbinden möchte, muss er den asynchronen Modus verwenden, da sonst ein Gerät die Zeit überschreitet und die anderen 49 zusammenzieht.

* * Vierter Pit: Byte-Sequenz - Problem - nicht der Topf der Bibliothek, aber jedes Mal ein Pit * *

Das Modbus-Protokoll selbst definiert nur das Übertragungsformat für 16 - Bit-Registers - Big-Endian, wobei die hohen Bytes vorkommen. Aber wenn Sie eine 32 - Bit-Fließkomma - Zahl mit zwei Registeren übergeben, sagt das Protokoll nicht, wer zuvor ist und wer danach ist. Die Behandlung unterscheidet sich von Hersteller zu Hersteller:

- Schneider PLC verwendet ein großes Double-End - Wort (ABCD): Register N speichert 16 Bits hoch, N + 1 speichert 16 Bits niedrig - Siemens S7 - 1200 mit Byte-Switched - Format (CDAB oder BADC) - Einige inländische Geräte verwenden reine Kleinteile (DCBA)

libmodbus bietet `modbus _ set _ float ()` und vier Byte-Sequenz - Konstanten, pymodbus hat `BinaryPayloadDecoder`, um die Byte-Sequenz anzugeben, FreeModbus hat nichts - selbst mit `union` oder `memcpy` buchstabiert.

Die Lektion des Blutes: Zwei Tage später stellte ich fest, dass die Temperaturmesswerte eine astronomische Zahl waren, und am Ende war die Byteordnung umgekehrt. Prüfen Sie zunächst, ob im Handbuch des anderen Geräts ein Float-Format geschrieben ist. Wenn nicht geschrieben, lesen Sie zwei Register selbst buchstabieren, um die vier Arten von Anordnung, immer eine ist richtig.

* * Fünfte Grube: Grube mit der Rundfunkadresse 0 * *

Modbus legt fest, dass die Adresse 0 die Broadcast-Adresse ist, die Master-Station sendet die Broadcast-Frame, alle Slaves-Stationen führen, aber nicht antworten. Aber in der Tat viele von der Station Geräte nicht unterstützen Broadcast, die Adresse 0 in der Vergangenheit direkt nicht reagiert. Es gibt Geräte, die zwar Broadcast unterstützen, aber nicht vollständig unterstützen - 06 (Schreiben eines einzigen Registers) Broadcast kann ausgeführt werden, 16 (Schreiben mehrerer Registers) Broadcast ignoriert werden.

Wenn Sie mit libmodbus _ set _ slave (ctx, 0) übertragen, erwarten Sie keine Antwort. modbus _ read _ registers () `Das Verhalten im Broadcast-Modus ist undefiniert.

Schnelle Entscheidungen zur Auswahl

Wenn Sie nicht mehr tausende von Wörtern sehen möchten, gibt es hier einen Entscheidungsbaum:

1. Zielplattform ist MCU Bare Metal → FreeModbus 2. Die Zielplattform ist Linux → libmodbus 3. Sie verwenden Python → pymodbus 4. Sie verwenden C # /. NET → NModbus 5. Sie verwenden Qt → QtModbus (TCP-Szenario) oder libmodbus (RTU-Szenario). 6. J2mod, nicht mit Jamod. 7. Sie müssen nur einen schnellen Test → modbus-tk machen, um pymodbus zu überprüfen

Alle Bibliotheken habe ich das minimale ausführbare Beispiel gepostet, kopieren und einfügen ändern Sie die Geräte-Adresse kann laufen. Wenn die Kommunikation nicht funktioniert, nehmen Sie zuerst Modbus Poll oder pymodbus eine reine Software-Loopback, um die Hardware-Links zu bestätigen, dass es kein Problem ist, und dann den Fehler des Protokollstacks zu vermuten.

Probleme kommen .modbus.cnForum ges prochen .

Sollte man diese Informationen für ein echtes Projekt verwenden?

Gehen Sie zum Tool Center, um Nachrichten zu analysieren, CRC-Prüfungen und Geräte-Debugging zu erledigen, oder senden Sie Anforderungen für Auswahl - und Zugangsvorschläge.

Ingenieur Mitglied

Verwandeln Sie diesen Artikel in ein umsetzbares Debuggermaterial

Erweiterte Nachrichtenanalyse, Paket-Downloads, Codebeispiele, Engineering-Szenarien und Priority-Technischer Support sind für die Real-Projekt - Bereitstellung möglich.

Unbegrenzte Werkzeuge
Datenpaket und Codepaket
Vollständige Engineering Case-Basis
Vorrangiger Zugang zum technischen Support

Antwort veröffentlichen

Ihre E-Mail - Adresse wird nicht öffentlich gemacht. Erforderliche Elemente wurden verwendet * markiert.