Жизнь есть жизнь!
Вид для печати
Жизнь есть жизнь!
"...В Z+ применяется трёхзначная логика, в которой логические переменные могут принимать не два, а четыре возможных значения: TRUE, FALSE и UNKNOWN..." - Л-логика!
А Codesys например делает так - если входной параметр ФУНКЦИИ не определён - выдаётся ошибка при компиляции. И тоже не надо беспокоиться.
Здравствуйте. возникла такая проблема, при выполнении функции на языке ST не происходит запоминания состояния локальных переменных в функции.
Вложение 62429 это общепринятое правило
если не ошибаюсь, то это новый лоджик, отсюда https://owen.ru/forum/showthread.php?t=36549
Всё открыл новым Лоджиком 2.0, если правильно понял работу функции, нужно сделать обратную связь по часам с задержкой на циклВложение 62431
И добавил R_триггер на вход тактов
не совсем. в функции реализован триггер регистрирующий возрастающий фронт, для этого использована локальная переменная но так как функция не запоминает состояние своих переменных каждый цикл опроса функции происходит инкремент переменной пока на входе true.
(как сделать с костылями я придумал :) хотелось бы чтоб без костылей работало)
Добрый день.
- Поддерживаются ли константы? В редакторе constant подсвечивается как ключевое слово, но использование вызывает ошибку
- какой размер стека у функции? объявил 6 массивов булеанов по 18 элементов, и один массив интеджеров на 18 элементов. При запуске симуляции ошибка - "Превышен максимальный размер стека"
Константы точно не поддерживаются.
Похоже, что есть ограничение на размер памяти для локальных переменных.
Спасибо.
В справке есть следующий текст:
ПРИМЕЧАНИЕ
При записи выражений допустимо использовать переменные (локальные и глобальные) и константы.
что в этом случае подразумевается под глобальными переменными? VAR_GLOBAL как ключевое слово не распознается
Функция не имеет памяти, поэтому инициализированая переменная неким значением это и есть константа, если её не записывать
спасибо за ответ.
к сожалению, переменная даже если ее не записывать не превратиться в константу. Так как все равно будет размещена в стеке.
Глобальные константы в стек не помещаются (по крайней мере обычно не помещаются), соответственно их использование могло бы помочь обойти проблему с ограниченным размером стека.
Добрый день,
Приведенный ниже код почему то возвращает 0 или 1 в зависимости от значения inputVariable
Если убрать оба exit; то возвращает как ожидается - 55 всегда
Такое ощущение что exit; неправильно работает внутри case of
может кто сталкивался?
версия 1.23.301.0
Код:function function1: udint;
var_input
inputVariable : bool;
end_var
var
localVariable : udint := 0;
end_var
repeat
case bool_to_udint(inputVariable) of
0:
localVariable := 55;
exit;
1:
localVariable := 55;
exit;
end_case
until true
end_repeat
function1 := localVariable;
end_function
Я собственно про некорректность работы компилятора и пишу.
Если компилятор код скомпилировал, то он должен работать в соответствии с документацией. Если не может скомпилировать - должен выдать ошибку.
Здесь налицо непредсказуемое поведение которое кому-нибудь точно потратит много времени
Я понимаю что у нас тут не gcc и никто ничего не вылизывал годами. Нашел ошибку, поделился с сообществом и разработчиками.
Пример написан для демонстрации неправильной работы компилятора, чтобы не утруждать Вас чтением 200+ строк кода.
Про логичность я кажется ничего не спрашивал.
Так автомат внутри ST функции. В чем может быть проблема? (кроме полного отсутствия отладки)
Вы совершенно правильно пишете. Функция исполняется каждый цикл, в течение исполнения состояния входов гарантировано не меняются. На следующий скан все повторяется.
Непонятно как из этого следует вывод что внутри функции нельзя несколько раз за один проход поменять состояние автомата описанного внутри функции?
Автомат это просто набор переходов между состояниями. Выход я записываю один раз (по-другому сделать и не получится) По сути это просто операции с локальными переменными.
Или проблема в том что используется цикл с нефиксированным количеством итераций? Ну так вроде никаких ограничений не наложено в документации.
Andrey G для простоты, расположите все элементы вашей функции на основной экран программы - сколько раз они будут выполнены?
Один раз за цикл ПР. Но в FBD нет циклов, я не понимаю к чему вы клоните
В основном выгода в уменьшении времени реакции системы. В ПР это конечно неважно. Так же такой подход в зависимости от ситуации помогает избежать дублирование кода, или даже сократить количество состояний автомата.
Вы утверждали что так работать не будет, повторно прошу пояснить почему.
Andrey G я клоню к тому, что функция, не имеющая памяти так же выполнится за один цикл один раз, как будто вы расположили ее потроха на основном экране.
Вот FBD можно заставить производить вычисления 1-но вычисление за один цикл и накапливать данные, и то придется попотеть... Например вам необходимо выполнить 10 вычислений в программе, но выполняться оно будет 10 циклов...
Да, выполнится один раз за один скан. Если в функции есть цикл, он так же выполнится весь в течение одного скана ПР.
Промежуточные результаты его работы получить нельзя. Зато можно вычислить за один скан то, на что в FBD понадобилось бы несколько.
Не совсем понимаю, что вы собрались вычислять за один скан при условии что входы у вас неизменны в течении всего цикла ? какой в этом попс?
могу понять конечно, если у вас цикл с каким-то приращением и расчет конечной переменной связан с этим, а еще что тут можно прикрутить ?
Задачи связанные с сортировкой и поиском, например. Обработка массива. Вычисления до выполнения условия. Про переключение состояний автомата писал уже.
У Вас довольно общий вопрос - зачем вообще нужны циклы если если вся программа и так цикл.
Ничего принципиально нового Вы на ПР конечно не сделаете ST функцией, и в ПЛК он не превратиться. Это просто дополнительный инструмент который может Вам пригодиться.
Респект вам что код посмотрели ) Я так то про exit спрашивал но почему то дискуссия в сторону циклов ушла и советов как мне писать автомат.
repeat с безусловным выходом использую чтобы выскочить из case вызвав там exit. Я вообще думал это стандартная конструкция для ST, странно что такой ажиотаж вокруг нее.
Andrey G я плохо знаю ST чтобы рассуждать о вашем коде. насколько понимаю exit это то, что в других break, и если есть совпадение то просто выход, не зачем искать что-то дальше....
на счет repeat вообще не в курсе что это :) разве в case есть циклы ? , хм, ну да, Валенок прав, зачем тулить цикл, который выйдет сразу по окончании кода ?
оператор CASE в ST:
"CASE
Аналогичен switch в C. Альтернативные ветки не имеют закрывающей программной скобки
и не могут выполняться одна за другой. Соответственно оператор break не имеет смысла и
отсутствует. "
в справке ОЛ по CASE тоже ни exit ни repeat не упоминаются
Совершенно верно, exit - просто выход из цикла. Выполнилось условие - вызвал exit и перешел сразу к инструкции после end_repeat. Просто exit не работал (по крайней мере в указаной версии OL)
case как и другие конструкции языка можно помещать в цикл.
repeat с безусловным выходом использую чтобы выскочить из case вызвав там exit. Из case в ST по другому по-моему выйти нельзя.
а я думал exit относится к case, но суть в другом, case это набор констант в некотором роде, зачем вы его в цикл, даже если у вас единственная итерация ?
з.ы. я не знаю, как там в C, но в C# вроде из switch case все таки выходят при найденном при помощи break. Может конечно еще какие реализации существуют, надо посмотреть...
break; в СИ так же удобно использовать если вам не нужно выполнять всю ветку.
например если у вас в ветке несколько проверок перед выполнением остального кода. Тогда у Вас есть вариант поместить код который должен выполнится под условие
Когда условий много, вложенность if становится большой.Код:case 1:
if (условие)
{
код;
}
break;
Код:case 1:
if (условие1)
{
if (условие2)
{
if (условие3)
{
код;
}
}
}
break;
В таком случае бывает удобно записать так:
Код:case 1:
if (!условие1) break;
if (!условие2) break;
if (!условие3) break;
код;
break;