uModbus | Modbus RTU Slave für Microcontroller

Letztes Jahr gab es eine kleine Herausforderung bei der Heimautomatisierung. Wie verbinde ich möglichst günstig einen Mikrocontroller mit meinem Server? Die Hardware war schon vorhanden und sollte nur erweitert werden.

Eine UART Schnittstelle gab es am Mikrocontroller. Daher entschied ich mich für eine simple Modbus RTU Kommunikation. Es musste ein Slave implementiert werden. Ich benötigte nur eine einzige Funktion „Read Holding Registers“. Also habe ich erstmal nur diese implementiert. Dies lief nun ca. 6 Monate ohne Störungen durch.

Ich habe nun die letzten Tage noch weiteren Funktionen implementiert und meinen Code auf Github gestellt. Link ist unten zu finden. Außerdem eine kurze Anleitung wie der Slave für eigene Projekte eingebunden werden kann.


uModbus Slave | Einbindung in eigene Projekte

Binde einfach die 4 Dateien modbusConf.h, modbusSlave.h, modbusSlave.c und modbusio.c in dein Projekt ein.

Folgende Function Codes wurden umplementiert:

  • 0x01 Read Coils
  • 0x02 Read Discrete Inputs
  • 0x03 Read Holding Registers
  • 0x04 Read Input Registers
  • 0x05 Write Single Coil
  • 0x06 Write Single Registers
  • 0x0F Write Multiple Coils
  • 0x10 Write Multiple Holding Registers

Konfiguration

Die Konfiguration wird in modbusConf.h gemacht.

  • BUFFERLENGTH – Größe des Send und Receive Buffers. Modbus Spezifikation Max. 256.
  • MAX_DISCRETE_INPUTS – Maximale Anzahl an Discrete Inputs
  • MAX_COILS – Maximale Anzahl an Coils
  • MAX_INPUT_REGISTERS – Maximale Anzahl an Input Registers
  • MAX_HOLDING_REGISTERS – Maximale Anzahl an Holding Registers

Wenn die Anzahl an Daten 0 ist werden die dazugehörigen Funktionen nicht kompiliert und bei einer Anfrage wird ein „Illegal Function Code“ zurück gesendet.

Einbindung

Binde die modbusSlave.h in dein Projekt ein. Außerdem musst du folgende Variablen erstellen.

  • mbDataMapping modbusData – hier stehen deine Daten drin. Inputs / Coils / Input Registers und Holding Registers
  • mbComm modbusComm – dies wird zur Kommunikation benutzt. Send/Receive Buffer usw.

Im Programm muss dann nur noch zyklisch modbusSlaveCyclic(&modbusComm ,&modbusData) aufgerufen werden.

Anpassung an die Hardware

Die Anpassung an die entsprechende Hardware muss in modbusio.c vorgenommen werden.

Rufe receiveModbusByte(&modbusComm, — emfpangenes Byte–) für jedes empfangene Byte auf und übergeben das entsprechende Byte

In MBsendMessage() muss eine Funktion rein an die der SendBuffer und die Länge übergeben werden kann.

MBcheckTimer() muss eine 1 zurückgeben wenn ein ganzer Frame empfangen werden. Laut Spezifikation ist eine Übertragung nach 3,5 Zeichen nach dem letzten Zeichen beendet.

MBTimer() wurde hier genutzt um dynamisch diese 3,5 Zeichen zu gewährleisten. Wird im Beispiel mit 1ms aufgerufen im Systemtimer aufgerufen.

Links