Seite 1 von 2

MODBUS IPTCP Server

Verfasst: 11.02.2026 17:28
von PIC18F2550
Hallo,

ich suche ein beispiel wie ich einen Server für dieses protokoll aufbauen Muss damit ich 4Byte Daten abfragen kann.

Ich weis das ich dem server eine Registeradresse z.B. 30865 und einige Paarameter übergeben muss.

Zu sendende Daten

Code: Alles auswählen

     PokeB(*b+0 ,   0) ; H-Transaktionskennung
     PokeB(*b+1 ,   1) ; L-Transaktionskennung 
     PokeB(*b+2 ,   0) ; immer 0
     PokeB(*b+3 ,   0) ; immer 0
     PokeB(*b+4 ,   0) ; H-Länge
     PokeB(*b+5 ,   6) ; L-Länge
     PokeB(*b+6 ,   5) ; Geräteadresse 
     PokeB(*b+7 ,   3) ; Funktionscode 
;     PokeB(*b+8 , $78) ; H-Registeradresse Batterieladezustand
;     PokeB(*b+9 , $7d) ; L-Registeradresse Batterieladezustand
     PokeB(*b+10,   0) ; H-benötigte Register 
     PokeB(*b+11,   1) ; L-benötigte Register 

Code: Alles auswählen

;------------------------------------------------------------------------------------
Ip$ =   "127.0.0.1"
Port = 8123
GerAdr = 200
;------------------------------------------------------------------------------------
If OpenWindow(0, 100, 200, 320, 40, "MOD-BUS Server v0.0 ("+Ip$+":"+Port+")")
  TextGadget(0, 10, 10, 300, 30, "Server Start.")
  *Buffer = AllocateMemory(10000)
  If *Buffer
    If CreateNetworkServer(0, Port, #PB_Network_IPv4 | #PB_Network_TCP, Ip$)
      SetGadgetText(0, "Wait of client.")
      Repeat
        Repeat
          Event = WindowEvent()
          Select Event 
            Case #PB_Event_CloseWindow 
              Quit = 1 
          EndSelect
        Until Event = 0
        
        ServerEvent = NetworkServerEvent()
        If ServerEvent
          ClientID = EventClient()
          Select ServerEvent
            Case #PB_NetworkEvent_Connect  ; New client connected
              SetGadgetText(0, "New client "+ClientID+"connected !")

            Case #PB_NetworkEvent_Disconnect  ; Client has closed the connection
              SetGadgetText(0, "Client "+ClientID+" NetworkEvent_Disconnect.")
          
            Case #PB_NetworkEvent_Data
              SetGadgetText(0, "Client "+ClientID+" NetworkEvent_Data.")
              RequestLength = ReceiveNetworkData(ClientID, *Buffer, 2000)
              
;***************************************************************************************************************************************              
              If PeekB(*Buffer+4) = 0 And PeekB(*Buffer+5) = 6 And PeekB(*Buffer+6) = GerAdr And PeekB(*Buffer+7) = 3 And PeekB(*Buffer+10) = 0 And PeekB(*Buffer+11) = 1
                Reg = PeekB(*Buffer+8)*256+PeekB(*Buffer+9)
                Select reg
                  Case $787d
                    SetGadgetText(0, "Client "+ClientID+" NetworkEvent_Data." + $787d)
    
                EndSelect
              EndIf
          
;***************************************************************************************************************************************              
          EndSelect
        Else
          Delay(20)
        EndIf
        
      Until Quit = 1
      CloseNetworkServer(0)  
    Else
      MessageRequester("Error", "Can't create the server (port in use ?).", 0)
    EndIf
  Else
    MessageRequester("Error", "Memory to smal.", 0)
  EndIf  
Else
  MessageRequester("Error", "Windows not create.", 0)
EndIf

End
;------------------------------------------------------------------------------------

Re: MODBUS IPTCP Server

Verfasst: 11.02.2026 20:23
von mk-soft
Du bist Client wenn du Daten von einem Modbus Gerät werte abfragen möchtest.
Der Standard Port des Modbus Gerät (Server) hat den Port 502

Bei Google z.B ein teil schon mal: https://ipc2u.de/artikel/wissenswertes/ ... eispielen/

Modbus Register sind immer Word (High/Low Byte Notation) umd musst die immer drehen. Um ein 32Bit wert zu lesen sind es immer zwei Register.
Die UnitID kannst du auf 1 setzen. Erst wenn zu ein Gateway von TCP/IP auf RTU verwendest, ist diese Slave ID
Die Register werden immer als Offset angegeben. Also beim ersten Holding-Register 40001 der Offset 0

Grober Anfang ...

Code: Alles auswählen

; Global

Structure udtSend
  TransactionID.w
  ProtocolID.w
  DataLen.w
  UnitID.a
  Functioncode.a
  Register.w
  Count.w
  ByteCount.a
  StructureUnion
    DataByte.b[256]
    DataWord.w[128]
  EndStructureUnion
EndStructure

Structure udtReceive
  TransactionID.w
  ProtocolID.w
  DataLen.w
  UnitID.a
  Functioncode.a
  ByteCount.a
  StructureUnion
    DataByte.b[256]
    DataWord.w[128]
  EndStructureUnion
EndStructure

Procedure bswap16(value.u)
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C
    !return __builtin_bswap16(v_value);
  CompilerElse
    !xor eax,eax
    !mov ax, word [p.v_value]
    !rol ax, 8
    ProcedureReturn
  CompilerEndIf
EndProcedure

Procedure bswap32(value.l)
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C
    !return __builtin_bswap32(v_value);
  CompilerElse
    !mov eax, dword [p.v_value]
    !bswap eax
    ProcedureReturn
  CompilerEndIf
EndProcedure

Procedure.q bswap64(value.q)
  CompilerIf #PB_Compiler_Backend = #PB_Backend_C
    !return __builtin_bswap64(v_value);
  CompilerElse
    CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
      !mov rax, qword [p.v_value]
      !bswap rax
    CompilerElse
      !mov edx, dword [p.v_value]
      !mov eax, dword [p.v_value + 4]
      !bswap edx
      !bswap eax
    CompilerEndIf
    ProcedureReturn
  CompilerEndIf
EndProcedure

; ----

Procedure CreateReadRegisters(UnitID, Function, Register, Count, *buffer.udtSend)
  Protected TransactionID.w
  With *buffer
    TransactionID = bswap16(\TransactionID)
    TransactionID + 1
    If TransactionID = 0
      TransactionID = 1
    EndIf
    \TransactionID = bswap16(TransactionID)
    \ProtocolID = 0
    \DataLen = bswap16(6)
    \UnitID = UnitID
    \Functioncode = Function
    \Register = bswap16(Register)
    \Count = bswap16(Count)
  EndWith
  
  ProcedureReturn 12 ; Return TCP/IP Send Len
  
EndProcedure

Re: MODBUS IPTCP Server

Verfasst: 12.02.2026 12:48
von PIC18F2550
Hallo mk-soft,

kein Client ich meine wirklich den Server.

Also vom IPC in ein Steuerung über Modbus

Re: MODBUS IPTCP Server

Verfasst: 12.02.2026 13:06
von SMaag
Für Modbus habe ich ein angefangenes Projekt. Ist aber nicht ganz fertig.
Weiterhin gibt es im englischen Forum bereits einen Thread zu Modbus

https://www.purebasic.fr/english/viewtopic.php?t=85050

Alternativ: libModus
das ist eine OpenSource Implementation in C. Gibts auf Github o
https://github.com/stephane/libmodbus

Hier der Link zu meiner Version von Modbus. Aber wie gesagt, das müsste man vollenden!
https://github.com/Maagic7/PureBasicFra ... e/main/PLC

Re: MODBUS IPTCP Server

Verfasst: 12.02.2026 16:57
von mk-soft
Da muss ich mal meine Projekte durchsuchen. Habe mal Modbus Gateway geschrieben als Server.

Eigendlich must du (nur) alles anders rum betrachten und deinen Server auf Port 502 (Default) betreiben.

Re: MODBUS IPTCP Server

Verfasst: 15.02.2026 13:29
von mk-soft
Möchtest du noch einen Modbus Server (Slave) schreiben und von wo werden die Daten für den Modbus Server gebildet (Data Sources)
Ich habe mal zur Ablenkung mal einen Simplen Modbus Server angefangen.

Bin aber weiter der Meinung das die Steuerung der Modbus Server ist oder sein sollte.
Ist es eine SPS (PLC), gibt es bei TIA Steuerungen die Möglichkeit einen fertigen Modbus-Server zu programmieren und starten.
Bei S7-300/400 kann man diesen Kaufen oder selber Programmieren (Habe den Fehler gemacht den zu Kaufen und daher später doch selber programmiert)
Bei CodeSys gibt es fertige Libraries für die Steuerungen.

Was läuft auf deinen IPC für Programme um auf die Daten zu kommen?

;)

