PDA

Просмотр полной версии : Помогите с синтаксисом ST!



ANDREY2002
26.09.2012, 01:32
есть 5 входных переменных типа BOOL и массив

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

VAR
arr: ARRAY [1..5] OF BYTE; (*êîä îøèáêè*)
x: INT;
END_VAR
VAR_INPUT
in1: BOOL;
in2: BOOL;
in3: BOOL;
in4: BOOL;
in5: BOOL;
END_VAR


FOR x:=1 TO 5 DO
IF in(x)=TRUE THEN ?????????
arr[x]:=3; END_IF
END_FOR
Помогите кто знает! очень нужно!

Yegor
26.09.2012, 07:06
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR

FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.

Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.

capzap
26.09.2012, 07:23
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR

FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.

Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.

A что, компилятор пропустил указатель на буль?

Yegor
26.09.2012, 08:25
Почему он не должен был его пропустить?

capzap
26.09.2012, 08:55
должен был ругаться что с такими переменными работает инструкция BITADR, но это по памяти, может уже что поменялось

lara197a
26.09.2012, 09:30
Указатель работает только с WORD и DWORD(справка КДС)
А компилиться с бит то же будет

ANDREY2002
26.09.2012, 09:40
VAR
in1, in2, in3, in4, in5: BOOL;
inp: POINTER TO BOOL;
x: INT;
END_VAR

FOR x := 0 TO 4 DO
inp := ADR(in1) + x;
IF inp^ THEN
(* Whatever *)
END_IF
END_FORТолько надо убедиться, что все переменные друг за другом в памяти идут и не попадают под выравнивание.

Вообще программисту, который пишет «IF что-то = TRUE THEN» вместо «IF что-то THEN», я настоятельно рекомендую не баловаться указателями и делать подобные вещи через промежуточный массив.
спасибо, Yegor
насчет промежуточного массива не совсем понятно
ведь каждому члену массива нужно присвоить какой то вход( а если их 100) для каждого писать?
но ведь мне и надо автоматизировать этот процесс!

capzap
26.09.2012, 09:42
присвоив указателю этот же указатель плюс один получим второй байт переменной, так что нижняя точка это все же байт. И у меня КДС ругается, может дело в настройках среды или в версии

Дмитрий Артюховский
26.09.2012, 10:26
хулиганством занимаетесь ))
вспомните, что битовые переменные простенько так объединяются в BYTE или WORD....
считайте их одним байтом, а в цикле пробегите по нему битововй маской с AND для проверки установки отдельных битов, а еще выстрее сделайте CASE на интересующие комбинации битов

Yegor
26.09.2012, 10:58
должен был ругаться что с такими переменными работает инструкция BITADRНе будет она с такими переменными работать. Даже не скомпилируется.
Указатель работает только с WORD и DWORD(справка КДС)
A pointer can point to any data type or function block even to user-defined types.
насчет промежуточного массива не совсем понятно
ведь каждому члену массива нужно присвоить какой то вход( а если их 100) для каждого писать?
но ведь мне и надо автоматизировать этот процесс!Как я вам показал — через указатели — сотню переменных автоматизировать тоже не получится. Там выравнивание всё поломает.
вспомните, что битовые переменные простенько так объединяются в BYTE или WORD....
считайте их одним байтомВ данном случае эти переменные даны неупакованными. И упаковывать их это та же головная боль, что и с занесением в промежуточный массив.

В кодесисе есть функции с переменным числом параметров, но пользователю почему-то не дают возможности их создавать.

ANDREY2002
26.09.2012, 23:42
Выходит , что не способа автоматизировать этот процесс ???????:confused:

Yegor
27.09.2012, 06:09
Опишите свой случай.

ANDREY2002
27.09.2012, 22:40
случай, банальный
система управления климатом в здании :
два десятка различных аналоговых датчиков , десяток дискретных датчиков все они могут могут быть не исправны или сигнализировать какую либо неисправность + еще с десяток различных аварий из работы программы итого около 40 различных аварийных сигналов типа BOOL.
все эти аварии должны фиксироваться и заносится в архив, и в последствии выводится на СП270 и т.д.
блок программы который следит за изменением сигнала на 40 входах не удается автоматизировать: т.е. приходится писать для каждого входа
IF in_1=true THEN arr[1]:= 1;
IF in_2=true THEN arr[2]:= 2; и тд. 40 раз


а потом еще для передачи в панель обратно
out_1:=arr[1];......

и никаким циклом автоматизировать этот процесс не удается(
для лучшей диагностики планируется расширить список аварий до 100
Не верится , что в CoDeSys эту простую имхо задачу нельзя решить!

capzap
27.09.2012, 23:05
случай, банальный
система управления климатом в здании :
два десятка различных аналоговых датчиков , десяток дискретных датчиков все они могут могут быть не исправны или сигнализировать какую либо неисправность + еще с десяток различных аварий из работы программы итого около 40 различных аварийных сигналов типа BOOL.
все эти аварии должны фиксироваться и заносится в архив, и в последствии выводится на СП270 и т.д.
блок программы который следит за изменением сигнала на 40 входах не удается автоматизировать: т.е. приходится писать для каждого входа
IF in_1=true THEN arr[1]:= 1;
IF in_2=true THEN arr[2]:= 2; и тд. 40 раз


а потом еще для передачи в панель обратно
out_1:=arr[1];......

и никаким циклом автоматизировать этот процесс не удается(
для лучшей диагностики планируется расширить список аварий до 100
Не верится , что в CoDeSys эту простую имхо задачу нельзя решить!

а такой способ не поможет решить Вашу проблему автоматизации http://www.owen.ru/forum/attachment.php?attachmentid=6963&d=1347859220

Yegor
28.09.2012, 07:07
Ну, если вы удостоверитесь, что булевые переменные идут одним куском без выравнивания либо сделайте поправку на него, то вот вам способ:
PROGRAM PLC_PRG
VAR
p: POINTER TO ARRAY [0..5] OF BOOL;
in0, in1, in2, in3, in4, in5: BOOL;
i: INT;
END_VAR

p := ADR(in0);

FOR i := 0 TO 5 DO
IF p^[i] THEN (* ... *) END_IF
END_FORИ на будущее: избегайте тавтологий вроде «IF in_1=true THEN» — достаточно написать «IF in_1 THEN».

--------->8---------
Проверил для 41 переменной. Вроде работает:
PROGRAM PLC_PRG
VAR
p: POINTER TO ARRAY [0..40] OF BOOL;
in0, in1, in2, in3, in4, in5, in6, in7, in8, in9, in10, in11, in12, in13, in14, in15, in16, in17, in18, in19, in20,
in21, in22, in23, in24, in25, in26, in27, in28, in29, in30, in31, in32, in33, in34, in35, in36, in37, in38, in39, in40: BOOL;
END_VAR

p := ADR(in0);
(* См. содержимое p^ при отладке *)Этим же способом и выводить можно:
p^[5] := TRUE; (* Делает in5 равным true *)

ANDREY2002
28.09.2012, 09:33
Спасибо огромное! Yegor и Сapzap.