1. Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
  2. Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
  3. Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
  4. За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
  5. Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
  6. Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
  7. Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.

Метод передачи длинной сетевой переменной

Обсуждение вопросов, не относящихся ни к одному из других подразделов

Модератор: kirillio

Ответить

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Метод передачи длинной сетевой переменной

Сообщение Холкин »

Требуется организовать передачу информации по сети Modbus из master в slave строго кадрами (один кадр = массив из нескольких переменных). Те фактически задача эквивалентна передаче одной большой переменной размером около 200 байт. Соответственно нужно определить момент, когда вся переменная полностью будет записана в slave.

Если не записан хотя бы один байт, устройство slave не сможет использовать такую переменную. Для предотвращения ошибок внутри переменной (массива переменных) имеется контрольная сумма.

Желательно сделать обмен средствами Codesys или HMI Weintek. В Codesys из master можно передавать переменные до 4 байт по времени или по событиям. Такой подход не гарантирует доставку большого массива, могут быть пролпуски отдельных элементов.
Помимо написания надстройки протокола, видится еще временное решение - в slave постоянно копировать сетевой массив из регистров Модбас в другую область памяти и проверять контрольную сумму. Однако такой метод не улучшит сетевой обмен.

Нужны идеи по решению проблемы ...

SaNNy
освоился
освоился
Сообщения: 230
Зарегистрирован: 01 фев 2010, 10:37
Имя: Александр
Страна: Россия
город/регион: Брянск
Благодарил (а): 9 раз
Поблагодарили: 26 раз

Re: Метод передачи длинной сетевой переменной

Сообщение SaNNy »

Интерфейс какой? Ehternet, RS-485?

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

RS-485, увы этот slave не поддерживает Ehternet.

SaNNy
освоился
освоился
Сообщения: 230
Зарегистрирован: 01 фев 2010, 10:37
Имя: Александр
Страна: Россия
город/регион: Брянск
Благодарил (а): 9 раз
Поблагодарили: 26 раз

Re: Метод передачи длинной сетевой переменной

Сообщение SaNNy »

Чем вам не нравится вариант вычитывания данных из нескольких регистров?
Аватара пользователя

san
преподаватель
преподаватель
Сообщения: 1357
Зарегистрирован: 01 сен 2008, 18:32
Имя: Пупена Александр
Страна: Украина
город/регион: Киев
Поблагодарили: 6 раз

Re: Метод передачи длинной сетевой переменной

Сообщение san »

Если ресурсы устройств позволяют, поменяйте Master и Slave местами. Тогда читайте и пишите все вместе, используя функции ПЛК.

Василий Иванович
авторитет
авторитет
Сообщения: 878
Зарегистрирован: 21 авг 2009, 14:25
Имя: Василий Иванович
Благодарил (а): 1 раз
Поблагодарили: 3 раза

Re: Метод передачи длинной сетевой переменной

Сообщение Василий Иванович »

Не надо постоянно копировать все двести байт в слейве, а тогда лишь, когда обновится переменная-триггер в одном из регистров.
Аватара пользователя

Exactamente
частый гость
частый гость
Сообщения: 409
Зарегистрирован: 20 ноя 2012, 13:45
Имя: :.О.N.Ф
Страна: Россия
Благодарил (а): 3 раза
Поблагодарили: 7 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Exactamente »

Мастер и слейв - это что именно за устройства?

Мб они из коробки поддерживают функцию записи нескольких регистров?

Откуда такое ограничение, почему нельзя записывать регистры под одному?

Зачем "определять момент, когда вся переменная полностью будет записана в slave"? Модбас разве так работает? Кажется, просто пишется в порт всё что хочется.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

Василий Иванович писал(а):Не надо постоянно копировать все двести байт в слейве, а тогда лишь, когда обновится переменная-триггер в одном из регистров.
так и хотел, но нет синхронности - об этом ниже
san писал(а):Если ресурсы устройств позволяют, поменяйте Master и Slave местами. Тогда читайте и пишите все вместе, используя функции ПЛК.
в ПЛК Codesys стандартно сетевой обмен определяется конфигурирование областей ввода-вывода. В соответствии с конфигурацией ОС ПЛК запускает в фоновом режиме процедуры сетевого ввода-вывода и обмен может идти по итнтервалам времени или по изменению значений переменных.
А вы какие именно функции Codesys имеете ввиду?


