# Eingänge zu Simulationszwecken softwaremäßig in CoDeSys setzen



## Silversurger (13 November 2010)

Hallo zusammen,

ich hab ein kleines Problem: 
Für Schulungszwecke möchte ich ein Stern-Dreieck-Anlauf programmieren lassen. Die Simulation habe ich gebastelt und die Schulungsteilnehmer sollen das Programm dazu entwerfen (im Hintergrund läuft ein weiteres Programm, um z.B. Bewegungen darzustellen). Damit es keine Probleme mit Variablennamen gibt, greifen meine aktiven Schaltsymbole der Visu (Schalter / Taster) auf Eingangsvariablen (z.B. %IX24.2) zu. Dies funktioniert ohne Probleme! Da ich aber sehr gerne ein Rückmeldekontakt eines Schützes simulieren möchte, sollte ich nun im Hintergrund-Programm ein Eingang setzen können, wie %IX24.5 := %QX24.3; . Dies funktioniert natürlich nicht ... aber ich weiß, dass man dies irgendwie manipulieren kann!! ...Ideen wie Kabel stecken geht nicht, da ja keine Hardware angeschlossen ist!!  

Vielleicht kenn mir jemand helfen!! Ich freu mich über jede Anregung!

Viele Grüße


----------



## ebt'ler (13 November 2010)

Mit Pointern kannst du auch die Eingänge Überschreiben. Aber das müsste in jeden Zyklus vor der Abfrage geschehen.

Wieso verwendest du nicht einfah irgentwelche Variablen?


----------



## Silversurger (13 November 2010)

Mit Pointern? ...wie sollte das funktionieren? Hab aber auch so etwas gelesen! ...ich hab jetzt mal versucht, ein Pointer auf das Eingangsarray zu legen! Hab dann mit der PUTBIT-Anweisung das fünfte Bit gesetzt und meinem Pointer zurückgegeben, aber mein Eingang bleibt statisch!!

Ich kann keine einfachen Variablen benutzen, da ich es meinen Schulungsteilnehmern gerne ermöglichen möchte, dass sie selbst die Variablennamen festlegen können!


----------



## Silversurger (14 November 2010)

*Lösung*

So, hab das Problem nun selbst gelöst!!

Zuerst muss man ein Array über die Inputs legen:

(* Übergabe der Eingangsbytes an Array *)
Adr_der_Inputs := ADR(%IB0); (* Deklaration: Adr_der_Inputs: POINTER TO ARRAY [0..63] OF BYTE; *)

Daraufhin kann man mit der PUTBIT-Funktion die einzelnen Bits verändern (hier das Bit 5) und schon funktionierts:

(* Manipulation der Inputs für Rückmeldekontakt Stern-Schütz *)
IF %QX24.2
THEN
    Adr_der_Inputs^[48] := DWORD_TO_BYTE(PUTBIT(Adr_der_Inputs^[48], 5, TRUE));
ELSE
    Adr_der_Inputs^[48] := DWORD_TO_BYTE(PUTBIT(Adr_der_Inputs^[48], 5, FALSE));
END_IF

Weshalb ich allerdings mit meinem Pointer auf das IB 48 zeigen muss, obwohl ich auf das IB24 zugreifen möchte habe ich nicht verstanden! ...nach 2std try and error hats dann funktioniert!! 

Vielleicht kann mir jemand dies erklären!!


----------



## ebt'ler (14 November 2010)

Ich hätte es so gelöst: 


```
PROGRAM PLC_PRG
VAR
    pt : POINTER TO WORD;
    bit_adr: WORD;
    wert: BOOL;
END_VAR
________________________________________________________

bit_adr := BITADR(%IX0.0);

pt := ADR(%IW0) + bit_adr / 16;
pt^ := pt^  AND NOT SHL( BOOL_TO_WORD (1) , bit_adr MOD 16);
IF wert = 1 THEN
pt^ := pt^ OR SHL( BOOL_TO_WORD (1) , bit_adr MOD 16);
END_IF
```
Mit "wert" bestimmst du dann ob das Bit auf 0 oder 1 gesetzt werden soll.

Die 48 aus deinen Bsp. kommen daher, dass der Pointer auf ein Array of BYTE gelegt ist, du aber die Eingänge im Format WORD vorliegen hast:
WORDadresse.BITadresse


----------



## Lohrer (24 November 2010)

Silversurger schrieb:


