На любом ПЛК от Овена есть разница. И это связано не с Овеном а с процем.
Вы проект выложите? Если нет (он секретно/гениальный за которым охотятся все агенты Моссада и т.п.) - так и скажите, чтоб время не тратить.
я сам не могу в нем разобраться..
Васильев Снова за долгое время мне хочется НАОРАТЬ! И я это СДЕЛАЮ!
Вот я тебе ТРИ РАЗА кидал свой пост (одобренный и проверенный Евгением Кисловым, между прочим) про этот приём!
Но нет же ты страдаешь ХРЕНЬЮ и УПЁРСЯ В ТУПОЙ ПУТЬ!
НЕ НАДО! НЕ НАДО! НЕ НАДО ТЕБЕ ИСПОЛЬЗОВАТЬ ЭТИ ДУРАЦКИЕ ПРЯМЫЕ АДРЕСА!
Это пусть к ошибкам и вникуда!!
Даю тебе СКРИНШОТЫ из того поста и ещё раз на него ссылку: https://cs-cs.net/codesys-modbus-kar...trov-struktury
1. С того места, откуда у тебя в конфигурации ПЛК будет привязана эта структура, прям в конфигурации ПЛК объявляешь переменную.
Это будет адресом начала твоей структуры.
В моём случае это MBSlaveData:
Вложение 88553
У тебя это может быть типа
vop01_Start
vop02_Start
2. В глобальных переменных объявляешь указатели на свои структуры.
У меня это так:
SysSlave : POINTER TO MBSlaveStruct;
У тебя будет так:
vop01 : POINTER TO vops;
vop02 : POINTER TO vops;
3. Потом в самой главной программе в самом начале пишешь код, который САМ вычислит адреса и привяжет указатели:
Вложение 88554
У тебя это будет так:
vop01 := ADR(vop01_Start);
vop02 := ADR(vop02_Start);
Адреса вычислятся САМИ по положению тех переменных, которые мы в кофигурации ПЛК указали.
4. Обращаешься чуть сложнее. Через символ крышечки так:
vop01^.power;
vop02^.klapan_value;
Всё. При этом после точки CodeSys так же будет давать тебе список полей, как и с обычной структурой.
PS. У меня [M02] - и на нём всё работает.
Сейчас, например, одна из структур занимает 264 байта аж (132 регистра).
согласен..балбес
Читал вашу статью 3раза (с пивом тоже).
Для чего я делаю сетевые переменные привязанные к адресам? - чтобы точно знать адрес по которому панель может прочитать данные.
Для чего разбиваю область переменных ВОП? - чтобы в панели заводить в график только нужные параметры
(к примеру в графике не нужно параметры ПИД)
Васильев Оо! Спасибо за то, что ты расписал "ЗАЧЕМ" и "ПОЧЕМУ". Это очень важно и нужно!
Вот я тоже туплю тогда :)
Почему ты НЕ можешь просто ВСЮ панель засунуть в структуру?
Прям начиная с адреса 0 - и далее?
Тогда ты и адреса вычислишь все (и прям в проекте напишешь, к примеру), и можешь вложенные структуры вставлять друг в друга.
Я ща покажу, как у меня это расписано для одного из проектов.
Там я прям расписал ВСЕ адреса и номера битов.
Код:(* Структура данных для связи с панелью оператора по Modbus Slave
!!!ПОСЛЕДОВАТЕЛЬНОСТЬ ЭЛЕМЕНТОВ КРАЙНЕ ВАЖНА (она описана в XLS-файле IO)!!! *)
TYPE SysOPData :
STRUCT
BitsAlarms1 : DWORD; (* Регистры 0, 1 = Биты тревог 0-32 *)
BitsAlarms2 : DWORD; (* Регистры 2, 3 = Биты тревог 33-63 *)
BitsStatus1 : DWORD; (* Регистры 4, 5 = Биты статуса 64-95 *)
BitsStatus2 : DWORD; (* Регистры 6, 7 = Биты статуса 96-127 *)
BitsButtons1 : DWORD; (* Регистры 8, 9 = Биты кнопок 128-159 *)
BitsButtons2 : DWORD; (* Регистры 10, 11 = Биты кнопок 160-191 *)
(* СИСТЕМНЫЕ ДАТА И ВРЕМЯ - Чтение (из ПЛК в панель) *)
TimeCurrYear : WORD; (* Регистр 12, Текущий Год *)
TimeCurrMonth : WORD; (* Регистр 13, Текущий Месяц *)
TimeCurrDay : WORD; (* Регистр 14, Текущий День *)
TimeCurrHour : WORD; (* Регистр 15, Текущие Часы *)
TimeCurrMin : WORD; (* Регистр 16, Текущие Минуты *)
TimeCurrSec : WORD; (* Регистр 17, Текущие Секунды *)
(* СИСТЕМНЫЕ СОСТОЯНИЯ - Работа подсистем *)
SysStateDay : WORD; (* Регистр 18, Режим времени: 0 = ?, 1 = Ночь, 2 = День *)
SysStatePLC : WORD; (* Регистр 19, Статус ПЛК на главном экране: 0 = ?, 1 = Work, 2 = Debug, 3 = Alarms, 4 = Пробел *)
SysStatePwMains : WORD; (* Регистр 20, Статус Ввода Сети (0 = Откл, 1 = Нет Фазы, 2 = Вкл) *)
SysStatePwGener : WORD; (* Регистр 21, Статус Ввода Генератора (0 = Откл, 1 = Вкл, 2 = в АВР) *)
SysStatePwUPS : WORD; (* Регистр 22, Статус Инвертора (0 = Откл, 1 = Вкл, 2 = Разряд АКБ) *)
SysStatePwFull : WORD; (* Регистр 23, Статус Питания Отпуск (0 = Откл, 1 = Вкл) *)
SysStateWater : WORD; (* Регистр 24, Статус Воды (0 = Закрыта, 1 = Открыта, 2 = Протечка, 3 = Ожидание выдержки) *)
(* СИСТЕМНЫЕ ДАТА И ВРЕМЯ - Настройка (из панели в ПЛК) *)
TimeSetYear : WORD; (* Регистр 25, Установить Год *)
TimeSetMonth : WORD; (* Регистр 26, Установить Месяц *)
TimeSetDay : WORD; (* Регистр 27, Установить День *)
TimeSetHour : WORD; (* Регистр 28, Установить Часы *)
TimeSetMin : WORD; (* Регистр 29, Установить Минуты *)
(* ИНТЕРВАЛЫ ДЛЯ НОЧНОГО РЕЖИМА по Кварталам - Зима, Весна, Лето, Осень *)
NightModeTimeKv1 : CSSetTimes; (* Регистры 30, 31, Время ЧЧ:ММ Начала Ночного режима, Зима *)
NightModeTimeKv2 : CSSetTimes; (* Регистры 32, 33, Время ЧЧ:ММ Начала Ночного режима, Весна *)
NightModeTimeKv3 : CSSetTimes; (* Регистры 34, 35, Время ЧЧ:ММ Начала Ночного режима, Лето *)
NightModeTimeKv4 : CSSetTimes; (* Регистры 36, 37, Время ЧЧ:ММ Начала Ночного режима, Осень *)
NightModeTimeEnd : CSSetTimes; (* Регистры 38, 39, Время ЧЧ:ММ КОНЦА Ночного режима (Утро) *)
(* Регистры для групп света в сценарии "КИНО" (6 штук): 0 = Не участвует, 1 = Участвует *)
ScenKinoLGroups : ARRAY [1..6] OF WORD; (* Регистры 40, 41, 42, 43, 44, 45 *)
(* НАСТРОЙКИ ПРИВОДОВ ШТОР *)
ShtorGostKuh : SysOPSetShtors; (* Регистры 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, Шторы Гостиная-Кухня *)
ShtorSpaln : SysOPSetShtors; (* Регистры 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, Шторы Спальня *)
ShtorStSyn : SysOPSetShtors; (* Регистры 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, Шторы Комната Старшего Сына *)
ShtorMlSyn : SysOPSetShtors; (* Регистры 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, Шторы Комната Младшего Сына *)
(* НАСТРОЙКИ ВЕНТИЛЯТОРОВ *)
VentV1 : SysOPSetVent; (* Регистры 86, 87, 88, 89, 90, 91, 92, 93, Настройки вентилятора В1 *)
VentV2 : SysOPSetVent; (* Регистры 94, 95, 96, 97, 98, 99, 100, 101, Настройки вентилятора В2 *)
(* НАСТРОЙКИ ТРЕВОГ ПО ВОДЕ *)
WaterDrainDelay : WORD; (* Регистр 102, Выдержка перед сигналом аварии, секунд *)
WaterDrainLock : WORD; (* Регистр 103, Удерживать режим аварии до сброса (Нет/Да) *)
WaterNasosOffByDrain : WORD; (* Регистр 104, Выключать насос скважины при авариях (Нет/Да) *)
WaterNasosOffDKoteln : WORD; (* Регистр 105, Выключать насос скважины при авариях Котельной (Нет/Да) *)
WaterNasosOffD1Etaj : WORD; (* Регистр 106, Разрешить работу датчиков 1 Этажа (Нет/Да) *)
WaterNasosOffD2Etaj : WORD; (* Регистр 107, Разрешить работу датчиков 2 Этажа (Нет/Да) *)
WaterNasosOffByTime : WORD; (* Регистр 108, Разрешить тревоги по времени работы насоса скважины (Нет/Да) *)
WaterNasosOffAmps : WORD; (* Регистр 109, Пороговый ток для работы насоса, Ампер x 100 *)
WaterNasosOffTimeOtp : WORD; (* Регистр 110, Пороговое время работы насоса, минут (когда не живут) *)
WaterSensorOnKoteln : WORD; (* Регистр 111, Разрешить работу датчиков Котельной (Нет/Да) *)
WaterSensorOn1Etaj : WORD; (* Регистр 112, Разрешить работу датчиков 1 Этажа (Нет/Да) *)
WaterSensorOn2Etaj : WORD; (* Регистр 113, Разрешить работу датчиков 2 Этажа (Нет/Да) *)
(* ДАННЫЕ ДЛЯ ЭКРАНОВ СТАТУСА СИСТЕМЫ *)
SysStatePLCTemper : REAL; (* Регистры 114, 115, Статус системы: Температура ПЛК (FLOAT) *)
SysStateNasosAmps : REAL; (* Регистры 116, 117, Статус системы: Ток насоса скважины (FLOAT) *)
SysStateNasosWTime : DWORD; (* Регистры 118, 119, Статус системы: Время непрервыного работы насоса скважины, секунды *)
(* НАСТРОЙКИ РЕЖИМА ОТПУСК (FullPower) *)
OtpuskCtlWater : WORD; (* Регистр 120, Режим Отпуск: Управлять Водой (Нет/Да) *)
OtpuskCtlLight : WORD; (* Регистр 121, Режим Отпуск: Гасить освещение с сохранением (Нет/Да) *)
OtpuskCtlOPS : WORD; (* Регистр 122, Режим Отпуск: Ставить на охрану (Нет/Да) *)
(* НАСТРОЙКИ СВЕТА *)
LtFasadAutoOff : WORD; (* Регистр 123, Свет Фасада: Гасить автоматически по времени (Нет/Да), иначе - утром *)
LtFasadAutoOffTime : CSSetTimes; (* Регистры 124, 125, Свет Фасада: Время Вечернего гашения, Часы/Минуты *)
LtFasadAutoOn : WORD; (* Регистр 126, Свет Фасада: Свет Фасада: Включать автоматически в ночное время (Нет/Да) *)
LtStPandusWorkTime : WORD; (* Регистр 127, Свет Стоянки, Пандуса: Время работы после конца движения ворот, минут *)
LtStPandusWorkNight : WORD; (* Регистр 128, Свет Стоянки, Пандуса: Включать от Ворот только в ночное время (Нет/Да) *)
LtVhGrpOnByMove : WORD; (* Регистр 129, Свет Входной Группы: Управлять по Датчику Движения (Нет/Да) *)
LtVhGrpOnByMoveAtNight : WORD; (* Регистр 130, Свет Входной Группы: Управлять по Датчику Движения только Ночью (Нет/Да) *)
LtVhGrpOnByMovePriority : WORD; (* Регистр 131, Свет Входной Группы: Включать ДДвижения параллельно (приоритет) (Нет/Да) *)
ScenNightOffDelay : WORD; (* Регистр 132, Сценарий "Ночь": Выдержка до отключения света, секунд *)
ScenNightDejDelay : WORD; (* Регистр 133, Сценарий "Ночь": Выдержка работы дежурного света, минут *)
(* НАСТРОЙКИ ПРОВОРОТА КРАНОВ (дополнение) *)
WaterAutoWashOn : WORD; (* Регистр 134, Водоснабжение: Включить автопрокрутку кранов воды (Нет/Да) *)
WaterAutoWashDay : WORD; (* Регистр 135, Водоснабжение: День месяца для запуска прокрутки кранов *)
WaterAutoWashHour : WORD; (* Регистр 136, Водоснабжение: Час для запуска прокрутки кранов *)
(* НАСТРОЙКИ ОБНОВЛЕНИЯ ВРЕМЕНИ ПО NTP (дополнение) *)
TimeGetNTPOn : WORD; (* Регистр 137, Время по NTP: Включен режим обновления (Нет/Да) *)
TimeGetNTPDelay : WORD; (* Регистр 138, Время по NTP: Период обновления, минут *)
TimeGetNTPState : WORD; (* Регистр 139, Время по NTP: Статус обновления (0 = Выкл, 1 = Ждёт, 2 = Обновлено, 3 = Ошибка) *)
(* ДОПОЛНЕНИЯ КАРТЫ РЕГИСТРОВ БЕЗ ГРУПП *)
WaterNasosOffTimeNorm : WORD; (* Регистр 140, Пороговое время работы насоса, минут (когда живут) *)
END_STRUCT
END_TYPE
Код:(**************************************************************************************************)
(* Номера битов для панели оператора - ТРЕВОГИ *)
VAR_GLOBAL CONSTANT
(* BitsAlarms1 = Регистры 0, 1 = Биты тревог 0-32 *)
SysOPAlmPLCTemperMid : BYTE := 0; (* Авария: Перегрев ПЛК (средний) *)
SysOPAlmPLCTemperHigh : BYTE := 1; (* Авария: Перегрев ПЛК (критичный) *)
SysOPAlmPLCBatteryLow : BYTE := 2; (* Авария: Разряд батареи часов ПЛК *)
SysOPAlmPLCDebug : BYTE := 3; (* Авария: Режим отладки ПЛК (IO) *)
SysOPAlmDevIntW2Err : BYTE := 4; (* Авария: Сбой связи с модулем W2 *)
SysOPAlmDevIntW3Err : BYTE := 5; (* Авария: Сбой связи с модулем W3 *)
SysOPAlmDevIntW4Err : BYTE := 6; (* Авария: Сбой связи с модулем W4 *)
SysOPAlmDevIntW5Err : BYTE := 7; (* Авария: Сбой связи с модулем W5 *)
SysOPAlmDevIntW6Err : BYTE := 8; (* Авария: Сбой связи с модулем W6 *)
SysOPAlmDevExtD1Err : BYTE := 9; (* Авария: Сбой связи Modbus Ext. 1 *)
SysOPAlmDevExtD2Err : BYTE := 10; (* Авария: Сбой связи Modbus Ext. 2 *)
SysOPAlmDevExtD3Err : BYTE := 11; (* Авария: Сбой связи Modbus Ext. 3 *)
SysOPAlmDevExtD4Err : BYTE := 12; (* Авария: Сбой связи Modbus Ext. 4 *)
SysOPAlmDevExtD5Err : BYTE := 13; (* Авария: Сбой связи Modbus Ext. 5 *)
SysOPAlmDevExtD6Err : BYTE := 14; (* Авария: Сбой связи Modbus Ext. 6 *)
SysOPAlmDevExtD7Err : BYTE := 15; (* Авария: Сбой связи Modbus Ext. 7 *)
SysOPAlmDevExtD8Err : BYTE := 16; (* Авария: Сбой связи Modbus Ext. 8 *)
SysOPAlmDevExtD9Err : BYTE := 17; (* Авария: Сбой связи Modbus Ext. 9 *)
SysOPAlmDevExtD10Err : BYTE := 18; (* Авария: Сбой связи Modbus Ext.10 *)
SysOPAlmOVRProtect : BYTE := 19; (* Авария: Сбой УЗИП (Автомат) *)
SysOPAlmOVRCartridge : BYTE := 20; (* Авария: Сбой УЗИП (Картриджи) *)
SysOPAlmPwrMainsL1 : BYTE := 21; (* Авария: Сбой ввод Сети (фаза L1) *)
SysOPAlmPwrMainsL2 : BYTE := 22; (* Авария: Сбой ввод Сети (фаза L2) *)
SysOPAlmPwrMainsL3 : BYTE := 23; (* Авария: Сбой ввод Сети (фаза L3) *)
SysOPAlmPwrGeneratorOn : BYTE := 24; (* Авария: Работа от Генератора *)
SysOPAlmPwrUPSFail : BYTE := 25; (* Авария: Сбой ввода Инвертора *)
SysOPAlmPwrUPSLow : BYTE := 26; (* Авария: Разряд АКБ Инвертора *)
SysOPAlmILCCommon : BYTE := 27; (* Авария: Авария важных нагрузок! - Общий синал аварии *)
SysOPAlmILCShKotelnL1 : BYTE := 28; (* Авария: Сбой ILC Котельная (L1) *)
SysOPAlmILCShKotelnL2 : BYTE := 29; (* Авария: Сбой ILC Котельная (L2) *)
SysOPAlmILCShKotelnL3 : BYTE := 30; (* Авария: Сбой ILC Котельная (L3) *)
SysOPAlmILCShSKS : BYTE := 31; (* Авария: Сбой ILC Щит СКС *)
(* BitsAlarms2 = Регистры 2, 3 = Биты тревог 33-63 *)
SysOPAlmILCWaterValves : BYTE := 0; (* Сбой ILC Краны Воды *)
SysOPAlmILCNasosSkvaj : BYTE := 1; (* Сбой ILC Насос Скважины *)
SysOPAlmILCNasosDrenaj : BYTE := 2; (* Сбой ILC Насос Дренажа *)
SysOPAlmILCHolodilnik : BYTE := 3; (* Сбой ILC Холодильник *)
SysOPAlmILCVorotaGaraj : BYTE := 4; (* Сбой ILC Ворота Гараж *)
SysOPAlmILCVorotaMain : BYTE := 5; (* Сбой ILC Ворота Въездные *)
SysOPAlmILCRegDEVI : BYTE := 6; (* Сбой ILC Авария DEVIreg *)
SysOPAlmDrainKoteln : BYTE := 7; (* Протечка Котельная! *)
SysOPAlmDrain1Etaj : BYTE := 8; (* Протечка 1 Этаж! *)
SysOPAlmDrain2Etaj : BYTE := 9; (* Протечка 2 Этаж! *)
SysOPAlmWaterWash : BYTE := 10; (* Прокрутка кранов воды *)
SysOPAlmOPSSetArm : BYTE := 11; (* ОПС: Постановка на охр. *)
SysOPAlmOPSAlarm : BYTE := 12; (* ОПС: Сработка (Тревога)! *)
SysOPAlmRolletsPort : BYTE := 13; (* Шторы: Сбой открытия порта *)
(* SysOPAlmXXX : BYTE := 1; (* Авария: XXX *) *)
END_VAR
(**************************************************************************************************)
(* Номера битов для панели оператора - ФЛАГИ СТАТУСОВ *)
VAR_GLOBAL CONSTANT
(* BitsStatus1 = Регистры 4, 5 = Биты статуса 64-95 *)
SysOPStateUZIPAutomat : BYTE := 0; (* Статус работы: УЗИП, Автомат защиты *)
SysOPStateUZIPCatridge : BYTE := 1; (* Статус работы: УЗИП, Картриджи *)
SysOPStateWaterPower : BYTE := 2; (* Статус работы: Краны Воды (Питание) *)
SysOPStateWaterOpen : BYTE := 3; (* Статус работы: Краны Воды (Вода открыта) *)
SysOPStateNasosPower : BYTE := 4; (* Статус работы: Насос Скважины (Питание) *)
SysOPStateNasosWork : BYTE := 5; (* Статус работы: Насос Скважины (Порог тока работы включен) *)
SysOPStateVorotaMain : BYTE := 6; (* Статус работы: Движение Ворот, Основные *)
SysOPStateVorotaGaraj : BYTE := 7; (* Статус работы: Движение Ворот, Гаража *)
SysOPStateStreetDark : BYTE := 8; (* Статус работы: Фотореле (Темно) *)
SysOPStateMoveVhodG : BYTE := 9; (* Статус работы: Датчик Движения Входная Группа *)
SysOPStateMoveHall : BYTE := 10; (* Статус работы: Датчик Движения Холлы *)
SysOPStateDrainKoteln : BYTE := 11; (* Статус работы: Датчики Протечки Котельная *)
SysOPStateDrain1Etaj : BYTE := 12; (* Статус работы: Датчики Протечки 1 Этаж *)
SysOPStateDrain2Etaj : BYTE := 13; (* Статус работы: Датчики Протечки 2 Этаж *)
SysOPStatexxx : BYTE := 0; (* *** *)
(* BitsStatus2 = Регистры 6, 7 = Биты статуса 96-127 *)
SysOPStateDefaultsLoad : BYTE := 31; (* Настройки из DEFAULT загружены успешно = TRUE *)
END_VAR
(**************************************************************************************************)
(* Номера битов для панели оператора - ФЛАГИ КНОПОК НА ПАНЕЛИ *)
VAR_GLOBAL CONSTANT
(* BitsButtons1 = Регистры 8, 9 = Биты кнопок 128-159 *)
SysOPBtnDimGostTrackPreset1OFF : BYTE := 0; (* Диммер LT-19 Гостиная Трек, Preset 1 (OFF) *)
SysOPBtnDimGostTrackPreset2 : BYTE := 1; (* Диммер LT-19 Гостиная Трек, Preset 2 *)
SysOPBtnDimGostTrackPreset3 : BYTE := 2; (* Диммер LT-19 Гостиная Трек, Preset 3 *)
SysOPBtnDimGostBraPreset1OFF : BYTE := 3; (* Диммер LT-20 Гостиная Бра, Preset 1 (OFF) *)
SysOPBtnDimGostBraPreset2 : BYTE := 4; (* Диммер LT-20 Гостиная Бра, Preset 2 *)
SysOPBtnDimGostBraPreset3 : BYTE := 5; (* Диммер LT-20 Гостиная Бра, Preset 3 *)
SysOPBtnDimKuhnaTrackPreset1OFF : BYTE := 6; (* Диммер LT-22 Кухня Трек, Preset 1 (OFF) *)
SysOPBtnDimKuhnaTrackPreset2 : BYTE := 7; (* Диммер LT-22 Кухня Трек, Preset 2 *)
SysOPBtnDimKuhnaTrackPreset3 : BYTE := 8; (* Диммер LT-22 Кухня Трек, Preset 3 *)
SysOPBtnDimSpalnaVerhPreset1OFF : BYTE := 9; (* Диммер LT-25 Спальня Верх, Preset 1 (OFF) *)
SysOPBtnDimSpalnaVerhPreset2 : BYTE := 10; (* Диммер LT-25 Спальня Верх, Preset 2 *)
SysOPBtnDimSpalnaVerhPreset3 : BYTE := 11; (* Диммер LT-25 Спальня Верх, Preset 3 *)
SysOPBtnDimKabinetPreset1OFF : BYTE := 12; (* Диммер LT-33 Кабинет Верх, Preset 1 (OFF) *)
SysOPBtnDimKabinetPreset2 : BYTE := 13; (* Диммер LT-33 Кабинет Верх, Preset 2 *)
SysOPBtnDimKabinetPreset3 : BYTE := 14; (* Диммер LT-33 Кабинет Верх, Preset 3 *)
SysOPBtnShtorGostKuhOpen : BYTE := 15; (* Шторы Гостиная-Кухня: Команда "Открыть" *)
SysOPBtnShtorGostKuhClose : BYTE := 16; (* Шторы Гостиная-Кухня: Команда "Закрыть" *)
SysOPBtnShtorGostKuhStop : BYTE := 17; (* Шторы Гостиная-Кухня: Команда "Стоп" *)
SysOPBtnSpalnOpen : BYTE := 18; (* Шторы Спальня: Команда "Открыть" *)
SysOPBtnSpalnClose : BYTE := 19; (* Шторы Спальня: Команда "Закрыть" *)
SysOPBtnSpalnStop : BYTE := 20; (* Шторы Спальня: Команда "Стоп" *)
SysOPBtnStSynOpen : BYTE := 21; (* Шторы Комната Старшего Сына: Команда "Открыть" *)
SysOPBtnStSynClose : BYTE := 22; (* Шторы Комната Старшего Сына: Команда "Закрыть" *)
SysOPBtnStSynStop : BYTE := 23; (* Шторы Комната Старшего Сына: Команда "Стоп" *)
SysOPBtnMlSynOpen : BYTE := 24; (* Шторы Комната Младшего Сына: Команда "Открыть" *)
SysOPBtnMlSynClose : BYTE := 25; (* Шторы Комната Младшего Сына: Команда "Закрыть" *)
SysOPBtnMlSynStop : BYTE := 26; (* Шторы Комната Младшего Сына: Команда "Стоп" *)
(* BitsButtons2 = Регистры 10, 11 = Биты кнопок 160-191 *)
SysOPBtnxxx : BYTE := 0; (* *** *)
END_VAR
(**************************************************************************************************)
(* Номера индексов массива - ГРУППЫ СВЕТА В СЦЕНАРИИ КИНО *)
VAR_GLOBAL CONSTANT
SceneKinoGroupGostVerh : WORD := 1; (* Сценарий "Кино", группа LT-18 Гостиная Верх (Откл/Вкл) *)
SceneKinoGroupGostTrack : WORD := 2; (* Сценарий "Кино", группа LT-19 Гостиная Трек (Откл/Вкл) *)
SceneKinoGroupGostBra : WORD := 3; (* Сценарий "Кино", группа LT-20 Гостиная Бра (Откл/Вкл) *)
SceneKinoGroupKuhnaVerh : WORD := 4; (* Сценарий "Кино", группа LT-21 Кухня Верх (Откл/Вкл) *)
SceneKinoGroupKuhnaTrack : WORD := 5; (* Сценарий "Кино", группа LT-22 Кухня Трек (Откл/Вкл) *)
SceneKinoGroupKuhnaFartuk : WORD := 6; (* Сценарий "Кино", группа LT-23 Кухня Фартук (Откл/Вкл) *)
END_VAR
я сейчас обязательно посмотрю...
вот только у меня переменных очень многооо и их почти все надо отображать в панели.
Не понял, в чём преимущество объявления сначала указателей на структуры, а потом их привязки на адреса переменных, объявленных в конфигурации?
Понятно, что эту пару прямых адресов придётся посмотреть в конфигурации и что они могут измениться, но и разыменовывать каждый раз указатель при обращении к сетевой переменной - по мне так не сильно удобно.
Чем хуже сразу написать
vop01 AT %QDX.X.X : vops;
vop02 AT %QDX.X.X : vops;
?
панель weintek.
У меня так и было.
Только по адресам были расписаны переменные для каждого воп, обрабатывал в цикле передавая указатель на воп, выполнял требуемые действия.
Потом создал структуры и тоже передавал как адрес - как вы и написали. (но появилась ошибка выше написано).
Теперь создал массив структур и обработка стала удобнее. Но нужно чтобы память была не фрагментирована.