поменять Slave и Master можно и можно выделить даже отдельную линию, но принципиально ничего ничего принципиально будучи Master ом, поймать из Slave флаг готовности (триггер по переднему фронту) массива к передаче сложнее, информация меняется, кадры обновляются.
SaNNy писал(а):Чем вам не нравится вариант вычитывания данных из нескольких регистров?
тем, что нет гарантии синхронности передачи всего массива. При использовании модлулей ввода-вывода Codesys потенциапльно могут быть ситуации, когда одни элементы массива обновились уже несколько раз, а какие-то еще не обновилдись. ОС ПЛК не знает, что это единая длинная переменная.

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

Exactamente писал(а):Мастер и слейв - это что именно за устройства? Мб они из коробки поддерживают функцию записи нескольких регистров[/url]?
Откуда такое ограничение, почему нельзя записывать регистры под одному?
Зачем "определять момент, когда вся переменная полностью будет записана в slave"? Модбас разве так работает? Кажется, просто пишется в порт всё что хочется.
Это была бы хорошая идея, если несколько регистров можно растянуть в объеме до 200 байт. Так можно ?

1. Мастером предполагался Овен ПЛК-100 или панель HMI Weintek . Вроде бы не поддерживают, но у меня нет 100% достоверной информации. Выше подсказывали про какие-то функции в ПЛК...
2. про поддержку этой функции у Slave пока не знаю, надо уточнить
3. Пишется все, что хочется, но 200-байтовая переменная имеет смысл если она передана гарантированно полностью.

SaNNy
освоился
освоился
Сообщения: 230
Зарегистрирован: 01 фев 2010, 10:37
Имя: Александр
Страна: Россия
город/регион: Брянск
Благодарил (а): 9 раз
Поблагодарили: 26 раз

Re: Метод передачи длинной сетевой переменной

Сообщение SaNNy »

Сделайте кольцевой буфер, пишите туда значения, отдельно сделайте регистр, куда будет заносится количество элементов в буфере. Затем вычитывайте поочередно данные из буфера, когда регистр, содержащий количество записей изменился.
А у вас с какой частотой необходимо эти 200 кб считывать?

Василий Иванович
авторитет
авторитет
Сообщения: 878
Зарегистрирован: 21 авг 2009, 14:25
Имя: Василий Иванович
Благодарил (а): 1 раз
Поблагодарили: 3 раза

Re: Метод передачи длинной сетевой переменной

Сообщение Василий Иванович »

Принципиально Modbus своей функцией FC16 позволяет запись сотни шестнадцатибитных регистров за один цикл передачи, обеспечивая таким образом консистентность (это называется консистентность, а не синхронность) данных. Однако не все мастера и слейвы поддерживают эту функцию. Если поддерживают, то проблема таким образом решается конфигурацией передачи сотни регистров разом. Если не поддерживают, то выйти из положения можно будет, согласововав события отправки и получения всех регистров. Но у Вас, как я понял, нет возможность контролировать чтение и запись регистров мастером и слейвом, мастер и слейв шлют и принимают данные по каким-то своим временным циклам и событиям. В данном случае, мне думается, проблему решить можно, присваивая каждому отдельно передаваемому куску из 200 байт один и тот же ID в мастере, и собирая исходную посылку из кусочков с одним и тем же ID на слейве. Ну и быть готовым, конечно, к пропаже пакетов.
Аватара пользователя

Exactamente
частый гость
частый гость
Сообщения: 409
Зарегистрирован: 20 ноя 2012, 13:45
Имя: :.О.N.Ф
Страна: Россия
Благодарил (а): 3 раза
Поблагодарили: 7 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Exactamente »

Если вайнтек под EasyBuilder'ом, то тут либо стандартной функцией SetDataEx, там можно задавать на запись несколько регистров (только не знаю как оно пишет - по одному или пачкой, ща такой панельки под рукой нет, чтоб проверить, проконсультируйтесь у Прософта), либо драйвер свой писать (тут хз как оно устроено). Если под виндой, то карты в руки, в интернетах есть библиотеки для модбаса и описание виндового API по работе с ком-портами.

Я всё ещё не понимаю проблемы неполной передачи) Чексумма же не сойдётся, если пакет передан не полностью. Нет, есть вероятность, что при обрыве передачи последние два слова, после которых оборвалось, внезапно окажутся подходящими значениями для чексуммы, но вероятность как-то маловата. Слейв присылает ответ, подтверждающий запись. В чём проблема-то? Связь такая плохая, что длинный пакет просто не пройдёт?

По ссылке-то пройдите. Ф-я записи нескольких регистров это так: "16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)".
Пакет будет выглядеть как-то так: [адрес_слейва][10][начальный_регистр_записи][количество_регистров][и][х][з][н][а][ч][е][н][и][я][чек][сумма]
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».

