# Automatische Adressierung



## Majestic_1987 (23 Juli 2008)

Hallo Leute, habe eine programmiertechnische Problematik zu lösen.

Folgendes ist die Anforderung:

Es existiert ein FB zur Steuerung eines Betriebsmittels. Es dient einer Funktionsauswahl und einer Steuerung eines Ausgangs.

Nun können von diesem Betriebsmittel bis zu X Stück an der Steuerung angeschlossen sein. Die Hardware ist dabei von der Struktur her komplett synchron zur Betriebsmittelnummer.

Heisst z.b. 
Eingang 1 des 1. Betriebsmittels liegt auf %IX1.0
Ausgang 1 des 1. Betriebsmittels liegt auf %QX1.0
Eingang 1 des 2. Betriebsmittels liegt auf %IX2.0
Ausgang 1 des 2. Betriebsmittels liegt auf %QX2.0
etc.

Eine maximale Zahl von Betriebsmitteln wird festgelegt.
Darüber hinaus soll eine real vorhandene Betriebsmittelzahl existieren.

Also habe ich als Eingaben für den zu erstellenden FB:
BM_Zahl (die Zahl der angeschlossenen Betriebsmittel von 0 - 100 Stück)
Eingang_Start (Byte-Nummer von Ein- und Ausgang des 1. Betriebsmittels)

Nun soll der FB den ich schreiben will folgendes tun:

Er liest die Anzahl der Betriebsmittel ein
Er ruft BM_Zahl von Instanzen des FB Betriebsmittel_Strg auf
Er parametriert die Input- und Output-Variablen JEDER Instanz automatisch auf %IX(BM_Nummer).0 bzw %QX(BM_Nummer).0

Soll heißen: Wenn ich X gleiche Betriebsmittel habe, die alle gleich angesteuert werden, möchte ich gerne alles andere, sprich zuweisungen von Eingangs und Ausgangsadressen von der Steuerung übernehmen lassen, sodass während des Betriebs per Visu einfach die Zahl der Betriebsmittel umgestellt werden kann ohne dass man das Programm an sich ändern muss.

Verstanden?

Mein Ansatz zum Aufruf der Instanzen war eine Array:

VAR
BM_Zahl: INT;
Zaehler: INT;
Aufruf: ARRAY [1..100] OF Loop_Test;
END_VAR


FOR Zaehler := 1 TO BM_Zahl DO

Aufruf[Zaehler](Eingang := , Ausgang := );

END_FOR;


Loop_Test ist hierbei der Name meines Test-FB welcher einfach Eingang = Ausgang setzen soll um das ganze schnell zu testen.

Problem ist hier: Der Array, in den VAR definiert, erzeugt scheinbar IMMER 100 Instanzen.....

Wer kann mir da helfen? Muss dazu sagen: Fange gerade an, mich mit dem TwinCat/Codesys-System zu befassen. Hatte schon über Pointer nachgedacht, aber absolut keine Ahnung, wie man mit den Dingern umgeht und auch keine ordentliche Dokumentation dazu gefunden....vllt kann mir das mal jemand näher bringen....


----------



## trinitaucher (23 Juli 2008)

Die Größe eines Arrays muss immer VOR dem Kompilieren feststehen. Elementaufruf mit Variablen ist möglich, aber keine Deklaration.

Hier kannst du nur die maximale Anzahl festlegen und in Abhängigkeit der tatsächlich benötigten Betriebsmittel den Aufruf gestalten.


----------



## Majestic_1987 (23 Juli 2008)

Gut Gut, also muss ich das Array so deklarieren. Ergo belegt es mal direkt den Speicher vor, den 50 oder 100 Calls des FB benötigen würden. Kann mir ja erstmal egal sein. Auch wenns mir nicht gefällt.

ABER 

wie Adressiere ich die Ein- und Ausgänge???

Hab keine Ahnung!

Ich will halt vermeiden, immer nen bedingten Aufruf machen zu müsen. Wärens maximal 10 Betriebsmittel wärs ja noch okay, aber bei 100 is das echt MORD...deshalb sollen sich die aufrufe selber auf die physikalischen ein und ausgänge parametrieren...


----------



## trinitaucher (23 Juli 2008)

