Показано с 1 по 8 из 8

Тема: Первые шаги в ST. Прошу совета по архитектуре программы

  1. #1

    Post Первые шаги в ST. Прошу совета по архитектуре программы

    Всем добрый день.

    Я только начинаю изучать язык Structured Text и программирование ПЛК в целом. Работаю с Owen Logic и контроллером ПР200. До этого в основном использовал FBD, но сейчас пытаюсь освоить ST, потому что для более сложной логики он кажется удобнее.В качестве практики пытаюсь написать программу управления коптильной камерой. Логика примерно такая:есть рецепты,в каждом рецепте есть несколько шагов,каждый шаг соответствует определённому процессу (нагрев, розжиг, копчение, проветривание и т.д.),оператор может редактировать рецепт, выбирая процесс для каждого шага,затем программа выполняет шаги по порядку.

    Пока я сделал простую архитектуру:
    Рецепты хранятся в массиве RecipeSteps,каждый элемент массива хранит номер процесса,по номеру процесса через CASE включаются нужные выходы.
    Это мой первый более-менее большой кусок ST, поэтому понимаю, что в нём могут быть ошибки и не самые правильные решения.
    Буду очень благодарен, если подскажете.Правильно ли я вообще выбрал архитектуру,есть ли более правильный способ хранить рецепты,как лучше организовать редактирование шагов,нет ли типичных ошибок начинающих, которые я уже допустилю

    Код прикладываю ниже:
    Скрытый текст:

    Код:
    FUNCTION_BLOCK koptilna
    
    VAR_INPUT
        ProgramRun : BOOL; //программа в работе
        BtnStart : BOOL; //запуск программы
        BtnStop : BOOL; //стоп рограммы
        SelectRecipe : UDINT;   // выбранный рецепт
        EditStep : UDINT; // редактирование шага
        SelectProcess : UDINT; // выбранный процесс
    END_VAR
    
    VAR_OUTPUT
        HeatCamera : BOOL; //нагрев камеры
        HeatGen    : BOOL; //розжиг дымогенератора
        Speed1     : BOOL; //двигатели скорость 1
        Speed2     : BOOL; //двигатели скорость 2
        Valve1     : BOOL; //выброс 1/3
        Valve2     : BOOL; //выброс 2/3
        Boost      : BOOL; //наддув
        Blowdown   : BOOL; //поддув
        Firefighting : BOOL; //пожаротушение
        Stirrer     : BOOL; //ворошитель
        Sink       : BOOL; //мойка
        Hydration  : BOOL; //увлажнение
        CurenStep : UDINT; //позицая шага
    END_VAR
    
     VAR
        RecipeSteps : ARRAY [0..200] OF UDINT;
        RecipeIndex : UDINT; // индекс рецепта
        EditIndex : UDINT; // индекс редактирования
        SelectProcessOld : UDINT; //старое значение выбраного процесса
        StepNomber : UDINT; //номер шага
     END_VAR
    
    //Значение по умолчанию для выходов
        HeatCamera := FALSE;
        HeatGen := FALSE;
        Speed1 := FALSE; 
        Speed2 := FALSE;
        Valve1 := FALSE;     
        Valve2 := FALSE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := FALSE;       
        Hydration := FALSE;  
    
     //Запуск программы
     IF BtnStart  THEN
        ProgramRun := TRUE;
        CurenStep := 1;
     END_IF;
     
     //Остановка программы
     IF BtnStop THEN
        ProgramRun := FALSE;
        CurenStep := 1;
     END_IF
    
     //Автоматическое сохранние при редактировании рецепта
     IF SelectProcess <> SelectProcessOld THEN
        IF (SelectProcess >= 0) AND (SelectProcessOld <=10) THEN
            IF (EditStep >= 0) AND (EditStep <=20) THEN
                EditIndex := (SelectRecipe - 1) * 20 + EditStep;
                RecipeSteps [EditIndex] := SelectProcess;
             END_IF
         END_IF
     END_IF
    
    StepNomber := RecipeSteps [RecipeIndex];
    
    //Режимы работы
    CASE StepNomber OF
        0://Завершение процессов  
        HeatCamera := FALSE;
        HeatGen := FALSE;
        Speed1 := FALSE; 
        Speed2 := FALSE;
        Valve1 := FALSE;     
        Valve2 := FALSE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := FALSE;       
        Hydration := FALSE;  
        1://Нагрев
        HeatCamera := TRUE;
        HeatGen := FALSE;
        Speed1 := TRUE; 
        Speed2 := FALSE;
        Valve1 := FALSE;    
        Valve2 := FALSE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := FALSE;       
        Hydration := FALSE;  
        2://Розжиг
        HeatCamera := TRUE;
        HeatGen := TRUE;
        Speed1 := TRUE; 
        Speed2 := FALSE;
        Valve1 := TRUE;    
        Valve2 := TRUE;    
        Boost := TRUE;      
        Blowdown := TRUE;   
        Firefighting := FALSE; 
        Stirrer := TRUE;    
        Sink := FALSE;       
        Hydration := TRUE;  
        3://Копчения
        HeatCamera := TRUE;
        HeatGen := TRUE;
        Speed1 := FALSE; 
        Speed2 := TRUE;
        Valve1 := FALSE;    
        Valve2 := TRUE;    
        Boost := TRUE;      
        Blowdown := TRUE;   
        Firefighting := FALSE; 
        Stirrer := TRUE;    
        Sink := FALSE;       
        Hydration := TRUE;    
        4://Проветривание
        HeatCamera := FALSE;
        HeatGen := FALSE;
        Speed1 := FALSE; 
        Speed2 := TRUE;
        Valve1 := TRUE;    
        Valve2 := TRUE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := FALSE;       
        Hydration := FALSE;   
        5://Мойка
        HeatCamera := TRUE;
        HeatGen := FALSE;
        Speed1 := FALSE; 
        Speed2 := FALSE;
        Valve1 := FALSE;    
        Valve2 := FALSE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := TRUE;       
        Hydration := FALSE;          
        6://Сушка
        HeatCamera := TRUE;
        HeatGen := FALSE;
        Speed1 := FALSE; 
        Speed2 := TRUE;
        Valve1 := FALSE;     
        Valve2 := FALSE;    
        Boost := FALSE;      
        Blowdown := FALSE;   
        Firefighting := FALSE; 
        Stirrer := FALSE;    
        Sink := FALSE;       
        Hydration := FALSE;    
    END_CASE;
    
    END_FUNCTION_BLOCK

    Заранее спасибо всем, кто подскажет, куда лучше двигаться дальше.
    Любая критика и советы приветствуются.
    Последний раз редактировалось sakanchik; 10.03.2026 в 18:53.

  2. #2

    По умолчанию

    Всё тоже самое делается циклами FOR или WHILE (использовать аккуратно) в 4-5 строк кода,
    пример использования тут
    Работа с циклами___ 4 насоса_Нараб_Ротация по времени_4 Уровня_10________ https://owen.ru/forum/showthread.php?t=38920&page=2#13
    Простой шаговый автомат, новый TON с паузой_____ https://owen.ru/forum/showthread.php...39&page=43#424
    Прогр. управление 6 нагрузками 6 реж. 12 шагов _ФБ_фунции_____https://owen.ru/forum/showthread.php...39&page=11#105
    Последний раз редактировалось kondor3000; 10.03.2026 в 19:25.

  3. #3

    По умолчанию

    C рецептами в OL будет некоторое неудобство, т.к:
    1. Энергонезависимых переменных нельзя сделать внутри блоков на ST
    2. Массивов в качестве входных/выходных переменных пока не завезли

    По поводу организации CASE предлагалось нечто подобное здесь

  4. #4

    По умолчанию

    Если рецепты хранить в панели оператора, тогда можно загружать их в ПР/ПЛК.
    Единственно, у ПР200 регистров для обмена по Modbus (сетевых Slave переменных) - кот наплакал, хотя, при некотором старании, на один рецепт может хватить.

  5. #5
    Пользователь
    Регистрация
    09.12.2013
    Адрес
    Ставрополь
    Сообщений
    2,015

    По умолчанию

    Помимо того, что показанный код не работает
    1. как уже говорили, в ST нет энергонезависимых переменных, поэтому использовать его для хранения рецептов не имеет смысла
    2. 200 энергонезависимых переменных сожрут почти всю память
    3. хранить 10 рецептов по 20 двадцать шагов в одномерном массиве, так себе идея
    4. помимо шагов не вижу в рецепте длительности нахождения на шаге
    5. процесс удобнее представить в виде битовой маски
    6. как то странно пожаротушение хранить в рецепте
    Последний раз редактировалось Dimensy; 11.03.2026 в 08:01.

  6. #6

    По умолчанию

    Боюсь, что как раз для логики этого приложения лучше всего подойдёт именно FBD:
    1. Необходимость редактировать рецепты (энергонезависимые переменные) через экран ПР200.
    2. Алгоритм не настолько сложен, чтобы его реализовывать в ST.
    3. Еще не известны условия перехода на следующий шаг (время, достижение уставки и т.д.)

  7. #7

    По умолчанию

    Здравствуйте, про отсутствие энергонезависимых переменных уже принял во внимание. То что код не рабочий понимаю. Длительность нахождения в шаге пока не делал, ну скорее всего и не буду. Лучше напишу всю логику работы установки на FBD. Про битовую маску вас услышал, буду изучать. А про пожаротушение, да, глупость с моей стороны. В любом случае спасибо за советы.

  8. #8

    По умолчанию

    Возможно, будет интересно ознакомиться с короткой статьёй
    Автоматное программирование в среде Owen Logic
    https://owen.ru/forum/showthread.php...l=1#post340279

    Она как раз о конечных автоматах в эпоху отсутствия в Owen Logic языка ST.

Похожие темы

  1. Первые шаги в Owen Logic
    от sertol64 в разделе Программируемые реле
    Ответов: 207
    Последнее сообщение: 04.01.2026, 22:21
  2. Первые шаги...
    от Александр И. в разделе Эксплуатация
    Ответов: 1
    Последнее сообщение: 02.11.2020, 13:42
  3. первые шаги
    от zrom31 в разделе ПЛК1хх
    Ответов: 17
    Последнее сообщение: 05.10.2018, 14:34
  4. Первые шаги
    от WhiteZebeer в разделе Master SCADA 3
    Ответов: 106
    Последнее сообщение: 06.09.2017, 16:43
  5. плк63 + сп270 первые шаги
    от Father в разделе ПЛК63/73
    Ответов: 9
    Последнее сообщение: 21.01.2010, 10:22

Метки этой темы

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •