PLC, HMI, SCADA, INVERTERS, TUTORIALS, INDUSTRIAL AUTOMATION

18:37
SIEMENS STEP7 SCL Функция управления ПЧ для поддержания размеров петель в заданном диапазоне Протекторный агрегат Дуплекс

 

// Функция управления частотными преобразователями для поддержания размеров петель в заданном диапазоне.
// Функция изменяет в массиве параметров петель значение скорости, предназначенной 
// для отсылки приводу.
// Данная функция в цикле вызывает рассчётную функцию по числу датчиков петель.
// Для приводов, у которых датчики петель могут отключаться, скорость принимется равной заданной.

FUNCTION SynchronizeSpeed : VOID    
TITLE = 'Функция управления частотными преобразователями для поддержания размеров петель в заданном диапазоне.';
CONST
    DRIVESNUM := 18;    // Количество приводов. 
    LOOPSNUM  := 13;    // Количество датчиков петель.
END_CONST

VAR_INPUT
    SensorsType    : ARRAY [1..LOOPSNUM] OF BOOL;               // Массив типов датчиков петли: 0 - прямой, 1 - инверсный.   
    StartLoop      : INT;                                       // Номер петли, с которой начинать синхронизацию. 
    LoopAmount     : INT;                                       // Количество контуров управления (петля - частотник).
    UseAllLoops    : BOOL;                                      // Использовать все петли, независимо от наличия датчиков.
    LoopPresence   : ARRAY [1..LOOPSNUM]  OF BOOL;              // Массив наличия петель.     
    InLoopData     : ARRAY [1..DRIVESNUM] OF LOOPPARAMS;        // Входной массив с параметрами петель.
    AutoAndFillSensPosition  : ARRAY[1..LOOPSNUM] OF BOOL;      // Массив положений датчиков для автоматического режима и заправки.
    ProtectorEndSensPosition : ARRAY[1..LOOPSNUM] OF BOOL;      // Массив положений датчиков для режима "Конец протектора". 
    
    SimulatorEnable     : BOOL; // Флаг работы симулятора узла реза.
    
    StartSynchronize    : BOOL; // Запустить режим синхронизации. 
    EndProtectorStarted : BOOL; // Режим работы линии "Конец протектора". 
       
    DisableHighRoller   : BOOL; // Отключить верхний усадочный рольганг. (EnableBottomRoller)
    EnableHighRoller    : BOOL; // Включить верхний усадочный рольганг.(DisableBottomRoller)
         
    CutTranspIndex   : INT;     // Индекс транспортёра резки заготовок в массиве параметров петель.
    CuttingCycle     : BOOL;    // Идёт цикл отрезания заготовки. Петля №12 (индекс в массиве 12).
                                // Этот сигнал блокирует выдачу данной функцией сигнала нарушения синхронизации транспортёров
                                // из-за провисания петли за счёт остановки транспортёра ножа для отрезания заготовки.
    LiftLoopSpeed    : INT;     // Скорость подъёма петли после цикла отрезания заготовки. 
    deltaT           : INT;     // Интервал времени на котором определяется величина приращения петли.                  
    VdhFactor        : REAL;    // Коэффициент скорости изменения размера петли.
   
    ShrinkRollerIndex   : INT;  // Индекс усадочного рольганга [3].
    CheckRollerIndex    : INT;  // Индекс контрольного рольганга [4].
    Cool3TranspIndex    : INT;  // Индекс 3-го транспортёра охлаждения.
    LongitudalCutIndex  : INT;  // Индекс транспортёра продольного реза [11].
    HWMLoaderIndex      : INT;  // Индекс питателя ВЧМ [2].
    CoilTranspIndex     : INT;  // Индекс транспортёра закатки.
    LineMaxSpeed        : INT;  // Максимальная скорость линии.
    
    Jointly         : ARRAY[1..(DRIVESNUM + 1)] OF BOOL;    // Массив совместной-раздельной работы агрегатов, +1 - АМЧХ совместно-раздельно. 
END_VAR