Majestic_1987 schrieb:


> Soll heißen: Wenn ich X gleiche Betriebsmittel habe, die alle gleich angesteuert werden, möchte ich gerne alles andere, sprich zuweisungen von Eingangs und Ausgangsadressen von der Steuerung übernehmen lassen, sodass während des Betriebs per Visu einfach die Zahl der Betriebsmittel umgestellt werden kann ohne dass man das Programm an sich ändern muss.


Schon nen Konzept wie du den Feldbus für den Fall umparametrierst? Die maximalen E/As sind doch bedingt durch die Hardwarekonfiguration. Es müssen doch so viele E/As vorhanden sein, wie maximal im laufenden Betrieb angewählt werden könnten. Verknüpfen musst du die also sowieso vorher, oder hab ich's immer noch nicht richtig kapiert?
Bei TwinCAT kannst du glaube ich überhaupt nicht absolut adressieren (außer bei den kleinen BC-Steuerungen), um's E/A verknüpfen kommst also nicht herum.


----------



## Majestic_1987 (23 Juli 2008)

Ich geh ma davon aus, dass ich alles, was an einem Buskoppler hängt, ohne umparametrierung ansprechen kann. Aber wie gesagt steig ich da grad erst ein deswegen bin ich dankbar für alle Tipps und Hilfestellungen ;-)


----------



## Larry Laffer (24 Juli 2008)

Also, wenn ich deine Problematik richtig verstanden habe, dann willst du z.B. einer Baugruppe 1 die Eingänge 1.0, 1.1 und 4.7 und die Ausgänge 12.0, 12.1 und 15.7 zuordnen und das Ganze per FB-Aufruf und in einem 2. Aufruf eine andere Baugruppe mit anderen E/A's (nach Möglichkeit flexibel) ?
Wenn das so stimmt, dann kannst du das nur machen, in dem du dir die Pointer auf die Quelle (ANY-Pointer) merkst. Ob der Aufwand, den du in dem Fall treiben müßtest den möglichen Vorteil rechtfertigt halte ich für fraglich. Aber vielleicht habe ich das auch falsch verstanden ...

Gruß
LL


----------



## Ralle (24 Juli 2008)

@Larry

Ja bei Step7, aber wie macht man das bei Beckhoff? Geht das dort auch so?


----------



## trinitaucher (24 Juli 2008)

@ Majestic:
Welche Hardware verwendest du überhaupt?

Bei Beckhoffs BC-Controllern ist absolute Adressierung möglich (mit %IW12 usw.), bei PC-Steuerungen NICHT! Dort muss per System Manager verknüpft werden. Man kann deshalb bei PC-Steuerungen ein konkrete Baugruppe nicht mittels absoluter Adresse ansprechen.

Meine denkweise dabei ist, ob der Aufwand überhaupt lohnt. Denn wenn es eine konkrete Hardware und eine "maximale Ausbaustufe" gibt, kann der Baustein doch für den größtmöglichen Aufbau ausgelegt werden. Welche der Schnittstellen letztendlich verknüpft werden, ist dann hardwareabhängig, muss aber (leider) bei Änderung der Hardware jedes mal neu gemacht werden.

In TwinCAT gibt's aber auch noch die Möglchkeit von "Multiverknüpfungen". Wenn du im Programm z.B. ein BYTE hast, was auf eine 8-kanaligen Ausgangsklemme gelegt wird, kannst du dieses Byte komplett mit den Prozessdaten der Klemme verknüpfen.

Zur Hardware:
Ist es ein Programm, was für unterschiedliche Hardware-Ausbaustufen geschrieben wird, und du möchtest dir die Verknüpfungen sparen? Ich sehr irgendwie sonst den Zweck der Geschichte nicht.


----------



## Larry Laffer (24 Juli 2008)

@Ralle:
Das hatte ich nicht überlesen ...
So, wie ich die Anfrage verstanden habe, ist es (für mich) der einzige Weg, an der Stelle mit Pointern zu arbeiten, da ich sonst keinen Weg wüßte (unabhängig von der Programmier-Umgebung), wie ich mir den Verweis auf die ursprüngliche Variable "merken" kann ...

