PDA

Просмотр полной версии : PLC110 modbus.lib MV110-8AC



GTS
16.06.2016, 11:45
Добрый день уважаемые эксперты! Осваиваю библиотеку modbus.lib. Задача подключить к PLC110 8 шт. MV110-8AC. Пытаюсь подключить пока один. Делал проект согласно примера но на MV110-8A. Просмотрел несколько примеров (немного отличающихся по структуре), несколько раз переделывал, искал ошибки - все равно не получается. Если кому не сложно наставить на путь истинный, буду премного благодарен.

P.S. Проект реальный не ради интереса, оборудование имеется, проект не коммерческий, исключительно для своего предприятия.

energvk
16.06.2016, 16:55
А что конкретно не получается то? У Вас в проекте меня смущают настройки порта (всё по нулям, кроме скорости). И пересобираете байты по-моему неправильно (но не утверждаю, мельком глянул), вроде там регистры флоат идут подряд начиная с 0х0120

Евгений Дударев
16.06.2016, 17:26
Если я не ошибаюсь, то сегодня я уже ответил GTS на почту. Дело в том, что Вы перепутали количество регистров и байтов. Вам нужно читать не 112 регистров, в двое меньше.
Попробуйте опросить для начала word-значения, потом переходите к Float

energvk
16.06.2016, 18:30
Если я не ошибаюсь, то сегодня я уже ответил GTS на почту. Дело в том, что Вы перепутали количество регистров и байтов. Вам нужно читать не 112 регистров, в двое меньше.
Попробуйте опросить для начала word-значения, потом переходите к Float

Кстати да, тоже обратил внимание на 112 регистров, забыл указать

GTS
16.06.2016, 18:49
Спасибо за ответ, завтра попробую. С регистрами маху дал. Да Евгений это я вам на почту писал, не знал что вы эту ветку курируете, а то бы не стал отвлекать. По поводу регистров, считываю все потому что в примере так было сделано. Решил сделать ближе к оригиналу. По поводу считывать один регистр, пробовал, причём все по очереди - получал ерунду. Вообще мне нужны значения в real и ошибки. Float в 8АС отличается от 8А, в первом 3 регистра, во втором 2. Евгений Вам лучше сюда писать или также на почту?

GTS
17.06.2016, 08:02
Валенок, огромное спасибо, буду разбираться.

GTS
17.06.2016, 10:47
Валенок, у Вас в проекте есть несколько POU, которые я нашел когда производил компиляцию и выскочила ошибка. Простите за глупый вопрос, как и где вы их прописали, не могу найти.

capzap
17.06.2016, 11:21
на скрине же нет ошибки, а если Вы про то где лежит такой тип данных, то ищите вкладку с пользовательскими типами данных

GTS
17.06.2016, 11:52
Нет ошибки потому что исправил. Хотел просто узнать где это находится. В проекте Валенка все что до буфера понимаю, а как он преобразует из буфера уже нет, MV8AC(FB) вообще не пойму.

capzap
17.06.2016, 11:53
Валенок, он такой :) , загадочный
попробуйте его проект экспортировать в файл, выбрав все пункты, в нем будет легче найти не достающие звенья

GTS
17.06.2016, 11:57
Вопрос не в копировании. а понятии структуры. Я думаю для начала попроще преобразовывать данные из буфера, как в примере, но не получается блин.

capzap
17.06.2016, 12:12
я присоединяюсь к Валенку о месте роста рук, очень неудобно структуру создавать, но Валенок же написал, я так понимаю ей уже пользоваться можно, а не понимать
И если кому то что то не понятно, то начинать надо с http://www.owen.ru/uploads/re_mv110-8ac_2113.pdf страницы 57

