Hello Guest it is October 15, 2019, 08:30:59 PM

Author Topic: two modbus TCP devices at a time ?  (Read 2379 times)

0 Members and 1 Guest are viewing this topic.

two modbus TCP devices at a time ?
« on: September 23, 2017, 01:06:32 PM »
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
Re: two modbus TCP devices at a time ?
« Reply #1 on: October 02, 2017, 01:32:13 PM »
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: [Select]
#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()




Re: two modbus TCP devices at a time ?
« Reply #2 on: September 04, 2018, 01:11:39 PM »
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 )
« Last Edit: September 04, 2018, 01:22:38 PM by magnetron »
Re: two modbus TCP devices at a time ?
« Reply #3 on: September 04, 2018, 01:38:56 PM »
you can always connect two ethernet interfaces with crossover - provided that you set matching  ip adresses manually.

Uli
Re: two modbus TCP devices at a time ?
« Reply #4 on: September 05, 2018, 08:39:32 AM »
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


Re: two modbus TCP devices at a time ?
« Reply #5 on: September 06, 2018, 12:47:53 AM »
Hi,

I am sorry but this has got nothing to do with my posted software here. It is an issue with your PLC.
You have to ask the manufacturer of the PLC for specifics, he should be able to help you.

Uli
Re: two modbus TCP devices at a time ?
« Reply #6 on: September 06, 2018, 12:07:16 PM »
dear friend ,

please , I am asking a simple question

did you connected your PLC to Mach3-PC via ethernet switch or router modem or something like that ?

or did you connected PLC and Mach3-PC direct to each other with ethernet cable ( without anything inbetween ) ?

thank you
Re: two modbus TCP devices at a time ?
« Reply #7 on: September 06, 2018, 01:51:46 PM »
Listen, the simple question was answered in my first (simple) answer.
There is no difference between cross-cable and switch connection- if addresses are set correctly.  Both will work identically. I used a cross cable.
And I can't say anything about your PLC. I don't know it and I do not have the time to work into it. Sorry.

Uli