Gruß
LL


----------



## Majestic_1987 (24 Juli 2008)

Ich machs an einem Beispiel konkret:

Du willts Lampen Steuern. Dazu hast du nen Baustein, den du parametrieren kannst (ob du dimmen oder schalten willst, wie schnell, wie lange, und auf welche art gedimmt werden soll, welche lichtszenarien diese lampe beinhalten etc.) das ist der FB den ich für jede vorhandene Lampe aufrufen möchte.

Für jede Lampe existiert ein Dimmermodul. Die maximalzahl der Lampen wird über die Zahl der vorhandenen Dimmermodule (sagen wir 20 Stück) limitiert. Jedes Dimmermodul wird z.b. über ein Byte angesprochen (%QB10, %QB20, etc.) und alle vorhandenen Taster liegen auf den entsprechenden Eingangsbits. 

Nun will ich, dass man in einer Visu einfach in ein Feld eingibt "20 Lampen" oder "17 Lampen" und demnach einfach der Lampen-Steuerbaustein exakt 20 mal aufgerufen wird und genau die ersten x (10, 20, 30) Eingangsbits zu gewiesen werden und ihm die ersten x Ausgangsbytes zugewiesen werden.

Die Überlegung hat folgenden Sinn: Wenns 100 oder 1000 Lampen WÄREN müsste ich, sofern ich einfach mal die Maximalzahl aufrufe, die Hardwareseitig überhaupt geht, 100 oder 1000 mal händisch die jeweiligen Peripherieadressen zuweisen. Das ist einfach ein heiden Aufwand.

Deswegen wäre es toll, wenn jeder Aufruf sich seine Adressen automatisch zuweisen würde...ich also nur festlegen muss, wie viele Aufrufe ich hab. Das geht natürlich nur, wenn zum Aufruf 1 immer das 1. Eingangbyte (oder Bit) sowie das erste Ausgangsbyte gehört.

Es ist mehr eine Machbarkeitssache, den Aufwand erstmal hintenangestellt.

Für einen konkreten Anwendungsfall mit überschaubaren z.b. Lampenmengen ist es natürlich wirklich einfacher erstmal die maximale (hardwarelimitierte) Menge an Aufrufen zu machen, dort händisch die Peripherie zuzuweisen und dann einfach den Bausteinaufruf mit einer Bedngung zu versehen...beispielsweise "wenn Lampenzahl < Aufrufnummer starte Aufruf, sonst stop" oder so. 

Meine Hintergrundidee war schon, mal mit Pointern zu arbeiten. Aber aus dem Grund: Ich hab keine Ahnung von Pointern und würd gern mal irgendwo ordentlich lernen, wie man mit denen umgeht. Für Step7 hab ich dazu in einem Buch eine brauchbare anleitung, aber das funktioniert wohl bei Beckhoff etwas anders.

Ach ja genau: Hardware wäre ein EtherCat Buskoppler an einer PC-Steuerung..also fällt wohl die direkte Adressierung flach (gut, wieder was dazu gelernt)

@ Larry Laffer:

Du hast übrigens den Begriff Betriebsmitel mit Baugruppe verwechselt. Es geht nich um eine Dynamische Zuweisung von Adressen zu Beckhoff-Klemmen sondern um die dynamische Zuweisung von E/A-Adressen zu den Input-Variablen von FB`s.
Mit Betriebsmittel meine ich wirklichj die Betriebsmittel, die mit den jeweiligen Ausgängen angesteurt werden.


----------



## trinitaucher (24 Juli 2008)

Generell muss bei TwinCAT die Anazhl der E/A-Adressen beim Aufstarten feststehen, schon wegen der Verknüpfung.
Du hast natürlich immer die Möglichkeit, Arrays von FB und Strukturen zu erstellen und in den FBs die Adressen in der Deklaration mittels %I* oder %Q* zuzuweisen. Dann werden beim kompilieren genau soviele In/Outputs erstellt, wie Bausteine deklariert wurden.

Beispiel:
Du deklarierst dein ARRAY [1..MAX_ANZAHL] OF BausteinFB , im Deklarationsteil VAR (nicht in VAR_INPUT / OUTPUT !!!) des BausteinFB werden die Ein/Ausgänge mit %I* und %Q* angelegt.
Der Baustein wird in einer FOR-Schleife aufgerufen, wobei der Endwert deiner gewünschten Anzahl Bausteine (einstellbar) entspricht.

FOR i := 1 TO GewuenschteAnzahl DO
  BausteinFB_();
END_FOR

Aber um's Verknüpfen kommste trotzdem nicht umher . Du hättest die E/As von MAX_ANZAHL Bausteinen zu verknüpfen_


----------



## Majestic_1987 (24 Juli 2008)

Anders ausgedrückt:

ich kann auf keinen fall die Input- und Output-Vars der Aufgerufenen Instanzen automatisch hochzählen lassen.


Ideal wäre halt wenn ich %IB* und %QB* hinschreiben könnte und er würde mir dann für den Stern _ einsetzen....

Bei Step 7 kann ich ja z.B. indirekt adressieren über L PEW[MW10] sofern denn im MW 10 eine Zahl steht...._


----------



## trinitaucher (24 Juli 2008)

Fakt bleibt: Bei Twincat musst du verknüpfen, direkt adressieren geht nicht, da das Programm hardwareneutral ist.
Mit %I* erlaubt du TwinCAT, die Zuordung zwischen Prozessabbild der Hardware und Prozessabbild der SPS (die sind bei TwinCat getrennt!!!) selbst herzustellen. Mit %IW10 kannst du die Speicheranorndung manuell beeinflussen und ggf. auch gewollte Speicherüberschneidungen erzeugen. Ansonsten herrscht klare Trennung zwischen SPS-Prozessabbbild und Hardware. Erst durch das Mapping im System Manager werden beide Speicherbereiche miteinander in Beziehung gebracht.
Nachteil: das was du möchtest geht so einfach nicht (wüsste jedenfalls  nicht wie).
Vorteil: du kannst das Programm hardwareunabhängig halten und auf beliebige Systeme portieren.

Wie wär's mit nem Zwischenschritt?
Du verknüpft vorab etliche Dummy-Bytes (evtl. Arrays) mit der Hardware, und zwar so viele, wie maximal an E/As vorhanden sind.
Im Programm dann weist du den Bausteinen mittels ADR(E_Byte_xy) oder  Indizes der Arrays  die jeweiligen Prozessdaten zu.

Da fällt mir ein, du kannst bei EtherCAt auch über einen Umweg absolut adressieren. Es gibt die Ethercat-Adresse für jeden Slave. Die kannst du im Programm mit entsprechenden Bibliotheken direkt ansprechen. Inwieweit das auch für Prozessdaten gilt, kann ich leider nicht sagen. Hab's noch nicht ausprobiert.


----------



## Majestic_1987 (25 Juli 2008)

Verstehe ich das richtig:

Prozessabbild der Hardware ist z.b. das Abbild von Lo oder Hi der einzelnen Bits z.b. in einer 8-fach DI-Klemme.

Prozessabbild der SPS sind die zugewiesenen %IX füts Programm

Aber wenn ich das so sehe, dann führt eine Automatische, beliebige Verknüpfung dazu, dass mein Ein-Taster der Hardwareseitig am Einganbsbyte 3 , Bit 0 liegt..nachher in der SPS nich mit %IX3.0 angesprochen werden kann....


----------



## trinitaucher (25 Juli 2008)

Mit %IX3.0 wird ein Bit im Wort 3 des logischen Twincat Prozessabbilds reserviert. Welches physikalisch Bit das letztendlihc ist, entscheidest du durch die Verknüpfung. Ohne Verknüpfung keine Auswirkung auf die HArdware.

Das logische Bit %IX3.0 kannst du auch mit dem physikalischen Bit %IX123.2 verküpfen. Um Überschneidungen zu vermeiden sollte man bei Twincat ja auch mit %I* adressieren.


----------



## Majestic_1987 (25 Juli 2008)

Ahja...okay...

ABER wenn man mit %I* adressieren sollte...woher weiß ich dann, was Twincat dann selbstständig damit assoziiert???

Ich weiß ja z.b. dass mein physikalisches Bit %IX3.0 auf dem 3. Byte, erstes Bit liegt. Also leg ich da z.b. meinen Not-Aus-Taster auf.

Wenn ich aber im Programm dann überall %I* hinschreib...dann steht da auch 100 oder 200 mal I* 

woher weiß ich dann, womit ich den physikalischen Eingang im System-Manager verknüpfen muss??


----------



## trinitaucher (25 Juli 2008)

Majestic_1987 schrieb:


> Ich weiß ja z.b. dass mein physikalisches Bit %IX3.0 auf dem 3. Byte, erstes Bit liegt. Also leg ich da z.b. meinen Not-Aus-Taster auf.


Das Bit ist NICHT physikalisch, es ist logisch!
Erstell doch mal ein Projekt mit drei Bit-Variablen (%IX3.0, %IX3.1 und %IX3.2). Im System Manager sieht du dann einfach 3 Variablen. Diese verknüpfst du mit Bit-orientierten Prozessdaten deiner Hardware. Adressen interessieren hier nicht mehr!


Majestic_1987 schrieb:


> woher weiß ich dann, womit ich den physikalischen Eingang im System-Manager verknüpfen muss??


Anhand deiner E/A-Konfiguration und der Verknüpfung, die du wählst.... 
Hast du überhaupt schonmal E/As im System Manager eingefügt?


----------



## Majestic_1987 (25 Juli 2008)

Hab grad ma was zusammengeklickt
Und ich glaub ich habs kapiert. Problem is halt dass ich noch nich über konkrete Hardware verfüge und momentan noch mit dem Simulations-Runtime-Ding rumexperimentiere (wie gesagt, ich steige grad in die Twincat-Welt ein). 

Hab bisher nur Erfahrung mit Simatic S7 + WinCC + WinCC flex und n bissl PCS7...das ist halt der Nachteil, wenn man bei Siemens lernt...dann lernt man nur Siemens....


----------



## trinitaucher (25 Juli 2008)

schau auch mal bei den Beispielprogrammen:
http://infosys.beckhoff.com/index.p...31/tcquickstart/html/tcquickstart_sample6.htm


----------



## ctb (30 Juli 2008)

trinitaucher schrieb:


> Fakt bleibt: Bei Twincat musst du verknüpfen, direkt adressieren geht nicht, da das Programm hardwareneutral ist.
> Mit %I* erlaubt du TwinCAT, die Zuordung zwischen Prozessabbild der Hardware und Prozessabbild der SPS (die sind bei TwinCat getrennt!!!) selbst herzustellen. Mit %IW10 kannst du die Speicheranorndung manuell beeinflussen und ggf. auch gewollte Speicherüberschneidungen erzeugen. Ansonsten herrscht klare Trennung zwischen SPS-Prozessabbbild und Hardware. Erst durch das Mapping im System Manager werden beide Speicherbereiche miteinander in Beziehung gebracht.
> Nachteil: das was du möchtest geht so einfach nicht (wüsste jedenfalls  nicht wie).
> Vorteil: du kannst das Programm hardwareunabhängig halten und auf beliebige Systeme portieren.



Cool, dass das gerade hier diskutiert wird. Ich habe gerade auch so gemacht.

```
Var_Global
     b_out           AT %Q* : BOOL;        
