Просмотр полной версии : Как сделать карту входов выходов в массиве.
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. Как мне в цикле к ним обратиться? Мне нужен способ сформировать имя переменной динамически. Этого нельзя. Значит использовать массив. Но как к элементу массива привязать выход ПЛК?
там где есть %QX2.3, там же значит должен быть и %QB2, если этот байт именуете, например value, то к третьему разряду можно обращаться как value.3 Надеюсь это не вызывает вопросов, теперь
на одной находится на %QX2.3 у другой на %QX0.1о каком цикле в этом случае может идти речь, если бы были одинаково %QX2.3 %QX0.3 тогда другое дело, ну или выкинуть Вашу идею и создать массив структуры, включающую в себя адрес байта, адрес бита и значение, первые два аргумента константные, а значение меняется в зависимости от ситуации. А дальше все просто, указатель на первый элемент, далее из соответствующего индекса массива смотрим какое смещение в адресе байта структуры, затем кейс из восьми элементов и в зависимости от адреса бита и присваиваем заданное значение
Serhioromano
01.03.2019, 15:36
ну или выкинуть Вашу идею и создать массив структуры, включающую в себя адрес байта, адрес бита и значение...
Ну если посмотрите мой пост, это и есть моя идея. У меня есть структура устройства, я создаю массив, делаю привязку. Допустим у меня есть адрес байта и бита, как я получу его значение? Можно пример кода?
наверное здесь что то должно быть 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х переменных?
Жаль что вы не поняли моего вопросане рассказывайте сказки
А если 63/73й - то как с выходами ? )))
не понял подкола, ну буду умножать i на четыре и вместо просто присвоения буля прогоню через SEL с 0 и 1000, в чем сложность то
а в структуру вносить ещё один описатель, 63/не 63 ?
а зачем там вообще структура о которой я говорил? Просто цикл, просто смещение на четыре байта, т.к. реалы у нас четырехбайтные и просто присвоение что там используется вместо буля
ТС хочет чего там с циклами замутить //см. про ПЛК и модули в п#1
Соотв. Do могут быть физически и логически одинаковые, а форма управления разная
ну не совсем, речь шла конкретно о %QX2.3 (см.пост 3), а в 63-м используетеся %QD0.1.0, об одинаковости выходов речи быть не может
Ну раз на булевскуя нельзя, то можно указатель на байт/слово + № бита
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));
Mikhail_NNT
12.12.2024, 13:58
Здравствуйте, у меня вопрос, похожий с Serhioromano, с которым также не могу разобраться, что не так.
Дано: Сборочная линия автомобилей с 20-ю станциями. На каждой станции стоят световая колонна(Красный, желтый, зеленый, зуммер) и кнопочные посты (Аварийная кнопка, подтверждение).
Задача: Данные элементы выполняют однотипные действия: в зависимости от времени включаются лампы на световой колонне, и в зависимости от ситуации на станции используются кнопки.
Чтобы не писать 20 блоков и не вызывать их 20 раз в главной программе, решил это реализовать через массивы и цикл.
Написал универсальный блок управления световыми колоннами и кнопками. Далее в главной программе объявил массивы ламп световых колонн и кнопок, и вызываю данный блок в цикле 20 раз (20 сборочных станций). В соотнесении входов/выходов модулей привязываю элементы массивов.
Заливаю программу в ПЛК 210 (по ModBus TCP подключены 5 МВ210-202, 5 МУ210-403 и панель СП310Р). При срабатывании условия модули и ПЛК уходят в ошибку, далее перезагрузка и перестают отвечать. Помогает сброс по питанию.
Никак не могу понять, что не так.
80745 80746 80747
Проверяйте значения индексов массивов в циклах.
Если выложите проект - может кто-нибудь даже найдёт конкретную проблему
Mikhail_NNT Идея правильная!
1exan говорит верно. Скорее всего где-то есть выход за границы массивов.
Если искать лень - можно добавить специальную функцию CheckBounds, а в ней сделать вызов исключения, чтобы потом понять, где именно что случилось.
Как это сделать, было описано у меня статье со скриншотами: https://cs-cs.net/codesys-kultura-koda-peremenniye-granicy-massivov#7 (заголовок 7)
PS. CheckBounds тормозит готовый проект. Поэтому потом её оттуда надо удалить. Или исключить из компиляции.
МихаилГл
12.12.2024, 16:08
Скорее всего у ТС где то неправильно с копированием. Я делаю так: 1. Копирую структуру механизма во временную структуру, 2. Временная структура обрабатывается подпрограммой, 3. Копирую временную структуру в структуру механизма, и следующим элементом цикла проделываю это уже со структурой второго механизма. А как сделано у ТС надо смотреть код.
PS Глянул 2 скрин... А где у ТС входы? У меня выше описан другой способ, но суть та же..
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot