# G120C in SCOUT TIA



## Neurorancer (3 Juli 2019)

Sehr geehrte Forum Mitglieder,

ich komme an einer Stelle nicht weiter:

Ich benutze eine safety CPU und eine Simotion D435, welche ich mit Scout 5.2 TIA programmiere.
Nun will ich noch einen G120C Frequenzumrichter über Scout ansteuern.

Frage: Wie macht man das?
Habe im TIA Portal einen G120C Frequenzumrichter in der Geräteliste eingefügt,
da ich es im Scout nicht machen kann.

Ich kann mit im TIA Portal mit dem G120C Frequenzumrichter verbinden.

Über Scout habe ich dem G120C eine IP und einen ProfinetNamen zugewiesen.

Problem: Der G120C Frequenzumrichter erscheint im Scout links in der Übersicht, aber ich kann mit dem Gerät nichts machen.

Ich habe im Internet ein Video gefunden, wo man mit Scout einen G120C ansteuert.
https://www.youtube.com/watch?v=HyxYv0yqWyQ
Leider kann ich in meinem Scout keinen "Single Drive Unit", so wie es im Video in der 1min gezeigt wird anlegen.
Bei mir fehlt einefach diese Auswahl. (Wahrscheinlich weil ich Scout TIA benutze) 

Ich habe schon mal einen G120C mit Hilfe von Starter in Betrieb genommen.

Dieses mal will ich es im Scout tun, ich hoffe dass es möglich ist. 

Falls Jemand einen Tipp für mich hat, bitte melden.


----------



## ChristophD (4 Juli 2019)

Hallo,

das ist nicht möglich.
Scout TIA hat keine unterstützung für SINAMICS G120 da dies über STARTDRIVE erfolgt.
Wenn Du das Gerät aus dem Ordner Antriebe angelegt hast dann erfolgt die Konfiguration im TIA Portal, für Scout TIA ist der G120 dann einfach wie ein GSD Slave und lediglich das Telegram wird ausgelesen mehr nicht.

Gruß
Christoph


----------



## Neurorancer (4 Juli 2019)

Hi Christoph,

Kann ich Startdrive und Scout TIA parallel betreiben?


----------



## ChristophD (4 Juli 2019)

Hi,

ja das ist möglich.
Aber wenn du den G120C schon eingefügt und verbunden hast dann ist startdrive doch schon installiert?

Gruß
Christoph


----------



## Neurorancer (4 Juli 2019)

Hi Christoph noch eine Frage:

Habe auf der Siemens Webseite den Startdrive V15 gefunden.
Leider kann ich nur die Version mit dem SP1 herunterladen.
Mein TIA PortalV15, Scout 5.2 und WinCC Advanced V15 haben aber kein SP1.

Wird es möglich sein StartDrive V15 SP1 in meinem Systen zu betreiben?

Ich finde nirgendwo StartDrive V 15 ohne service-Packs.


----------



## ChristophD (4 Juli 2019)

Hi,

1.) es gibt kein SP1, nicht von Startdrive, nicht von TIA, nicht bon Step7 V15 nicht von WinCC V15
V15.1 ist eine eigener Version und kein SP von V15!

Startdrive V15 findest du hier:
https://support.industry.siemens.com/cs/ww/de/view/109754382

gruß
christoph


----------



## Neurorancer (4 Juli 2019)

Gut,

danke für die Information!

Ich installiere gerade StartDrive Advanced V15 SP1.
Ich hoffe es funktioniert!

Christoph, eine Frage:

Aus Sicht des TIA-Portals:
Kann man Variablen aus einem Datenbaustein (Steuerung des G120C über SINA_SPEED) mit einer bestimmten Anweisung an die Ausgangsadresse der CPU kopieren,
damit die Simotion diese Daten über das I-Device lesen kann?

Mein Ziel ist es, den G120C über Scout zu steuern.


----------



## ChristophD (4 Juli 2019)