VAR_OUTPUT
    OutLoopData     : ARRAY [1..DRIVESNUM] OF LOOPPARAMS;   // Выходной массив с параметрами петель.
    LoopSizes       : ARRAY [1..LOOPSNUM] OF INT;           // Массив с размерами петель. 
    LoopBeforeDrive : ARRAY[1..13] OF BOOL;                 // Массив расположения датчиков перед приводами для рабочей станции.
    LoopAfterDrive  : ARRAY[1..13] OF BOOL;                 // Массив расположения датчиков сзади приводов для рабочей станции.                        //  
    OutOfSync       : BOOL;                                 // Нарушение синхронизации скоростей транспортёров.
    ProtectorEnd    : BOOL;                                 // Признак подтверждения конца протектора.
    HighRollerSelected : BOOL;                              // Выбран верхний усадочный рольганг. 
    LampHighRollerSelected :BOOL;                           // Лампа выбора верхнего яруса усадочного рольганга.
END_VAR

VAR_IN_OUT
    CutCycleMemory       : BOOL;            // Память того, что был цикл отрезания заготовки.
    BottomRollerSelected : BOOL;            // Выбран нижний усадочный рольганг.
    Hprevsize : ARRAY[1..LOOPSNUM] OF REAL; // Предыдущий размер петли.
    
END_VAR    

VAR_TEMP
    DrivesCounter     : INT;     // Счётчик контуров управления (петля - частотник). 
    LongLoopCounter   : INT;     // Счётчик расположенных подряд недопустимо удлинённых петель.
    LoopBeforeTransp  : INT;     // Петля расположена перед транспортёром.
    LoopAfterTransp   : INT;     // Петля расположена за транспортёром.
    LoopPos           : INT;     // Положение петли, до или после транспортёра. 
    LoopSensorNumber  : INT;     // Номер датчика петли.
    BoostSpeed        : BOOL;    // Флаг повышения скорости транспортёра ножа для поднятия петли после цикла резания.
    
    Source      : LOOPPARAMS;    // Буфер для приёма элемента входного массива.
END_VAR

LABEL
    M1;
END_LABEL    
//---------------------------------------------------
BEGIN
//-> Индикация лампы выбора яруса усадочного рольганга:
  IF DisableHighRoller = TRUE
     THEN
     LampHighRollerSelected := FALSE;
  END_IF;
  IF EnableHighRoller = TRUE
     THEN
     LampHighRollerSelected := TRUE;
  END_IF;


//-> Заполнение информационного массива размерами петель:
  DrivesCounter := 0;
WHILE DrivesCounter <  LOOPSNUM
  DO
  DrivesCounter := DrivesCounter + 1; 
  IF LoopPresence[DrivesCounter] = TRUE OR
     UseAllLoops               = TRUE
     THEN   
     LoopSizes[DrivesCounter] := InLoopData[DrivesCounter].H; 
  END_IF;
END_WHILE;    
//-<

//-> Заполнение для рабочей станции массивов используемых приводами петель:
DrivesCounter := 0;
WHILE DrivesCounter <  LOOPSNUM
  DO
  DrivesCounter := DrivesCounter + 1; 
  IF (LoopPresence[DrivesCounter] = TRUE OR
      UseAllLoops                 = TRUE) AND
      StartSynchronize = TRUE
      THEN   
      LoopBeforeDrive[DrivesCounter] := InLoopData[DrivesCounter].LoopBefore;
      LoopAfterDrive[DrivesCounter]  := InLoopData[DrivesCounter].LoopAfter; 
  ELSE
      LoopBeforeDrive[DrivesCounter] := FALSE; 
      LoopAfterDrive[DrivesCounter]  := FALSE; 
  END_IF;
END_WHILE;
//-<

  OutOfSync    := FALSE;
  ProtectorEnd := FALSE;        // Признак подтверждения конца протектора.  
 
//=> Запоминание текущей расчётной скорости для транспортёра охлаждения 3:
IF EndProtectorStarted = FALSE
    THEN
    OutLoopData[Cool3TranspIndex].Vautotoend := InLoopData[Cool3TranspIndex].V;       
END_IF;        
//=> Замена заданных скоростей движения трансп. охлаждения 3 и продольного реза для режима конца протектора:
IF EndProtectorStarted = TRUE 
    THEN
    OutLoopData[Cool3TranspIndex].Vtask   := OutLoopData[Cool3TranspIndex].Vautotoend; 
    OutLoopData[LongitudalCutIndex].Vtask := OutLoopData[Cool3TranspIndex].Vtask;
END_IF;
//=<  
  
IF StartSynchronize = TRUE
  THEN
  LongLoopCounter  := 0; 
  LoopBeforeTransp := 1;
  LoopAfterTransp  := 2; 
   
