Einausgaenge in Structur initialisieren

Ebias

Level-1
Beiträge
12
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich moechte die IO variablen in folgender Structur initialisieren:
TYPE T_CYL :
STRUCT
ndi_on : BOOL;
ndi_off :BOOL;
ndo_on :BOOL;
ndo_off :BOOL;
pb_on :BOOL;
pb_off :BOOL;

END_STRUCT
END_TYPE

Habe folgendes versucht:

IF NOT bFlag
THEN
bFlag := TRUE;
cyl_sig.ndi_off := %IX0.0 ;
cyl_sig.ndi_on := %IX0.1;
cyl_sig.ndo_off := %QX0.0;
cyl_sig.ndo_on := %QX0.1;
cyl_sig.pb_off :=%M*;
cyl_sig.pb_on :=%M*;

END_IF;

cyl_sig.ndo_off := cyl_sig.ndi_off OR cyl_sig.pb_off;
cyl_sig.ndo_on:= cyl_sig.ndi_on OR cyl_sig.pb_on;

Funtioniert aber leider nicht.
%IX0.0 kann einschalten, aber cyl_sig.ndi_off wird nicht gesetzt.
Natuerlich cyl_sig.ndo_off natuerlich auch nicht.

Vielen Dankf fuer jede Hilfe.
 
IF NOT bFlag
THEN
bFlag := TRUE;
cyl_sig.ndi_off := %IX0.0 ;
cyl_sig.ndi_on := %IX0.1;
cyl_sig.ndo_off := %QX0.0;
cyl_sig.ndo_on := %QX0.1;
cyl_sig.pb_off :=%M*;
cyl_sig.pb_on :=%M*;

END_IF;

cyl_sig.ndo_off := cyl_sig.ndi_off OR cyl_sig.pb_off;
cyl_sig.ndo_on:= cyl_sig.ndi_on OR cyl_sig.pb_on;

Funtioniert aber leider nicht.
%IX0.0 kann einschalten, aber cyl_sig.ndi_off wird nicht gesetzt.
Natuerlich cyl_sig.ndo_off natuerlich auch nicht.

Vielen Dankf fuer jede Hilfe.
cyl_sig.ndi_off := %IX0.0 gilt nur für einen Zyklus, nämlich solange bFlag = FALSE ist. Nur in diesem Zyklus findet eine Zuweisung des Zustands von %IX0.0 auf cyl_sig.ndi_off usw. statt. War %IX0.0 im Zyklus der Zuweisung = FALSE, dann bleibt das auch so.

Das Konzept geht so nicht, wenn du damit bezwecken willst, dass während des ganzen Programms die EIn-/Ausgänge abgefragt werden.

Du könntest gleich bei der Deklaration in der Struktur die E/As zuweisen oder das ganze gleich über Variablen machen.
Oder lass gleich diese bFlag-Abfrage sein.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Die IO variablen sollen eher auf die physicalischen Ein/Ausgaenge zeigen.
Pointer habe ich auch schon versucht, aber nicht den richtigen Weg gefunden.
Die Structure direkt zu initialisieren geht nicht, da ich sie ja fuer eine Anzahl von
Cylindern einsetzen will.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und wieso mappst du nicht zunächst alle in Frage kommenden I/Os auf Variablen ...
Code:
bIn1 := %IX0.0;
bIn2 := %IX0.1;
Und später im Programmablauf machst du dann nur noch:
Code:
cyl_sig.ndi_off  := bIn1  ;
cyl_sig.ndi_on  := bIn2 ;
usw.

Ich verstehe noch nicht so recht den Anwendungsfall und den Grund für dein "bFlag". Eine einmalige Zuweisung macht für mich keinen Sinn, wenn du später auf die Eingänge reagieren willst.
Wenn du während des Programms dynamisch die I/Os auf verschiedene Strukturinstanzen mappen willst, bleibt dir gar keine andere Möglichkeit als entweder (statisch) die I/Os durch Variablen (oder auch direkt) zuzuweisen oder (dynamisch) mit Pointern zu arbeiten.
Kannst du mal bitte näher erläutern?