Hi,

was installierst du V15.1? Dann wird das nicht klappen weil du dann 2 TIA Versionen hast, einmal V15 mit deinem Step7/ WinCC / Scout und einmal V15.1 mit deinem Startdrive.

Was meinst Du den mit "Scout steuern"?
wenn ich das richtig verstanden habe willst du den G120C über die Simotion Steuern, da braucht es kein i-Device oder irgendwelche Umkopierereien.

Gruß
Christoph


----------



## Neurorancer (4 Juli 2019)

Hi Christoph,
Habe Startdrive V15 installiert (nicht 15.1) .
Das TIA Portal V15 scheint soweit zu funktionieren.

Christoph, ich möchte den G120C Frequenzumrichter über die Simotion steuern. Kannst du mir ein Tipp geben wie ich das machen kann?


----------



## ChristophD (4 Juli 2019)

einfach den G120C anlegen , der simotion assign, 
den antrieb im tia in betrieb nehmen und laden
in Scout tia eine achse anlegen und auf den G120C verschalten

das war es schon, mehr muss man nicht tun.


----------



## Neurorancer (4 Juli 2019)

Danke Christoph, du bist mein Retter!

Bei mir hackt es noch an einer Stelle:
Wie weise ich den G120C der Simotion zu?


----------



## ChristophD (4 Juli 2019)

wenn du das gerät vom Katalog in das projekt gezogen hast und die netzsicht auf hast steht ne blaue zeile am G120c
draufklicken und die Schnittstelle der Simotion auswählen mit der verschaltet werden soll.
dann steht der name der simotion blau am g120c und er ist der simotion zugewiesen


----------



## Neurorancer (4 Juli 2019)

Achso, das habe ich bereits getan.
Jetzt schaue ich mal ob ich das mit der Achse hinkriege.


----------



## Neurorancer (4 Juli 2019)

Hi ChristophD, 
zu dem aktuellen Stand des Problems: 
Ich habe den G120C Frequenzumrichter im TIA Portal angelegt. 
Über StartDrive habe ich den G120C in Betrieb genommen. 
Im Scout habe ich eine Achse angelegt, welche mir den G120C steuert.
 In Scout kann ich über die Steuertafel die Achse drehen lassen. 

Letzte Frage: Nun will ich die Achse über die Software ansteuern. 
Wo sehe ich die Steuer- und die Status-Bits zur Steuerung der Achse?
Im Drive-Navigator der Achse sehe ich ja wo die Soll-Werte herkommen sollen.
Das Problem ist, dass die Quelle des Soll-Wertes leer und ausgegraut ist.


----------



## ChristophD (4 Juli 2019)

Hi,

was brauchst du Steuer/Status bits wenn du ne Achse verwendest?
Das ist ja das schicke an der Achse das sie das alles für dich übernimmt.
Du must einzig nur noch die motion Befehle nutzen zu steuerung alles andere ist dir egal.
_enable-/_disableAxis (MC_POWER)
_move (MC_MOVE)

Gruß
Christoph


----------



## Neurorancer (4 Juli 2019)

Hi ChristophD,

ich bin gerade dabei die Achse zu aktivieren, dazu nutze ich die Funktion "_enableAxis".

Ich habe eine Frage zu einem Parameter der Funktion _enableAxis



Was macht der Parameter "servoControlMode"? Wie soll ich diesen Verschalten? Habe bis jetzt noch nichts im Internet gefunden.

Hier ist ein kurzer Ausschnitt meiner Software:



```
101:    
                                    
                //Check Dryer for Errors
                IF FAN_CIRCULATION.error = no
                    FAN_CIRCULATION.actorMonitoring.driveError = no
                    FAN_CIRCULATION.actorMonitoring.cyclicInterface = active
                    FAN_CIRCULATION.sensorMonitoring.cyclicInterface = active
                    FAN_CIRCULATION.sensordata[1].state = valid
                THEN 
                    DryerState[i]                   := 110;
                END_IF;
                
            110:
                //Init & Release FAN 
                tempTime1[i]                    := _getinternaltimestamp();
                DryerState[i]                   := 120;
                    
            120:
                //DryerFanCTL_PLC[i]              := TRUE;
                _enableAxis(
                    axis := FAN_CIRCULATION
                    ,enableMode := ALL
                    ,servoControlMode := 
                    ,servoCommandToActualMode :=  INACTIVE
                    ,nextCommand := WHEN_COMMAND_DONE
                    ,commandId := 
                    ,forceControlMode := 
                    ,STWBitSet := 
                    ,movingMode := 
                ); 
                
                tempTime2[i]                    := _getinternaltimestamp();
                difTime[i]                      :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 130; 
                END_IF;
```


----------



## ChristophD (4 Juli 2019)

auf = Active legen oder gleich ganz weglassen


```
_enableAxis(axis := [COLOR=#333333][FONT=Courier]FAN_CIRCULATION[/FONT][/COLOR],enableMode := ALL,nextCommand := IMMEDIATELY,commandId:=_getcommandid()) ;
```

ich welcher task läuft das program?


----------



## Neurorancer (4 Juli 2019)

Das Programm läuft in der TimerInterruptTask_1 (24ms).

ChristophD, durch welchen Parameter der Achse gebe ich die Soll-Geschwindigkeit vor?


----------



## ChristophD (4 Juli 2019)

Hi,

timerinerrupttask , dann solltest du auf solche sachen wie When_Command_Done verzichten, das führt nur zu überläufen.

mit dem parameter Velocity am _move Befehl


----------



## Neurorancer (4 Juli 2019)

Hi ChristphD,

mir ist aufgefallen, dass der Geschwindigkeitswert des _move Befehls nur einmal übernommen wird.
Beim Starten des Motors habe ich den Geschwindigkeitswert auf 60°/min gestellt.
Danach habe ich den Sollwert auf 0°/min verändert.

Das Problem ist, dass der Motor trotzdem mit 60°/min weiterläut, egal welchen Sollwert man vorgibt.

Frage: Ist es normal? Muss man einen speziellen Bit Triggern, um den neuen Soll-Wert einzulesen?


----------



## ChristophD (4 Juli 2019)

hi,
hast du den move den neu gestartet? und der neue befehl lösst den alten ab?

Gruß
Christoph


----------



## Neurorancer (4 Juli 2019)

ja genau, das habe ich gerade noch mehrmals kontrolliert.


----------



## Neurorancer (4 Juli 2019)

Moment, die Achse liefert einen technologischen Alarm.
Ich muss gleich schauen, was da genau los ist.


----------



## Neurorancer (4 Juli 2019)

Der Wert des Technologischen Alarms ist 173,
jetzt muss ich mal schauen wo man die Fehlernummern aufschlüsseln kann.


----------



## Neurorancer (4 Juli 2019)

Die Simotion liefert folgenden Fehler:

Freigabe Lageregler fehlt
oder
Nachführbetrieb abgewählt


----------



## Neurorancer (4 Juli 2019)

Habe die Ursache des Problems:


Ich bekomme in der Simotion zwei Fehlermeldungen:


Information    10.01.92   00:57:44:560     PLC1 : FAN_CIRCULATION    3    30002 : Befehl abgebrochen (Grund: 2, Befehlstyp: 1038 )





Information    10.01.92   00:57:52:740     PLC1 : FAN_CIRCULATION    8    30003 : Befehl wegen belegtem Befehlspuffer abgebrochen (Befehlstyp: 1001)


----------



## ChristophD (5 Juli 2019)

sieht für mich so aus das du permanent befehle auf die achse rausjagst und die siche gegenseitig abbrechen und den puffer füllen.

was meintest du mit Wert des alarm ist 173? Wo hast du den alarm bekommen, eine solche Alarmnummer gibt es bei simotion nicht.


