Hi zusammen,

ich habe folgendes Problem:

Grundsätzlich ist es ja so, dass jeder Funktionsblock bei jedem Programmdurchlauf aufgerufen wird und durch Enable oder Execute auf TRUE oder FAlSE entschieden wird ob was gemacht wird oder nicht.

Jetzt habe ich aber das Problem, dass ich das so nicht machen kann.
Ich darf die Funkionsblöcke nur dann aufrufen, wenn kein digitales Signal anliegt, da ich dann die Motoren über die RS232-Schnittstelle steuern muss.

Jetzt habe ich das Grundgerüst der Software fertig, habe aber das Problem, dass immer wieder Fehler passieren, die jedoch (zumindestens für mich) sehr willkürlich auftreten. Mal starten beide Motoren, wenn ein digitales Signal anliegt, wenn ich das Signal wegnehme, dann stoppen sie auch. Mal startet nur ein Motor, dann wieder beide, wobei mal der eine, mal der andere startet. Dann stoppt nur ein Motor, dann wieder beide, auch völlig willkürlich.
Die Programmierugn erfolgt auf einem EPOS P Controller der Firma Maxon.

Variablendeklaration
Code:
VAR_EXTERNAL
    Axis0_AnalogInput1 : INT;
    Axis0_AnalogInput2 : INT;
END_VAR

VAR_GLOBAL
    
END_VAR

VAR
        XStart : BOOL := FALSE;
        xREAD : BOOL := TRUE;
        fbReadI : FB_ReadInputs;
        Pointer : BOOL := FALSE;
        
        myAxis0 : AXIS_REF := (AxisNo := 0);
        wProgramState1    : UINT    := 1;
        wCounter1        : UINT    := 0;
        dVelocityTot1    : UDINT    := 0;
        dVelocity1        : UDINT    := 0;
        iAnalogIn1        : INT    := 0;
        iAnalogIn1Old1    : INT    := 0;
        
        myAxis1 : AXIS_REF := (AxisNo := 2);
        fbMove1 : MC_MoveVelocity;
        myPow1  : MC_Power;
        fbStop1 : MC_Stop;
        fbReadStatus1 : MC_ReadStatus;
        MRead1 : BOOL := FALSE;
        PStart1 : bool := TRUE;
        MStart1 : bool := FALSE;
        MStop1  : bool := FALSE;
        MRichtung1 : MC_Direction;
        acce1     : UDINT := 5000;
        dece1     : UDINT := 5000;
(* Variablen fuer die zweite Achse *)
        wProgramState2    : UINT    := 1;
        wCounter2        : UINT    := 0;
        dVelocityTot2    : UDINT    := 0;
        dVelocity2        : UDINT    := 0;
        iAnalogIn2        : INT    := 0;
        iAnalogIn1Old2    : INT    := 0;
        
        myAxis2 : AXIS_REF := (AxisNo := 3);
        fbMove2 : MC_MoveVelocity;
        myPow2  : MC_Power;
        fbStop2 : MC_Stop;
        fbReadStatus2 : MC_ReadStatus;


        fbReset1 : MC_Reset;
        fbReset2 : MC_Reset;
        xReset1 : BOOL := FALSE;
        xReset2 : BOOL := FALSE;


        MRead2 : BOOL := FALSE;
        PStart2 : bool := TRUE;
        MStart2 : bool := FALSE;
        MStop2  : bool := FALSE;
        MRichtung2 : MC_Direction;
        acce2     : UDINT := 5000;
        dece2     : UDINT := 5000;

END_VAR
Der eigentliche Code
Code:
if fbReadI.D1 then    
    XStart := TRUE;
else
    XStart := FALSE;
end_if;

