Показано с 1 по 10 из 689

Тема: Функциональные блоки на языке ST

Комбинированный просмотр

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #1

    По умолчанию

    Добрый день!
    Подскажите пожалуйста, почему при изменении переменной udisel оператор if не переключает выходы?
    Необходимо что бы выход Start кратковременно менял значение при изменении udisel для работы Rise_fall.

    //область кода

    xOut1 := 0;
    xOut2 := 0;
    xOut3 := 0;
    Start := false ;

    if (udiSel >= 0) or (udiSel <= 1) then
    xOut1 := IN0_0;
    xOut2 := IN0_1max;
    xOut3 := D0_1;
    Start := true ;
    ELSIF udiSel >= 2 THEN
    Start := false ;

    ELSIF (udiSel >= 2) or (udiSel <=7) then
    xOut1 := IN0_1max;
    xOut2 := IN2_7max;
    xOut3 := D2_7;
    Start := true ;
    ELSIF udiSel >= 8 THEN
    Start := false ;

    end_if

    end_function_block

  2. #2
    Пользователь Аватар для capzap
    Регистрация
    25.02.2011
    Адрес
    Киров
    Сообщений
    10,575

    По умолчанию

    Цитата Сообщение от Александр_004 Посмотреть сообщение
    Добрый день!
    Подскажите пожалуйста, почему при изменении переменной udisel оператор if не переключает выходы?
    Необходимо что бы выход Start кратковременно менял значение при изменении udisel для работы Rise_fall.

    //область кода

    xOut1 := 0;
    xOut2 := 0;
    xOut3 := 0;
    Start := false ;

    if (udiSel >= 0) or (udiSel <= 1) then
    xOut1 := IN0_0;
    xOut2 := IN0_1max;
    xOut3 := D0_1;
    Start := true ;
    ELSIF udiSel >= 2 THEN
    Start := false ;

    ELSIF (udiSel >= 2) or (udiSel <=7) then
    xOut1 := IN0_1max;
    xOut2 := IN2_7max;
    xOut3 := D2_7;
    Start := true ;
    ELSIF udiSel >= 8 THEN
    Start := false ;

    end_if

    end_function_block
    Answer | Phind Instant Model

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

    Ваш код содержит несколько блоков ELSIF, каждый из которых проверяет различные диапазоны значений udiSel. Однако, последовательность этих условий и их формулировка могут приводить к непредвиденному поведению. В частности, если udiSel находится в диапазоне от 2 до 7 включительно, то выполняется только первый блок ELSIF, который устанавливает Start в true, но не обновляет значения xOut1, xOut2, и xOut3. Это происходит потому, что после выполнения первого условия, остальные условия не проверяются из-за использования ключевого слова ELSIF.

    Чтобы исправить это, вам нужно либо объединить условия, чтобы они корректно перекрывались, либо использовать отдельные операторы if для каждого условия, чтобы каждое из них могло быть проверено независимо.
    Использование OR вместо >=

    Вы используете оператор or (or) для проверки диапазонов значений udiSel. Это может привести к тому, что одно из условий будет истинным даже если udiSel находится вне этого диапазона. Например, (udiSel >= 0) or (udiSel <= 1) будет истинным для любого значения udiSel, поскольку хотя бы одно из условий всегда выполняется. Возможно, вы хотели использовать оператор and (and), чтобы оба условия должны выполняться одновременно.
    Рекомендации по исправлению

    Пересмотрите логику условий: Убедитесь, что условия корректно перекрывают все возможные значения udiSel и что нет случайных истинностей из-за неправильного использования операторов or или and.

    Используйте отдельные операторы if для каждого блока: Это позволит каждому блоку условий быть проверенным независимо, избегая проблем с перекрытием.

    Проверьте логику установки Start: Убедитесь, что установка Start в false соответствует вашим требованиям и не мешает правильной работе системы.

    Пример исправленного кода:
    Код:
    xOut1 := 0;
    xOut2 := 0;
    xOut3 := 0;
    Start := false;
    
    if (udiSel >= 0) and (udiSel <= 1) then
    begin
        xOut1 := IN0_0;
        xOut2 := IN0_1max;
        xOut3 := D0_1;
        Start := true;
    end
    else if udiSel >= 2 and udiSel < 8 then
    begin
        xOut1 := IN0_1max;
        xOut2 := IN2_7max;
        xOut3 := D2_7;
        Start := true;
    end
    else if udiSel >= 8 then
    begin
        Start := false;
    end;
    так ответила бездушная машина, вдруг угадала
    Bad programmers worry about the code. Good programmers worry about data structures and their relationships

    среди успешных людей я не встречала нытиков
    Барбара Коркоран

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

    По умолчанию

    Цитата Сообщение от Александр_004 Посмотреть сообщение
    Добрый день!
    Подскажите пожалуйста, почему при изменении переменной udisel оператор if не переключает выходы?
    Необходимо что бы выход Start кратковременно менял значение при изменении udisel для работы Rise_fall.

    //область кода

    xOut1 := 0;
    xOut2 := 0;
    xOut3 := 0;
    Start := false ;

    if (udiSel >= 0) or (udiSel <= 1) then
    xOut1 := IN0_0;
    xOut2 := IN0_1max;
    xOut3 := D0_1;
    Start := true ;
    ELSIF udiSel >= 2 THEN
    Start := false ;

    ELSIF (udiSel >= 2) or (udiSel <=7) then
    xOut1 := IN0_1max;
    xOut2 := IN2_7max;
    xOut3 := D2_7;
    Start := true ;
    ELSIF udiSel >= 8 THEN
    Start := false ;

    end_if

    end_function_block
    А можно поинтересоваться, как вы именно хотите моргать переменной Start? При каждом изменении udiSel взвести на один цикл или сбросить на один цикл?
    И да, у вас тут несколько ошибок
    1. if (udiSel >= 0) or (udiSel <= 1) then - сразу отбрасывает все остальные сравнения, наверное, вы хотели if (udiSel = 0) or (udiSel = 1)
    2. ELSIF udiSel >= 2 THEN - отбрасывает следующее сравнение, вероятно здесь вы пытались моргнуть
    3. ELSIF (udiSel >= 2) or (udiSel <=7) then - отбрасывает следующее сравнение, тут, наверное ELSIF (udiSel >= 2) and (udiSel <=7)
    4. ELSIF udiSel >= 8 THEN - как бы лишний, потому что вначале вы уже сбросили переменную Start
    Последний раз редактировалось Dimensy; 12.08.2024 в 12:54.

  4. #4

    По умолчанию

    Да, мне нужно при каждом изменении значения udiSel, на один цикл изменять выход Start. Спасибо за поправки

    С поправками выше, стало работать, переключает. Но как кратковременно менять значение выхода Start (bool) в цикле программы? При переключении выходов должен сбросится регулятор подключенный к данным выходам.
    Последний раз редактировалось Александр_004; 12.08.2024 в 13:06.

  5. #5

    По умолчанию

    Цитата Сообщение от Александр_004 Посмотреть сообщение
    Да, мне нужно при каждом изменении значения udiSel, на один цикл изменять выход Start. Спасибо за поправки

    С поправками выше, стало работать, переключает. Но как кратковременно менять значение выхода Start (bool) в цикле программы? При переключении выходов должен сбросится регулятор подключенный к данным выходам.
    Для этого можно использовать код R_Trig, включение выхода на 1 цикл, где In и Q вход и выход
    Код:
    var //объявление локальных переменныx
           R:bool; //локальная переменная с типом данных bool
    end_var    
    
        Q:=In and not R;
        R:=In;

  6. #6

    По умолчанию

    Какие еще есть варианты отключить выход на короткий промежуток времени при смене значения на входе? Возможно ли после каждого оператора If поставить условие отключения выхода, к примеру на 1 мс?
    Моргнуть при изменении этапа, кратковременно выключить выход (сбросить Start).

  7. #7

    По умолчанию

    Цитата Сообщение от Александр_004 Посмотреть сообщение
    Какие еще есть варианты отключить выход на короткий промежуток времени при смене значения на входе? Возможно ли после каждого оператора If поставить условие отключения выхода, к примеру на 1 мс?
    Моргнуть при изменении этапа, кратковременно выключить выход (сбросить Start).
    Дописать код в конце и добавить переменную udiSel_ в VAR
    Код:
    if udiSel<> udiSel_ then
        Start:=false;
        udiSel_:=udiSel;
      else Start:=True;
    end_if
    Последний раз редактировалось kondor3000; 12.08.2024 в 14:43.

  8. #8

    По умолчанию

    Цитата Сообщение от kondor3000 Посмотреть сообщение
    Дописать код в конце и добавить переменную udiSel_ в VAR
    Код:
    if udiSel<> udiSel_ then
        Start:=false;
        udiSel_:=udiSel;
    else Start:=True;
    end_if
    Спасибо! Работает!

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

    По умолчанию

    Цитата Сообщение от Александр_004 Посмотреть сообщение
    Да, мне нужно при каждом изменении значения udiSel, на один цикл изменять выход Start. Спасибо за поправки

    С поправками выше, стало работать, переключает. Но как кратковременно менять значение выхода Start (bool) в цикле программы? При переключении выходов должен сбросится регулятор подключенный к данным выходам.
    Еще раз хочу уточнить.
    У вас первый этап занимает два шага, второй этап - 6 шагов. Вы хотите моргнуть при изменении шага (udiSel) или изменении этапа (выходы)? И как моргнуть - кратковременно сбросить переменную Start или кратковременно взвести ее?

Похожие темы

  1. ПЛК73 (Функциональные кнопки)
    от necro в разделе ПЛК63/73
    Ответов: 8
    Последнее сообщение: 18.05.2022, 10:03
  2. Функциональные блоки
    от ribamuka в разделе СПК2xx (архив)
    Ответов: 4
    Последнее сообщение: 08.04.2018, 15:01
  3. Функциональные блоки насосов в CoDeSys
    от Алексей Ермолаев в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 28.03.2017, 13:50
  4. Функциональные блоки- где искать?
    от Xops в разделе ПЛК1хх
    Ответов: 16
    Последнее сообщение: 01.03.2016, 11:07
  5. СПК функциональные клавиши
    от Lyohin в разделе Трёп (Курилка)
    Ответов: 0
    Последнее сообщение: 30.03.2015, 15:10

Ваши права

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