- Обязательно представиться на русском языке кириллицей (заполнить поле "Имя").
- Фиктивные имена мы не приветствуем. Ивановых и Пупкиных здесь уже достаточно.
- Не писать свой вопрос в первую попавшуюся тему - вместо этого создать новую тему.
- За поиск, предложение и обсуждение пиратского ПО и средств взлома - бан без предупреждения.
- Рекламу и частные объявления "куплю/продам/есть халтура" мы не размещаем ни на каких условиях.
- Перед тем как что-то написать - читать здесь и здесь, а студентам - обязательно здесь.
- Не надо писать в ЛС администраторам свои технические вопросы. Администраторы форума отлично знают как работает форум, а не все-все контроллеры, о которых тут пишут.
Метод передачи длинной сетевой переменной
Модератор: kirillio
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
Метод передачи длинной сетевой переменной
Требуется организовать передачу информации по сети Modbus из master в slave строго кадрами (один кадр = массив из нескольких переменных). Те фактически задача эквивалентна передаче одной большой переменной размером около 200 байт. Соответственно нужно определить момент, когда вся переменная полностью будет записана в slave.
Если не записан хотя бы один байт, устройство slave не сможет использовать такую переменную. Для предотвращения ошибок внутри переменной (массива переменных) имеется контрольная сумма.
Желательно сделать обмен средствами Codesys или HMI Weintek. В Codesys из master можно передавать переменные до 4 байт по времени или по событиям. Такой подход не гарантирует доставку большого массива, могут быть пролпуски отдельных элементов.
Помимо написания надстройки протокола, видится еще временное решение - в slave постоянно копировать сетевой массив из регистров Модбас в другую область памяти и проверять контрольную сумму. Однако такой метод не улучшит сетевой обмен.
Нужны идеи по решению проблемы ...
Если не записан хотя бы один байт, устройство slave не сможет использовать такую переменную. Для предотвращения ошибок внутри переменной (массива переменных) имеется контрольная сумма.
Желательно сделать обмен средствами Codesys или HMI Weintek. В Codesys из master можно передавать переменные до 4 байт по времени или по событиям. Такой подход не гарантирует доставку большого массива, могут быть пролпуски отдельных элементов.
Помимо написания надстройки протокола, видится еще временное решение - в slave постоянно копировать сетевой массив из регистров Модбас в другую область памяти и проверять контрольную сумму. Однако такой метод не улучшит сетевой обмен.
Нужны идеи по решению проблемы ...
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
-
- освоился
- Сообщения: 233
- Зарегистрирован: 01 фев 2010, 10:37
- Имя: Александр
- Страна: Россия
- город/регион: Брянск
- Благодарил (а): 10 раз
- Поблагодарили: 27 раз
Re: Метод передачи длинной сетевой переменной
Чем вам не нравится вариант вычитывания данных из нескольких регистров?
-
- преподаватель
- Сообщения: 1357
- Зарегистрирован: 01 сен 2008, 18:32
- Имя: Пупена Александр
- Страна: Украина
- город/регион: Киев
- Поблагодарили: 6 раз
Re: Метод передачи длинной сетевой переменной
Если ресурсы устройств позволяют, поменяйте Master и Slave местами. Тогда читайте и пишите все вместе, используя функции ПЛК.
-
- авторитет
- Сообщения: 878
- Зарегистрирован: 21 авг 2009, 14:25
- Имя: Василий Иванович
- Благодарил (а): 1 раз
- Поблагодарили: 3 раза
Re: Метод передачи длинной сетевой переменной
Не надо постоянно копировать все двести байт в слейве, а тогда лишь, когда обновится переменная-триггер в одном из регистров.
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
Re: Метод передачи длинной сетевой переменной
Мастер и слейв - это что именно за устройства?
Мб они из коробки поддерживают функцию записи нескольких регистров?
Откуда такое ограничение, почему нельзя записывать регистры под одному?
Зачем "определять момент, когда вся переменная полностью будет записана в slave"? Модбас разве так работает? Кажется, просто пишется в порт всё что хочется.
Мб они из коробки поддерживают функцию записи нескольких регистров?
Откуда такое ограничение, почему нельзя записывать регистры под одному?
Зачем "определять момент, когда вся переменная полностью будет записана в slave"? Модбас разве так работает? Кажется, просто пишется в порт всё что хочется.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
Re: Метод передачи длинной сетевой переменной
так и хотел, но нет синхронности - об этом нижеВасилий Иванович писал(а):Не надо постоянно копировать все двести байт в слейве, а тогда лишь, когда обновится переменная-триггер в одном из регистров.
в ПЛК Codesys стандартно сетевой обмен определяется конфигурирование областей ввода-вывода. В соответствии с конфигурацией ОС ПЛК запускает в фоновом режиме процедуры сетевого ввода-вывода и обмен может идти по итнтервалам времени или по изменению значений переменных.san писал(а):Если ресурсы устройств позволяют, поменяйте Master и Slave местами. Тогда читайте и пишите все вместе, используя функции ПЛК.
А вы какие именно функции Codesys имеете ввиду?
поменять Slave и Master можно и можно выделить даже отдельную линию, но принципиально ничего ничего принципиально будучи Master ом, поймать из Slave флаг готовности (триггер по переднему фронту) массива к передаче сложнее, информация меняется, кадры обновляются.
тем, что нет гарантии синхронности передачи всего массива. При использовании модлулей ввода-вывода Codesys потенциапльно могут быть ситуации, когда одни элементы массива обновились уже несколько раз, а какие-то еще не обновилдись. ОС ПЛК не знает, что это единая длинная переменная.SaNNy писал(а):Чем вам не нравится вариант вычитывания данных из нескольких регистров?
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
Re: Метод передачи длинной сетевой переменной
Это была бы хорошая идея, если несколько регистров можно растянуть в объеме до 200 байт. Так можно ?Exactamente писал(а):Мастер и слейв - это что именно за устройства? Мб они из коробки поддерживают функцию записи нескольких регистров[/url]?
Откуда такое ограничение, почему нельзя записывать регистры под одному?
Зачем "определять момент, когда вся переменная полностью будет записана в slave"? Модбас разве так работает? Кажется, просто пишется в порт всё что хочется.
1. Мастером предполагался Овен ПЛК-100 или панель HMI Weintek . Вроде бы не поддерживают, но у меня нет 100% достоверной информации. Выше подсказывали про какие-то функции в ПЛК...
2. про поддержку этой функции у Slave пока не знаю, надо уточнить
3. Пишется все, что хочется, но 200-байтовая переменная имеет смысл если она передана гарантированно полностью.
-
- освоился
- Сообщения: 233
- Зарегистрирован: 01 фев 2010, 10:37
- Имя: Александр
- Страна: Россия
- город/регион: Брянск
- Благодарил (а): 10 раз
- Поблагодарили: 27 раз
Re: Метод передачи длинной сетевой переменной
Сделайте кольцевой буфер, пишите туда значения, отдельно сделайте регистр, куда будет заносится количество элементов в буфере. Затем вычитывайте поочередно данные из буфера, когда регистр, содержащий количество записей изменился.
А у вас с какой частотой необходимо эти 200 кб считывать?
А у вас с какой частотой необходимо эти 200 кб считывать?
-
- авторитет
- Сообщения: 878
- Зарегистрирован: 21 авг 2009, 14:25
- Имя: Василий Иванович
- Благодарил (а): 1 раз
- Поблагодарили: 3 раза
Re: Метод передачи длинной сетевой переменной
Принципиально Modbus своей функцией FC16 позволяет запись сотни шестнадцатибитных регистров за один цикл передачи, обеспечивая таким образом консистентность (это называется консистентность, а не синхронность) данных. Однако не все мастера и слейвы поддерживают эту функцию. Если поддерживают, то проблема таким образом решается конфигурацией передачи сотни регистров разом. Если не поддерживают, то выйти из положения можно будет, согласововав события отправки и получения всех регистров. Но у Вас, как я понял, нет возможность контролировать чтение и запись регистров мастером и слейвом, мастер и слейв шлют и принимают данные по каким-то своим временным циклам и событиям. В данном случае, мне думается, проблему решить можно, присваивая каждому отдельно передаваемому куску из 200 байт один и тот же ID в мастере, и собирая исходную посылку из кусочков с одним и тем же ID на слейве. Ну и быть готовым, конечно, к пропаже пакетов.
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
Re: Метод передачи длинной сетевой переменной
Если вайнтек под EasyBuilder'ом, то тут либо стандартной функцией SetDataEx, там можно задавать на запись несколько регистров (только не знаю как оно пишет - по одному или пачкой, ща такой панельки под рукой нет, чтоб проверить, проконсультируйтесь у Прософта), либо драйвер свой писать (тут хз как оно устроено). Если под виндой, то карты в руки, в интернетах есть библиотеки для модбаса и описание виндового API по работе с ком-портами.
Я всё ещё не понимаю проблемы неполной передачи) Чексумма же не сойдётся, если пакет передан не полностью. Нет, есть вероятность, что при обрыве передачи последние два слова, после которых оборвалось, внезапно окажутся подходящими значениями для чексуммы, но вероятность как-то маловата. Слейв присылает ответ, подтверждающий запись. В чём проблема-то? Связь такая плохая, что длинный пакет просто не пройдёт?
По ссылке-то пройдите. Ф-я записи нескольких регистров это так: "16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)".
Пакет будет выглядеть как-то так: [адрес_слейва][10][начальный_регистр_записи][количество_регистров][и][х][з][н][а][ч][е][н][и][я][чек][сумма]
Я всё ещё не понимаю проблемы неполной передачи) Чексумма же не сойдётся, если пакет передан не полностью. Нет, есть вероятность, что при обрыве передачи последние два слова, после которых оборвалось, внезапно окажутся подходящими значениями для чексуммы, но вероятность как-то маловата. Слейв присылает ответ, подтверждающий запись. В чём проблема-то? Связь такая плохая, что длинный пакет просто не пройдёт?
По ссылке-то пройдите. Ф-я записи нескольких регистров это так: "16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)".
Пакет будет выглядеть как-то так: [адрес_слейва][10][начальный_регистр_записи][количество_регистров][и][х][з][н][а][ч][е][н][и][я][чек][сумма]
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- не первый раз у нас
- Сообщения: 321
- Зарегистрирован: 31 авг 2011, 22:14
- Имя: Кузнецов Владимир Сергеевич
- Страна: Россия
- город/регион: Казань
- Поблагодарили: 1 раз
Re: Метод передачи длинной сетевой переменной
Требуется более подробное описание процесса.
Из того что есть пока можно сделать такую выжимку:
- нужно передать 200 байт
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени
- для контроля согласованности полученного набора есть CRC
Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери).
Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась).
Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер
- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче
- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает
Из того что есть пока можно сделать такую выжимку:
- нужно передать 200 байт
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени
- для контроля согласованности полученного набора есть CRC
Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери).
Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась).
Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер
- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче
- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
Re: Метод передачи длинной сетевой переменной
Не знаю что даст кольцевой буфер, а поочередно вычитывать невозможно тк момент окончания или гарантирования записи неизвестен.SaNNy писал(а):Сделайте кольцевой буфер, пишите туда значения, отдельно сделайте регистр, куда будет заносится количество элементов в буфере. Затем вычитывайте поочередно данные из буфера, когда регистр, содержащий количество записей изменился. А у вас с какой частотой необходимо эти 200 кб считывать?
Не 200 кб, а 200 байт - частоту еще не определили но она будет небольшая вполне посильная для ПЛК
Василий Иванович писал(а):Принципиально Modbus своей функцией FC16 позволяет запись сотни шестнадцатибитных регистров за один цикл передачи, обеспечивая таким образом консистентность (это называется консистентность, а не синхронность) данных. Однако не все мастера и слейвы поддерживают эту функцию. Если поддерживают, то проблема таким образом решается конфигурацией передачи сотни регистров разом. Если не поддерживают, то выйти из положения можно будет, согласововав события отправки и получения всех регистров. Но у Вас, как я понял, нет возможность контролировать чтение и запись регистров мастером и слейвом, мастер и слейв шлют и принимают данные по каким-то своим временным циклам и событиям. В данном случае, мне думается, проблему решить можно, присваивая каждому отдельно передаваемому куску из 200 байт один и тот же ID в мастере, и собирая исходную посылку из кусочков с одним и тем же ID на слейве. Ну и быть готовым, конечно, к пропаже пакетов.
Уточнил - у slave есть функция 0x10. Кстати slave не может слать данные по своим временным циклам, а только в ответ на запрос мастера.
Насчет ID идея интересная, но пришлось бы писать надстройку над протоколом, чтобы сообщать мастеру какой из регистров не записан в случае сбоя сетевых данных.
Да, спасибо , Easy Builder и EB -PRO, панели есть в наличии и те и другие. По функции 0x10 и отсутствии(наличии) для нее возможной оптимизации порядка передачи в Weintek буду уточнять дополнительно, но вероятно придется использовать ПЛК Овен как мастер. Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?Exactamente писал(а):Если вайнтек под EasyBuilder'ом, то тут либо стандартной функцией SetDataEx, там можно задавать на запись несколько регистров (только не знаю как оно пишет - по одному или пачкой, ща такой панельки под рукой нет, чтоб проверить, проконсультируйтесь у Прософта), либо драйвер свой писать (тут хз как оно устроено). Если под виндой, то карты в руки, в интернетах есть библиотеки для модбаса и описание виндового API по работе с ком-портами.
Я всё ещё не понимаю проблемы неполной передачи) Чексумма же не сойдётся, если пакет передан не полностью. Нет, есть вероятность, что при обрыве передачи последние два слова, после которых оборвалось, внезапно окажутся подходящими значениями для чексуммы, но вероятность как-то маловата. Слейв присылает ответ, подтверждающий запись. В чём проблема-то? Связь такая плохая, что длинный пакет просто не пройдёт?
По ссылке-то пройдите. Ф-я записи нескольких регистров это так: "16 (0x10) — запись значений в несколько регистров хранения (Preset Multiple Registers)".
Пакет будет выглядеть как-то так: [адрес_слейва][10][начальный_регистр_записи][количество_регистров][и][х][з][н][а][ч][е][н][и][я][чек][сумма]
1)- нужно передать 200 байт/ /верно, из мастера в slave, затем slave выдаст результат в другой переменной (массиве)Владимир Кузнецов писал(а):Требуется более подробное описание процесса.
Из того что есть пока можно сделать такую выжимку:
- нужно передать 200 байт
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени
- для контроля согласованности полученного набора есть CRC
Тут пока непонятно насколько важно поймать все изменения в данных (насколько допустимы потери).
Так же не до конца ясно что за данные передаются и как они формируются (может ли к примеру новый пакет частично состоять из старого? а то вдруг там всего пара байт поменялась).
Из того что известно можно предложить решение:
- мастер-слейв поменять местами, читать данные должен мастер
- на источнике (слейве) в момент когда пакет полностью сформирован, его нужно скопировать в отдельную область и выставить флаг готовности к передаче
- читатель (мастер) проверяет флаг готовности и по нему ставит флаг запрета обновления читаемой области, после чего спокойно всю её вычитывает
- данные внутри этой области обновляются сами по себе и согласованы только в течении непродолжительного времени / Их явным образом формирует мастер, момент готовности 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 :
из описания ПЛК-100 http://www.owen.ru/uploads/plc_configuration_owen__.pdf :
«Номер команды протокола» (Command) – значения выбираются из
списка возможных вариантов, значение по умолчанию – «preset single
register (0x06)» для выходной строковой переменной («write multiple
registers (0x10)» для 2-байтной переменной и др.) (см. п. 3.2.2.1).
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
Re: Метод передачи длинной сетевой переменной
>Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?
Нет, это протокол так устроен, ничего дополнительно делать не надо, слейв просто присылает ответ: в случае успешной записи - одного формата, в случае неудачи - другого.
Нет, это протокол так устроен, ничего дополнительно делать не надо, слейв просто присылает ответ: в случае успешной записи - одного формата, в случае неудачи - другого.
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».
-
- здесь недавно
- Сообщения: 9
- Зарегистрирован: 14 окт 2013, 10:49
- Имя: Холкин
Re: Метод передачи длинной сетевой переменной
как этот ответ достать на ПЛК в Codesys?Exactamente писал(а):>Вы пишете - slave присылает ответ, подтверждающий запись. Есть такая функция или нужно писать надстройку?
Нет, это протокол так устроен, ничего дополнительно делать не надо, слейв просто присылает ответ: в случае успешной записи - одного формата, в случае неудачи - другого.
-
- почётный участник форума
- Сообщения: 5639
- Зарегистрирован: 07 окт 2011, 09:12
- Имя: Гаско Вячеслав Эриевич
- Страна: Россия
- город/регион: Рязань
- Благодарил (а): 602 раза
- Поблагодарили: 760 раз
Re: Метод передачи длинной сетевой переменной
Через стандартную системную библиотечную функцию, с помощью которой Вы отправляете посылку.
Читайте описание библиотек.
У Вас часом не Овен?
А то сходите к ним на форум, там растолкуют подробно.
Читайте описание библиотек.
У Вас часом не Овен?
А то сходите к ним на форум, там растолкуют подробно.
---------------------------------------------------
«У человека в душе дыра размером с Бога, и каждый заполняет её как может.» (Жан-Поль Сартр)
"Ту пустоту, которая остаётся в душе, когда в ней нет Бога, и весь мир не может заполнить." (святитель Николай Сербский)
«У человека в душе дыра размером с Бога, и каждый заполняет её как может.» (Жан-Поль Сартр)
"Ту пустоту, которая остаётся в душе, когда в ней нет Бога, и весь мир не может заполнить." (святитель Николай Сербский)
-
- частый гость
- Сообщения: 409
- Зарегистрирован: 20 ноя 2012, 13:45
- Имя: :.О.N.Ф
- Страна: Россия
- Благодарил (а): 3 раза
- Поблагодарили: 7 раз
Re: Метод передачи длинной сетевой переменной
Ни с Овеном, ни с codesys не знаком, не подскажу. По идее-то ничего доставать не надо. Делаете запись в слейв, а мастер сам должен ждать ответа с результатом, который куда-нибудь в переменную кладётся, чтоб можно было в программе его дальше обработать - мне кажется, такой функционал должен быть уже реализован, остаётся только разобраться в нём =)
«Сразу видно внимание к каждой мелочи, неиспорченным не осталось ничто».