Third party software and hardware support forums. > Modbus

two modbus TCP devices at a time ?

(1/2) > >>

ulihuber:
Hi all,

I have connected my Danfoss VFD (FC302) to Mach3 by Modbus TCP.
Now I want to extend  I/Os with another Modbus TCP device. But I have only one IP address I can configure in the Mach3 Modbus TCP plugin.
Is this really this step backwards from serial Modbus RTU, wher I can configure several Modbus addresses ??
Or have I missed something?

Thanks
Uli

ulihuber:
OK, as no one offered a solution, I did my own thing - the 'TCP Modbus Broker'... >:D

I found out that the Modbus-TCP-packet still  contains the slave address which can be entered in each row of the Modbus plugin.
So I wrote a piece of software which presents itself to Mach3 as a single Modbus-TCP Client and uses the slave address to divert the Modbus telegrams to different IP adresses (or DNS-names)
For portability reasons it is done in Python (ver 3.3.).

It has to be started before Mach3 manually or in a batch unsing the command line

mmb.py [-test] [-quiet] Client-Address_1 ...[Client-Address_n]

-quit       Makes the program just count packets as indication of proper operation.  If it is omitted, full data of all packages is displayed
-test       Allows local testing with TCP echo-clients by diverting to two adresses and using port 503 and 504 instead of modbus port 502.  Not for production usage!

In Mach3 Modbus-TCP-plugin you enter 127.0.0.1 as IP-address if the program runs on the same computer. If you decide to run it on an other computer (i.e. Raspberry or cheap Orange-Pi), use the appropriate address of the device.

Have fun!
Uli


--- Code: ---#UHU Modbus TCP Message Broker
#
# Ermöglicht die Nutzung mehrerer Modbus-TCP-Devices an Mach3, das im Modbus-TCP-Plugin zwar Slave-
# Adressen zur Eingabe anbietet, aber leider nur eine IP-Adresse verwalten kann.
#
# Das Programm stellt  sich gegenüber Mach3 als Modbus-TCP-Device dar und verteilt Modbus-Anfragen
# auf die angegebenen im Netz befindlichen Clients (Netzwerkadressen oder DNS-Namen)
# Dabei entspricht der erste angegebene Client dem Slave #1 aus der Mach3 Modbus TCP Konfiguration.
#
# Voraussetzung: Installierter Python Interpreter >Ver3.0 (frei im Web verfuegbar)
#
# Aufruf mit mmb.py [-test] [-quiet] Client-Adresse_1 [Client-Aderess_n]
#
# -quiet    Statt der Ausgabe der vollständigen Daten der Modbus-Telegramme wird nur ein Zähler
#           dargestellt, an dem man erkennen kann ob Pakete einwandfrei transportiert werden.
#
# -test     baut eine Verbindung zu zwei angebbaren Clients unter den Portadressen 503 und 504 auf.
#           Dies ist nützlich, wen man für Tests statt echter Hardware lokale, virtuelle Modbus-TCP Clients
#           mit dem Tool TCP-Responder.py nutzen möchte
#
# Eingebaute Features:
#   Reconnect bei Ausfall eines (oder aller) Clients
#   Reconnect bei Neustart von Mach3. Leider baut Mach3 eine abgebrochene Verbindung zu einem Modbus-TCP-Client
#       nicht von selbst wieder auf, auch nicht durch RESET. Dies kann ein Problem geben, wenn der Modbus-Broker
#       auf einem anderen Rechner läuft und dieser z.B. neu startet. Dann muss man Mach3 neu starten oder in
#       den Einstellungen für das TCP-Modbus-Plugin 'APPLY' drücken.
#
#
import socket
import sys
import struct

PORT = 502

def printInline(t):
    global pkgCtr
    if quiet:
        pkgCtr +=1
        t = str(pkgCtr)
        delete = "\b" * len(t)
        print("{0}{1}".format(delete, t), end="")
        sys.stdout.flush()
    else:
        print(t)

def connHost(sockH):
    print ("Waiting for Modbus Host on port " + str(PORT))
    connection, NetAddr = sockH.accept()
    print( 'Connected by '+str(NetAddr))
    print()
    return connection