> Hallo zusammen,
> 
> ich hab ein kleines Problem:
> (Schalter / Taster) auf Eingangsvariablen (z.B. %IX24.2) zu. Dies Vielleicht kenn mir jemand helfen!! Ich freu mich über jede Anregung!
> ...


 
Hi,

also ich mache meine Eingangssimulation etwas einfacher als die Kollegen:

ptrEingang := ADR(%IW160);
ptrEingang^.0 := bAblaufrutscheBelegt_i;
ptrEingang^.1 := bMagazinschieberHinten_i; 
ptrEingang^.2 := bMagazinschieberVorne_i; 
ptrEingang^.3 := bHubQuerEinheitRechts_i; 
ptrEingang^.4 := bHubQuerEinheitMitte_i; 
ptrEingang^.5 := bHubQuerEinheitLinks_i; 
ptrEingang^.6 := bHubQuerEinheitOben_i;  
ptrEingang^.7 := bHubQuerEinheitUnten_i;
ptrEingang^.8 := bGreiferOffen_i;  
ptrEingang^.9 := bGreiferGeschlossen_i;
ptrEingang^.10 := bBandeinlaufBelegt_i; 
ptrEingang^.11 := bMagazinLeer_i;  
ptrEingang^.12 := bBehaelterTypA_i; 
ptrEingang^.13 := bBehaelterBereit_i; 
ptrEingang^.14 := bTeilAinZufuehrung_i;
ptrEingang^.15 := bTeilBinZufuehrung_i;

Gruß

Michael


----------



## ebt'ler (24 November 2010)

Die Bitadresse ist zwar nicht dynamisch, aber je nach Anwendung ist es eine schönere Lösung.


----------



## Ralle (16 Januar 2011)

ebt'ler schrieb:


> Ich hätte es so gelöst:
> 
> 
> ```
> ...



Weil du in einem andern Beitrag auf diesen Thread hier verweist hätte ich eine Frage zu deinem Code.

Wo genau wird der Variablen "wert" ein Wert zugewiesen oder wo wird auf "wert" verwiesen?


----------



## BerndAllgäu (16 Januar 2011)

hier noch meine "Version"

(*Kassetten-Vorhanden über Visu simulieren*)
IF KassetteVorhanden
THEN
    pBool:=ADR(ST01_403_B3_6.BitInToCheck);
    pBool^:=TRUE;
    pBool:=ADR(ST01_403_B3_7.BitInToCheck);
    pBool^:=TRUE;
END_IF


----------



## Thomas_v2.1 (16 Januar 2011)

BerndAllgäu schrieb:


> hier noch meine "Version"
> 
> (*Kassetten-Vorhanden über Visu simulieren*)
> IF KassetteVorhanden
> ...



Hallo Bernd,
ich hatte das mal so wie du in einer etwas anderen Weise probiert, siehe hier:
http://www.sps-forum.de/showpost.php?p=296163&postcount=4
musste aber nachher feststellen dass es nicht ging. Welchen Datentyp hat deine Variable pBool? Ich nehme doch an auch POINTER TO BOOL oder?


----------



## ebt'ler (16 Januar 2011)

Ralle schrieb:


> Wo genau wird der Variablen "wert" ein Wert zugewiesen oder wo wird auf "wert" verwiesen?



In dem Codeschnipsel sollte nur verdeutlicht werden wie man den Wert von "wert" auf eine beliegige Bitadresse zuweisen kann. 
Wie die Variable dabei zu ihren Wert kommt ist für die Funktion erstmal egla, daher hab ich es auch weggelassen.
Das Beispiel ist nicht vollkommen ausgereift, sicherlich ist es auch sinnvoller sowas in einen FB auszulagern, dem dann der zu setzende Wert, die Offsetaddresse und der Speicherbereich (I,Q oder M) übergeben wird.

Man kann da also noch ein bischen feilen.


----------



## BerndAllgäu (16 Januar 2011)

Thomas_v2.1 schrieb:


> Hallo Bernd,
> ich hatte das mal so wie du in einer etwas anderen Weise probiert, siehe hier:
> http://www.sps-forum.de/showpost.php?p=296163&postcount=4
> musste aber nachher feststellen dass es nicht ging. Welchen Datentyp hat deine Variable pBool? Ich nehme doch an auch POINTER TO BOOL oder?



ja klar ->  POINTER TO BOOL 

    pBool                            :    POINTER TO BOOL;

hätt ich ja gleich dazu schreiben können *g*

funzt bei mir einwandfrei...

Gruß Bernd


----------

