PDA

Просмотр полной версии : Не могу добить код на ST



Клаус
20.09.2023, 23:45
Добрый вечер. Суть вопроса такая 40 датчиков температуры и 40 клапанов к каждому. Есть фиксированная температура уставки, соответственно опрашивается каждый датчик, и если T[i] превышает Ust, то клапан V[i] открывается до стабилизации темп-ры. И при этом, вот в этом и затык у меня почему-то, если хотя бы одна T[i]>Ust, то должно сигнализироваться (грубо говоря лампочка горит). Код на ST вот так выглядит (для простоты пока выбрал массив не из 40, а из 3 элементов), но вот хоть убей, клапана отрабатывают нормально, а вот лампочка загорается/гаснет, только когда выполняется условия для третьего клапана. Не могу понять, в чём дело? Понимаю, что задача фигня, но вот ступор какой-то. Особо программированием не занимался, если что, познаю сейчас.

PROGRAM PLC_PRG
VAR
Ust: REAL:=5;//Температура уставки
Temp: ARRAY [1..3] OF REAL;//Измеренная температура
Valve: ARRAY [1..3] OF BOOL;//Клапан
lamp: BOOL;//Сигнальная лампа
i: BYTE;
END_VAR

Тело программы

FOR i:=1 TO 3 DO;
IF Temp[i] > UST THEN
lamp:=TRUE;
Valve[i]:=TRUE;

ELSE
Valve[i]:=FALSE;
lamp:=FALSE;

END_IF
END_FOR

melky
20.09.2023, 23:48
Так у вас если НЕ, то лампа гаснет... Лампа то у вас не [i] а надо чтобы тоже бала lamp[i] и потом уже проверка, если хоть одна true то и лампочка Гори...

через OR все Valve[i] соберите и на лампу, без всяких уже там лампа true не true...

Клаус
20.09.2023, 23:49
Так лампа одна на все 40 узлов. Если на CFC я понимаю как сделать, то тут что-то никак. Но, на CFC это такое полотно получится :))

melky
20.09.2023, 23:51
я вижу что одна. Ну вот клапан 2 сработал, а последний 40-й выключен и лампа у вас будет выключена вполне естественно.
Как вариант в своем цикле можете делать ADD на все ваши true и после цикла проверять >0 - лампа гори.
перед началом цикла соответственно обнулять переменную lamp

Клаус
20.09.2023, 23:51
Понял, попробую.

melky
20.09.2023, 23:57
можно так же, но потом в цикле проверять же. Лучше сделайте перед циклом lamp := 0;

если условие выполняется то lamp := lamp + 1;
если не выполняется, ничего не делайте, а после цикла IF lamp > 0 THEN "гори", если Не, то гасни...

Клаус
21.09.2023, 00:12
можно так же, но потом в цикле проверять же. Лучше сделайте перед циклом lamp := 0;

если условие выполняется то lamp := lamp + 1;
если не выполняется, ничего не делайте, а после цикла IF lamp > 0 THEN "гори", если Не, то гасни...

Спасибо огромное!!! Вот так заработало:

PROGRAM PLC_PRG
VAR
Ust: REAL:=5;//Температура уставки
Temp: ARRAY [1..3] OF REAL;//Измеренная температура
Valve: ARRAY [1..3] OF BOOL;//Клапана
lamp: BOOL;//Сигнальная лампа
xlamp: INT;
i: BYTE;
END_VAR

xlamp:=0;
FOR i:=1 TO 3 DO;
IF Temp[i] > UST THEN
xlamp:= xlamp + 1;
Valve[i]:=TRUE;
ELSE
Valve[i]:=FALSE;
END_IF
IF xlamp > 0 THEN Lamp:=TRUE;
ELSE lamp:=FALSE;
END_IF
END_FOR

МихаилГл
21.09.2023, 04:11
Можно было проще, вернее без суммирования. Я например для механизма с 32мя возможными авариями делаю так:
AlarmSum:=false
Далее в цикле:
If alarm(i) then alarmSum:=true
Условие "иначе" не ставлю, просто взвел бит и все.
И в итоге ваш код почти такой же, но не суммирую и не проверяю что больше нуля.

МихаилГл
21.09.2023, 04:15
Lamp:=false;
FOR i:=1 TO 3 DO;
IF Temp[i] > UST THEN
lamp:= true;
Valve[i]:=TRUE;
ELSE
Valve[i]:=FALSE;
END_IF
END_FOR

