Step 7 Erste Übung mit UDT-Array (Fehler beim CPU Start)

Noebsi

Level-2
Beiträge
25
Reaktionspunkte
1
Ein erneutes Hallo!
Auf meinem Weg mir selbstständig die S7 PLC Programmierung beizubringen bin ich bei einem neuen Projekt auf einen Fehler gestoßen.

Ich habe eine SCL Quelle erstellt und diese in einen FB umgewandelt und im OB1 aufgerufen. Der dazugehörige DB wurde erstellt und die Zuweisungen in der Symbolliste wurden angegeben. Beim Übersetzen gibt es keine Fehler.

Mein SCL Programm soll ein Parkhaus darstellen, bei welchem mittels eines UDT Array (in einem globalen DB2) in dem sich je eine Ticketnummer(INT), eine Aktivierungsabfrage(BOOL) und eine Zahlungsabfrage(BOOL) befinden, Tickets beim Einfahren ausgegeben werden sollen.
Danach muss das Ticket bezahlt werden und erst mit Erhalt eines Tickets das bezahlt wurde soll die Ausfahrt möglich sein.
Es gibt auch eine Ampelregelung und einige andere Funktionen, aber ich denke der Fehler liegt irgendwo beim UDT, da ich noch nie mit einem gearbeitet habe.

Mir ist bewusst dass, bei dem Programm noch deutlich Zeilen gespart werden können, jedoch lasse ich es vorerst zum Funktionstest in der Rohform.

Bei meinem ersten Versuch das Programm zu testen bekomme ich nun leider einen CPU Stopp mit einem Bereichslängenfehler.
Ich vermute, dass das bedeutet, dass ich an irgendeiner Stelle im Programm Daten auf eine Variable schreiben will, die nicht genug Speicherplatz dafür besitzt, oder?

Beim Anklicken von "Gehe zu" springt er zur Zeile mit dem Inhalt: "IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN".
Ist eventuell mein Aufruf des Bool "Bezahlt" von UDT im DB2 falsch? N wird bei der Deklarierung mit 1 beschrieben und sollte nicht leer sein.

Ich hänge hier mein Programm (Im nächsten Post, sonst zu lang) sowie ein Bild vom Fehler und der Symbolliste an.
Eventuell will mir ja jemand beim Fehlersuchen helfen.(Programmiert auf einer 300erCPU)

Für Tipps, Verbesserungsvorschläge, etc. bin ich jeder Zeit offen, da mir das hoffentlich beim weiteren Lernen helfen wird!

1731576224341.png1731576254558.png
 
Hier der Code:

Code:
//TYPE
// Erstellen einer UDT für Tickets
//    UDT0 STRUCT
//            Nummer : INT := 0;
//            Aktivierung : BOOL := FALSE;
//            Bezahlt : BOOL := FALSE;
//        END_STRUCT;
//END_TYPE

FUNCTION_BLOCK FB1