Re: MODBUS IPTCP Server

Verfasst: 15.02.2026 19:41
von PIC18F2550
Der IPC sammelt über WLAN, USB, CAN-BUS,... mehrere Sensorwerte ein und soll diese über MODBUS Protokoll vorläufig einen Server zur verfügung stellen.

Die Software ist Eigenkonstruktion.

Re: MODBUS IPTCP Server

Verfasst: 15.02.2026 22:49
von mk-soft
Bin noch nicht ganz fertig ...

Re: MODBUS IPTCP Server

Verfasst: 16.02.2026 01:21
von mk-soft
Noch einmal zur klar Stellung ...
Sollst du die gesammelten Daten aktive zur Steuerung schreiben (Also selber Modbus-Client) oder die gesammelten Daten zu lesen bereit stellen (Also selber Modbus-Server)

Re: MODBUS IPTCP Server

Verfasst: 16.02.2026 15:08
von PIC18F2550
Hatt etwas gedauert, aber ich habe heute mir das Problem vor Ort angeschaut.(Stille Post ist nicht immer optimal.)

Code: Alles auswählen

Folgender Zustand:
 - S7-400 über Ethernet an IPC mit WinCC
 - PV-Wechselrichter über Modbus/TCP auch auf IPC
 - Verschiedene Messgeäte gehen auf eine weitere Kleinsteuerung (Hersteller unbekannt)
   die Messwerte können aber über den USB Anschluss abgefragt werden
 
Ziel:
Übertragen der Messwerte von der Kleinsteuerung in WinCC.

Vorhanden:
Software zum Auslesen der Messwerte (kommt auf den IPC).

Datenfluss:
WinCC liest über Modbus/TCP Register aus Software.
Software ließt über USB Register von der Kleinsteuerung aus

Problem
//- nur eine Netzwerkbuchse -> geht das auch mit 127.0.0.1:502 // erledigt
- wie kann ich Modbus und USB so trennen das bei einer Blokade einer die Andere nicht behindert wird?
Anderst gesagt sollen beide unabhängig von einander Arbeiten und über ein *Buffer daten austauschen.