Step 7 SCL FB in AWL oder FUP umwandeln

Zuviel Werbung?
-> Hier kostenlos registrieren
Mal zum Verständnis des Codes:
Code:
DATA_BLOCK DB32  FB32BEGIN
END_DATA_BLOCK


FUNCTION_BLOCK FB32
TITLE='Ablauf Einschub'


VAR
    bTeilEinschubGesehen:BOOL;
END_VAR


// Überwachung Teileeinschub


IF oLinearschiene_eFrei = false THEN
    bTeilEinschubGesehen := true;
END_IF;


// Schrittkette


CASE BYTE_TO_INT(a1c_step) OF


    1:  // Warten auf Start
    
        IF (a1c_sync = 0) THEN
            sm_wsb := false;
        END_IF;
        
    2:  // Prüfen ob Nest leer ist
    
        IF oLinearschiene_eFrei = false THEN
            IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ;
            ELSE
                sf_fehler(Fehlernummer := 1327, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step)); 
            END_IF;    
            sc_nextstep := a1c_step;
        ELSIF oEinschub_eTeil_InHalter = true AND oDebug_BrueckenTeilInHal = false THEN
            IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ;
            ELSE
                sf_fehler(Fehlernummer := 1324, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step));
            END_IF;
            sc_nextstep := a1c_step;
        ELSIF oDebug_BrueckenTeilInHal = true THEN
            sf_fehler(Fehlernummer := 1326, Fehlerart := sk_hinweis, Diagnosenummer := BYTE_TO_INT(a1c_step));     
        END_IF;
        
        bTeilEinschubGesehen := false; // Vorbereitung um Teileeinschub zu sehen
        
    3:    
    
        sf_wait(wait_time := T#30000ms);
        
        IF xa0_run.bLeerfahrtRundtischAktiv = true then
            a1c_sync := 0;
            sc_nextstep := 1;            
        ELSIF sc_Funktionsprogramm_nr = 1 THEN // Geistermodus
            IF oZufuehrung_eTeilBereit = true THEN
                sf_fehler(Fehlernummer := 1322, Fehlerart := sk_Hinweis, Diagnosenummer := BYTE_TO_INT(a1c_step));
            ELSE
                sm_wsb := true;
            END_IF;
        elsIF oZufuehrung_eTeilBereit = true THEN
            sm_wsb := true;
        ELSIF sm_wsb = true AND xa0_run.bLeerfahrtLinearAktiv = true THEN
            xa0_run.bLeerfahrtRundtischAktiv := true;
            a1c_sync := 0;
            sc_nextstep := 1;         
        elsIF sm_wsb = true then
            sf_fehler(Fehlernummer := 1320, Fehlerart := sk_Hinweis, Diagnosenummer := BYTE_TO_INT(a1c_step));
            sm_wsb := false;            
        END_IF;    
        
    4:
    
        oVereinzelung1(bewegung := 1);
        
    5:
    
        oVereinzelung2(bewegung := 1);
        
    6:
        
        sf_wait(wait_time := T#10000ms);
        
        IF sc_Funktionsprogramm_nr = 1 THEN // Geistermodus
            sm_wsb := true;
        elsIF oZufuehrung_eTeilBereit = false THEN
            sm_wsb := true;
        elsIF sm_wsb = true then
            sf_fehler(Fehlernummer := 1321, Fehlerart := sk_Hinweis, Diagnosenummer := BYTE_TO_INT(a1c_step));
            sm_wsb := false;            
        END_IF;        
        
    7:  ;
        
    8:
    
        oTeilemitnehmer(bewegung := 1);
        
    9:    
    
        oEinschubachse(bewegung := 1);
        
    10: // Klaus "Warten bis Endlage wirklich erreicht"
    
        sf_wait(wait_time := T#1000ms);
        
    11: // Gegenprüfung Sensor Spalt Linearschiene Rundschalttisch
    
        IF bTeilEinschubGesehen = false THEN
            IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ;
            ELSE
                sf_fehler(Fehlernummer := 1323, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step));
            END_IF;
            sc_nextstep := a1c_step;
        END_IF;
        
    12:     
    
        xa0_run.aoTeile[(xa0_run.iAktuelleStellung - 1 + 6) MOD 6].bVorhanden := true;
        xa0_run.aoTeile[(xa0_run.iAktuelleStellung - 1 + 6) MOD 6].bGebohrt := false; 
        xa0_run.aoTeile[(xa0_run.iAktuelleStellung - 1 + 6) MOD 6].bAbgeblasen := false;         
        xa0_run.aoTeile[(xa0_run.iAktuelleStellung - 1 + 6) MOD 6].bGemessen := false;         
        xa0_run.aoTeile[(xa0_run.iAktuelleStellung - 1 + 6) MOD 6].bBewertungGO := false;  
    
    13: // TWE@20160128 - Versuch von Nils Teilmitnehmer während Bewegung Einschubachse nach oben zu fahren.
    
        // oEinschub_aGS := true;
        // oEinschub_aAS := false;


        // sf_wait(wait_time := DINT_TO_TIME(XXD_ALLG_DATEN.iVerzoegerungTeilemitneh)); 
        
        // TWE@20160330 - Neuer Versuch von Nils mit Ventil "Mittelstellung entlüftet" für Einschubachse       
        
        oEinschub_aGS := false;
        oEinschub_aAS := false;
        
        sf_wait(wait_time := T#1000ms);
        
    14:
    
        oTeilemitnehmer(bewegung := 0);
    
    15:
        
        oEinschubachse(bewegung := 0);   
        
    16:    
        
        oVereinzelung1(bewegung := 0);
    
    17:
    
        oVereinzelung2(bewegung := 0);
        
    18: // Prüfen ob Nest belegt ist
    
        IF sc_Funktionsprogramm_nr = 0 AND oEinschub_eTeil_InHalter = false AND oDebug_BrueckenTeilInHal = false THEN
            IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ;
            ELSE
                sf_fehler(Fehlernummer := 1325, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step));
            END_IF;    
            sc_nextstep := a1c_step;
        END_IF;    
        
    19:    
    
        a1c_sync := 0;
        sc_nextstep := 1;
                
ELSE:
    
    sf_fehler(Fehlernummer := 10, Fehlerart := sk_Warnung, Diagnosenummer := BYTE_TO_INT(a1c_step));
    sc_nextstep := a1c_step;
 
END_CASE;


END_FUNCTION_BLOCK
In Zeile 5 z.B.: oVereinzelung2(bewegung := 1);
d.h. er steuert dann den Ausgang oVereinzelung1(A11.0) an und in Zeile 17
oVereinzelung2(bewegung := 0); schaltet den A11.0 ab
richtig?
 
Ich habe jetzt nicht alles duchgelesen aber:


Statt
Code:
IF oLinearschiene_eFrei = false THEN
     bTeilEinschubGesehen := true;
END_IF;

Schreibt man besser:
Code:
IF NOT oLinearschiene_eFrei THEN
     bTeilEinschubGesehen := true;
END_IF;

Etwas vom AWL wegkommen :p
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin Kehrer,

In Zeile 5 z.B.: oVereinzelung2(bewegung := 1);

ich denke mal, Du meinst nicht Zeile 5, sondern das CASE-Ergebnis 5?


d.h. er steuert dann den Ausgang oVereinzelung1(A11.0) an

nein, oVereinzelung ist eine Funktion, die aufgerufen wird und der über den Formalparameter "bewegung" eine 1 mitgegeben wird.


und in Zeile 17
oVereinzelung2(bewegung := 0); schaltet den A11.0 ab
richtig?

s.o.


VG

MFreiberger
 
Und diese ELSE Konstrukte finde ich auch nicht sehr gut:
Code:
IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ; 
ELSE
     sf_fehler(Fehlernummer := 1327, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step)); 
END_IF

Code:
IF a2m_sync = 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
    sf_fehler(Fehlernummer := 1327, Fehlerart := sk_Fehler, Diagnosenummer := BYTE_TO_INT(a1c_step)); 
END_IF
 
Dann hier
Code:
ELSIF oEinschub_eTeil_InHalter = true AND oDebug_BrueckenTeilInHal = false THEN
so?
Code:
ELSEIF oEinschub_eTeil_InHalter  AND NOT oDebug_BrueckenTeilInHal  THEN
 
Da ist ja wohl noch mehr falsch:
Code:
// < 150 ist a0_run Kette// 150 -199 = Funktion
// 200 - 254 = Grunstellung
      L     150
      L     "a0c_step"
      >I    
      SPB   norb


      L     200
      T     #ii
      L     "a0c_step"
      >I    
      SPB   funk


// Grundstellung anfahren
      CALL  "a0_grundstellung" , "xa0_grundstellung"
      SPA   aren


// Funktionen anfahren
funk: CALL  "a0_funktionen" , "xa0_funktionen"
      SPA   aren


[U][B]norb: CALL  "a0_Rundschalttisch" , "xa0_run"[/B][/U]


aren: NOP   0
 
Moin Kehrer,

Da ist ja wohl noch mehr falsch:
Code:
// < 150 ist a0_run Kette// 150 -199 = Funktion
// 200 - 254 = Grunstellung
      L     150
      L     "a0c_step"
      >I    
      SPB   norb


      L     200
      T     #ii
      L     "a0c_step"
      >I    
      SPB   funk


// Grundstellung anfahren
      CALL  "a0_grundstellung" , "xa0_grundstellung"
      SPA   aren


// Funktionen anfahren
funk: CALL  "a0_funktionen" , "xa0_funktionen"
      SPA   aren


[U][B]norb: CALL  "a0_Rundschalttisch" , "xa0_run"[/B][/U]


aren: NOP   0

aha .. jetzt AWL!

Bisher war ja nichts falsch, es gab nur Optimierungsmöglichkeiten :cool:

Die unterstrichene Zeile ist ein FB-Aufruf. Einem FB wird, im Gegensatz zu einer FC ein Instanz-DB mitgegeben. Das ist mit ', "xa0_run"' geschehen.
Also auch nicht falsch...


VG

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
OPEaMAEHgAAAABJRU5ErkJggg==
 
FB4.JPG
so sieht er halt im Projekt aus. D.h den FB gibt es aber und den DB dazu auch
 
Zuletzt bearbeitet:
Wenn ich Einzelsatz ausführe dann passiert bei Case 61 nichts. 60,62,63,64 und 65 werden aber korrekt abgearbeitet
Müsste dann nicht dort stehen also vor case 61
Code:
oTeileauflage(bewegung := 1);

Code:
DATA_BLOCK DB31  FB31
BEGIN
END_DATA_BLOCK

TYPE 
    udtTeil:STRUCT
        bVorhanden:BOOL;
        bGebohrt:BOOL;
        bAbgeblasen:BOOL;
        bGemessen:BOOL;
        bBewertungGO:BOOL;   
    END_STRUCT;
END_TYPE

FUNCTION_BLOCK FB31
TITLE='Ablauf ...'

// Positionen Ablauf                        
//      Aktuelle Stellung
//      |   Nest / Teil                        
//      |   0    1    2    3    4    5
//      1   E                    
//      2   B    E                
//      3   A    B    E            
//      4   M    A    B    E        
//      5   I    M    A    B    E    
//      6   N    I    M    A    B    E(inlegen)
//      1   E    N    I    M    A    B(ohren)
//      2   B    E    N    I    M    A(bblasen)
//      3   A    B    E    N    I    M(essen)
//      4   M    A    B    E    N    I(o-Abwurf)
//      5   I    M    A    B    E    N(iO-Abwurf)
//      6   N    I    M    A    B    E

VAR_TEMP
    step: INT;
END_VAR

VAR
    iAktuelleStellung:INT; // An Zuführung
    aoTeile:ARRAY[0..5] OF udtTeil;
    iTeileInKiste:INT;
    iTeileInNioKiste:INT;
    bLeerfahrtRundtischAktiv:BOOL; // Direktfunktion
    bLeerfahrtLinearAktiv:BOOL; // Direktfunktion
    bTeilNIOAbwurfGesehen:BOOL;
    Zyklus_old:INT;            // Alter Stand Zykluszähler 
    iSchichtIOTeile:DINT;
    iSchichtNIOTeile:DINT;
    iAuftragIOTeile:DINT;
    iAuftragNIOTeile:DINT;
END_VAR

IF oNIORutsche_eTeilSensor1 = true OR oNIORutsche_eTeilSensor2 = true THEN
    bTeilNIOAbwurfGesehen := true;
END_IF;

IF sc_auto_taste = 1 OR oMasch_eTastRundTFertigM = true OR oDebug_Rund_Abbarbeit = true THEN
    oDebug_Rund_Abbarbeit := false;
    bLeerfahrtRundtischAktiv := true;
    sc_auto_taste := 0;
elsIF sc_auto_taste = 5 THEN
    bLeerfahrtLinearAktiv := true;
    sc_auto_taste := 0;        
END_IF;

IF bLeerfahrtRundtischAktiv = true THEN // Anforderung "Rundtschalttisch abbarbeiten und Zyklusende" anzeigen
    oMasch_aTastRundTFertigM := sm_blink0_2;
ELSE
    oMasch_aTastRundTFertigM := false;
END_IF;

IF sm_mod_aktiv = true AND sm_run = false THEN
    sf_fehler(Fehlernummer := 1310, Fehlerart := sk_Hinweis, Diagnosenummer := 0); 
END_IF;

// Anzeigen auf Oberfläche ansteuern
oVisu_mZyklusende := sm_zst_Zyklusende;
oVisu_mRundAbarbeiten := bLeerfahrtRundtischAktiv;

step := BYTE_TO_INT(a0c_step);

CASE step OF

    1: // Warten auf start
        sf_start();
    
    2: 
        
        bLeerfahrtRundtischAktiv := false;
        bLeerfahrtLinearAktiv := false;
    
    3:    
    
        IF iDB_oAutomatikUeberwachu.bAutomatikWarNichtRaus = true THEN
            sc_nextstep := 10;
        END_IF;
    
    4:
        
        iAktuelleStellung := 1;
        sc_nextstep := 60;
        
    10: // Eigentlicher Zyklus - Rundtakt vorbereiten
    
        oTeileauflage(bewegung := 0);
        
    11: 
    
        oAusblasenUnten(bewegung := 1);
    
    12: // Takt
    
        oRundschalttischTakt.iDB_oRundschalttischTakt(); 
        
    13:
    
        iAktuelleStellung := iAktuelleStellung + 1;
        
        IF iAktuelleStellung > 6 then              
            iAktuelleStellung := 1;
        END_IF;  
        
    14:    
    
        oAusblasenUnten(bewegung := 0);
        
    15:     
    
        oTeileauflage(bewegung := 1);
        
    16:
    
        a3c_sync := 1; // Aufgabenverteilung starten
 
    17: // Auf Abarbeitung der Aufgaben warten
    
        IF a3c_sync <> 0 OR a1m_sync <> 0 OR a2m_sync <> 0 OR a11m_sync <> 0 OR a12m_sync <> 0 OR a13m_sync <> 0 OR a16m_sync <> 0 THEN
            sm_wsb := false;         
        END_IF;
        
    18:
    
        sf_wait(wait_time := T#100ms); // Damit Schritt angezeigt wird
        
    19:
    
        IF aoTeile[(iAktuelleStellung - 4 + 6) MOD 6].bVorhanden = true AND aoTeile[(iAktuelleStellung - 4 + 6) MOD 6].bBewertungGO = true THEN
            sf_statistik(IO_1_NIO_0 := 1);
        ELSE
            sf_statistik(IO_1_NIO_0 := 0);    
        END_IF;
        
    20:
        IF bLeerfahrtRundtischAktiv = true THEN
            IF aoTeile[0].bVorhanden = false AND aoTeile[1].bVorhanden = false AND aoTeile[2].bVorhanden = false AND aoTeile[3].bVorhanden = false AND aoTeile[4].bVorhanden = false AND aoTeile[5].bVorhanden = false then 
                sm_zst_Zyklusende := true;
                bLeerfahrtRundtischAktiv := false;
                bLeerfahrtLinearAktiv := false;
            END_IF;
        END_IF;
        
    21:            
    
        sc_nextstep := 50;
        
    50:
        
        IF sm_zst_Zyklusende = true THEN
            sm_zst_Zyklusende := false;
            sc_nextstep := 1;
            sm_run := false;
            iDB_oAutomatikUeberwachu.bAutomatikWarNichtRaus := true;
        ELSE
            sc_nextstep := 10;
        END_IF;
        
// --- Rundtakttisch leeren      
        
    60:
    
        sf_wait(wait_time := T#10s);
    
        IF sm_wsb = true THEN
            IF a2m_sync <> 0 THEN // Wenn Bohren aktiv sollte kein Fehler gemeldet werden um Spindel zu schützen
                ;
            ELSE
                sf_fehler(Fehlernummer := 1311, Fehlerart := sk_Fehler, Diagnosenummer := 0);
            END_IF;
            sm_wsb := false;
        elsIF oNIORutsche_eTeilSensor1 = false and oNIORutsche_eTeilSensor2 = false THEN
            sm_wsb := true;
        END_IF;    
    
        bTeilNIOAbwurfGesehen := false;
        
    61:    
    
        oTeileauflage(bewegung := 0);
        
    62:    
        
        oRundschalttischTakt.iDB_oRundschalttischTakt();
        
    63:
    
        oNIOAuswerfer(bewegung := 1);
        
    64:
    
        oNIOAuswerfer(bewegung := 0);
        
    65:
    
        sf_wait(wait_time := T#3s);
        
        IF bTeilNIOAbwurfGesehen = true THEN
            iTeileInNioKiste := iTeileInNioKiste + 1;
            iSchichtNIOTeile := iSchichtNIOTeile + 1;
            iAuftragNIOTeile := iAuftragNIOTeile + 1;            
            sm_wsb := true;
        END_IF;
    
    66:
    
        aoTeile[iAktuelleStellung - 1].bVorhanden := false;
        aoTeile[iAktuelleStellung - 1].bBewertungGO := false;
        aoTeile[iAktuelleStellung - 1].bGebohrt := false;
        aoTeile[iAktuelleStellung - 1].bAbgeblasen := false;
        aoTeile[iAktuelleStellung - 1].bGemessen := false;        
    
        iAktuelleStellung := iAktuelleStellung + 1;
        
        IF iAktuelleStellung > 6 then              
            sc_nextstep := 10;
        ELSE
            sc_nextstep := 60;
        END_IF;  
    
    ELSE:
        
        sf_fehler(Fehlernummer := 10, Fehlerart := sk_Fehler, Diagnosenummer := step);
     
    END_CASE;
    
    a0c_step := INT_TO_BYTE(step);

END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Zurück
Oben