VAR_INPUT
    //Eingänge
    IS1_E : BOOL := FALSE; //Induktionsschleife 1 Parkhaus Einfahrt
    IS2_E : BOOL := FALSE; //Induktionsschleife 2 Parkhaus Einfahrt
    TASTER : BOOL := FALSE; //Ticketanforderung
    ZAHLEN : BOOL := FALSE; //Taster zum zahlen des Tickets
    IS1_A : BOOL := FALSE; //Induktionsschleife 1 Parkhaus Ausfahrt
    IS2_A : BOOL := FALSE; //Induktionsschleife 2 Parkhaus Ausfahrt
    N : INT := 1; //Ticketnummer welche beim Bezahlen und Ausfahren angegeben werden muss
    //Induktionsschleifen 1.OG
    IS1_1OG_E : BOOL := FALSE;
    IS2_1OG_E : BOOL := FALSE;
    IS1_1OG_A : BOOL := FALSE;
    IS2_1OG_A : BOOL := FALSE;
    //Induktionsschleifen 2.OG
    IS1_2OG_E : BOOL := FALSE;
    IS2_2OG_E : BOOL := FALSE;
    IS1_2OG_A : BOOL := FALSE;
    IS2_2OG_A : BOOL := FALSE;
    //Induktionsschleifen 3.OG
    IS1_3OG_E : BOOL := FALSE;
    IS2_3OG_E : BOOL := FALSE;
    IS1_3OG_A : BOOL := FALSE;
    IS2_3OG_A : BOOL := FALSE;
    //Induktionsschleifen 4.OG
    IS1_4OG_E : BOOL := FALSE;
    IS2_4OG_E : BOOL := FALSE;
    IS1_4OG_A : BOOL := FALSE;
    IS2_4OG_A : BOOL := FALSE;
    //Induktionsschleifen 5.OG
    IS1_5OG_E : BOOL := FALSE;
    IS2_5OG_E : BOOL := FALSE;
    IS1_5OG_A : BOOL := FALSE;
    IS2_5OG_A : BOOL := FALSE;
    //Induktionsschleifen 6.OG
    IS1_6OG_E : BOOL := FALSE;
    IS2_6OG_E : BOOL := FALSE;
    IS1_6OG_A : BOOL := FALSE;
    IS2_6OG_A : BOOL := FALSE;
    //Induktionsschleifen 7.OG
    IS1_7OG_E : BOOL := FALSE;
    IS2_7OG_E : BOOL := FALSE;
    IS1_7OG_A : BOOL := FALSE;
    IS2_7OG_A : BOOL := FALSE;
    //Induktionsschleifen 8.OG
    IS1_8OG_E : BOOL := FALSE;
    IS2_8OG_E : BOOL := FALSE;
    IS1_8OG_A : BOOL := FALSE;
    IS2_8OG_A : BOOL := FALSE;              
END_VAR

VAR_OUTPUT
    //Ausgänge
    R_E : BOOL := FALSE; //Rot Einfahrt
    G_E : BOOL := TRUE; //Grün Einfahrt
    //Ampel 1.OG
    R_1 : BOOL := FALSE;
    G_1 : BOOL := TRUE;
    //Ampel 2.OG
    R_2 : BOOL := FALSE;
    G_2 : BOOL := TRUE;
    //Ampel 3.OG
    R_3 : BOOL := FALSE;
    G_3 : BOOL := TRUE;
    //Ampel 4.OG
    R_4 : BOOL := FALSE;
    G_4 : BOOL := TRUE;
    //Ampel 5.OG
    R_5 : BOOL := FALSE;
    G_5 : BOOL := TRUE;
    //Ampel 6.OG
    R_6 : BOOL := FALSE;
    G_6 : BOOL := TRUE;
    //Ampel 7.OG
    R_7 : BOOL := FALSE;
    G_7 : BOOL := TRUE;
    //8.OG hat keine Ampel
    SCHRANKE_E : BOOL := FALSE; //Öffne Schranke am Eingang (Schließt automatisch nach wegnehmen der Ansteuerung)
    SCHRANKE_A : BOOL := FALSE; //Öffne Schranke am Ausgang (Schließt automatisch nach wegnehmen der Ansteuerung)
    NUMMER : INT := 1; //Ticketnummer, welche von Array ausgegeben wird
    SPACES : INT := 288; //Anzahl der gesamt freien Parkplätze
END_VAR

VAR_IN_OUT
    //INOUT Variablen
END_VAR

VAR_TEMP
    //Temporäre Variablen
END_VAR

VAR
    //Statische Variablen
    //Anzahl Parkplätze in OGs
    s1OG : INT := 32;
    s2OG : INT := 32;
    s3OG : INT := 32;
    s4OG : INT := 32;
    s5OG : INT := 32;
    s6OG : INT := 32;
    s7OG : INT := 32;
    s8OG : INT := 32;