----------



## Neurorancer (5 Juli 2019)

ChristopD, ich habe eine Verständnis-Frage.

Ich aktiviere einmalig die Achse über den Befehl "_enableAxis".

Danach laufe ich in den Zustand wo der Befehl "_move" gestartet wird. Beim ersten Start des Befehls setzt sich die Ache in Bewegung. Jetzt will ich die Geschwindigkeit der Achse ändern. Wenn sich der Soll-Wert der Geschwindigkeit durch den Bediener ändert, wieder der _move Befehl mit der neuen Soklgeschwindigkeit aufgerufen. Dies führt zu Problemen.

Frage: wie gebe ich der Achse einen neuen Geschwindigkeitssoll-Wert vor?

Den _move Befehl muss man doch wieder aufrufen,oder?

Gibt es einen bestimmten Ablauf der Befehlsfolge an den ich mich richten soll?


----------



## ChristophD (5 Juli 2019)

ja der move befehl muss wieder aufgerufen werden wenn ein neuer sollwert aktiviert werden soll.
ich kenne den code nicht den du geschrieben hast daher kann ich wenig zu sagen, stell doch einfach mal den code ein und sag welche probleme genau du hast


----------



## Neurorancer (5 Juli 2019)

Ich stelle den code gleich ein, wenn ich am Rechner bin.


----------



## Neurorancer (5 Juli 2019)

Ich bekomme nun zusätzlich eine Fehlermeldung in der Simotion, wenn ich die Geschwindigkeit anpasse, nachdem der Lüfter Läuft.


Fehler	10.01.92   16:44:05:080 	PLC1 : FAN_CIRCULATION	1	40005 : Fehlende Freigabe (Parameter1: 3) und/oder falscher Modus (Parameter2: 1)

Hier ist mein Quellcode:
Das Programm läuft in der timerinterrupttask


