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 du mit dem Mauszeiger auf die rote Zeile gehst, dann zeigt er dir an was falsch ist.

Ich vermute mal, das der Eintrag in der Symboltabelle zu dem InstanzDB fehlerhaft ist.
 
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