Как по мне, то код должен быть простым и понятным, даже для новичков. Как вариант, уже предлагал считывать все параметры МВ 8А не байтами, а массивом WORD, что для многих будет проще, так как почти все параметры и читаются в этом виде и не собирать их из байтов. Как известно все регистры занимают 96 байт, разбиваем их пополам, для удобства (не надо высчитывать номера всех регистров, а только половины). В конфигурацию добавляем два String и присваиваем им имена Str14 с 0 адреса, длиной 48 байт и Str58 с 24 адреса и тоже 48 байт.
Стринги.jpg
А что бы уйти от ручной привязки, по команде AT %QB..., можно объявить указатель на массив WORD по 24 регистра (48 байт) и сделать это в глобальных, чтобы был доступ из любого ФБ. Ну и конечно, тут же объявим нужные нам переменные. Целочисленные без смещения точки, объявляем как INT, чтобы не потерять знак.
Код:
VAR_GLOBAL
w_1 : POINTER TO ARRAY [0..23] OF WORD; (* Указатели на массив WORD *)
w_2 : POINTER TO ARRAY [0..23] OF WORD;
w1,w2,w3,w4,w5,w6,w7,w8 : INT ; (* Целочисленное значение без смещения INT *)
d1,d2,d3,d4,d5,d6,d7,d8 : WORD; (* Смещение точки WORD *)
r1,r2,r3,r4,r5,r6,r7,r8 : REAL; (*Значения REAL *)
r_1 : REAL;
END_VAR
Далее создаём ФБ, например "Opros_MVA", в котором будет только присвоение начальных адресов массивов, ну и если понадобиться присвоение нужных нам переменных.
Код:
FUNCTION_BLOCK Opros_MVA
VAR
END_VAR
____________________________________________________________________________________________________________
w_1:=ADR(Str14); (*Начальный адрес в массиве WORD *)
w_2:=ADR(Str58);
Осталось только объявить в PLC_PRG и в его теле, наш функциональный блок (ФБ). Добавил ещё в примечании, все нужные нам регистры МВА8, для наглядности, пример вызова некоторых переменных из массивов и расчёт REAL из целочисленного значения.
Код:
PROGRAM PLC_PRG
VAR
(* Модули МВА_8А нужны регистры - 0,6,12,18,24,30,36,42 - положение десятичной точки, 1,7,13,19,25,31,37,43 - измеренное целое значение без смещения,
2,8,14,20,26,32,38,44 - статус канала, 3,9,15,21,27,33,39,45 - циклическое время, 4-5, 10-11 , 16-17, 22-23, 28-29, 34-35, 40-41, 46-47 - значение REAL *)
Opros_MVA:Opros_MVA;
END_VAR
_____________________________________________
Opros_MVA();
(* Смещение точки WORD *)
d1:=w_1^[0];
(* Целочисленное значение без смещения INT *)
w1:=w_1^[1];
(* Расчёт REAL из целочисленного значения *)
r_1:=w1/10.0;
(* Склейка 2 _ WORD для получения REAL *)
TWO_WORD_TO_REAL(wIn1:=w_1^[5] , wIn2:=w_1^[4] , rOut=>r1 );
Запускаем программу и видим такую простыню из значений в глобальных, далее каждый выберет, то что ему нужно.
Глобальные.jpg
Ниже выложил пример проекта. Если кому то будет мало одного знака после запятой, добавил ещё ФБ для склейки REAL из двух WORD и пример его использования. Кстати таким же образом можно считать и массивы из REAL, правда WORD будут перепутаны и остальные данные потеряем. Проект написан для ПЛК 154УМ, при желании можно поменять на любой ПЛК, достаточно добавить в конфиг. UMD с вашим адресом МВА и два String.
Весь код без объявления переменных и примера вызова занял 4 строки!!! Это конечно, не такой красивый код, как у
Валенка, но простой и понятный.