if XStart then 
    
    CASE wProgramState1 OF

        1:    (*Power Enable Axis2*)
            PStart1 := TRUE;
            IF myPow1.Status THEN
                wProgramState1 := 2;
                MRead1 := TRUE;
            ELSIF myPow1.Error THEN
                PStart1 := FALSE;
            END_IF;
        
        2:     (*Set Velocity by Analog Input 1*)
            iAnalogIn1 := Axis0_AnalogInput1;

            IF (iAnalogIn1 <> iAnalogIn1Old1) THEN
                IF (wCounter1 < 30) THEN
                    dVelocityTot1 := dVelocityTot1 + INT_TO_UDINT(iAnalogIn1);
                    MStart1 := FALSE;
                    wCounter1 := wCounter1 + 1;
                ELSE
                    dVelocity1 := dVelocityTot1 / 30;
                    IF dVelocity1 > 2500 THEN
                        dVelocity1 := (dVelocity1-2500)*2;
                        MRichtung1 := MCNegative;
                    ELSE 
                        if dVelocity1 <= 2500 then
                            dVelocity1:=5000-(dVelocity1*2);
                            MRichtung1 := MCPositive;
                        (* else
                            dVelocity1 := 0;
                            PStart1 := False;
                            wProgramState1 := 1; *)
                        end_if;    
                    END_IF;    
                    if fbReadStatus1.Done then
                        MStart1 := TRUE;
                        dVelocityTot1 := dVelocity1;
                        wCounter1 := 1;
                    end_if;
                END_IF;
            ELSE
                MStart1 := FALSE;
            END_IF;

            IF MStart1 THEN
                dVelocity1 := dVelocityTot1;
                IF fbMove1.InVelocity THEN
                    iAnalogIn1Old1 := iAnalogIn1;
                    MStart1 := FALSE;
                    
                ELSIF fbMove1.Error THEN
                    MStart1 := FALSE;
                    wProgramState1 := 999;
                    
                END_IF;
            END_IF;        
    
        999: PStart1 := FALSE;    
             wProgramState1 := 1;
             
    END_CASE;
 
    (* Bedingungen füer Achse 2 *)
    CASE wProgramState2 OF

    1:    (*Power Enable Axis2*)
            PStart2 := TRUE;
            IF myPow2.Status THEN
                wProgramState2 := 2;
                MRead2 := TRUE;
            ELSIF myPow2.Error THEN
                PStart2 := FALSE;
            END_IF;
        
        2:     (*Set Velocity by Analog Input 1*)
            iAnalogIn2 := Axis0_AnalogInput2;

            IF (iAnalogIn2 <> iAnalogIn1Old2) THEN
                IF (wCounter2 < 30) THEN
                    dVelocityTot2 := dVelocityTot2 + INT_TO_UDINT(iAnalogIn2);
                    MStart2 := FALSE;
                    wCounter2 := wCounter2 + 1;
                ELSE
                    dVelocity2 := dVelocityTot2 / 30;
                    IF dVelocity2 > 2500 THEN
                        dVelocity2 := (dVelocity2-2500)*2;
                        MRichtung2 := MCNegative;
                    ELSE 
                        if dVelocity2 <= 2500 then
                            dVelocity2:=5000-(dVelocity2*2);
                            MRichtung2 := MCPositive;
                        (* else
                            dVelocity2 := 0;
                            PStart2 := False;
                            wProgramState2 := 1; *)
                        end_if;    
                    END_IF;    
                    if fbReadStatus2.Done then
                        MStart2 := TRUE;
                        dVelocityTot2 := dVelocity2;
                        wCounter2 := 1;
                    end_if;
                END_IF;
            ELSE
                MStart2 := FALSE;
            END_IF;

            IF MStart2 THEN
                dVelocity2 := dVelocityTot2;
                IF fbMove2.InVelocity THEN
                    iAnalogIn1Old2 := iAnalogIn2;
                    MStart2 := FALSE;
                    
                ELSIF fbMove2.Error THEN
                    MStart2 := FALSE;
                    wProgramState2 := 999;
                    
                END_IF;
            END_IF;        
    
        999: PStart2 := FALSE;    
             wProgramState2 := 1;
    END_CASE;
else
    PStart1 := FALSE;
    PStart2 := FALSE;
    MStart1:= FALSE;
    MStart2:= FALSE;
    if fbMove1.Invelocity AND fbMove2.InVelocity THEN
        (* 
        MRead1 := FALSE;
        MRead2 := FALSE; *)
        
        Pointer := TRUE;
        
    end_if;
    wProgramState1 := 1;
    wProgramState2 := 1; 
end_if;
(* Ende der Bedingungen fuer Achse 2 *)

    
fbReadI(Axis:= myAxis0, Device:=1, Port:=0, Enable:=xRead);
fbReadStatus1(Axis:=myAxis1, Enable:= MRead1);
fbReadStatus2(Axis:=myAxis2, Enable:= MRead2);

if XStart then 
    myPow1(Axis:=myAxis1, Enable:=PStart1);    
    fbMove1(Axis:=myAxis1,Execute:=MStart1,Velocity:=dVelocity1,Acceleration:=acce1,Deceleration:=dece1, Direction:=MRichtung1);
    fbStop1(Axis:=myAxis1,Execute:=MStop1,Deceleration:=dece1);

    myPow2(Axis:=myAxis2, Enable:=PStart2);
    fbMove2(Axis:=myAxis2,Execute:=MStart2,Velocity:=dVelocity2,Acceleration:=acce2,Deceleration:=dece2, Direction:=MRichtung2);
    fbStop2(Axis:=myAxis2,Execute:=MStop2,Deceleration:=dece2);

    

    if myPow2.Status AND myPow1.Status then 
        Pointer := TRUE;
    (* else
        Pointer := FALSE; *)  
    end_if; 
else
    if Pointer then
        fbStop1(Axis:=myAxis1,Execute:=TRUE,Deceleration:=dece1);
        fbStop2(Axis:=myAxis2,Execute:=TRUE,Deceleration:=dece2);
        if fbStop1.Done AND fbStop2.Done then
            Pointer := FALSE;    
        end_if;
    end_if;
end_if;
Wäre cool, wenn Ihr mir den einen oder anderen Tipp geben könntet.

Herzliche Grüße
Moody