END_VAR
    // Anweisungsteil
   
    //Schrankensteuerung Einfahrt
    IF IS1_E AND R_E <> TRUE AND TASTER THEN
        SCHRANKE_E := TRUE;
    ELSE
        SCHRANKE_E := FALSE;
    END_IF;

    //Schrankensteuerung Ausfahrt
    IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN
        SCHRANKE_A := TRUE;
    ELSE
        SCHRANKE_A := FALSE;
    END_IF;
   
    //Ticketberechnung
    //Bei Einfahren  
    IF SCHRANKE_E THEN
        NUMMER := 1;
        WHILE DB2.TICKET[NUMMER].Aktivierung = TRUE DO //Checke nächstes freies Ticket bei neuem PKW
            NUMMER := NUMMER+1;
        END_WHILE;      
        DB2.TICKET[NUMMER].Nummer := NUMMER;
        DB2.TICKET[NUMMER].Aktivierung := TRUE;
    END_IF;
    //Bei Bezahlen
    IF ZAHLEN AND DB2.TICKET[N].Aktivierung AND NOT DB2.TICKET[N].Bezahlt THEN
        DB2.TICKET[N].Bezahlt := TRUE;
    END_IF;
    //Bei Ausfahren
    IF SCHRANKE_A AND IS2_A THEN
        DB2.TICKET[N].Nummer := 0; //N ist vom Autofahrer selbst einzugeben (Normalerweise Ticketcode)
        DB2.TICKET[N].Aktivierung := FALSE;
        DB2.TICKET[N].Bezahlt := FALSE;
    END_IF;
   
    //Platzberechnung
    //Gesamtes Parkhaus
    //Bei Einfahrt 1 Platz gesamt weniger
    IF IS1_E AND IS2_E THEN
          SPACES:=SPACES-1;
          IF SPACES < 0 THEN
            SPACES := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt 1 Platz gesamt mehr
    IF IS1_A AND IS2_A THEN
        SPACES:=SPACES+1;
        IF SPACES > 288 THEN
            SPACES := 288;
        END_IF;
    END_IF;
    //1.OG
    //Bei Einfahrt in 1.OG 1 PLatz weniger
    IF IS1_1OG_E AND IS2_1OG_E THEN
          s1OG:=s1OG-1;
          IF s1OG < 0 THEN
            s1OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 1.OG 1 Platz mehr
    IF IS1_1OG_A AND IS2_1OG_A THEN
        s1OG:=s1OG+1;
        IF s1OG > 32 THEN
            s1OG := 32;
        END_IF;
    END_IF;
    //2.OG
    //Bei Einfahrt in 2.OG 1 PLatz weniger
    IF IS1_2OG_E AND IS2_2OG_E THEN
          s2OG:=s2OG-1;
          IF s2OG < 0 THEN
            s2OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 2.OG 1 Platz mehr
    IF IS1_2OG_A AND IS2_2OG_A THEN
        s2OG:=s2OG+1;
        IF s2OG > 32 THEN
            s2OG := 32;
        END_IF;
    END_IF;
    //3.OG
    //Bei Einfahrt in 3.OG 1 PLatz weniger
    IF IS1_3OG_E AND IS2_3OG_E THEN
          s3OG:=s3OG-1;
          IF s3OG < 0 THEN
            s3OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 3.OG 1 Platz mehr
    IF IS1_3OG_A AND IS2_3OG_A THEN
        s3OG:=s3OG+1;
        IF s3OG > 32 THEN
            s3OG := 32;
        END_IF;
    END_IF;
    //4.OG
    //Bei Einfahrt in 4.OG 1 PLatz weniger
    IF IS1_4OG_E AND IS2_4OG_E THEN
          s4OG:=s4OG-1;
          IF s4OG < 0 THEN
            s4OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 4.OG 1 Platz mehr
    IF IS1_4OG_A AND IS2_4OG_A THEN
        s4OG:=s4OG+1;
        IF s4OG > 32 THEN
            s4OG := 32;
        END_IF;
    END_IF;
    //5.OG
    //Bei Einfahrt in 5.OG 1 PLatz weniger
    IF IS1_5OG_E AND IS2_5OG_E THEN
          s5OG:=s5OG-1;
          IF s5OG < 0 THEN
            s5OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 5.OG 1 Platz mehr
    IF IS1_5OG_A AND IS2_5OG_A THEN
        s5OG:=s5OG+1;
        IF s5OG > 32 THEN
            s5OG := 32;
        END_IF;
    END_IF;
    //6.OG
    //Bei Einfahrt in 6.OG 1 PLatz weniger
    IF IS1_6OG_E AND IS2_6OG_E THEN
          s6OG:=s6OG-1;
          IF s6OG < 0 THEN
            s6OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 6.OG 1 Platz mehr
    IF IS1_6OG_A AND IS2_6OG_A THEN
        s6OG:=s6OG+1;
        IF s6OG > 32 THEN
            s6OG := 32;
        END_IF;
    END_IF;
    //7.OG
    //Bei Einfahrt in 7.OG 1 PLatz weniger
    IF IS1_7OG_E AND IS2_7OG_E THEN
          s7OG:=s7OG-1;
          IF s7OG < 0 THEN
            s7OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 7.OG 1 Platz mehr
    IF IS1_7OG_A AND IS2_7OG_A THEN
        s7OG:=s7OG+1;
        IF s7OG > 32 THEN
            s7OG := 32;
        END_IF;
    END_IF;
    //8.OG
    //Bei Einfahrt in 8.OG 1 PLatz weniger
    IF IS1_8OG_E AND IS2_8OG_E THEN
          s8OG:=s8OG-1;
          IF s8OG < 0 THEN
            s8OG := 0;
          END_IF;
    END_IF;
    //Bei Ausfahrt aus 8.OG 1 Platz mehr
    IF IS1_8OG_A AND IS2_8OG_A THEN
        s8OG:=s8OG+1;
        IF s8OG > 32 THEN
            s8OG := 32;
        END_IF;
    END_IF;
   
    //Ampelsteuerung
    //Einfahrt Parkhaus
    IF SPACES = 0 THEN
        R_E := TRUE;
        G_E := FALSE;
    ELSE
        R_E := FALSE;
        G_E := TRUE;      
    END_IF;
    //1.OG
    IF s1OG = 0 THEN
        R_1 := TRUE;
        G_1 := FALSE;
    ELSE
        R_1 := FALSE;
        G_1 := TRUE;
    END_IF;
    //2.OG
    IF s2OG = 0 THEN
        R_2 := TRUE;
        G_2 := FALSE;
    ELSE
        R_2 := FALSE;
        G_2 := TRUE;
    END_IF;
    //3.OG
    IF s3OG = 0 THEN
        R_3 := TRUE;
        G_3 := FALSE;
    ELSE
        R_3 := FALSE;
        G_3 := TRUE;
    END_IF;
    //4.OG
    IF s4OG = 0 THEN
        R_4 := TRUE;
        G_4 := FALSE;
    ELSE
        R_4 := FALSE;
        G_4 := TRUE;
    END_IF;
    //5.OG
    IF s5OG = 0 THEN
        R_5 := TRUE;
        G_5 := FALSE;
    ELSE
        R_5 := FALSE;
        G_5 := TRUE;
    END_IF;
    //6.OG
    IF s6OG = 0 THEN
        R_6 := TRUE;
        G_6 := FALSE;
    ELSE
        R_6 := FALSE;
        G_6 := TRUE;
    END_IF;
    //7.OG
    IF s7OG = 0 THEN
        R_7 := TRUE;
        G_7 := FALSE;
    ELSE
        R_7 := FALSE;
        G_7 := TRUE;
    END_IF;
   
    END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Hab mir das Programm nur kurz angesehen. Als ich das erste mal mit SCL in Kontakt gekommen bin hat der Tutor vor While..Do gewarnt, er meinte "macht das besser mit einer For..Next Schleife, die hat man besser im Griff". Aber das ist nicht (direkt) der Auslöser deines Bereichslängenfehlers. Ich gehe davon aus:
