MODBUS IPTCP Server

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
PIC18F2550
Beiträge: 112
Registriert: 29.04.2024 09:10
Computerausstattung: Server HP Proliant G7
PC AMD FX(tm)-9590, 64Gb Ram, 2x 2TB Raid5 SAS

MODBUS IPTCP Server

Beitrag 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
;------------------------------------------------------------------------------------
Barbarus hic ergo sum, quia non intellegor ulli.
Ein Barbar bin ich hier, da ich von keinem verstanden werde.
ʎɐqǝ ıǝq ɹnʇɐʇsɐʇ ǝuıǝ ɹǝpǝıʍ ǝıu ǝɟnɐʞ ɥɔı ´uuɐɯ ɥo
Benutzeravatar
mk-soft
Beiträge: 3894
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: MODBUS IPTCP Server

Beitrag 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
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
PIC18F2550
Beiträge: 112
Registriert: 29.04.2024 09:10
Computerausstattung: Server HP Proliant G7
PC AMD FX(tm)-9590, 64Gb Ram, 2x 2TB Raid5 SAS

Re: MODBUS IPTCP Server

Beitrag von PIC18F2550 »

Hallo mk-soft,

kein Client ich meine wirklich den Server.

Also vom IPC in ein Steuerung über Modbus
Barbarus hic ergo sum, quia non intellegor ulli.
Ein Barbar bin ich hier, da ich von keinem verstanden werde.
ʎɐqǝ ıǝq ɹnʇɐʇsɐʇ ǝuıǝ ɹǝpǝıʍ ǝıu ǝɟnɐʞ ɥɔı ´uuɐɯ ɥo
SMaag
Beiträge: 188
Registriert: 08.05.2022 12:58

Re: MODBUS IPTCP Server

Beitrag 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
Benutzeravatar
mk-soft
Beiträge: 3894
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: MODBUS IPTCP Server

Beitrag 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.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3894
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: MODBUS IPTCP Server

Beitrag 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?

;)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
PIC18F2550
Beiträge: 112
Registriert: 29.04.2024 09:10
Computerausstattung: Server HP Proliant G7
PC AMD FX(tm)-9590, 64Gb Ram, 2x 2TB Raid5 SAS

Re: MODBUS IPTCP Server

Beitrag 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.
Zuletzt geändert von PIC18F2550 am 16.02.2026 00:07, insgesamt 1-mal geändert.
Barbarus hic ergo sum, quia non intellegor ulli.
Ein Barbar bin ich hier, da ich von keinem verstanden werde.
ʎɐqǝ ıǝq ɹnʇɐʇsɐʇ ǝuıǝ ɹǝpǝıʍ ǝıu ǝɟnɐʞ ɥɔı ´uuɐɯ ɥo
Benutzeravatar
mk-soft
Beiträge: 3894
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: MODBUS IPTCP Server

Beitrag von mk-soft »

Bin noch nicht ganz fertig ...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3894
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: MODBUS IPTCP Server

Beitrag 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)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
PIC18F2550
Beiträge: 112
Registriert: 29.04.2024 09:10
Computerausstattung: Server HP Proliant G7
PC AMD FX(tm)-9590, 64Gb Ram, 2x 2TB Raid5 SAS

Re: MODBUS IPTCP Server

Beitrag 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.
Barbarus hic ergo sum, quia non intellegor ulli.
Ein Barbar bin ich hier, da ich von keinem verstanden werde.
ʎɐqǝ ıǝq ɹnʇɐʇsɐʇ ǝuıǝ ɹǝpǝıʍ ǝıu ǝɟnɐʞ ɥɔı ´uuɐɯ ɥo
Antworten