btw.:
Verwendet du TwinCAT oder nen allgemeines CoDeSys?
 
Der Gedanke hinter dem bFlag ist das am begin des Programs initialisiert wird. Eben Pointer oder dergleichen.
Und dann laeuft das Program ja eh zyklisch im Task.
Die cyl_sig structure soll eben alle signale halten, die fuer einen simplen zylinder noetig sind. Die structure soll dann in einem FB_Cyl sein Zuhause finden. Der FB_cyl waere dann der blue print fuer simple zylinder.
Pointer waeren eh okay. Aber wie ist die frage. Auf ein/ausgaenge kann ich nur mit BITADR dereferenzieren. Sobald ich dann aber versuche mit ^ zu referenzieren stuerzt mit die echtzeit mit einem page fehler ab. D.h. der pointer pointed nicht richtig.
Was waere das gegenstueck fuer BITADR, oder wie kann ich IO referenzen an einen FB weiter reichen. Oder gibt es ein array mit einem system namen in dem die IOs liegen ?

Vielen Dank fuer die Hilfe!

P.S. TwinCat
 
Na wenn du eh TwinCAT nutzt, dann pfeiff doch auf die Adressierung ;)

Bastel dir den Baustein und mach die Adressierung so:
Code:
FUNCTION BLOCK FB_Zylinder
VAR
  ndi_on [B]AT%I*[/B]: BOOL;
  ndi_off [B]AT%I*[/B]: BOOL;
...
END_VAR
Oder du deklarierst die I/Os noch eine Ebene höher schon in den Strukturen:
Code:
TYPE T_CYL :
  STRUCT
    ndi_on [B]AT%I*[/B]: BOOL;
    ndi_off [B]AT%I*[/B]: BOOL;
    ndo_on [B]AT%Q*[/B]: BOOL;
    ndo_off [B]AT%Q*[/B]: BOOL;
    pb_on :BOOL;
    pb_off :BOOL;
  END_STRUCT
END_TYPE
Später instanzierst du dann soviele FBs wie du willst. Im System Manager tauchen die dann alle als I/Os deiner FBs auf:
Code:
FB_1.ndi_on
... 
FB_2.ndi_on
...
oder tiefer in den Strukturen
Code:
FB_1.stMyStruct.ndi_on
... 
FB_2.stMyStruct.ndi_on
...
und du kannst die schön verlinken.

Mit Pointer arbeiten würde ich dir nicht empfehlen. Wie du schon bemerkt hast, kann da einiges in die Hose gehen.
Da die I/Os ja eh beim Systemstart feststehen, benötigst du doch auch gar keine dynamische Adressierung, oder? Oder ändert sich die elektrische Verschaltung während des Ablaufs? Denke mal eher nicht.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
@trinitaucher

Genau das meinte ich. Den Beitrag hatte ich nicht mehr gefunden, indem das vor einiger Zeit mal behandelt wurde.
 
Das hoert sich soweit gut an,
gibt mir aber den compiler error:

ERROR 3278: T_CYL(5) invalid address: '%I*'

Gleiches natuerlich auch fuer die Ausgaenge.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Das setzt sich dann aber bei allen instantzen der structure fort.
Dh.

cyl1 T_CYL;
cyl2 T_CYL;

Verwenden die gleichen Ein/Ausgaenge.
Das sollte aber nicht sein.

Vielen Dank.
 
... heisst das, nicht dies ( IX0.0) verwenden,
oder die Ausgaengen sollen sich nicht ueber die structuren kopieren?
 
@Gerhard K
Ja, der Fehler muss irgendwo anders liegen. Ich verwende z.B. in meinen Programmen keine einzige direkt adressierte Variable. Genau das macht für mich eine Hardware unabhängige Programmierung aus.

LG
 
TwinCAT kann mit indirekten Adresse umgehen. %I* oder %Q* sollte kein Problem sein! ...ich nutz auch nichts anderes.

@ Ebias:
Was fürn Zielsystem verwendest du? Einen PC/CX oder nen BC?
 
Zurück
Oben