WHILE DB2.TICKET[NUMMER].Aktivierung = TRUE DO //Checke nächstes freies Ticket bei neuem PKW NUMMER := NUMMER+1; END_WHILE;
Du wirst mit dem NUMMER := NUMMER +1; über der max. Länge sein. Begrenze das mal dann sollte der Fehler weg sein...
 
Hab mir das Programm nur kurz angesehen. Als ich das erste mal mit SCL in Kontakt gekommen bin hat der Tutor vor While..Do gewarnt, er meinte "macht das besser mit einer For..Next Schleife, die hat man besser im Griff". Aber das ist nicht (direkt) der Auslöser deines Bereichslängenfehlers. Ich gehe davon aus:

Du wirst mit dem NUMMER := NUMMER +1; über der max. Länge sein. Begrenze das mal dann sollte der Fehler weg sein...
Hat leider nicht geholfen, ich bekomme nach wie vor einen Bereichslängenfehler, der mir auf die Zeile (sieh Bild) zeigt.
Danke trotzdem für deinen Beitrag, ich versuche While dann in Zukunft nicht zu verwenden wenn möglich.
1731578662757.png
 
Schreibst du auf N direkt dein EW drauf? Dann wird es daran liegen das ein INT von -32768 bis 32767 geht...
Du meinst weil mein Array nur 288 groß ist und ich ein Int zum identifizieren nehme?
Aber der Int ist doch schon bei Beginn mit 1 definiert, damit nicht ein undefinierter Wert hinterlegt ist.