//=> Оределение необходимости кратковременного увеличения скорости до максимальной возможной 
//   после завершения цикла реза для быстрого поднятия петли:   
//-> Запоминание того, что был цикл отрезания заготовки:
  IF CuttingCycle = TRUE
    THEN
    CutCycleMemory := TRUE;    
  END_IF;
    
//-> Определение необходимости ускорения работы транспортёра ножа для быстрого поднятия петли после цикла отрезания заготовки:
  IF CutCycleMemory = TRUE  AND
     CuttingCycle   = FALSE AND
    (InLoopData[CutTranspIndex].H <= InLoopData[CutTranspIndex].Hminlim) // Петля ниже нижнего допустимого предела (для варианта инверсных петель).
    THEN
    BoostSpeed := TRUE; 
  END_IF; 
  IF CuttingCycle   = FALSE AND
    (InLoopData[CutTranspIndex].H > InLoopData[CutTranspIndex].Hminlim)  // Петля ниже нижнего допустимого предела (для варианта инверсных петель).
    THEN
    BoostSpeed     := FALSE;
    CutCycleMemory := FALSE;      
  END_IF;  
//=<  
//-> Переключение на нижний усадочный рольганг:
  IF DisableHighRoller = TRUE
     THEN
     BottomRollerSelected := TRUE;
  END_IF;
//-> Переключение на верхний усадочный рольганг:
  IF EnableHighRoller = TRUE
     THEN
     BottomRollerSelected := FALSE;
  END_IF;      

//-> Цикл рассчёта скоростей частотных преобразователей:   
  DrivesCounter := StartLoop;
  WHILE DrivesCounter <= LoopAmount
    DO
//--------------------------------------------------        
//-> Автоматический режим или заправка.
//   Номер петли управления совпадает с номером датчика:        
      IF EndProtectorStarted = FALSE                        
        THEN
        LoopSensorNumber := DrivesCounter;                        // Номер датчика совпадает с номером петли управления.    
        IF AutoAndFillSensPosition[DrivesCounter] = TRUE          // Массив положений датчиков для автоматического режима и заправки.                                                            
          THEN
          LoopPos := LoopBeforeTransp;                            // Датчик перед транспортёром.                   
          OutLoopData[DrivesCounter].LoopAfter  := FALSE;         // Индикация датчика, с которым работает транспортёр.
          OutLoopData[DrivesCounter].LoopBefore := TRUE;          //
        ELSE
          LoopPos := LoopAfterTransp;                             // Датчик после транспортёра.                     
          OutLoopData[DrivesCounter].LoopAfter  := TRUE;          // Индикация датчика, с которым работает транспортёр.
          OutLoopData[DrivesCounter].LoopBefore := FALSE;         //
        END_IF;
        
//--------------------------------------------------        
//-> Режим "Конец протектора".
//   У части петель управления номер датчика на 1 больше номера петли управления - переключение на расположенные сзади транспортёров датчики:                
      ELSE                                    
        IF ProtectorEndSensPosition[DrivesCounter] = FALSE        // Массив положений датчиков для режима "Конец протектора".                                                            
          THEN
          LoopPos := LoopAfterTransp;                             // Датчик сзади транспортёра.
          OutLoopData[DrivesCounter].LoopAfter  := TRUE;          // Индикация датчика, с которым работает транспортёр.  
          OutLoopData[DrivesCounter].LoopBefore := FALSE;         //   
          IF DrivesCounter <= HWMLoaderIndex                      // [2] - питатели НЧМ и ВЧМ всегда работают с расположенными сзади датчиками.                                                            
             THEN 
             LoopSensorNumber := DrivesCounter;                   // Номер датчика совпадает с номером петли управления.                
          ELSE                                              
             LoopSensorNumber := DrivesCounter + 1;               // Переключение на расположенный сзади транспортёра датчик.
          END_IF;      
        ELSE
          LoopPos := LoopBeforeTransp;                            // Датчик перед транспортёром.
          LoopSensorNumber := DrivesCounter;                      // Номер датчика совпадает с номером петли управления.            
          OutLoopData[DrivesCounter].LoopAfter  := FALSE;         // Индикация датчика, с которым работает транспортёр.  
          OutLoopData[DrivesCounter].LoopBefore := TRUE;          //
        END_IF;              
      END_IF;