GTS
17.06.2016, 12:42
Простите о месте роста рук не понял. К сожалению не работает. Тот мануал который Вы указали открыт постоянно. Чем мне поможет страница 57?:
Г.3.4 Считывание версии программы прибора
Посылка: $AAF[CHK](cr),
где АА – адрес модуля, от 00 до FF,
[CHK] – контрольная сумма,
(cr) – символ перевода строки (0х0D).
Ответ: !АА(версия(7 символов))[CHK](cr).
Пример – !ААVx.yy[CHK](cr).
При запросе данных с несуществующего канала выдается ответ ?AA[CHK](cr).
При синтаксической ошибке или ошибке в контрольной сумме не выдается никакого ответа.

GTS
17.06.2016, 13:16
Прошу прощения у нас мануалы разных версий. с указанной Вами таблицей знаком. Вопрос как преобразовать из буфера данные в real и word?
ptr_byte:=ADR(srd1);
ptr_byte^:=buffer[7];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[6];

ptr_byte:=ADR(real1);
ptr_byte^:=buffer[13];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[12];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[11];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[10];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[9];
ptr_byte:=ptr_byte+1;
ptr_byte^:=buffer[8];
Так верно?

capzap
17.06.2016, 13:59
как верно можно сказать только имея прибор на руках, обычно байты требуется менять,но может и словами можно ограничится.

Валенок
17.06.2016, 13:59
.. К сожалению не работает..
Да ладно. Значит чего-то вокруг не так напилили. У меня несколько лет именно так* работает.
(*в смысле обработки данных, а не обмена)

GTS
17.06.2016, 14:10
В Индию больше не пойду. Напилил вот что.

Валенок
17.06.2016, 14:47
Глянул на сам обмен. Взяли за основу очень корявый пример.
В конфигураторе для 8АС, rs.dl = ?

GTS
17.06.2016, 14:56
Ну пример какой был. Пример в 12 посту.
"В конфигураторе для 8АС, rs.dl = ?" - это о чем простите не понял.

Валенок
17.06.2016, 15:17
Пример коряв.
rs.dl - один из параметров настройки в конфигураторе модуля

GTS
17.06.2016, 15:25
Было 45. поставил 0.

Валенок
17.06.2016, 17:15
0 - отл. зачем нужно 45, когда речь про модбас - все равно никто внятно не объяснит.