Update: Habs trotzdem mal ausprobiert und alle N und NUMMER Aufrufe einfach durch die Zahl 1 ersetzt. Der Fehler bleibt gleich.
Update2:
Hab folgenden Code aus kommentiert und die CPU läuft tadellos:

Code:
//Schrankensteuerung Einfahrt
    IF IS1_E AND R_E <> TRUE AND TASTER THEN
        SCHRANKE_E := TRUE;
    ELSE
        SCHRANKE_E := FALSE;
    END_IF;

    //Schrankensteuerung Ausfahrt
    IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN
        SCHRANKE_A := TRUE;
    ELSE
        SCHRANKE_A := FALSE;
    END_IF;
  
    //Ticketberechnung
    //Bei Einfahren 
    IF SCHRANKE_E THEN
        NUMMER := 1;
        WHILE DB2.TICKET[NUMMER].Aktivierung = TRUE AND NUMMER <= 288 DO //Checke nächstes freies Ticket bei neuem PKW
            NUMMER := NUMMER+1;
        END_WHILE;     
        DB2.TICKET[NUMMER].Nummer := NUMMER;
        DB2.TICKET[NUMMER].Aktivierung := TRUE;
    END_IF;
    //Bei Bezahlen
    IF ZAHLEN AND DB2.TICKET[N].Aktivierung AND NOT DB2.TICKET[N].Bezahlt THEN
        DB2.TICKET[N].Bezahlt := TRUE;
    END_IF;
    //Bei Ausfahren
    IF SCHRANKE_A AND IS2_A THEN
        DB2.TICKET[N].Nummer := 0; //N ist vom Autofahrer selbst einzugeben (Normalerweise Ticketcode)
        DB2.TICKET[N].Aktivierung := FALSE;
        DB2.TICKET[N].Bezahlt := FALSE;
    END_IF;

Liegt es an dem Intechar Problem von dem rar gesprochen hat? Und falls ja, kann mir das jemand genauer erklären?
Sind meine DB Aufrufe korrekt, oder gehören die für die UDTs eventuell anders verfasst?

Benütze wie gesagt zum ersten Mal UDTs.