Клаус
21.09.2023, 07:00
Можно было проще, вернее без суммирования. Я например для механизма с 32мя возможными авариями делаю так:
AlarmSum:=false
Далее в цикле:
If alarm(i) then alarmSum:=true
Условие "иначе" не ставлю, просто взвел бит и все.
И в итоге ваш код почти такой же, но не суммирую и не проверяю что больше нуля.

Спасибо, возьму на вооружение!

melky
21.09.2023, 08:40
МихаилГл ну, лишний цикл все же, так мы в любом случае проверяем в цикле условие на Уставку. Дополнительно можно показывать на экране количество, и в принципе заносить в массив в начальном цикле кто из ху и тоже показать.

Если количество не важно и т.д, то последний код вообще минималочка в #9 посте.

Spawn
21.09.2023, 09:58
Какое оборудование-то?

Биты в байтах (словах) соответствующих переменных "править", не?

Потом


IF MyVar > 0 THEN
lamp := TRUE;
ELSE
lamp := FALSE;
END_IF

МихаилГл
21.09.2023, 21:42
МихаилГл ну, лишний цикл все же, так мы в любом случае проверяем в цикле условие на Уставку. Дополнительно можно показывать на экране количество, и в принципе заносить в массив в начальном цикле кто из ху и тоже показать.

Если количество не важно и т.д, то последний код вообще минималочка в #9 посте.

Ну я так общую аварию показываю. Красная лампа на кнопке сброс аварии... А для каждого механизма 32 аварии и на визуализации в сп315 просто номер аварии показываю. Если их много для одного механизма, то они просто по приоритету поверх друг друга наложены. Я год этот алгоритм отрабатывал, механизм не запустился, не остановился, не сошёл с концевого, не дошёл до концевого, и всё это же при реверсивном движении в обратную сторону, потом выбило автомат один из 4х без выдержки времени, сработал датчик один из 8ми с таймером на срабатывание... Там такой ужас, но всё в минимуме кода, при этом структура в программе одна, я её просто для любого количества механизмов использую, ограничение только мощностью плк. Алгоритм работает без сбоев, а вот контроллеры плк210 уже 2 с нова 2023 года выпуска были бракованными, а 4 2022 оказались более качественными.

ВладОвен
27.11.2023, 13:29
Решил не создавать новую тему. Спрошу тут.
Я объявил перечисление:


TYPE Steps :
(
start,
success,
error,
stop
);
END_TYPE


и переменную:
eStep : Steps := Steps.start;
Потом пытаюсь вывести ее на экран через "Тестовое поле ", текст - %s.
Но на дисплее я вижу число 1, а не "start".
Как мне вывести именно "start"?

capzap
27.11.2023, 13:44
Решил не создавать новую тему. Спрошу тут.
Я объявил перечисление:


TYPE Steps :
(
start,
success,
error,
stop
);
END_TYPE


и переменную:
eStep : Steps := Steps.start;
Потом пытаюсь вывести ее на экран через "Тестовое поле ", текст - %s.
Но на дисплее я вижу число 1, а не "start".
Как мне вывести именно "start"?

перечитайте документацию https://help.codesys.com/webapp/_cds_datatype_enum;product=codesys;version=3.5.13. 0 дополнение к стандарту (2)

saii
27.11.2023, 13:45
Решил не создавать новую тему. Спрошу тут.
Я объявил перечисление:


TYPE Steps :
(
start,
success,
error,
stop
);
END_TYPE


и переменную:
eStep : Steps := Steps.start;
Потом пытаюсь вывести ее на экран через "Тестовое поле ", текст - %s.
Но на дисплее я вижу число 1, а не "start".
Как мне вывести именно "start"?
Попробуйте перед строкой "TYPE Steps :" поставить "{attribute 'to_string'}" и при использовании приводить to_string(eStep)

ВладОвен
06.12.2023, 19:35
Спасибо. Это заработало.
А как вывести код ошибки строкой?
Есть библиотека. Она возвращает код ошибки. Т.е. там внутри уже объявлено перечисление с возможными ошибками, и я не могу этому перечислению добавить "{attribute 'to_string'}".
Я пытаюсь вывести код ошибки на экран, использую to_string(eError). Но вижу все равно именно код ошибки - 1, 2, 3 и т.д.
Что я делаю не так?

nick2015
07.12.2023, 09:27
Я так понимаю у вас СПК, можно сделать список текстов с названиями из библиотеки, а потом подставить этот список в свойствах графического элемента.

ВладОвен
07.12.2023, 09:36
Да. Это СПК и бибилиотека OwenCommunication.
Хочу получить код "Нет датчика на связи", а получаю - код 50...
Предложенный метод опробую. Спасибо.