```
INTERFACE
    USES dDryer, dDW, dEKSGlobal, dEKSHmi;
    PROGRAM Trockner;
END_INTERFACE


IMPLEMENTATION   
    PROGRAM Trockner
        VAR    
            i                   : INT := 0;
            flagDryerOPStarted  : ARRAY [1..NUMBER_OF_DRYERS] OF BOOL;
            PID_Regler          : ARRAY [1..NUMBER_OF_DRYERS] OF _CTRL_pid;
            PID_Parameter       : ARRAY [1..NUMBER_OF_DRYERS] OF Struct_CTRL_dataPid;
            PID_Regler_Act      : ARRAY [1..NUMBER_OF_DRYERS] OF BOOL;
            
            FB_S_Trockner_Ein   : ARRAY [1..NUMBER_OF_DRYERS] OF R_TRIG;
            FB_S_Trockner_Aus   : ARRAY [1..NUMBER_OF_DRYERS] OF R_TRIG;
            
            tempTime1           : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
            tempTime2           : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
            difTime             : ARRAY [1..NUMBER_OF_DRYERS] OF UDINT;
            
            myRetDINT1           : DINT;
            myRetDINT2           : DINT;
            myRetDINT3           : DINT;
            myRetDINT4           : DINT;
            
            var_FanCircSetSpeed : LREAL;
            var_FanCircSetSpeed_old : LREAL;
        END_VAR
       
FOR i := 1 TO NUMBER_OF_DRYERS BY 1 DO
        
        FB_S_Trockner_Ein[i](var_S_Trockner_Ein[i]);
        FB_S_Trockner_Aus[i](var_S_Trockner_Aus[i]);
          
        //Fan-Spped adaptation
        //FAN CIRCULATION 0-50Hz => 0 - 2950/min => 0 - xxxxx
        //FAN EXHAUST 0-50Hz => 0 - 2920/min => 0 - xxxxx
     
        //Dryer Start
        IF FB_S_Trockner_Ein[i].q 
        THEN 
            DryerState[i] := 100;
        END_IF;
            
        //Dryer Stop
        IF FB_S_Trockner_Aus[i].q THEN 
            DryerState[i] := 500;
        END_IF;
            
        //Check if the Dryer and the Fan are in proper state
        IF (*var_sicherheit_trockner      = TRUE 
            AND*) fehler_steuerspannung   = FALSE 
            AND fehler_notaus           = FALSE
        THEN 
            ;    
        ELSE        
            //Dryer / Fan has errors   
            DryerState[i] := 0;    
        END_IF;
           
        PID_Regler[i](enable :=PID_Regler_Act[i],dataPid :=PID_Parameter[i]);
                  
        //Regler Sollwert
        IF DryerSollTemp[i] >=0 
            AND DryerSollTemp[i] <=120 
        THEN
            PID_Parameter[i].setpointValue     := DryerSollTemp[i]*10.0;
        END_IF;
            
        //Regler Ist_Wert
        PID_Parameter[i].numericActValue := LREAL_TO_REAL(DryerTempSensor[i]*10.0);
        //Regler Parameter Anpassung
        PID_Parameter[i].propGain          := var_Regler_P[i];      //
        PID_Parameter[i].integTime         := var_Regler_I[i];      //
        PID_Parameter[i].derivativeTime    := var_Regler_D[i];      //
        
        //Aktuelle Leisung ausrechnen und am Display anzeigen
        DryerPIDoutPower[i]     := (DryerPIDoutValue[i] / 4096.0) * 100.0;
            
        CASE DryerState[i] OF
            //Dryer Stop
            0:
                //PID deactivate
                PID_Regler_Act[i]      := FALSE;
                PID_Parameter[i].reset := TRUE;
                    
                //DryerFanSetSpeed[i] := 0;
                DryerPIDoutValue[i] := 0;
                
                IF DryerFanActSpeed[i] <10 THEN 
                    DryerFanOn[i]           := FALSE;
                    DryerFanInOperation[i]  := FALSE;
                END_IF;
                    
            //Dryer&Fan Start
            100:
            
                DryerPIDoutValue[i] :=0; 
                //DryerFanSetSpeed[i] := 0;
                
                DryerState[i]                   := 101;
                
            101:    
                flagDryerOPStarted[i]              := TRUE;    
                //Init PID
                PID_Parameter[i].reset             := TRUE;
                PID_Parameter[i].manualMode        := FALSE;    
                PID_Parameter[i].setPController    := TRUE;   //+ P-Anteil ein
                PID_Parameter[i].setIController    := TRUE;   //+ I-Anteil ein
                PID_Parameter[i].holdIValue        := FALSE;
                PID_Parameter[i].setIValue         := FALSE;
                PID_Parameter[i].setDController    := FALSE; //+ D-Anteil einschalten                  
                //PID_Parameter[i].setpointValue     := 60.0;        // Sollwert, Bediener 
                PID_Parameter[i].propGain          := var_Regler_P[i];    //
                PID_Parameter[i].integTime         := var_Regler_I[i];  //
                PID_Parameter[i].derivativeTime    := var_Regler_D[i];  //
                //                    
                PID_Parameter[i].upperLimit         := 4096;
                PID_Parameter[i].lowerLimit         := 0;      
    
                DryerFanCTL_PLC[i]              := FALSE;
                DryerFanStopC[i]                := FALSE;
                DryerFanStopQ[i]                := FALSE;
                DryerFanEnableOperation[i]      := FALSE;
                DryerFanEnableRampGenerator[i]  := FALSE;
                DryerFanUnfreezaRamp[i]         := FALSE;
                DryerFanEnableSetpoint[i]       := FALSE;
                DryerFanOn[i]                   := FALSE;
                    
                //Check Dryer for Errors
                IF //FAN_CIRCULATION.error = no
                    FAN_CIRCULATION.actorMonitoring.driveError = no
                    AND FAN_CIRCULATION.actorMonitoring.cyclicInterface = active
                    AND FAN_CIRCULATION.sensorMonitoring.cyclicInterface = active
                    //AND FAN_CIRCULATION.sensordata[1].state = valid
                THEN 
                    DryerState[i]                   := 110;
                END_IF;
                              
            110:
                //Init & Release FAN 
                tempTime1[i]                    := _getinternaltimestamp();
                DryerState[i]                   := 120;
                    
            120:
    
                tempTime2[i]                    := _getinternaltimestamp();
                difTime[i]                      :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );               
                
                myRetDINT1 :=
                _enableAxis(
                    axis                := FAN_CIRCULATION 
                    ,enableMode         := ALL
                    //,servoControlMode   := ACTIVE
                    //,servoCommandToActualMode := INACTIVE
                    ,nextCommand        := IMMEDIATELY 
                    ,commandId          := _getcommandid()
                    //,forceControlMode   := INACTIVE
                    //,STWBitSet          := 0
                    //,movingMode         := SPEED_CONTROLLED 
                );
  
                DryerState[i]   := 130;
                
            130:
                 
                tempTime2[i]        := _getinternaltimestamp();
                difTime[i]          :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 140; 
                END_IF;
                    
            140:
                
                tempTime2[i]        := _getinternaltimestamp();
                difTime[i]          :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 150; 
                END_IF;
                    
            150:
                    
                tempTime2[i]        := _getinternaltimestamp();
                difTime[i]          :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 160; 
                END_IF;  
                
            160:


                tempTime2[i]   := _getinternaltimestamp();
                difTime[i]     :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 170; 
                END_IF; 
                    
            170:
              
                tempTime2[i]   := _getinternaltimestamp();
                difTime[i]     :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 180; 
                END_IF; 
                    
            180:
                 
                tempTime2[i]   := _getinternaltimestamp();
                difTime[i]     :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 190; 
                END_IF; 
                    
            190:
                   
                tempTime2[i]    := _getinternaltimestamp();
                difTime[i]      :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                IF difTime[i]  >= 1*1*1000000 THEN //1sek. verweilen
                    tempTime1[i]    := _getinternaltimestamp();
                    DryerState[i]   := 200; 
                END_IF; 
                    
            200:    
                DryerState[i]   := 210;  
            210:    
                   
                DryerState[i]   := 220;


            220:


                DryerState[i]   := 230;


            230:    
                DryerState[i]       := 240;
                    
            240:    
                //Dryer is in action
                PID_Parameter[i].reset  := FALSE;
                PID_Regler_Act[i]       := TRUE;                  
                DryerPIDoutValue[i]     := PID_Parameter[i].numericOutValue;
                 
                var_FanCircSetSpeed := (var_Soll_Geschw_FAN[1]*2950.0)/6000.0;
                
                IF var_FanCircSetSpeed >= 49
                THEN 
                    var_FanCircSetSpeed := 49;
                END_IF;
                
                IF var_FanCircSetSpeed < 0
                THEN 
                    var_FanCircSetSpeed := 0;
                END_IF;
                
                //HIER DER MOVE BEFEHL
                IF var_FanCircSetSpeed_old <> var_FanCircSetSpeed
                THEN
                    myRetDINT2 := _move(axis := FAN_CIRCULATION,
                        velocity := var_FanCircSetSpeed
                        //velocityType := DIRECT
                    ); //Werteingabe
 
                    var_FanCircSetSpeed_old := var_FanCircSetSpeed;
                    
                END_IF;
                  
            //Dryer Stop    
            500:   
                //Dryer Stop
                
                //PID deactivate
                PID_Regler_Act[i]      := FALSE;
                PID_Parameter[i].reset := TRUE;
                    
                DryerPIDoutValue[i] := 0;
                       
                myRetDINT3 :=
                _move(
                    axis := FAN_CIRCULATION
                    // ,direction := USER_DEFAULT
                    // ,velocityType := USER_DEFAULT
                    ,velocity := 0.0
                );
(*                
                IF FAN_CIRCULATION.actorData.actualSpeed <=1 
                THEN 
                    tempTime1[i]        := _getinternaltimestamp();
                    DryerState[i]       := 510;
                END_IF;
*)                
  
                DryerState[i]       := 510;
                
            510:
                tempTime2[i]        := _getinternaltimestamp();
                difTime[i]          :=_gettimedifferenceofinternaltimestamps(t1 := tempTime1[i] ,t2 := tempTime2[i] );
    
                
                myRetDINT4 :=
                _disableAxis(
                    axis := FAN_CIRCULATION
                    ,disableMode := ALL
                // ,servoControlMode := INACTIVE
                // ,servoCommandToActualMode := ACTIVE
                // ,nextCommand := IMMEDIATELY
                // ,commandId := (0,0)
                // ,forceControlMode := INACTIVE
                // ,STWBitSet := 0
                );
 
                DryerState[i]   := 520;
            520:   
               
                DryerState[i]       := 530;


            530: 
                ;
    
            ELSE
                ;
        END_CASE;
    END_FOR;     
    
    (*
        
        // **********************
        // Struct_CTRL_dataPid
        // **********************
        //myCTRL_dataPid : Struct_CTRL_dataPid;
            myCTRL_dataPid.reset := FALSE; // [IN] complete restart
            myCTRL_dataPid.manualMode := TRUE; // [IN] manual value on
            myCTRL_dataPid.actValueType := FALSE; // [IN] process variable peripherie on
            myCTRL_dataPid.setPController := TRUE; // [IN] proportional action on
            myCTRL_dataPid.setIController := TRUE; // [IN] integral action on
            myCTRL_dataPid.holdIValue := FALSE; // [IN] integral action hold
            myCTRL_dataPid.setIValue := FALSE; // [IN] initialization of the integral action
            myCTRL_dataPid.setDController := FALSE; // [IN] derivative action on
            myCTRL_dataPid.cycleTime := 1000; // [IN] sample time in ms
            myCTRL_dataPid.setpointValue := 0.0; // [IN] internal setpoint
            myCTRL_dataPid.numericActValue := 0.0; // [IN] process variable in
            myCTRL_dataPid.binActValue := 0; // [IN] process variable peripherie
            myCTRL_dataPid.manualValue := 0.0; // [IN] manual value
            myCTRL_dataPid.propGain := 2.0; // [IN] proportional gain
            myCTRL_dataPid.integTime := 20000; // [IN] integration time in ms
            myCTRL_dataPid.derivativeTime := 10000; // [IN] derivative time in ms
            myCTRL_dataPid.delayTime := 2000; // [IN] time lag of the derivative action in ms
            myCTRL_dataPid.deadBand := 0.0; // [IN] dead band width
            myCTRL_dataPid.upperLimit := 100.0; // [IN] manipulated value high limit
            myCTRL_dataPid.lowerLimit := 0.0; // [IN] manipulated value low limit
            myCTRL_dataPid.actValueFactor := 1.0; // [IN] process variable factor
            myCTRL_dataPid.actValueOffset := 0.0; // [IN] process variable offset
            myCTRL_dataPid.outValueFactor := 1.0; // [IN] manipulated value factor
            myCTRL_dataPid.outValueOffset := 0.0; // [IN] manipulated value offset
            myCTRL_dataPid.initialIValue := 0.0; // [IN] initialization value of the integral action
            myCTRL_dataPid.disturbValue := 0.0; // [IN] disturbance variable


        *)
    
    END_PROGRAM   
END_IMPLEMENTATION
```


----------



## Neurorancer (5 Juli 2019)

OK, so wie es ausschaut fehlte noch ein Paremeter in dem Move-Befehl:

mergeMode := IMMEDIATELY

Jetzt scheint es zu funktionieren.


----------