Update 3:
Soooo, per Ausschlussverfahren hab ich mittlerweile die CPU ohne Crash zum Laufen bekommen, solange ich diese beiden Code-Blöcke aus kommentiert lasse:

1731585113097.png
 
Zuletzt bearbeitet:
Ich schreibe einfach Mal meinen Suchprozess/Gedankengang mit, da ich nicht sicher bin ob ich das richtig mache.


Stand jetzt weiß ich, dass mir folgende Zeilen das Problem bereiten:
1.
IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN
END_IF;

2.
IF ZAHLEN AND DB2.TICKET[N].Aktivierung AND NOT DB2.TICKET[N].Bezahlt THEN
DB2.TICKET[N].Bezahlt := TRUE;
END_IF;

Sieht aus als würde das wirklich irgendwas mit dem Int zu tun haben.
Kann mir das jemand erklären? Ich verstehe es nicht ganz.

Die anderen IF wo N und NUMMER verwendet wird, geben wahrscheinlich kein Problem aus, da diese noch nicht aufgerufen werden.
Da bei den 2 IF das N oder NUMMER in der Definition steht wird, das wahrscheinlich der Auslöser sein.

Danke.
BG

Update:
Bingo! Die N und NUMMER Aufrufe sind das Problem, genau wie rar gesagt hat.
Leider weiß ich noch nicht warum.
Mit den aus kommentierten aufrufen und ohne erfüllen der IF Bedingungen stirbt die CPU zumindest nicht mehr.

IF IS1_A (*AND DB2.TICKET[N].Bezahlt = TRUE*) THEN
IF ZAHLEN (*AND DB2.TICKET[N].Aktivierung AND NOT DB2.TICKET[N].Bezahlt*) THEN
 
Zuletzt bearbeitet:
Hast du denn dein EW5 an den IN N deines Bausteines geschrieben? Dann nimmt der nicht die 1 vom Baustein sondern den Wert vom Wert am IN N. Zeig doch mal den Baustein Aufruf
 
Hast du denn dein EW5 an den IN N deines Bausteines geschrieben? Dann nimmt der nicht die 1 vom Baustein sondern den Wert vom Wert am IN N. Zeig doch mal den Baustein Aufruf
Achsoo, ok danke ich denke ich verstehe das Problem.
Ja ich habe EW 5 an den Eingang gehängt, da ich später meine "Ticketnummer" händisch eingeben möchte. (Quasi statt des QR Lesers bei Parkgaragen)
Problem wird sein, dass ich dem Input zwar im Programm 1 zuweise, aber am OB1 EW 5 den Wert 0 einschreibt und die 1 überspielt oder?
Hier der OB1 Aufruf:
1731586791263.png

Wie löse ich denn dann das Problem, wenn ich trotzdem vor Ausfahren oder Bezahlen meine Ticketnummer eingeben möchte?
Einfach das IF nur Aufrufen, wenn N oder NUMMER zwischen 1 und 288 liegen?
BG
 
Danke für die ganzen Hilfestellungen!
Der Fehler war dass mir das EW5 immer 0 in das Programm geschrieben hat und das Array aber bei 1 startet.
Somit die Zahl außerhalb des Bereiches lag.

Ich spiele mich noch etwas, damit ich trotz EW5 ein funktionierendes Programm habe.
Ich möchte ja nach wie vor die Ticketnummer (EW5) händisch eingeben können.

Eigentlich hatte rar es mir am Anfang ja bereits gesagt, aber ich habe leider mit meinem Beginner Wissen nicht ganz verstanden, was er meinte.😅

Update:
Danke noch einmal an alle die geholfen habe!
Das hat im Endeffekt jetzt gereicht, damit die CPU nicht mehr stirbt.
Code:
//N auf 1-288 Begrenzen
    IF N <= 1 THEN
        N := 1;
    ELSIF N >=288 THEN
        N :=288;
    END_IF;
    //NUMMER auf 1-288 Begrenzen
    IF NUMMER <= 1 THEN
        NUMMER := 1;
    ELSIF NUMMER >= 288 THEN
        NUMMER := 288;
    END_IF;