end_var
```
Allerdings meckert der Compiler:


```
Warnung 1990: Kein VAR_CONFIG für 'b_out'
```
In einem anderen Projekt wurde die Liste als ein readonly-file (TwinCat_Configuration (VAR_CONFIG) <R>)  erzeugt
Bsp: 
	
	



```
Var_Config
       .Ix_B_AbsaugungOK AT %IX126.4 : BOOL;
end_var
```
Welche Einstellung muss ich n da noch vornehmen? Ich habe beide Projekte miteinander verglichen, aber konnte nix feststellen.


----------



## trinitaucher (30 Juli 2008)

ctb schrieb:


> Cool, dass das gerade hier diskutiert wird. Ich habe gerade auch so gemacht.
> 
> ```
> Var_Global
> ...


Das ist nur eine Warnung. Wenn das .tpy-File erstmalig im System Manager eingebunden und die Konfiguration aktiviert wurde, findest du danach automatisch die VAR_CONFIG im PLC-Projekt. Das macht TwinCAT von sich aus.
Ist ja logisch, da er ohne die Verknüpfungen keine Zuordnung im Prozessabbild (mit Adressierungen) erstellen kann.


----------



## zeda (27 Mai 2009)

Habe das gleiche Problem. Finde einfach nicht heraus welche nummer ich für die ein und ausgänge verwenden muss. (%IX???.1 und %QX???.1) wo finde ich die Lösung für dieses Problem?