Почему пример коряв ? Зачем-то 2 автомата + куча внешних if'ов.
Modbus.lib давно не юзал (обхожусь одним syslibcom'ом), но насколько помню поведение enable нужно толчковое - передним фронтом запустили блок обмена - и дальше скинули enable.

GTS
17.06.2016, 21:06
Спасибо, в понедельник попробую. Что за автомат, простите за глупый вопрос?

GTS
20.06.2016, 09:04
Добрый день уважаемые господа! Толи лыжи не едут, толи я такой невезучий. Скинул контроллер, очистил все в проекте, загрузил, опять показывает ерунду. 8 канал.

GTS
20.06.2016, 09:35
Подключил один канал через конфигуратор, Работает.

GTS
20.06.2016, 09:45
Уважаемый Валенок можно получить коментарии построчно в ФБ MV8AC кратко.

GTS
20.06.2016, 18:18
Кто нибудь может подсказать как из буфера "вытащить байты, перевернуть"- что бы получить real? В 8АС 3 регистра под Float как быть в этом случае?

capzap
20.06.2016, 18:40
Кто нибудь может подсказать как из буфера "вытащить байты, перевернуть"- что бы получить real? В 8АС 3 регистра под Float как быть в этом случае?

так Вы внимательно прочтите, там в трех регистрах флоат(IEEE754)два регистра и плюсом одно слово метки времени

GTS
20.06.2016, 21:56
Как из буфера получить real? Переместить последний байт на первый? Пример который мне предоставили Вам не понравился, выше я написал что ФБ Валенка я не понял. Есть простой понятный пример?

Валенок
21.06.2016, 18:03
Выложи то что грузишь (1:1), настройки 8АС
На линии есть еще кто-нить кроме 8АС и ПЛК ?

Валенок
21.06.2016, 18:05
Уважаемый Валенок можно получить коментарии построчно в ФБ MV8AC кратко.
Там же они есть 8( ?

GTS
22.06.2016, 08:26
Проект во вложении. Настройки 8АС стандартные 115200 8n1 adress = 21, задерка 0. На этой линии ничего больше нет.

GTS
22.06.2016, 08:37
Подключил один канал через конфигуратор, Работает.

Через конфигуратор работает же!

Валенок
22.06.2016, 09:35
Мне положить на конфигуратор
За основу вы где-то или качнули реальный мусор или что-то пропустили. Вот и разбирайтесь как это работает, например :
1.Из-за строки 55 можете выкинуть строки 21..22, 46,49, 54..57 как рукоблудие.
2.Из-за строки 23 можете выкинуть enable, и передать в блок_обмена.enable вечный true (именно так работает этот кусок мусора, выкинуть строки 23,47 а после прочитать пост #23
3.Ошибок обработки данных у меня - нет. Разбирайтесь с окружением (выше)

GTS
22.06.2016, 10:00
Я извиняю Валенок, но пример на основе которого я сделал, Ваш. Откуда мусор! Это конечно верх наглости с моей стороны, но я допилил Ваш проект, там где Вы указали в коментах! Сейчас буду разбираться, но может быть дело в регистрах всетаки?

Валенок
22.06.2016, 14:52
Ну говорю же - пропустили.

Забудьте эти мутные слова - регистр, буфер. Есть структуры - исходные и конечные.
Исходные - это и есть таблица регистров. Конечные - это то, с чем можно нормально работать в конкретной среде.
Иногда (редко) они совпадают. Для 8AC - нет. Блок MV8AC - это приведение исходной структуры к конечной.
Исходная здесь - это непрерывно расположенная в памяти область {SRD, Read - см.карту в РЭ}.

Но ! Это же модбас (как протокол), у него свой сетевой порядок байт. А modbus.lib (как биб-ка) работает нормально, но не допилена до нормального использования (я ее не юзаю).
Почему не допилена ? Потому что сетевой порядок байт протокола модбас относится к порядку байт приборов овен как 2143/1234, а процедура "тудой/сюдой" не впендюрена в саму б-ку.

В данном случае по получению данных от прибора их еще нужно привести к исходному виду, например :
var
pw : pointer to array[1..32] of word;
......
pw := adr(MV8AC.SRD);
for i := 1 to 32 do //получение исходной структуры из сетевого набора байт
pw^[i] := rol(pw^[i],8);
end_if
MV8AC(); //а вот теперь из исходной {SRD,Read} => конечную {Ai}

И я бы принципиально не стал делать в одном проходе из сетевого набора байт конечную структуру

Почему руки афтора таблицы растут не из плеч ? Потому-что в подавляющем большинстве случаев модули опрашиваются контроллерами Овен (хотя модули и не привязаны к овену) а таблицы рег-ов желательно привязывать к формату. C учетом выравнивания в 8AC/2AC это невозможно.
Я уж молчу про общее несоответствие ВСЕХ овен-модулей с данными размером в 4 байта порядку данных любого овен-плк.Порядок данных не специфицирован в протоколе ? Дык замечательно - сопоставили б сразу данные в связке плк/модули. Но поезд ушел.

GTS
23.06.2016, 09:15
Спасибо, буду пробовать разобраться, хотя не все понятно.

GTS
23.06.2016, 14:35
Добрый день уважаемы господа! Опрос модуля 8АС по real и srd получился (причем по всем 8 входам). Если кому то интересно выложу проект. Теперь задача стоит опрашивать 6 модулей 8АС. Но выяснилась небольшая особенность: если физически отключить модуль от ПЛК, то последние значения real и srd сохраняются, ошибка err в modbus.lib =0, а complete (признак завершения операции) постоянно переключается False на True, как будто модуль продолжает опрашиваться.

energvk
24.06.2016, 09:57
Вы уверены, что ошибка =0? Я точно помню видел при физическом отключении 255. Может просто не успеваете глазами увидеть? Попробуйте записывать в какой-нибудь массив все значения отличные от нуля для проверки.

P.S. Каюсь, вспомнил, что ошибку я видел в библиотеке к CDS 3.5, но всё равно, не может же быть, что висит 0 при отключении

GTS
24.06.2016, 10:07
Добрый день. Нет 0 не висит, постоянно переключается с 0 на 255. Но complete (признак завершения операции) постоянно переключается False на True, как будто модуль продолжает опрашиваться. И значения real сохраняются последние и не сбрасываются.

energvk
24.06.2016, 11:41
При наличии ошибки 255 вы их просто принудительно обнуляйте или присваивайте какие вам нужно значения

GTS
24.06.2016, 13:22
Это я понял, но почему 255 не постоянно, а переключается на 0 переодически.

energvk
24.06.2016, 14:43
Не могу сказать, это лучше у разработчиков библиотеки уточнить

GTS
28.06.2016, 14:54
Добрый день. Вопрос ко всем кто использует библиотеку: Если физически отключить RS-485, err (ошибка modbus) постоянно переключается с 0 на 255, и complete (признак завершения операции) постоянно переключается False на True, как будто модуль продолжает опрашиваться - так должно быть или что-то не верно в примере?

energvk
29.09.2016, 10:49
Подчистил для Воронежа, но не настаиваю на единственном способе

Валенок очень понравился ваш вариант, изящно и красиво. Решил убрать у себя все эти "индии" и начал опробовать на модуле 2АС. В ФБ изменил:



FUNCTION_BLOCK (*строго ФБ ...*) MV2AC
(*(C) Валенок*)
VAR_OUTPUT
Ai : ARRAY[1..2] OF MV_2AC;
END_VAR
VAR
(*читаем 8 регистров за раз с адреса 16#106*)
SRD : ARRAY[1..2] OF WORD;
READ : ARRAY[1..2,1..3] OF WORD;
x : ARRAY[1..240] OF BYTE; (*просто добил буфер до 256 байт*)
(*!*)
i : INT;
p : POINTER TO ARRAY[1..2] OF WORD;
END_VAR

---------------------------------------------------------------------------
FOR i := 1 TO 2 DO
Ai[i].Status := SRD[i];
Ai[i].Cyclic := Read[i,3];
p := ADR(Ai[i].Value);
p^[1] := Read[i,2];
p^[2] := Read[i,1];
END_FOR


Структуру оставил как есть


TYPE MV_2AC :
STRUCT
Status :ENUM_STATUS := STATUS_UNREADY;
Cyclic :WORD;
Value :REAL;
END_STRUCT
END_TYPE


В программе соответственно:


CASE state OF
0:
enable:=1;
(* функция 03 флоат - ФБ считывает значение параметров *)

PBuffer := ADR(MV2AC.SRD);
get3_modbus(
Enable:=enable, (* разрешение работы блока *)
Mode:=MB_RTU , (* режим передачи*)
DevAddr:=40 , (* адрес*)
FirstAddr:= (*16#106*)262, (* номер регистра*)
Quantity:=8, (* количество регистров*)
ComHandle:=Settings.Port , (* номер COM-порта*)
TimeOut:=TimeOut , (* таймаут *)
Buffer:= PBuffer^ , (*Buffer,*) (* буфер данных *)
Complete=>cmpl , (* скопировать признак завершения операции *)
Exception=>err , (* скопировать регистр ошибок *)
ByteCnt=>DataSize ); (*кол-во считанных байтов *)
(*если установлен признак завершения операции, то *)

IF cmpl THEN
IF err=0 THEN (*Если нет ошибок, то получаем данные из буфера, формируем переменные*)
MV2AC;
IF MV2AC.Ai[1].Status <>0 THEN errAi1:=TRUE; ai1 := 0; ELSE errAi1:=FALSE; ai1 := MV2AC.Ai[1].Value; END_IF;
ai1w := REAL_TO_WORD (ai1);
IF MV2AC.Ai[2].Status <>0 THEN errAi2:=TRUE; ai2 := 0; ELSE errAi2:=TRUE; ai2 := MV2AC.Ai[2].Value; END_IF;
state:=1;
enable:=0;
ELSE
state:=1;
END_IF
END_IF

1:
state:=0;
END_CASE


Но значения получаю неправильные (что-то там в -30 или т.п. степени). Через "индию" всё норм, но некрасиво :(.

Что-то подсказывает мне, что в ФБ что-то неправильно, но что не пойму, карта регистров 2ас и 8ас вроде как совпадает (только количеством каналов отличается) :confused:.

Не подскажете что не так?

energvk
29.09.2016, 15:36
Спасибо, так заработало. Только бы въехать в назначение функции...(((

Как я понял функция - аналог кода в 37 посте:
var
pw : pointer to array[1..32] of word;
......
pw := adr(MV8AC.SRD);
for i := 1 to 32 do //получение исходной структуры из сетевого набора байт
pw^[i] := rol(pw^[i],8);
end_if

Что мне непонятно это присвоение pw, да и PBuffer ADR(MV8AC.SRD). Почему не ADR(MV8AC)?

И по идее нормально будет работать на 2А, 8А модулях

В таком виде мне понятно, что происходит, не уверен, что код корректный, но данные обрабатывает правильно:


SysMemCpy(ADR(MV2AC),ADR(Buffer),16);
pw := ADR(MV2AC);
FOR j := 1 TO 8 DO (*получение исходной структуры из сетевого набора байт*)
pw^[j] := ROL(pw^[j],8);
END_FOR;
MV2AC; (*Исходные => конечные *)

energvk
02.10.2016, 22:27
В примере данные заносятся с адреса mv2ac.SRD, а то что SRD в расположена самой первой в структуре mva2c момент условно случайный. Сделай :
var
i : int;
SRD....
...
и все поймешь..


Понял:).

Вообще, спасибо большое за подробные объяснения. Понял, что как и почему.

ЗЫ


function get_original_from_net : bool
//Сетевые -> в исходные (для modbus.lib)
var_input
pdata : pointer to word;
size : byte; (*в байтах*)
end_var
------------
get_original_from_net := (pdata <> 0) and ((pdata mod 1) = 0); //не nil и четный

if get_original_from_net then
szdata := szdata / 2; //в регистрах-словах
...
end_if


Я так понимаю, что должно быть:


var_input
pdata : pointer to word;
size : byte; (*в байтах*)
end_var
var
szdata : byte; (*в байтах*)
end_var
------------
get_original_from_net := (pdata <> 0) and ((pdata mod 1) = 0); //не nil и четный

if get_original_from_net then
szdata := size / 2; //в регистрах-словах
...
end_if


ЗЗЫ. И ещё: Вы не рекомендуете
И я бы принципиально не стал делать в одном проходе из сетевого набора байт конечную структуру. При этом ваша функция это делает за раз. Или я что-то неправильно понимаю?

energvk
03.10.2016, 00:49
)) Да. Очепятался. Просто size на входе, size := size / 2, и далее везде size, дополнительно водить переменную здесь особо и не нужно


В смысле за раз ? И сетевого в исходный - да, за раз. Когда исходная=конечная этого достаточно (например считать все счетчики МДВВ). Но тут еще и исходная=>конечная нужно сделать, что дальше MV2/8A() и делает.

И, кстати, делать раздельные структуры единичного ai для 2AC и 8AC - не нужно. Описание статуса одинаково для 2A,8A,2AC,8AC,MVA8,PLC63/73/150/154/160 (конечно, афтару INCORRECT для 160-ого развальцевать кое-чего не помешало бы). Да и структура входа 2/8AC легко приводится (в целях унификации) к виду соответствующему 2/8A/MVA8. Или наоборот.

Огромное спасибо)))