Das Programm selbst hat noch ein-zwei kleinere Fehler die ich ausbessern muss.

BG
 
Zuletzt bearbeitet:
Bau dir doch ein N_intern (als INT im Var anlegen) am Anfang des Bausteins

Code:
N_intern := N;

IF N_intern <=0 Then
     N_intern :=1;
ELSIF N_intern >288 Then
     N_intern :=288;
END_IF;
 
Falls es noch jemanden interessiert, hier ist mein funktionierender Code (noch nicht aufgehübscht/gekürzt, aber funktionsfähig).
Musste das ganze leider als .txt hochladen, da das sonst zu viele Zeichen für einen Post wären.

Bg
 

Anhänge

Hallo Noebsi,

wenn ich so etwas sehe, frage ich mich: Warum?
Code:
//Schrankensteuerung Einfahrt
    IF IS1_E AND R_E <> TRUE AND TASTER THEN          // bezieht sich das <> nur auf R_E oder auf (IS1_E und R_E), was ist gemeint/gewollt?
        SCHRANKE_E := TRUE;
    ELSE
        SCHRANKE_E := FALSE;
    END_IF;

    //Schrankensteuerung Ausfahrt
    IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN
        SCHRANKE_A := TRUE;
    ELSE
        SCHRANKE_A := FALSE;
    END_IF;

warum nicht so:
Code:
//Schrankensteuerung Einfahrt
    SCHRANKE_E := IS1_E AND NOT(R_E) AND TASTER;    // Je nach dem, was gewollt ist, nur diese
    SCHRANKE_E := NOT(IS1_E AND R_E) AND TASTER;    // oder diese Zeile verwenden!

//Schrankensteuerung Ausfahrt
    SCHRANKE_A := IS1_A AND DB2.TICKET[N].Bezahlt;
 
Hallo Noebsi,

wenn ich so etwas sehe, frage ich mich: Warum?
Code:
//Schrankensteuerung Einfahrt
    IF IS1_E AND R_E <> TRUE AND TASTER THEN          // bezieht sich das <> nur auf R_E oder auf (IS1_E und R_E), was ist gemeint/gewollt?
        SCHRANKE_E := TRUE;
    ELSE
        SCHRANKE_E := FALSE;
    END_IF;

    //Schrankensteuerung Ausfahrt
    IF IS1_A AND DB2.TICKET[N].Bezahlt = TRUE THEN
        SCHRANKE_A := TRUE;
    ELSE
        SCHRANKE_A := FALSE;
    END_IF;

warum nicht so:
Code:
//Schrankensteuerung Einfahrt
    SCHRANKE_E := IS1_E AND NOT(R_E) AND TASTER;    // Je nach dem, was gewollt ist, nur diese
    SCHRANKE_E := NOT(IS1_E AND R_E) AND TASTER;    // oder diese Zeile verwenden!

//Schrankensteuerung Ausfahrt
    SCHRANKE_A := IS1_A AND DB2.TICKET[N].Bezahlt;
Schranke_E und Schranke_A müsste noch initialisiert werden oder? Sonst bleibt es dauerhaft TRUE.
 
Wieso?? Die Zuweisungen werden bei jedem Programmdurchlauf bei jedem möglichen Verknüpfungsergebnis ausgeführt - auch bei FALSE. In der normalen "richtigen" Programmversion von Peter Wahlen als auch in der IF-Schwuchtelei IF-Schwurbelei.

PS: Oh sorry, nicht dass sich jemand diskrimiert fühlt. Ich meinte "IF-Schwurbelei", das Wort war mir leider nicht gleich eingefallen. Tut mir leid.
 
Zuletzt bearbeitet:
Zurück
Oben