----------



## Cerberus (27 Mai 2009)

zeda schrieb:


> Habe das gleiche Problem. Finde einfach nicht heraus welche nummer ich für die ein und ausgänge verwenden muss. (%IX???.1 und %QX???.1) wo finde ich die Lösung für dieses Problem?


 
Willst du unbedingt spezielle Adressen?? Ansonsten empfehle ich dir wie oben bereits gezeigt %I* bzw. %Q* zu verwenden. Dann wird die Adressvergabe intern geregelt.


----------



## caret (12 Oktober 2009)

Wie sieht den der "Beckhoff'sche Königsweg" aus um eine große Anzahl IOs von der PLC aus zu adressieren? Hab nämlich ein ähnlich gelagertes Problem wie der Threadstarter: Es gilt eine sehr große Anzahl IOs (Größenordung mehrere hundert) anzusteuern. Direkt adresseiren kann ich die also offenbar nicht. Mehrere hundert IOs per Hand im System-Manager zu Verknüpfen ist ein "tödlicher" Aufwand, mal ganz abgesehen von der schlechten Fehlerqoute die man bei solchen manuellen Arbeiten hat. 

Jemand hat hier bereits auf Multiverknüpfungen hingewiesen. Das würde insoweit helfen, dass die IOs auf den Klemmen direkt hintereinander liegen und ich zumindest recht große Blöcke verknüpfen könnte. Problem bei der Sache ist: Multiverknüpfungen werden mir nur bei der Mehrfachauswahl von BOOL Variablen angeboten. Bei einem ARRAY OF BOOL sehe ich im linken Fensters des System Managers zwar in der Baumansicht alle Arrayelemente als BOOL-Werte, aber im rechten Fenster in dem man ja die Multiverknüpfung macht, kann ich nur noch das Array an sich und nicht mehr die Elemente sehen.
Weiteres Problem mit dem ARRAY OF BOOL ist, dass, soweit ich verstanden hab,  die Elemente intern als Bytes gespeichert werden und somit eine Arraydeklaration wie die folgende

VAR_GLOBAL
    i AT %I*: ARRAY [0..1023] OF BOOL;
END_VAR

VAR_CONFIG
    .i AT %IB0 : ARRAY [0..1023] OF BOOL;
END_VAR

gleich mal 8kB statt 1kB Speicher verbraucht. Deshalb also: Wie sieht den der "Beckhoff'sche Königsweg" aus um eine große Anzahl IOs von der PLC aus zu adressieren?


----------



## RobiHerb (13 Oktober 2009)

trinitaucher schrieb:


> Fakt bleibt: Bei Twincat musst du verknüpfen, direkt adressieren geht nicht, da das Programm hardwareneutral ist.
> 
> ...
> 
> Da fällt mir ein, du kannst bei EtherCAt auch über einen Umweg absolut adressieren. Es gibt die Ethercat-Adresse für jeden Slave. Die kannst du im Programm mit entsprechenden Bibliotheken direkt ansprechen. Inwieweit das auch für Prozessdaten gilt, kann ich leider nicht sagen. Hab's noch nicht ausprobiert.



Ich habe mal ein Programm geschrieben für eine "beliebige" Anzahl von SoftMotion EtherCat Antrieben (Lenze 9400 State/High Line). Das Ganze wurde über Pointer gelöst.

Vorraussetzung ist, dass das Mapping aller Antriebe im Prinzip gleich sein muss, d.h. gleich grosser Speicherbereich im Konfigurator und gleiche Bedeutung der gemappten Parameter. 

Hinweis: Lenze verwendet den ACONTIS EtherCAT Stack, der etwas anders (effektiver) mappt als Beckhoff, aber es müsste auch da gehen.

ggf PN an mich.


----------