//--------------------------------------------------    
//===> Если датчик петли у привода имеется:    
      IF LoopPresence[DrivesCounter] = TRUE OR 
         UseAllLoops = TRUE
         THEN                        
//-> Проверка, не начался ли цикл отрезания заготовки:
         IF DrivesCounter  <> CutTranspIndex OR   
           (DrivesCounter  = CutTranspIndex  AND
            CuttingCycle   = FALSE           AND 
            BoostSpeed     = FALSE)
           THEN 
//-1-> Автомат или заправка и включён (ON) верхний ярус усадочного рольганга, нижний не используется:
             IF EndProtectorStarted  = FALSE AND
                BottomRollerSelected = FALSE                        
                THEN
                Source := InLoopData[DrivesCounter];                 
             END_IF;
//-2-> Конец протектора и включён (ON) верхний ярус усадочного рольганга, нижний не используется:            
             IF EndProtectorStarted  = TRUE AND
                BottomRollerSelected = FALSE                        
                THEN
                Source.Hminlim := InLoopData[LoopSensorNumber].Hminlim;
                Source.Hmaxlim := InLoopData[LoopSensorNumber].Hmaxlim;
                Source.Hmin    := InLoopData[LoopSensorNumber].Hmin;
                Source.Htask   := InLoopData[LoopSensorNumber].Htask;
                Source.Hmax    := InLoopData[LoopSensorNumber].Hmax;
                Source.Vmax    := InLoopData[DrivesCounter].Vmax;
                Source.Vtask   := InLoopData[DrivesCounter].Vtask;
                Source.H       := InLoopData[LoopSensorNumber].H;
                Source.V       := InLoopData[DrivesCounter].V;
                Source.LoopVeryLong  := InLoopData[LoopSensorNumber].LoopVeryLong;
                Source.LoopVeryShort := InLoopData[LoopSensorNumber].LoopVeryShort;
                Source.NullDivision  := InLoopData[LoopSensorNumber].NullDivision;
                Source.LoopBefore    := InLoopData[DrivesCounter].LoopBefore;
                Source.LoopAfter     := InLoopData[DrivesCounter].LoopAfter;
                Source.ReadingError  := InLoopData[LoopSensorNumber].ReadingError;
                Source.WritingError  := InLoopData[LoopSensorNumber].WritingError;
                Source.Vmin          := InLoopData[DrivesCounter].Vmin;                                
             END_IF;           
//-3-> Автомат или заправка и отключён (OFF) верхний ярус усадочного рольганга, используется нижний:
             IF EndProtectorStarted  = FALSE AND
                BottomRollerSelected = TRUE                             // Выбран нижний ярус усадочного рольганга.
                THEN
                IF DrivesCounter = ShrinkRollerIndex                    // Датчик петли верхнего яруса усадочного рольганга.
                   THEN
                   OutLoopData[ShrinkRollerIndex].V := 0;               // Задание нулевой скорости неработающему верхнему ярусу.
                   GOTO M1;                                             // Для этого случая функция ComputeSpeed() не вызывается, так как привод отключен.
                END_IF;   
                IF DrivesCounter = CheckRollerIndex                     // Датчик петли верхнего яруса усадочного рольганга.
                   THEN  
                    OutLoopData[DrivesCounter].LoopVeryLong  := FALSE;  // Блокировка выдачи сообщения о нарушении синхронизации движения транспортёров.
                    OutLoopData[DrivesCounter].LoopVeryShort := FALSE;  //                                 
             
                    Source.Hminlim := InLoopData[ShrinkRollerIndex].Hminlim;
                    Source.Hmaxlim := InLoopData[ShrinkRollerIndex].Hmaxlim;
                    Source.Hmin    := InLoopData[ShrinkRollerIndex].Hmin;
                    Source.Htask   := InLoopData[ShrinkRollerIndex].Htask;
                    Source.Hmax    := InLoopData[ShrinkRollerIndex].Hmax;
                    Source.Vmax    := InLoopData[DrivesCounter].Vmax;
                    Source.Vtask   := InLoopData[DrivesCounter].Vtask;
                    Source.H       := InLoopData[ShrinkRollerIndex].H;
                    Source.V       := InLoopData[DrivesCounter].V;
                    Source.LoopVeryLong  := InLoopData[ShrinkRollerIndex].LoopVeryLong;
                    Source.LoopVeryShort := InLoopData[ShrinkRollerIndex].LoopVeryShort;
                    Source.NullDivision  := InLoopData[ShrinkRollerIndex].NullDivision;
                    Source.LoopBefore    := InLoopData[DrivesCounter].LoopBefore;
                    Source.LoopAfter     := InLoopData[DrivesCounter].LoopAfter;
                    Source.ReadingError  := InLoopData[ShrinkRollerIndex].ReadingError;
                    Source.WritingError  := InLoopData[ShrinkRollerIndex].WritingError;
                    Source.Vmin          := InLoopData[DrivesCounter].Vmin;
                END_IF;     
                IF DrivesCounter <> ShrinkRollerIndex AND
                   DrivesCounter <> CheckRollerIndex
                   THEN
                   Source := InLoopData[DrivesCounter];
                END_IF;                    
             END_IF; 
