Можно ли косвенно индексировать массив в структурированном тексте (IEC 61131-3 стандарт) - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть массив структуры: myStructure[0..100]

Я хотел бы проиндексировать эту структуру по имени.

Он работает, присваивая каждому индексу имя:

P101_AI := 9
P102_AI := 10
P103_AI := 11
P104_AI := 12

Таким образом, индексирование члена в структуре: myStructure[P103_AI].value (то есть индексирование myStructure [11] .value)

Однако возможно ли это индексировать косвенно?

то есть, если delcaring TempString : STRING[30];

изменение TempString во время выполнения для индексации массива.

Вот псевдокада, описывающая то, что я хотел бы сделать:

FOR i:=101 TO 104 DO
   TempString := CONCAT('P',i);
   TempString := CONCAT(TempString,'_AI');
   MyStructure[ indirect(TempString)].value := 'some value';
END_FOR;

Ответы [ 3 ]

1 голос
/ 04 февраля 2020

А как насчет создания перечисления?

{attribute 'qualified_only'}
TYPE E_AnalogInput :
(
    P101_AI := 9,
    P102_AI,
    P103_AI,
    P104_AI
);
END_TYPE

Затем вы можете объявить:

analogInputs : ARRAY[E_AnalogInput.P101_AI..E_AnalogInput.P104_AI] OF INT;

Запуск для l oop:

FOR inputCount:=E_AnalogInput.P101_AI TO E_AnalogInput.P104_AI BY 1 DO
    //Do something
END_FOR

Надежда это помогает

0 голосов
/ 20 февраля 2020

Вот как я это решил.

TYPE infoType: STRUCT
    name: STRING[20];
    END_STRUCT
END_TYPE
TYPE sensorType: STRUCT
    value: INT;
    info:  infoType;
    END_STRUCT
END_TYPE
TYPE IO_Type: STRUCT
    AI: ARRAY[1..100] OF sensorType;
    END_STRUCT
END_TYPE
TYPE E_AnalogInput :
(
    P101_AI := 9,
    P102_AI,
    P103_AI,
    P104_AI
);
END_TYPE
PROGRAM PLC_PRG:
    VAR
        IOs: IO_Type;
    END_VAR

    IOs.AI[P101_AI].info.name := 'P101_AI';

    FOR i:=101 TO 104 DO
        TempString := CONCAT('P',i);
        TempString := CONCAT(TempString,'_AI');
        FOR i:=0 TO SIZE_OF(ADR(IOs.AI)) / SIZE_OF(ADR(IOs.AI[0]))  DO
            IF TempString = IOs.AI[i].info.name THEN
                IOs.AI[i].value := 123; // Some value
                EXIT;
            END_IF;
        END_FOR;
    END_FOR;

END_PROGRAM
0 голосов
/ 06 февраля 2020

Я бы использовал указатели и отображение. Сначала измените структуру на указатель.

TYPE MyType: STRUCT
        input: POINTER TO INT;
        value: INT;
        // other properties
    END_STRUCT
END_TYPE

Затем создайте глобальный массив.

VAR_GLOBAL
    MyStructure: ARRAY[1..100] OR MyType;
END_VAR

Теперь в программе создайте один раз выполняющийся код.

PROGRAM PLC_PRG:
    VAR
        xInit:= FALSE;
    END_VAR

    IF NOT xInit THEN
        xInit := TRUE;
        mMap();
    END_IF
END_PROGRAM

Теперь в методе или действии mMap сделайте это для каждого элемента массива.

MyStructure[1].input:= ADR(AI_Name);
MyStructure[2].input:= ADR(P102_AI);
MyStructure[3].input:= ADR(%ID0.1);

Я использовал 3 разных способа привязки указателя. Порядок не важен, я думаю. Затем в программе вы можете сделать это.

FOR i := 1 TO 100 DO
   MyStructure[i].value := 'MyStructure[i].input^;
END_FOR;
...