Владимир Кузнецов
не первый раз у нас
не первый раз у нас
Сообщения: 321
Зарегистрирован: 31 авг 2011, 22:14
Имя: Кузнецов Владимир Сергеевич
Страна: Россия
город/регион: Казань
Поблагодарили: 1 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Владимир Кузнецов »

Требуется более подробное описание процесса.
Из того что есть пока можно сделать такую выжимку:
- нужно передать 200 байт
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени
- для контроля согласованности полученного набора есть CRC

Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери).
Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась).

Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер
- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче
- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

SaNNy писал(а):Сделайте кольцевой буфер, пишите туда значения, отдельно сделайте регистр, куда будет заносится количество элементов в буфере. Затем вычитывайте поочередно данные из буфера, когда регистр, содержащий количество записей изменился. А у вас с какой частотой необходимо эти 200 кб считывать?
Не знаю что даст кольцевой буфер, а поочередно вычитывать невозможно тк момент окончания или гарантирования записи неизвестен.
Не 200 кб, а 200 байт - частоту еще не определили но она будет небольшая вполне посильная для ПЛК
Василий Иванович писал(а):Принципиально Modbus своей функцией FC16 позволяет запись сотни шестнадцатибитных регистров за один цикл передачи, обеспечивая таким образом консистентность (это называется консистентность, а не синхронность) данных. Однако не все мастера и слейвы поддерживают эту функцию. Если поддерживают, то проблема таким образом решается конфигурацией передачи сотни регистров разом. Если не поддерживают, то выйти из положения можно будет, согласововав события отправки и получения всех регистров. Но у Вас, как я понял, нет возможность контролировать чтение и запись регистров мастером и слейвом, мастер и слейв шлют и принимают данные по каким-то своим временным циклам и событиям. В данном случае, мне думается, проблему решить можно, присваивая каждому отдельно передаваемому куску из 200 байт один и тот же ID в мастере, и собирая исходную посылку из кусочков с одним и тем же ID на слейве. Ну и быть готовым, конечно, к пропаже пакетов.


Уточнил - у slave есть функция 0x10. Кстати slave не может слать данные по своим временным циклам, а только в ответ на запрос мастера.
Насчет ID идея интересная, но пришлось бы писать надстройку над протоколом, чтобы сообщать мастеру какой из регистров не записан в случае сбоя сетевых данных.
Exactamente писал(а):Если вайнтек под EasyBuilder'ом, то тут либо стандартной функцией SetDataEx, там можно задавать на запись несколько регистров (только не знаю как оно пишет - по одному или пачкой, ща такой панельки под рукой нет, чтоб проверить, проконсультируйтесь у Прософта), либо драйвер свой писать (тут хз как оно устроено). Если под виндой, то карты в руки, в интернетах есть библиотеки для модбаса и описание виндового API по работе с ком-портами.

Я всё ещё не понимаю проблемы неполной передачи) Чексумма же не сойдётся, если пакет передан не полностью. Нет, есть вероятность, что при обрыве передачи последние два слова, после которых оборвалось, внезапно окажутся подходящими значениями для чексуммы, но вероятность как-то маловата. Слейв присылает ответ, подтверждающий запись. В чём проблема-то? Связь такая плохая, что длинный пакет просто не пройдёт?

По ссылке-то пройдите. Ф-я записи нескольких регистров это так: "16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)".
Пакет будет выглядеть как-то так: [адрес_слейва][10][начальный_регистр_записи][количество_регистров][и][х][з][н][а][ч][е][н][и][я][чек][сумма]
Да, спасибо , Easy Builder и EB -PRO, панели есть в наличии и те и другие. По функции 0x10 и отсутствии(наличии) для нее возможной оптимизации порядка передачи в Weintek буду уточнять дополнительно, но вероятно придется использовать ПЛК Овен как мастер. Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?

Владимир Кузнецов писал(а):Требуется более подробное описание процесса.
Из того что есть пока можно сделать такую выжимку:
- нужно передать 200 байт
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени
- для контроля согласованности полученного набора есть CRC

Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери).
Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась).

Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер
- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче
- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает
1)- нужно передать 200 байт/ /верно, из мастера в slave, затем slave выдаст результат в другой переменной (массиве)
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени / Их явным образом формирует мастер, момент готовности 200-байтовой переменной всегда известен мастеру.

