# Ansteuerung WAGO 750-352 - Anfänger Fragen



## Hölligma (19 April 2022)

Hallo,

mittlerweile habe ich meine WAGO 750-352 komplett, mit Relaiskarten, Analog- und Digital-Ausgängen. Ich möchte nun die WAGO mittels Python Scripte ansprechen, welche auf meinem Server liegen, dazu habe ich schon ein paar Vorlagen gefunden und mich mit Modbus beschäftigt.




Allerdings so wie ich es verstehe, brauche ich jetzt die Adressen von meinen I/O-Ausgängen. CoDeSys 3.5 habe ich mir heruntergeladen, bin aber gerade etwas überfordert, was die Bedienung davon angeht.

Wie mache ich das jetzt, leider bin ich absoluter Anfänger, würde aber dennoch gerne mein Projekt damit umsetzen. Bitte könnte mir jemand weiterhelfen?

Danke und LG


----------



## Thruser (20 April 2022)

Hallo,

man kann es zwar auch von Hand machen nach Studium der Handbücher, am leichtesten geht es aber mit dem Wago Modbus Master Konfigurator unter Codesys 2.3. Auch mit e!cockpit kann man sich die Adressen leicht anzeigen lassen. Wie es mit nativem Codesys 3.5 aussieht weiß ich nicht.



Die digitalen Ausgänge werden hier als Coils, s. FC15, angesprochen. Es ginge zwar auch als Register, da muß dann aber nochmal raussuchen unter welchen Adressen die zugängig sind. 

Gruß


----------



## Hölligma (20 April 2022)

Danke vielmals für die schnelle Hilfe, ich habe mit CoDeSys Schwierigkeiten. Die Version 2.3 zeigt, wenn ich auf neues Projekt erstellen gehe keine Auswahl, vermutlich weil keine Bibliotheken vorhanden sind und mit Version 3.5 ist es ähnlich. Benötige ich zwangsläufig eine Runtime, um mit CoDeSys zu arbeiten, ich habe da noch einige Verständnisprobleme so wie es aussieht.

Ich werde mir morgen auch mal das e!cockpit ansehen, allerdings ist das halt eine Testversion. Die Vollversion ist mir zu teuer, leider.


----------



## Thruser (20 April 2022)

Hallo,

e!cockpit und Codesys 2.3 nützen Dir eigentlich gar nichts. Dazu benötigst Du entsprechende programmierbare Controller. Für e!cockpit die PFC100 oder PFC200 von Wago. Für Codesys 2.3 unter anderem die ganzen Wago 8xx Controller, dazu wird aber die Wago Version von Codesys 2.3 benötigt.

Der 352 ist nur ein Koppler, der die I/Os per Modbus TCP zur Verfügung stellt.

Für Codesys 3.5 gibt es ansonsten auch eine Version für den Raspberry Pi. 

Da Du aber mit Python arbeiten willst benötigst Du es gar nicht. Da kannst Du per Modbus TCP direkt auf den Koppler zugreifen

Gruß


----------



## Hölligma (20 April 2022)

Hi,
ja mit Python, dann muss ich jetzt quasi rausfinden, wie ich die Adressen richtig mit Modbus anspreche?

Viele Grüße


----------



## Thruser (20 April 2022)

Adressen sind 512 -519 für die digitalen Ausgänge und 512-513 für analog.


----------



## Hölligma (20 April 2022)

Irgendwie funktioniert es nicht mit meinem Script, ich komme mir gerade richtig blöd vor. Könntest du mir bei der Implementierung etwas helfen, bitte?

Das habe ich bisher gemacht, bzw. habe mir etwas zusammen kopiert:


```
#! /usr/bin/env python
#  -*- coding: utf-8 -*-
#
#  Support module generated by PAGE version 4.20
#  in conjunction with Tcl version 8.6
#  Apr 20, 2022 10:00:00 PM CET  platform: Linux

import sys
import itertools as it
from pymodbus.client.sync import ModbusTcpClient
import datetime

try:
    import Tkinter as tk
except ImportError:
    import tkinter as tk

try:
    import ttk
    py3 = False
except ImportError:
    import tkinter.ttk as ttk
    py3 = True

client = ModbusTcpClient(host='192.168.0.50',port=502)
client.connect()
bus = client.read_input_registers(0x2030, 65)

class WagoData:
        def __init__(self, master):
                self.master = master
                self.updateTemp()
                self.updateTime()

        def updateTime(self):
                time = datetime.datetime.now().strftime("Data: %d.%m.%Y  Time:  %H:%M:%S:%f")[:-4]
                w.lblTime.configure(text=time)
                root.after(100, self.updateTime)

        def Output_Relais(self):

                response = client.read_holding_registers(0x00,4,unit=1)
                t = response.registers[0]
                w.lblT1.configure(text=float(t/10.0))

                result = client.read_coils(0,1)
                if(result.bits[0]):
                    print(bit 0 on)

                else:
                    print(bit 0 off)

                root.after(100, self.updateTemp)

def exit():
    root.destroy()

#def setOutput1():

def init(*args, **kwargs):

        client.write_coil(0,False)
        client.write_coil(1,False)
        client.write_coil(2,False)
        client.write_coil(3,False)
        root.attributes("-fullscreen", True)
        root.config(cursor="none")
        WagoData(root)
```


Auf dem Linux Server sind Python und die Pymodbus Pakete installiert, der Code scheint zwar durchzulaufen, aber ich bekomme vermutlich keine Ausgabe, weil da was grundlegend etwas falsch programmiert ist.

VG


----------



## Hölligma (20 April 2022)

Ok, ich glaube ich habe es geschafft 

Im Endeffekt ist es eine Art Schieberegister wie ich es jetzt zum Laufen gebracht habe, hier mein aktueller Code:


```
#!/usr/bin/env python
from pymodbus.client.sync import ModbusTcpClient

client = ModbusTcpClient(host='192.168.0.50', port=502)
#client.connect()
#client.write_coil(1, True)

#send write command to modbus server
write_value = 4
write_register = 2

client.write_register(write_register, write_value)
print("Output: ", write_value)


#send read command to modbus server
read_register = 3
read_qty = 1

rr = client.read_holding_registers(read_register, read_qty)
print("input: ", rr.getRegister(0))
```


----------



## Thruser (21 April 2022)

Wo ist denn da das Schieberegister in dem Beispiel?

rr.getRegister(0) funktioniert bei mir auch nicht.

Habe hier jetzt nur unter Windows getestet. Da ich auch gerade kein 352 hier habe, habe ich es simuliert:

```
import time
from pymodbus.client.sync import ModbusTcpClient as ModbusClient

UNIT = 0x1
HOST = 'localhost'
PORT = 502
COILBASE = 512 # Coil Output Base Address

def main():
    client = ModbusClient(host=HOST, port=PORT)
    client.connect()

    #set all digital outputs to OFF with FC15 Write Multiple Coils
    rq = client.write_coils(COILBASE + 0, [False]*8, unit= UNIT)
    time.sleep(1)
    
    #set single digital output to ON with FC5 Write Single Coil
    rq = client.write_coil(COILBASE + 0, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 1, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 2, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 3, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 7, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 6, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 5, True, unit= UNIT)
    time.sleep(1)
    
    rq = client.write_coil(COILBASE + 4, True, unit= UNIT)

    client.close()

if __name__ == "__main__":
    main()
```

Schreiben auf die Outputs funktioniert zwar auch mit den Adressen ab 0, besser ist es aber ab Adresse 512 darauf zuzugreifen falls man doch mal digitale Eingänge haben sollte, die werden nämlich ab 0 adressiert.

Gruß


----------



## Hölligma (21 April 2022)

Absolut genial, vielen vielen Dank für den Code!!!

Also, das Programm läuft durch und das Relais wird sauber geschaltet, leider werden die analogen 550 und digitalen 504 Outputs gar nicht geschaltet?

Also alles, was nach der 750-601 kommt, wird nicht angesprochen. Liegt das daran das dort keine Spannung angelegt wurde oder evtl. ein Defekt vorliegt?

VG

Edit:

Ich habe das 601 Modul mal herausgenommen aber die wie vorher werden die AO und DO nicht angesprochen?


----------



## Hölligma (21 April 2022)

Komisch aber auch, dass hier nichts passiert, alos theoretisch sollten doch auch die Relais angesprochen werden?

