Kein Zugriff per <FB instance>.<variable> auf VAR_IN_OUT?! :(

Jörn

Level-1
Beiträge
58
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

vielleicht hatte ja schon jemand das Problem und hat einen Workaround gefunden?! Ich hab einen FB_Conveyor geschrieben. Da die Freigaben von den vorhergehenden und den nachfolgenden Förderbändern sowohl gelesen, als auch geschrieben werden sollen, habe ich sie in VAR_IN_OUT plaziert:

Code:
FUNCTION_BLOCK FB_Conveyor

VAR_INPUT
    ixSensors: ST_ConvSens;
END_VAR

VAR_IN_OUT
    iqxEnables: ST_ConvEn;
END_VAR

In einer globalen Variablenliste lege ich ein Array des FB_Conveyor an, nebst zugehöriger Sensoren und Enable Signale.

Code:
VAR_GLOBAL
(* Array of instances of the conveyors *)
afbConv: ARRAY[1..3] OF FB_Conveyor;

(* Sensors Conveyor 202 *)
IxC202S1 AT %IX0.1: BOOL; (* Conveyor 202, Sensor 1  = Infeed front *)
IxC202S2 AT %IX0.2: BOOL; (* Conveyor 202, Sensor 2  = Fore stop front *)
IxC202S3 AT %IX0.3: BOOL; (* Conveyor 202, Sensor 3  = Outfeed front *)

(* Enable signals Conveyor 202 *)
iqxEnC202: ST_ConvEn;

Zuletzt werden die Werte in einer FC geschrieben. Bereits hier wird es "unschön". Leider ist es so, daß man auf in VAR_IN_OUT deklarierte Variablen von außen keinen Zugriff mit <function block instance name>.<variable name> hat (1). Deshalb muss ich in der VAR_GLOBAL schon die iqxEnC202 vom Typ ST_ConvEn anlegen, sie auf unten zu sehende Weise mit Werten füttern und in der MAIN schießlich ...

Code:
FC_ConfigConveyors
afbConv[E_Conv.C202].ixSensors.ST_Front.ixInfeed    := IxC202S1;
afbConv[E_Conv.C202].ixSensors.ST_Front.ixForeStop  := IxC202S2;
afbConv[E_Conv.C202].ixSensors.ST_Front.ixOutfeed   := IxC202S3;

(*
    Deshalb in VAR_IN_OUT! Wenn ich die qx... in VAR_OUTPUT plaziere
    bekomme ich für die erste Zeile eine Fehlermeldung:
    'qxReqOutfFromFoll' is no input of 'FB_Conveyor'
*)
iqxEnC202.ST_Back.qxReqOutfFromFoll := iqxEnC203.ST_Front.ixForeReqAlwOut;
iqxEnC202.ST_Back.ixFollAlwOutf     := iqxEnC203.ST_Front.qxAlwOutfToFore;

... beim Aufruf jedes FB_Conveyors als Parameter übergeben. Außerdem ist eine Abfrage auch nur über die "Krücke" iqxEnC202 möglich, was den Code, wie ich finde, sehr unschön gestaltet, weil es mal so und mal so geschrieben werden muss, wie hier zu sehen:

Code:
MAIN
FC_ConfigConveyors();

afbConv[E_Conv.C202](iqxEnables := iqxEnC202);

(*
    Eine Abfrage muss so geschrieben werden, damit es
    funktioniert. 
*)
IF iqxEnC202.ST_Back.qxReqOutfFromFoll THEN
    afbConv[E_Conv.C203].ixStartTransp := TRUE;
END_IF

(*
     Versucht man es so, dann kommt folgende Fehlermeldung dabei heraus:
    'No external access to 'VAR_IN_OUT' parameter 'iqxEnables' of 'FB_CONVEYOR'
*)
IF afbConv[E_Conv.C202].iqxEnables.ST_Back.qxReqOutfFromFoll THEN
    afbConv[E_Conv.C203].ixStartTransp := TRUE;
END_IF

Hat schonmal jemand das gleiche Problem gehabt und/oder weiß eine hübsch(er) aussehende bzw. handhabbare Lösung?

Vielen Dank schonmal für jeden Tip. :)

Gruß
Jörn



(1)
Quelle:
Infosys -> TwinCAT 3 -> TE1000 XAE -> PLC -> Referenz Programmierung -> Variablentypen und spezielle Variablen -> Eingabe-/Ausgabevariablen - VAR_IN_OUT, VAR_IN_OUT CONSTANT
Als LINK: https://infosys.beckhoff.com/conten...45035998802476171.html?id=5478484394449973595
 
Eine IN_OUT Variable ist nur eine Referenz. Du übergibst ihr keinen Wert sondern die Adresse der Variablen in der FB lesen und beschreiben soll.

Du kannst nicht direkt mit dem . Operator darauf zugreifen, weil da nichts ist.

In deinem Fall greift der FB über die Referenz iqxEnables direkt auf die Struktur iqxEnc202 zu, ohne Umwege. Anders ist das bei Input und Output Variablen des FBs, da werden Werte kopiert. Deshalb kannst du auf sie zugreifen, da sie im Speicher existieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Warum es nicht geht, hat MasterOhh schon geschrieben. Zum Punkt "Hübscher machen":
Warum legst Du die Conveyor-Inputs ausserhalb ihrer FBs an? Sie gehören doch zum Conveyor dazu und sollten besser in den FBs angelegt werden. Dann allerdings nicht mit absoluten Adressen wie "AT %IX0.1", sondern mit Platzhaltern "AT %I*". Dann sorgt der Compiler dafür, dass jede FB-Instanz indivduelle I/Q-Adressen erhält. Dann brauchst Du nichts von aussen übergeben, und statt der Config-FC kannst Du eine FB-Aktion oder -Methode schreiben. Beide haben genauso Zugriff auf die FB-Variablen wie der FB bei seinem eigentlichen Aufruf.
 
@ MasterOhh:
Daß bei der VAR_IN_OUT nur eine Adresse übergeben wird, über die die eigentliche Variable dann bedient wird, hatte ich auf der verlinkten Seite schon so rausgelesen. Ich hatte nur die Hoffnung, daß man mit irgendeinem "kleinen Trick" trotzdem irgendwie Variablen in einem FB mit Schreib- und Lesezugriff deklarieren kann. Vielleicht auch zwei Variablen, input und output, die man irgendwie miteinander verknüpfen kann, oder irgendwie sowas. Manchmal kommen die Leute ja auf die dollsten Dinger. :ROFLMAO:

@ StructuredTrash:
Die absoluten Adressen mit dem AT deshalb, weil an der Anlage die Sensoren ja an bestimmten Eingängen angeschlossen werden und ich auf das richtige Signal gucken muss. Offensichtlich geht das auch anders?!
Das mit den Platzhaltern kenne ich nicht und hab deshalb die letzten 2 Stunden danach gesucht, um mich einzulesen, aber das AT ist als Suchwort zu kurz und unter Kommunikationsvariablen, flexible Adressierung, AT-Deklaration, Adresse Platzhalter, ... findet man nur spärlich Infos. An einigen Stellen ist zu lesen, daß "mit dem Platzhalter * (%I*, %Q* bzw. %M*) ... eine flexible und optimierte Adressierung von TwinCAT automatisch durchgeführt [wird]". Auf Details wird aber nirgendwo weiter eingegangen. Wenn mir da mal jemand mit einem weiterführenden Link oder gar mit einer kurzen Erklärung aushelfen möchte!? Danke. :)

Gruß
Jörn
 
E/A - Variablen werden in der Regel im E/A - Baum deines Projektes mit der Hardware verlinkt (Da wo du auch alle Geräte und Boxen die an deine SPS angeschlossen sind eingefügt hast).
Jede Box stellt dir entsprechende Inputs (gelb) und/oder Outputs(rot) bereit. Wenn du in deinem Projekt Variablen mit AT%I* oder AT%Q* deklariert hast werden dir diese Variablen für die verlinkung mit der Hardware bereit gestellt (Projekt muss vorher erstellt werden damit die Variablenkonfig erzeugt wird).
Du kann dann auf einen Hardware Kanal gehen, rechte Maustaste drauf und dann "change link". TwinCAT zeigt dir dann alle Variablen an die du mit diesem Kanal verlinken kannst. Wähle die entsprechende aus und schon hast du die Verbindung zw. Variable und Hardware hergestellt (Hardwarekonfig aktivieren nicht vergessen) ...

changelink1.PNGchangelink2.PNG
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Auch hier war MasterOhh schneller. Aber vielleicht noch ein paar Grundlagen zum besseren Verständnis.
Bei Beckhoff hat das PLC-I/O-Abbild, das Du mit dem Anlegen von Variablen AT %I/Q anlegst, mit den realen HW-I/O erst mal nichts zu tun. Die Steuerung erzeugt aus den angeschlossenen HW-Komponenten ein eigenes I/O-Abbild, sofern sie die HW kennt. Wenn Du das Programm fertig hast und es fehlerfrei erstellt ist, musst Du die I/O-Variablen des Programms mit denen des HW-I/O-Abbildes verknüpfen, so wie es MasterOhh beschrieben hat.
Der Grund für das eigene HW-I/O-Abbild ist, dass auf einem Beckhoff-PC durchaus mehrere Softwaregeräte laufen können (SPS und NC oder auch mehrere SPSen), die alle auf einen Teil der HW zugreifen müssen. Damit das nicht in Wildwest-Manier geschieht, gibt es ein Hintergrundprogramm, das du als Anwender nicht zu Gesicht bekommst. Dieses Programm übernimmt das Kopieren der I/O-Daten zwischen den Abbildern.
Im Vergleich zu Steuerungen, bei denen PLC-I/O und HW-I/O identisch sind, ist das Verknüpfen natürlich eine zusätzliche Arbeit. Die Trennung hat aber den Vorteil, dass man seine PLC-I/O nicht unbedingt als globalen Variebalenblock anlegen muss, sondern sie dort unterbringen kann, wo sie hingehören, nämlich in die FBs für die Baugruppen. Aus diesem Grund ist die Deklaration mit AT %I*/Q* bei Beckhoff gang und gäbe.
 
Ich hab gerade mal testweise einen Eingang mit AT %I* in dem FB angelegt. TwinCAT bietet mir beim Verknüpfen diesen Eingang sogar für jede Instanzen separat an! Top, das vereinfacht einiges.

VariablenverknüpfungInput.JPG

Vielen Dank Euch beiden. :s12:

Gruß
Jörn
 
Zurück
Oben