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

Тема: Проблема с функцией

  1. #1

    По умолчанию Проблема с функцией

    я реализовал функцию внутри функции есть кейс
    При первом запуске функции проблем нет
    При повторном запуске функция начинает не с кейс 0 а с того места где последний раз закончилась (понял по переменной error)
    Код:
    press:= getpress();
    CASE PLC_PRG.iStateSetPress OF
    	0: // определение вектора создания давления и запуск двигателя
    		IF press < 0.5 THEN
    			IF press < pressS THEN
    				driveDOWN();
    				PLC_PRG.iStateSetPress := 1;
    			ELSE
    				driveUP();
    				PLC_PRG.iStateSetPress := 2;
    			END_IF
    		ELSE
    			IF press < pressS THEN
    				//driveDOWN();
    				PLC_PRG.iStateSetPress := 3;
    			ELSE
    				//driveUP();
    				PLC_PRG.iStateSetPress := 4;
    			END_IF
    		END_IF
    	1: // давим на зоготвку
    		IF press >= 0.5 THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 3;
    		END_IF
    	2: //уменьшаем давление на заготовку
    		IF press <= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 4;
    		END_IF
    	3: // поэтапное давление на заготовку
    		CASE PLC_PRG_SM.pre OF
    			0://проверка условия
    				IF press >= pressS THEN
    					stopMOTORS();
    					PLC_PRG.iStateSetPress := 9;
    				ELSE				
    					PLC_PRG_SM.pre:= 1;
    					driveDOWN();
    				END_IF
    			1://давим
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 2;
    				END_IF
    			2://ждём стабилизации
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 0;
    				END_IF
    		END_CASE
    	4: // поэтапное уменьшение давления на заготовку
    		CASE PLC_PRG_SM.pre OF
    			0://проверка условия
    				IF press >= pressS THEN
    					stopMOTORS();
    					PLC_PRG.iStateSetPress := 9;
    				ELSE
    					PLC_PRG_SM.pre:= 1;
    					driveUP();
    				END_IF
    			1://уменьшаем давление
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 2;
    				END_IF
    			2://ждём стабилизации
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 0;
    				END_IF
    		END_CASE
    	5: // 
    	6: // 
    	7: // давим на зоготвку
    		IF press >= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 9;
    		END_IF
    	8: //уменьшаем давление на заготовку
    		IF press <= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 9;
    		END_IF 
    	9: // 	
    	 	targetvars.error:= 1;
    END_CASE
    Возможно я как-то неправильно создал функцию или ещё что-то сделал нет так?
    Последний раз редактировалось Стас Ц.; 11.10.2023 в 16:11.

  2. #2
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    12,193

    По умолчанию

    Не очень понятно, как вы из функции обращаетесь к переменным программы - компилятор должен был выдать ошибку.
    Возможно, "функцией" вы называете не то, что под этим термином подразумевается в CODESYS.
    Выложите ваш проект - посмотрим, в чем дело.

  3. #3

    По умолчанию

    Цитата Сообщение от Стас Ц. Посмотреть сообщение
    я реализовал функцию внутри функции есть кейс
    При первом запуске функции проблем нет
    При повторном запуске функция начинает не с кейс 0 а с того места где последний раз закончилась (понял по переменной error)
    Возможно я как-то неправильно создал функцию или ещё что-то сделал нет так?
    Функция по определению не имеет памяти и имеет только 1 выход, носящий имя функции, если у вас функция запоминает значения, то это уже ФБ. Вы даже код выложили не полностью, а только тело.
    Либо эта переменная error, подана на вход функции в следующем цикле программы или присвоена при выполнении кода.
    Последний раз редактировалось kondor3000; 11.10.2023 в 16:19.

  4. #4

    По умолчанию

    Я создал объект POU и в нем написал это код
    В варе я объявил только press: real а а также в варинпут pressS
    К сожелению я смогу открыть целиком код только завтра утром
    Последний раз редактировалось Стас Ц.; 11.10.2023 в 16:20.

  5. #5

    По умолчанию

    Код:
    FUNCTION setPRESS : REAL
    VAR_INPUT
    	pressS: REAL;		// нужное давление
    END_VAR
    VAR
    	press: REAL;  		// текушее давление
    END_VAR
    Это инициализация а дальше что мы в ней делаем
    Код:
    press:=getPRESS();
    CASE PLC_PRG.iStateSetPress OF
    	0: // определение вектора создания давления и запуск двигателя
    		IF press < 0.5 THEN
    			IF press < pressS THEN
    				driveDOWN();
    				PLC_PRG.iStateSetPress := 1;
    			ELSE
    				driveUP();
    				PLC_PRG.iStateSetPress := 2;
    			END_IF
    		ELSE
    			IF press < pressS THEN
    				//driveDOWN();
    				PLC_PRG.iStateSetPress := 3;
    			ELSE
    				//driveUP();
    				PLC_PRG.iStateSetPress := 4;
    			END_IF
    		END_IF
    	1: // давим на зоготвку
    		IF press >= 0.5 THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 3;
    		END_IF
    	2: //уменьшаем давление на заготовку
    		IF press <= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 4;
    		END_IF
    	3: // поэтапное давление на заготовку
    		CASE PLC_PRG_SM.pre OF
    			0://проверка условия
    				IF press >= pressS THEN
    					stopMOTORS();
    					PLC_PRG.iStateSetPress := 9;
    				ELSE				//возможно надо сделать elseif для контроля состояния дверей
    					PLC_PRG_SM.pre:= 1;
    					driveDOWN();
    				END_IF
    			1://давим
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 2;
    				END_IF
    			2://ждём стабилизации
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 0;
    				END_IF
    		END_CASE
    	4: // поэтапное уменьшение давления на заготовку
    		CASE PLC_PRG_SM.pre OF
    			0://проверка условия
    				IF press >= pressS THEN
    					stopMOTORS();
    					PLC_PRG.iStateSetPress := 9;
    				ELSE
    					PLC_PRG_SM.pre:= 1;
    					driveUP();
    				END_IF
    			1://уменьшаем давление
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 2;
    				END_IF
    			2://ждём стабилизации
    				PLC_PRG_SM.preX:= PLC_PRG_SM.preX + 1;
    				IF PLC_PRG_SM.preX >= 5 THEN
    					stopMOTORS();
    					PLC_PRG_SM.pre:= 0;
    				END_IF
    		END_CASE
    	5: // 
    	6: // 
    	7: // давим на зоготвку
    		IF press >= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 9;
    		END_IF
    	8: //уменьшаем давление на заготовку
    		IF press <= pressS THEN
    			stopMOTORS();
    			PLC_PRG.iStateSetPress := 9;
    		END_IF 
    	9: // 	
    	 	targetvars.error:= 1;
    END_CASE
    Возможно мне надо создать POU программу, а не функцию, но я всё равно не понимаю почему функция не работает

  6. #6

  7. #7

    По умолчанию

    к сожелению нет
    при первом запуске норм а при следующих начинает с того место где остановился

  8. #8
    Супер Модератор Аватар для Евгений Кислов
    Регистрация
    27.01.2015
    Адрес
    Москва
    Сообщений
    12,193

    По умолчанию

    Ваш проект не проходит компиляцию.

    12-10-2023 9-06-28.png

    Но, в целом, вот что можно сказать:

    1. Использовать программы с VAR_INPUT - это плохой подход. Лучше перенесите эти переменные в VAR, а функцию setPRESS оформите как метод программы PLC_PRG (ПКМ на PLC_PRG - Добавление объекта - Метод)

    2.

    "При повторном запуске функция начинает не с кейс 0 а с того места где последний раз закончилась
    Потому что значением iStateSetPress управляете вы (как уже выше указал capzap).
    Если присвоите туда 0 - то функция "начинет с кейс 0".

  9. #9

    По умолчанию

    1 попробую
    2 я обнулял iStateSetPress а функция не начинала с кейса 0
    ну попробую поменять на метод и буду надеятся что поможет
    Спасибо за помощь

  10. #10

    По умолчанию

    По документации Codesys программу нельзя вызывать из функции.
    Programs and function blocks can call a program. A program call is not allowed in a function. There are not instances of programs.
    Кроме того, PRG сохраняет свои переменные между вызовами, т.е. ведёт себя как функциональный блок, только у него нет экземпляра. У него своя собственная область памяти, общая для любых вызовов извне.
    PLC_PRG с переменной iStateSetPress возможно переделать в простую функцию?

Похожие темы

  1. Исключение при работе с функцией OSU.WReplaceSubstring
    от alekstani в разделе Помощь Разработчикам
    Ответов: 3
    Последнее сообщение: 13.03.2023, 15:26
  2. Работа в c функцией на ST в OWEN LOGIC
    от Lev_Cheg в разделе Среда программирования OWEN Logic
    Ответов: 6
    Последнее сообщение: 27.05.2022, 12:48
  3. Ответов: 21
    Последнее сообщение: 24.12.2021, 20:58
  4. проблема с функцией blinker
    от mp3moto в разделе ПЛК1хх
    Ответов: 6
    Последнее сообщение: 22.12.2008, 19:19
  5. проблема с функцией Real_to_string
    от mettled в разделе ПЛК1хх
    Ответов: 0
    Последнее сообщение: 25.04.2008, 17:23

Ваши права

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