Hatte das mal so angepasst, ich denke das es vernünftig ist, gleich die richtigen Adressen zu verwenden, falls sich beim Aufbau der Module mal was ändern sollte...


```
rq = client.write_coil(COILBASE + 514, True, unit= UNIT)

    rq = client.write_coil(COILBASE + 514, False, unit= UNIT)
```

COILBASE = 512 oke, beinahe übersehen^^


----------



## Hölligma (21 April 2022)

Dann was mir gerade noch eingefallen und ich nicht verstehe ist, wenn man mehr DO hat als man mit 8 Adressieren kann?


----------



## Thruser (21 April 2022)

Moin,

ja an die 601 muß auch 24VDC angelegt werden. Damit werden die 'Leistungsausgänge' versorgt. Mit dem Code werden eigentlich auch die 504 DO angesprochen. Die liegen ja auf den Adressen 516, 517, 518 und 519.

Die Analog Out habe ich noch nicht angesprochen, da mußt Du mit einer anderen Funktion arbeiten.


```
rq = client.write_registers(512, [8192, 4096], unit=UNIT)
```

Gruß


----------



## Hölligma (21 April 2022)

Hi,

danke ja stimmt, habe jetzt die 601er ebenfalls ans Netzteil angeschlossen und siehe da, es tut sich etwas 

Was komisch ist, dass wenn die DO noch ausgeschalten sind, Spannung anliegt, hatte das mit einem Phasenprüfer getestet?
Nach dem Messen mit einem Multimeter liegen erst nach dem Schalten die 24 V an, passt also.




Das mit den AO werde ich später auch noch testen.

Wäre das dann analog mit registers?


```
rq = client.write_registers(512, [8192, 4096], unit=UNIT)
    time.sleep(1)

    rq = client.write_registers(512 + 0, True, unit= UNIT)
    time.sleep(1)
```


----------



## Hölligma (21 April 2022)

Wie bist du auf den Code gekommen, also hast du Erfahrung im Programmieren, weil so wirklich gute Beispiele habe ich kaum gefunden.


----------



## Thruser (21 April 2022)

Hallo,

für den Code habe ich mir die Beispiele und den Quellcode von pymodbus auf github angesehen und dann ein bisschen ausprobiert. Ist ja leider etwas schlecht dokumentiert.

Mit

```
rq = client.write_registers(512, [8192, 4096], unit=UNIT)
```
werden gleich mehrere Register geschrieben und zwar 512 -> 8192 und 513 -> 4096. So wie es aussieht werden mehrere Werte als Liste übergeben. Anzahl der Elemente der Liste-> Anzahl der zu schreibenden Register. 

Wenn nur ein einzelnes Register geschrieben werden soll kann man nur den Wert angeben oder in eckigen Klammer als Liste mit einem Element. Oder die Funktion write_register verwenden.


```
rq = client.write_registers(512 + 0, True, unit= UNIT)
```

Funktioniert zwar, es wird aber der Wert 1 in das Register geschrieben.

Die Frage oben mit den 8 Do habe ich nicht ganz verstanden. Alle digitalen Ein- und Ausgänge werden als Coils fortlaufend adressiert. Eingänge ab Adresse 0, Ausgänge ab 512.

Gruß


----------



## Hölligma (21 April 2022)

Du bist einfach genial, tausend Dank an der Stelle noch mal!!!

Ich habe auch herausgefunden was diese Werte bedeuten, bei dem 550er Modul, kann man eine Spannung zwischen 0...10 V einstellen, ich habe dazu mal folgendens ausprobiert:


```
rq = client.write_registers(512, [0, 32767], unit=UNIT)
    time.sleep(1)
```

In diesem Handbuch steht eine Tabelle mit den Werten: https://www.wago.com/medias/m075005...c2YzI5YWU2NTA1ODI2MDU0MmM0NzY&attachment=true

Wobei 32767 = 10 V entsprechen und 81292 = 2,5 V





Also bei 0 erhalte ich auch 0 V und bei zB. 4096 genau 1,25 V. Das mit der Dokumentation ist wahr, die ist wirklich eher dürftig, ich habe so viel gegoogelt und da kam wirklich nicht viel bei rum, eine Art Anleitung für Wago 750 mit pymodbus wäre super.


----------

