Automatische Adressierung

Majestic_1987

Level-1
Beiträge
270
Reaktionspunkte
22
Zuviel Werbung?
-> Hier kostenlos registrieren
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....
 
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.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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...
 
Zuletzt bearbeitet:
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.
 
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 ;-)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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
 
@Larry

Ja bei Step7, aber wie macht man das bei Beckhoff? Geht das dort auch so?
 
@ 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.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@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
 
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.
 
Zuletzt bearbeitet:
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 :ROFLMAO:. Du hättest die E/As von MAX_ANZAHL Bausteinen zu verknüpfen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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....
 
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.
 
Zuletzt bearbeitet:
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....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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.
 
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??
 
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!
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?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
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....
 
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.
Code:
Var_Global
     b_out           AT %Q* : BOOL;        
end_var
Allerdings meckert der Compiler:

Code:
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:
Code:
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.
 
Zurück
Oben