PDA

Просмотр полной версии : Как сделать карту входов выходов в массиве.



Serhioromano
28.02.2019, 17:41
Допустим у меня куча входов и выходов как на плк так и на модуля. Они обслуживают установки однотипные. Каждая установка занимает 2 входа и 2 выхода. Я хочу создать массив этих установок и обрабатывать их в массиве. Первое я создаю структуру.


TYPE SR_ZONE :
STRUCT
xStart: POINTER TO BOOL;
xReset: POINTER TO BOOL;
xTempr: POINTER TO WORD;
xPV: POINTER TO WORD;
END_STRUCT
END_TYPE

Теперь я объявляю глобальную переменную


VAR_GLOBAL
glbZones: ARRAY[1..10] OF SR_ZONE;
END_VAR

Уже в коде я могу просто сделать код в цикле.


VAR
i: INT;
END_VAR

FOR i := 1 TO 10 DO
IF (glbZones[i].xTempr^ < glbZones[i].xPV^) THEN
glbZones[i].Start := TRUE;
END_IF;
END_FOR

Все написано от руки, это не реальный код, а что бы продемонстрировать идею. Так вот что бы это работало, в начале программы на первом запуске нужно сделать карту или привязать значения к входам и выходам. Это получается хорошо с не булевыми переменными.


glbZones[1].xTempr:= ADR(wTemperZone1);
glbZones[1].xPV:= ADR(wTemperZone1);
glbZones[2].xTempr:= ADR(wTemperZone1);
glbZones[2].xPV:= ADR(wTemperZone1);

Но как назначить переменную типа BOOL что бы потом можно было сделать glbZones[i].Start := TRUE; и выходу назначалось значение?

Serhioromano
01.03.2019, 07:23
Ну как это сделать? У меня на модулях где WORD и там побитно а где каждый вход выход это отдельная переменная. Можно пример кода? Я не совсем пойму. Моя идея в том что после привязки я работаю унифицированно с одним массивом одинаково обращаясь к переменным. А если обращаться на прямую они же разные, не получиться это сделать в цикле.

Serhioromano
01.03.2019, 10:48
а записи вроде xStart: POINTER TO BOOL; больше ни кому не показывайте

Я не идиот, понятное дело что это не работает. Это просто я отобразил что бы можно было понять мою идею.

И все же ваше решение не совсем мне понятно. Допустим у меня 2 установки. Включение нагрева на каждой, на одной находится на %QX2.3 у другой на %QX0.1. Как мне в цикле к ним обратиться? Мне нужен способ сформировать имя переменной динамически. Этого нельзя. Значит использовать массив. Но как к элементу массива привязать выход ПЛК?

capzap
01.03.2019, 11:55
там где есть %QX2.3, там же значит должен быть и %QB2, если этот байт именуете, например value, то к третьему разряду можно обращаться как value.3 Надеюсь это не вызывает вопросов, теперь
на одной находится на %QX2.3 у другой на %QX0.1о каком цикле в этом случае может идти речь, если бы были одинаково %QX2.3 %QX0.3 тогда другое дело, ну или выкинуть Вашу идею и создать массив структуры, включающую в себя адрес байта, адрес бита и значение, первые два аргумента константные, а значение меняется в зависимости от ситуации. А дальше все просто, указатель на первый элемент, далее из соответствующего индекса массива смотрим какое смещение в адресе байта структуры, затем кейс из восьми элементов и в зависимости от адреса бита и присваиваем заданное значение

Serhioromano
01.03.2019, 15:36
ну или выкинуть Вашу идею и создать массив структуры, включающую в себя адрес байта, адрес бита и значение...

Ну если посмотрите мой пост, это и есть моя идея. У меня есть структура устройства, я создаю массив, делаю привязку. Допустим у меня есть адрес байта и бита, как я получу его значение? Можно пример кода?

capzap
01.03.2019, 15:43
наверное здесь что то должно быть http://www.owen.ru/forum/showthread.php?t=15455&p=142016&viewfull=1#post142016

Serhioromano
03.03.2019, 07:32
наверное здесь что то должно быть http://www.owen.ru/forum/showthread.php?t=15455&p=142016&viewfull=1#post142016

Жаль что вы не поняли моего вопроса, потому что я чувствую что как раз вы бы могли помочь. Но я не знаю как объяснить. Я знаю что можно через точку получить доступ биту. Вопрос как сделать динамическое имя переменной. Для примера РНР


$MyVar = 10;
$var = "MyVar";
echo ${$var};

Тоже самое тут. Например у меня есть переменные Zone1, Zone2 и в цикле я хочу использовать i для составления имени


for (i = 0; i < 2; i++) {
echo ${"Zone".$i}
}

Подобная техника в ST не возможна. По этому нужно использовать массив и тогда i будет просто иметь доступ к массиву. Если это не биты то я могу элементы массива заранее привязать к ячейкам памяти через указатели, и работать одинаково с массивом, но разные переменные разных входов выходов будут использоваться. Но когда речь заходит о битах входов и выходов не понятно как это реализовать. Через указатель ADR не получается. Ну допустим я знаю что в этом элементе массива мой бит хранится в AdrOfBit := '%QB0' в бите NumOfBit := 3. Как мне получить значение бита из этих 2х переменных?

capzap
03.03.2019, 09:50
Жаль что вы не поняли моего вопросане рассказывайте сказки

capzap
04.03.2019, 07:40
А если 63/73й - то как с выходами ? )))

не понял подкола, ну буду умножать i на четыре и вместо просто присвоения буля прогоню через SEL с 0 и 1000, в чем сложность то

capzap
04.03.2019, 08:44
а в структуру вносить ещё один описатель, 63/не 63 ?

а зачем там вообще структура о которой я говорил? Просто цикл, просто смещение на четыре байта, т.к. реалы у нас четырехбайтные и просто присвоение что там используется вместо буля

capzap
04.03.2019, 09:02
ТС хочет чего там с циклами замутить //см. про ПЛК и модули в п#1
Соотв. Do могут быть физически и логически одинаковые, а форма управления разная

ну не совсем, речь шла конкретно о %QX2.3 (см.пост 3), а в 63-м используетеся %QD0.1.0, об одинаковости выходов речи быть не может

pt200
12.03.2019, 12:21
Ну раз на булевскуя нельзя, то можно указатель на байт/слово + № бита


TYPE SR_ZONE :
STRUCT
xStart_WORD: POINTER TO WORD;
xStart_Nbit: WORD;
...
END_STRUCT
END_TYPE

glbZones[1].xStart_WORD := ADR( INPUT_WORD1);
glbZones[1].xStart_Nbit := 5;


#Set bit
glbZones[1].xStart_WORD^ := glbZones[1].xStart_WORD^ OR SHL( 1, glbZones[1].xStart_Nbit);

#Clear bit
glbZones[1].xStart_WORD^ := glbZones[1].xStart_WORD^ AND ( NOT SHL( 1, glbZones[1].xStart_Nbit));