2)- для контроля согласованности полученного набора есть CRC/ / да, но CRC не влияет на согласованность во времени (как писали выше - консистентность). Мастер в момент готовности переменной (массива из 200 байт) дописывает в нее (него) контрольную сумму CRC

3) Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери). /Важно поймать не сами изменения в данных (с этим мастер справится без проблем), а целостный кадр сформированный мастером и переданный в slave, а затем ответ slave для мастера. Нецелостный кадр - на выброс, небольшие потери приемлемы, от них никуда не деться.

4) Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась). /Так может быть, корреляция между предыдущими и последующими данными присутствует от 0 до 100%. Данные - разноородные по формату данные с других устройств сети, которые собрал мастер

5) Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер / /Мастер сначала записывает в slave, а потом читает ответ примерно из slave. Замена мастера на slave возможна, но не знаю что это даст.

6)- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче / Cогласен, до начала передачи силами састера сбросить мастером флаг внутри slave, затем передать 200 байт по функции 0x10 и опять выставить силами састера флаг в slave; slave по переднему фронту флага флагу скопирует данные в отдельную область и обработает их.

7)- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает/да, верно

************
PS: Есть вероятность, что мастером придется ставить ПЛК Овен (Weintek не ПЛК, а просто панель с расширенными возможностями в макро), а умеет ли Овен работать по функции Модбас 0х10 и именно из тела программы, а не "сбоку прикрепленного" конфигуратора ввода-вывода - пока нет ответа.

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

PPS: вроде бы ПЛК Овен поддерживает 0x10, но так как это не в программе, а в модуле ввода-вывода (конфигуратор), то непонятно как вытащить момент завершения работы 0х10, чтобы по нему установить флаг?

из описания ПЛК-100 http://www.owen.ru/uploads/plc_configuration_owen__.pdf :
«Номер команды протокола» (Command) – значения выбираются из
списка возможных вариантов, значение по умолчанию – «preset single
register (0x06)» для выходной строковой переменной («write multiple
registers (0x10)» для 2-байтной переменной и др.) (см. п. 3.2.2.1).
Аватара пользователя

Exactamente
частый гость
частый гость
Сообщения: 409
Зарегистрирован: 20 ноя 2012, 13:45
Имя: :.О.N.Ф
Страна: Россия
Благодарил (а): 3 раза
Поблагодарили: 7 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Exactamente »

>Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?

Нет, это протокол так устроен, ничего дополнительно делать не надо, слейв просто присылает ответ: в случае успешной записи - одного формата, в случае неудачи - другого.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».

Автор темы
Холкин
здесь недавно
здесь недавно
Сообщения: 9
Зарегистрирован: 14 окт 2013, 10:49
Имя: Холкин

Re: Метод передачи длинной сетевой переменной

Сообщение Холкин »

Exactamente писал(а):>Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?
Нет, это протокол так устроен, ничего дополнительно делать не надо, слейв просто присылает ответ: в случае успешной записи - одного формата, в случае неудачи - другого.
как этот ответ достать на ПЛК в Codesys?

Ryzhij
почётный участник форума
почётный участник форума
Сообщения: 5620
Зарегистрирован: 07 окт 2011, 09:12
Имя: Гаско Вячеслав Эриевич
Страна: Россия
город/регион: Рязань
Благодарил (а): 544 раза
Поблагодарили: 706 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Ryzhij »

Через стандартную системную библиотечную функцию, с помощью которой Вы отправляете посылку.
Читайте описание библиотек.
У Вас часом не Овен?
А то сходите к ним на форум, там растолкуют подробно.
---------------------------------------------------
«У человека в душе дыра размером с Бога, и каждый заполняет её как может.» (Жан-Поль Сартр)
"Ту пустоту, которая остаётся в душе, когда в ней нет Бога, и весь мир не может заполнить." (святитель Николай Сербский)
Аватара пользователя

Exactamente
частый гость
частый гость
Сообщения: 409
Зарегистрирован: 20 ноя 2012, 13:45
Имя: :.О.N.Ф
Страна: Россия
Благодарил (а): 3 раза
Поблагодарили: 7 раз

Re: Метод передачи длинной сетевой переменной

Сообщение Exactamente »

Ни с Овеном, ни с codesys не знаком, не подскажу. По идее-то ничего доставать не надо. Делаете запись в слейв, а мастер сам должен ждать ответа с результатом, который куда-нибудь в переменную кладётся, чтоб можно было в программе его дальше обработать - мне кажется, такой функционал должен быть уже реализован, остаётся только разобраться в нём =)
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
Ответить

Вернуться в «Общие вопросы»