//-4-> Конец протектора и отключён (OFF) верхний ярус усадочного рольганга, используется нижний:
             IF EndProtectorStarted  = TRUE AND
                BottomRollerSelected = TRUE                                 // Выбран нижний ярус усадочного рольганга.
                THEN
                IF DrivesCounter = ShrinkRollerIndex                        // Датчик петли верхнего яруса усадочного рольганга.
                   THEN
                   OutLoopData[DrivesCounter].V := 0;                       // Задание нулевой скорости неработающему верхнему ярусу.
                   OutLoopData[DrivesCounter].LoopVeryLong  := FALSE;       // Блокировка выдачи сообщения о нарушении синхронизации движения транспортёров.
                   OutLoopData[DrivesCounter].LoopVeryShort := FALSE;       //
                   GOTO M1;                                                 // Для этого случая функция ComputeSpeed() не вызывается, так как привод отключен.   
                ELSE
                   IF DrivesCounter = CheckRollerIndex                      // Датчик петли контрольного рольганга.
                      THEN
                      OutLoopData[DrivesCounter].LoopVeryLong  := FALSE;    // Блокировка выдачи сообщения о нарушении синхронизации движения транспортёров.
                      OutLoopData[DrivesCounter].LoopVeryShort := FALSE;    // 
                   END_IF;                   
                    Source.Hminlim := InLoopData[LoopSensorNumber].Hminlim;
                    Source.Hmaxlim := InLoopData[LoopSensorNumber].Hmaxlim;
                    Source.Hmin    := InLoopData[LoopSensorNumber].Hmin;
                    Source.Htask   := InLoopData[LoopSensorNumber].Htask;
                    Source.Hmax    := InLoopData[LoopSensorNumber].Hmax;
                    Source.Vmax    := InLoopData[DrivesCounter].Vmax;
                    Source.Vtask   := InLoopData[DrivesCounter].Vtask;
                    Source.H       := InLoopData[LoopSensorNumber].H;
                    Source.V       := InLoopData[DrivesCounter].V;
                    Source.LoopVeryLong  := InLoopData[LoopSensorNumber].LoopVeryLong;
                    Source.LoopVeryShort := InLoopData[LoopSensorNumber].LoopVeryShort;
                    Source.NullDivision  := InLoopData[LoopSensorNumber].NullDivision;
                    Source.LoopBefore    := InLoopData[DrivesCounter].LoopBefore;
                    Source.LoopAfter     := InLoopData[DrivesCounter].LoopAfter;
                    Source.ReadingError  := InLoopData[LoopSensorNumber].ReadingError;
                    Source.WritingError  := InLoopData[LoopSensorNumber].WritingError;
                    Source.Vmin          := InLoopData[DrivesCounter].Vmin;
                END_IF;                
             END_IF;                    
