Работа с вакуумметром ВМЦ по ModBus
- Войдите на сайт для отправки комментариев
Пт, 23/03/2018 - 14:38
Доброе!
Необходимо получать данные о давлении с вакуумметра ВМЦ (http://e-beam.ru/production/measurement/vmd). Из формуляра следует, что давление считывается из регистров входа 1000 и 1001 в формате float. Формат данных CDAB.
накидал обычный скетч
#include <ModbusRtu.h> uint16_t au16data[32]; //читаем сразу 2 регистра uint8_t u8state; Modbus master(0,0,0); modbus_t telegram[2]; unsigned long u32wait; void setup() { master.begin(19200); master.setTimeOut(2000); u32wait = millis() + 1000; u8state = 0; } void loop() { switch(u8state) { case 0: if (millis() > u32wait) u8state++; break; case 1: telegram[0].u8id = 10; // slave address telegram[0].u8fct = 4; // function code (this one is registers read) telegram[0].u16RegAdd = 1000; // start address in slave telegram[0].u16CoilsNo = 2; // читаем 2 регистра telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino master.query(telegram[0]); u8state++; break; case 2: master.poll(); // check incoming messages if (master.getState() == COM_IDLE) { u8state = 0; u32wait = millis() + 1000; } break; } }
Есть несколько вопросов
1) правильно ли я указал uint16_t au16data[32]; Читаем то 2 регистра сразу
2) как получить из au16data[32] данные в нормальном виде учитывая, что данные нам вернули в формате CDAB?
3) Из того же формуляра следует, что перед измерениями необходимо записать 1 в регистр флагов 1000, правилен ли следующий код?
telegram[1].u8id = 10; // slave address telegram[1].u8fct = 15; // function code (this one is registers read) telegram[1].u16RegAdd = 1000; // start address in slave telegram[1].u16CoilsNo = 1; telegram[1].au16reg = 1; // pointer to a memory array in the Arduino master.query(telegram[1]);
т.е. строка telegram[1].au16reg = 1; немного смущает
Тип float занимает 4 байта или 2 слова, т.е. 2 регистра modbus. Бывает прямой и обратный (инверсный) float. У инверсного регистры имеют обратный порядок.
Чтобы получить значение во float, нужно сохранить в памяти оба регистра modbus (они должны находиться рядом), далее нужно получить указатель на первый и них, затем преобразовать его в указатель на float и разыменовать его. Это один из возможных способов. Есть и другие варианты.
был бы благодарен за код т.к. сам я этого в ближайшее время не накидаю
Могу ошибиться, но вроде мы обсуждали подобное в этом топике http://arduino.ru/forum/proekty/modbusrtu-modbustcp-arduino-i-owen-plc?page=1#comment-237810
там на посте #58 вопрос аналогичный встает, а в #59 снимается настройками ПЛК. так что собственно ответа на мой вопрос №2 я там не нашел (
3) Из того же формуляра следует, что перед измерениями необходимо записать 1 в регистр флагов 1000, правилен ли следующий код?
т.е. строка telegram[1].au16reg = 1; немного смущает
Нет, код не правильный. telegram[1].au16reg - это указатель на область памяти, т.е. на буфер (массив), где и содержится передаваемое значение 1.
Спасибо!
Переделал так:
Немного доработал
Посоветуйте из практики экран, чтобы можно было график выводить. По цене шибко не дорогой.
Доброе
Просьба подсказать, что не так в части
пробовал передать и uint16_t flag[] = {1}; - результат один: светодиод загорается, но ВМЦ не видит переданные данные
Нужно убедиться, что операция прошла успешно.
Описание протокола Modbus RTU.
Нужно убедиться, что операция прошла успешно.
Вы про ответ на запрос записи и/или возврат кода ошибки?
Будет ли (сразу позле запроса на запись) чтение состояния соответсвующего флага регистров являться этим самым ответом? Просто я никде не встречался с функциями чтения ответа и/или получения ошибки данной библиотеки.
PS. Про ответ от слейва нашел ))
> Вы про ответ на запрос записи и/или возврат кода ошибки?
Я про ответ на запрос. Что отвечает прибор. У вас бы не возникало вопросов, если посмотреть на ответ. Лучше всего купить переходник USB-RS485 и посмотреть что происходит на линии.
Вот более полное описание протокола: Modbus_Application_Protocol_V1_1b3.pdf
У вас бы не возникало вопросов, если посмотреть на ответ. Лучше всего купить переходник USB-RS485 и посмотреть что происходит на линии.
заказал, уже вылетело с китая...
за ссылки спасибо
Просто пока идет девайс меня гложет вопрос, а нет ли там путаницы с типом передаваемых данных, для коила то бит нужен...
Вы хорошо даташит читали ?
Мне почему то там написали, что данные нужно читать по адресу 1004....
Вы хорошо даташит читали ?
Мне почему то там написали, что данные нужно читать по адресу 1004....
Даташит чего/кого? Если Вы про вакуумметр, то с ним идет формуляр, на странице 7 "Протокол обмена" где ясно сказано откуда читать.
Ясно..
http://e-beam.ru/images/stories/VTRD/vtrd.pdf
Это другой документ ?
Увас там ВТРЦ, я про ВМЦ
Ссылка на формуляр есть ?
Нашел. Там действительно 1000. Все правильно.
Не очень понятно что вы делаете, но нужно так
По поводу ответа:
получается так, я шлю для записи 10 0F E8 03 01 00 01 01 00 CRC - ID 10, запись, адресс 1000, 1 флаг, пишу 1 бит
в ответ при удаче должен получить 10 0F E8 03 01 00 CRC
а в случае неудачи 10 8F Код_ошибки CRC
Не очень понятно что вы делаете, но нужно так
пытаюсь передить 1 бит для записи )))
Спасибо за код, попробую
По поводу ответа:
получается так, я шлю для записи 10 0F E8 03 01 00 01 01 00 CRC - ID 10, запись, адресс 1000, 1 флаг, пишу 1 бит
в ответ при удаче должен получить 10 0F E8 03 01 00 CRC
а в случае неудачи 10 8F Код_ошибки CRC
А что получаете в реале ?
завтра только смогу ответить
... но нужно так
наскоком ничего не вышло ((( запись не прошла. нарыл вот такую вещь https://intenso.name/index.php/icpdas/248-i7561
завтра попробую им прочитать/записать.
Возможно у меня ошибка в схеме?
Собрано все так:
Выход Data(+) ВМЦ подключен ко входу А, выход Data(-) к В
Косяк, возможно, еще и в строке
видимо надо
Косяк, возможно, еще и в строке
видимо надо
Надо, очень надо.
Если у Вас есть Proteus, то можно отладить работу схемы виртуально.
Для этого нужен набор ПО:
- Eltima Software Serial Port Monitor (видит обмен на последовательной линии);
- com0com или 2 реальных COM порта, соединённых нуль-модемным кабелем;
- Modbus PLC Simulator или Modbus Slave (Witte Software).
Всё искать в сети самостоятельно. В Proteus есть компонент COMPIN, который позволяет делать вывод Rx/Tx на реальный последовательный порт. Нужна программа-симулятор salve устройства, второй порт и нуль-модемный кабель.
В принципе, чтобы проверить только передачу, я думаю достаточно одного Serial Port Monitor, в котором просто слушать передающий порт. Там хоть пакет увидите, который формируется.
Отладка Modbus RTU протокола - штука, требующая дополнительные программные/аппаратные средства и время.
Кстати, сам Proteus тоже имеет "осциллограф", на котором можно посмотреть что на выходе мк происходит. Нужно только знать как работает UART, чтобы декодировать передаваемые символы.
надо, очень надо.
С этой строкой меня товарищ VaDoSiQ из http://arduino.ru/forum/programmirovanie/rabota-s-modbus-rtu знатно потролил: то Modbus master(0,0,0); то Modbus master(0,0,10); потом опять Modbus master(0,0,0); и главное пишет, что код у него работает )))) Совсем запутал. Заполночь гуглил и выяснял.
Если у Вас есть Proteus, то можно отладить работу схемы виртуально.
...
Спасибо за подробный расклад. За Proteus ничего не знаю. Вчера возникла надобность нарисовать схему соединения вот и установил ее. Подкупила красивость картинок в нем. А уж потом посмотрел пару видео про симуляцию. Так что протеус это на потом )
Сегодня попробую погонять запросы с эмулятором Modbus мастер-устройства
Ахтунг! Все что знал или пришло в голову перепробовал. QModBus все замечательно передает и принимает, ВМЦ откликается. Но вот скетч даже не читает данные! (((((
Что еще проверить?
Можно ли как-нить проверить что возвращает ВМЦ? Смотрел компорт - так там какие-то кубики идут, видимо библиотека модбаса туда что-то шлет
Я писал, что посмотреть можно при помощи Serial Port Monitor. Он позволяет прослушивать последовательные соединения на ПК в различном виде.
В Termite я вижу, что посылаю правильные запросы, вот ответа там не вижу
Погуглю "Serial Port Monitor", спасибо
Посмотрел, в принципе вижу то же самое что и в Termite т.е. отправляемые запросы, а вот ответы, как в случае с QModBus, не вижу.
Нужен вид dump только, где показаны непосредственно данные. И выложите ещё раз тестовую программу с указанием откуда взята библиотека modbus.
кажет такую картину (что и Термит показывает)
последний вариант скетча чуть выше: #27
а библиотеку брал тут: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino
интересная картинка:
а в библиотеке modbus первой строкой и не пахнет
Нужно проверять работу max485 на вашем модбас шилдике. У китайцев была большая партия глюка. Лечилось только заменой max485.
Потому что запрашиваете по 1 регистру, а не два сразу.
Раз у вас есть QModBus, то можно проверить работу на приём для Arduino. Попробуйте написать скетч для режима modbus rtu slave. Библиотека его поддерживает. Нужно поискать простые примеры для slave и протестировать работу преобразователя, подавая запросы с помощью QModBus.
Потому что запрашиваете по 1 регистру, а не два сразу.
Не факт, на чтение 1го регистра откликается так:
[28/03/2018 18:11:55] Written data (COM7)
Отвечу и на последние два вопроса. На двух шилдах проверил следующий код
На обоих слейв на ардуинке непрерывно слал пакеты, а QModBus, подключенный к нетбуку их отлавливал. Значит и шилд работает и как слейв вся схема работает.
У вас какая-то путаница в объяснениях.
> На обоих слейв на ардуинке непрерывно слал пакеты
Слейв не может ничего непрерывно слать, он может только отвечать на запросы и не более того. Slave - это сервер, он находится в режиме ожидания запросов. Хотя картинка с логом приведена правильная.
> Не факт, на чтение 1го регистра откликается так
Это не "отклик", это дамп запроса 1 регистра 4-й функцией с 1000 адреса.
У вас в #33 посту показано окно, в котором указано считывать 2 регистра, а в программе в #27 (и как видно по #32) делает запросы на чтение по одному регистру. Поэтому я и написал, что запросы по форме разные. В одном случае читается 2 регистра с одного адреса, а во втором по одному регистру с разных адресов.
Теперь скачайте программу симулятор Modbus Slave (http://www.plcsimulator.org/) и попробуйте её использовать как slave устройство, делая запросы к нему. Это примерно то же, что и с QModbus, только наоборот. На Arduino запустите свой скетч клиента (мастера), а на ПК симулятор. Покажите дамп обмена в Serial Port Monitor.
del
У вас какая-то путаница в объяснениях.
ну, не совсем, просто в процессе поиска решения проблемы и немного эмоцианирую
> На обоих слейв на ардуинке непрерывно слал пакеты
Слейв не может ничего непрерывно слать, он может только отвечать на запросы и не более того. Slave - это сервер, он находится в режиме ожидания запросов. Хотя картинка с логом приведена правильная.
Согласен и по-этому предлагаю следующую редакцию предложения "На обоих слейв на ардуинке непрерывно слал пакеты в ответ на запросы мастера"
> Не факт, на чтение 1го регистра откликается так
Это не "отклик", это дамп запроса 1 регистра 4-й функцией с 1000 адреса.
Эту ситуацию я понял так(начиная с поста #33), поправьте если ошибся. Имеем любой модбас мастер и сканер ком порта. Мастер шлет запросы, сканер их отображает. Сейчас не важно есть ответ от слейва или нет. Если даже ответ и есть, то он должен попасть в лог сканера. 1) Шлем запрос от масетра на ардуино - в сканере видим лог Read data 2) Шлем тот же самый запрос от QModBus и в ответ видим в логе того же самого сканера Written data и Read data! Это меня и удивило и потому написал "интересная картина". И делаю вывод, что мастер на ардуино что-то недосылает в порт, видимо по-этому и ВМЦ не отвечает, он просто не получает запросы. А от программного мастера получает и отвечает. И мое "не факт" на до относить к тому, читаю я один или два регистра все равно в порт попадает запись типа Written data. Собственно вопрос теперь: должен ли я видеть в логе сканера записи типа Written data и Read data при отправке запросов от ардуино?
У вас в #33 посту показано окно, в котором указано считывать 2 регистра, а в программе в #27 (и как видно по #32) делает запросы на чтение по одному регистру. Поэтому я и написал, что запросы по форме разные. В одном случае читается 2 регистра с одного адреса, а во втором по одному регистру с разных адресов.
тут все просто и с Вами я согласен. Я понимаю, что запросы разные и ответы разные...в скетче отдельно запрашиваются по одному регистры 1000 и 1001. QModBus-ом я читал и по одному регистру отдельно и вместе...видимо запутал Вас запостив картинку чтения двух портов сразу.
Теперь скачайте программу симулятор Modbus Slave (http://www.plcsimulator.org/) и попробуйте её использовать как slave устройство, делая запросы к нему. Это примерно то же, что и с QModbus, только наоборот. На Arduino запустите свой скетч клиента (мастера), а на ПК симулятор. Покажите дамп обмена в Serial Port Monitor.
Спасибо за советы. На день-два выехал в командировку, по возвращении сделаю и отпищусь.
> Собственно вопрос теперь: должен ли я видеть в логе сканера записи типа Written data и Read data при отправке запросов от ардуино?
Вообще говоря, Written data и Read data могут не соответствовать фактическим действиям на линии. Это зависит от "режима прослушивания". Я обычно не обращаю внимание на эти подсказки, а разбираю дамп по его содержимому. Зная протокол, всегда понятно где запрос, а где ответ, кроме некоторых частных случаев.
Теперь скачайте программу симулятор Modbus Slave (http://www.plcsimulator.org/) ...
Попробовал...хм...вот, что вижу:
Не совсем понял как работать с программой
1) не нашел окно для указания ID слейва
2) судя по названию используется протокол RS-232, а у меня выход с шилда RS-485
Правда иногда в логе проскакивали записи типа "reading regisr 1001", но стабильно их получать никак не удалось (
симулятор Modbus Slave (http://www.plcsimulator.org/)
так ничего от него и не добился. Вот, этот товарищ показывает наличие обмена:
У меня такие настройки:
Адрес сервера задавать не нужно, т.к. симулятор поддерживает все адреса - это квадратики снизу. Когда идёт обмен с конкретным адресом, то вокруг адреса появляется жёлтая рамка. Проверить наличие обмена можно "пассивно" (без открытия порта) с помощью Serial Port Monitor. При этом симулятор должен быть запущен.
Возможно нужно отключить RTS contorl.
У меня такие же настройки. По поводу ID слейва была такая мысль и я потыкал в каждый квадратик и сделал их красными, кроме нужного мне 10го - эфекта никакого. Попробую читать адреса с 40001, а не 1000 и 1001. Интересно, что когда я отключал ардуинку то строки типа Modem status тоже переставали сыпаться...
Красный - это имитация отключения сервера, чтобы проверить как реагирует клиент на отстутствие ответа. Читать адреса нужно как раз как есть - с 1000. Если нет данных в окне лога, то какая-то проблема с соединением.
> У меня такие же настройки.
Судя по титульной строке - нет. "R - en" - у меня такой надписи нет.
Судя по титульной строке - нет. "R - en" - у меня такой надписи нет.
пардон, не та картинка в посте. Я пробовал со всеми настройками...а теперь мэджик!
Ничего не менял со вчера, просто собрал и запустил!
А там где пропали запросы это я немного изменил скетч и все рухнуло! Собранный макет вообще не трогал! Вернул изменения обратно - нихрена не читает!
Этот слейв вроде как победил, видать не совсем драйвера сдружились на компьютере, тем не менее получаю четкую картину
но есть но - запросы идут только на чтение одного регистра, хотя в коде читаю оба, вот
между чтениями поставил задержку, думал быстро читаю. Эффекта нет. Чтение 1001 регистра нет нет ппроскакивает в логе, но только при первых итерациях цикла, далее запрос на 1001 просто пропадает. если завершить работу слейва и запустить его, то первым пойдет запрос на чтение 1001 регистра, а дальше везде 1000й