def connSlave(NetAddr,i):
    if not testClients:
        port = PORT
    else:   
        if i == 1:
            port = 503
        else:
            port = 504
       
    print ("\nConnecting slave " + str(i) + " to " + NetAddr + " on port " + str(port))
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connected = False
    while not connected:
        try:
            sock.connect((NetAddr, port))
            sock.settimeout(2)
            print ("Slave " +str(i) + "  connected to " + NetAddr)
            connected = True
        except Exception:
            pass
    return sock

def connectSlaves(Slaves):
    for s in Slaves:
        SlaveArray = Slaves[s]
        i = SlaveArray[0]
        SlaveArray[1] = connSlave(s,i)
        Slaves[s] = SlaveArray
    print("\n------------------------------------------")
    return Slaves

def closeSlaves(Slaves):
    print()
    for s in Slaves:
        SlaveArray = Slaves[s]
        print ("Closing slave " + str(SlaveArray[0]) + " : " + s)
        SlaveArray[1].close()
   
def relay(Slaves):
    HOST = ''               
    sockH = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sockH.bind((HOST, PORT))
    sockH.listen(1)
    Host = connHost(sockH)
   
    Slaves = connectSlaves(Slaves)
       
    print ("Connected to Modbus devices")
    while 1:
        try:
            dataOut = Host.recv(1024)
        except socket.timeout:
            print ('Timeout')
            Host.close()
            Host = connHost(sockH)
            break
        except Exception as e:
            print("Exception")
            print(e)
            break
               
        if not dataOut: break
        printInline('%15s %30s' %('Host: ',repr(dataOut)))
               
        modSlave =  dataOut[6]
           
        for s in Slaves:
            SlaveArray = Slaves[s]
            i = SlaveArray[0]
            if str(modSlave) ==  str(SlaveArray[0]):
                try:
                    SlaveArray[1].send(dataOut)
                except Exception:
                    closeSlaves(Slaves)
                    Slaves = connectSlaves(Slaves)
                           
                try:
                    dataIn= SlaveArray[1].recv(1024)
                    printInline('%15s %30s' %(s +': ',repr(dataIn)))
                    if len(dataIn) < 100:
                        Host.send(dataIn)       
                except Exception:
                    closeSlaves(Slaves)
                    Slaves = connectSlaves(Slaves)   
 
    Host.close()
    closeSlaves(Slaves)


def _main():
    global pkgCtr
    global testClients
    global quiet

    Slaves = {}
    testClients = False
    quiet = False
    pkgCtr = 1
    if len(sys.argv)== 1:
        print("\n\nAufruf:  mmb.y [-test] [-quiet] Net-Address1 [Net-Address2] ... [NetAddress(n)]\n\n")
        while 1: pass
    else:
        CntSlaves = 0
        for i in range(1, len(sys.argv)):
            if sys.argv[i] == "-test":
                testClients = True
                print("Option: Test")
            if sys.argv[i] == "-quiet":
                quiet = True
                print("Option: Quiet")
            if not sys.argv[i][0] == "-":
                CntSlaves += 1
                NetAddr = sys.argv[i]
                SlaveArray = [CntSlaves,"x"]
                Slaves[NetAddr] = SlaveArray
    relay(Slaves)
     
if __name__=='__main__':
    _main()


--- End code ---



magnetron:
hello ,

can I ethernet connect Mach3 MODBUS TCP - PC to STM32 via modem router or
is it possible only with crossover cable ?

thank you

( STM32 is the microcontroller at my own board )

ulihuber:
you can always connect two ethernet interfaces with crossover - provided that you set matching  ip adresses manually.

Uli

magnetron:
hello thanks for answering

but I am afraid I couldot express myself clearly

I am trying to MODBUS TCP IP comunicate the Mach3 with my own made ethernet plc

this here:
http://www.oem-plc.com/index15.htm

however I am stuck at the step of TCP IP connection process

whatever I do Mach3 gives "connetion tinmeout" error

my Mach3 PC and the PLC are connected to each other via router modem

now I want ask how did you connect Mach3 with PLC ?
is there a modem or switch inbetween

or did you conected your Mach3 to the PLC with crossover cable ?

I am wondering it is posible with modem router or shall I use crossover cable absolutely

thank you


Navigation

[0] Message Index

[#] Next page

Go to full version