//-> Вызов функции рассчёта скорости частотного преобразователя:
             IF Jointly[DrivesCounter] = TRUE AND
                DrivesCounter <> CoilTranspIndex
               THEN
               ComputeSpeed( InLoopData     := Source,                                      // In:  Элемент массива с параметрами просчитываемого контура регулирования. 
                           LoopPosition   := LoopPos,                                     // In:  Положение петли по отношению к транспортёру.
                           InverseSensors := SensorsType[LoopSensorNumber],               // In:  Признак перевёрнутых датчиков - укорочение петли - увеличение показаний датчика.                            
                           VdhFactor      := VdhFactor,                                   // In:  Коэффициент скорости изменения размера петли.
                           deltaT         := deltaT,                                      // In:  Интервал времени на котором определяется величина приращения петли. 
                           Vfqc           := OutLoopData[DrivesCounter].V,                // Out: Вычисленная для текущей величины петли скорость привода транспортёра.
                           LoopVeryLong   := OutLoopData[LoopSensorNumber].LoopVeryLong,  // Out: Признак слишком длинной петли - обрыва петли.
                           LoopVeryShort  := OutLoopData[LoopSensorNumber].LoopVeryShort, // Out: Признак слишком короткой петли.
                           NullDivision   := OutLoopData[LoopSensorNumber].NullDivision,  // Out: Деление на 0 - неправильно заданы параметры петли. 
                           Hprevsize      := Hprevsize[LoopSensorNumber]                  // InOut: Предыдущий размер петли.
                         );                        
             END_IF;

//-> Формирование сигнала о нарушении синхронизации транспортёров линии из-за недопустимого поднятия одной из петель:
//-> Для петель, расположенных после транспортёров:
M1:
           IF LoopPos = LoopAfterTransp    
             THEN
             IF OutLoopData[LoopSensorNumber].LoopVeryShort = TRUE 
               THEN
               OutOfSync := TRUE;                               // Если хотя бы одна петля выше допустимой величины, выставляется признак нарушения синхронизации транспортёров линии.  
             END_IF;                
           ELSE 
//-> Для петель, расположенных перед транспортёрами:                   
             IF OutLoopData[LoopSensorNumber].LoopVeryLong = TRUE 
               THEN
               OutOfSync := TRUE;                               // Если хотя бы одна петля выше допустимой величины, выставляется признак нарушения синхронизации транспортёров линии.  
             END_IF;    
//-> Формирование сообщения об обрыве протектора:
             IF OutLoopData[LoopSensorNumber].LoopVeryLong = TRUE
               THEN 
               LongLoopCounter := LongLoopCounter + 1;
               IF LongLoopCounter > 2     
                 THEN                
                 ProtectorEnd := TRUE;                          // Если две петли подряд ниже допустимого значения, то протектор заканчивается.
               END_IF;        
             ELSE              
               LongLoopCounter := 0;       
              END_IF;
           END_IF;                       
         END_IF;                      
       
//-> Форсирование или  обнуление скорости транспортёра реза: 
         IF DrivesCounter = CutTranspIndex
           THEN
           IF BoostSpeed = TRUE
             THEN
             OutLoopData[CutTranspIndex].V := LiftLoopSpeed;    // Скорость привода транспортёра для поднятия петли.
           END_IF;
           IF CuttingCycle = TRUE 
             THEN     
             OutLoopData[CutTranspIndex].V := 0;                // Обнуление скорости привода транспортёра на время отрезания заготовки. 
           END_IF;
         END_IF;
      END_IF;           
//===> Если датчика петли у привода нет:
      IF LoopPresence[DrivesCounter] = FALSE AND
         UseAllLoops               = FALSE
         THEN
//         OutLoopData[DrivesCounter].V := Source.Vtask;                // Вычисленная для текущей величины петли скорость привода транспортёра.
         OutLoopData[DrivesCounter].LoopVeryLong  := FALSE;           // Признак слишком длинной петли - обрыва петли.
         OutLoopData[DrivesCounter].LoopVeryShort := FALSE;           // Признак слишком короткой петли.
         OutLoopData[DrivesCounter].NullDivision  := FALSE;           // Деление на 0 - неправильно заданы параметры петли.        
         OutLoopData[DrivesCounter].H := Source.Hmaxlim;              // Текущая величина петли.
//-> Задание скорости для транспортёра закатки, который всегда движется с максимальной возможной скоростью:
         IF DrivesCounter = CoilTranspIndex
            THEN
            OutLoopData[DrivesCounter].V := LineMaxSpeed;
         END_IF;         
      END_IF;
    DrivesCounter := DrivesCounter + 1;
  END_WHILE;
END_IF;
HighRollerSelected := NOT BottomRollerSelected;
END_FUNCTION


Скачать/Download - 000000e6.SCL


 

Категория: SIEMENS | Просмотров: 91 | Добавил: gt7600 | Теги: Step7, siemens, SCL | Рейтинг: 0.0/0
Всего комментариев: 0
avatar