-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Здравствуйте,
имеется:
— MegaD-2561-31I15O-RTC
— MegaD-16I-XT
— Адаптер RS485-TTL-Auto
— теплосчетчик Danfoss Sonometer 500 с M-Bus (кабель с 2 проводами)
пытаюсь получить со счетчика показания, но проблема в том, что я не могу найти описание протокола M-Bus для него. в инструкции лишь сказано:
Теплосчетчик Sonometer 500 поставляется со встроенным M-bus модулем, предназначенным для подключения к распределенным сетям автоматизированного сбора данных. Передача данных осуществляется по кабелю типа медная витая пара с автоматически устанавливаемой
скоростью передачи 300 или 2400 бод.
и
Interfaces (already built-in)
— Optical: ZVEI interface as standard, for communication and testing, M-Bus protocol.
— M-Bus: Configurable telegram (via IZAR@SET software), according to EN13757. Data reading and parameterization are via two wires with polarity reversal protection.
пытался делать запросы типа
Код: Выделить всё
http://192.168.1.111/sec/?uart_tx=010300000020&mode=rs485 # получить 32 регистра с 0 адреса
но все время получаю ошибку
в чем проблема? можно ли как-то перебрать все возможные регистры/адреса? какие параметры можно менять и в каких интервалах, а какие не надо? всегда ли функциональный код должен быть 03? и SlaveId 01 (если у меня всего одно устройство)?
PS: + еще такой момент, у меня плата адаптера с обратной стороны выглядит примерно так:

как видно слева помимо А+ и В- есть еще третий контакт с иероглифами, позже выяснилось что это земля. сначала я его вообще не подключал (были ошибки CRC Error), потом подключил к тому же контакту, что и GND (и опять все те же ошибки CRC Error).
-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 06 июн 2022, 00:56
Petros писал(а): ↑
06 июн 2022, 00:36
A m-bus и modbus разве одно и то же?
Нет, не одно и то же.
Сразу не обратил внимание на фото адаптера. Адаптер RS485 не подойдёт. Нужен примерно вот такой адаптер:
- TTL-MBUS-Master-Slave-UART-MBUS.jpg_640x640.jpg (22.15 КБ) 1023 просмотра
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 06 июн 2022, 11:47
Petros писал(а): ↑
06 июн 2022, 00:36
A m-bus и modbus разве одно и то же?
что посоветовали в теме https://www.ab-log.ru/forum/viewtopic.php?t=1909 — то и заказал ![]()
d.v.ermakov писал(а): ↑
06 июн 2022, 00:56
Сразу не обратил внимание на фото адаптера. Адаптер RS485 не подойдёт. Нужен примерно вот такой адаптер:
TTL-MBUS-Master-Slave-UART-MBUS.jpg_640x640.jpg
искать на алиэкспрессе? и есть ли какая-нибудь инфа, как подключать его к меге и работать с ним?
Адаптер RS485 не подойдёт
речь о том что этот адаптер не подойдет? или о том, что другой протокол используется? просто в настройках uart меги есть только RS485…
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 14 июн 2022, 14:30
заказал вот это https://aliexpress.ru/item/33009939864.html (slave). нужен же именно slave, не master, верно?
так же раздобыл описание протокола для своего счетчика: https://disk.yandex.ru/i/Z1GXEGAx7FMOiw (на форуме, на который Вы дали ссылку, спасибо!)
d.v.ermakov писал(а): ↑
06 июн 2022, 22:17
RS485 и M-Bus имеют немного разную физическую часть. С точки зрения Меги они одинаковые (и то и другое — UART).
В предыдущую тему не вникал. Остальным простительно, M-Bus — редкость, и очень созвучен с MODBUS.
еще раз хочу повторить свой вопрос:
я к тому, что в меге в конфиге все равно надо будет указывать UART=RS485?
но для запросов надо будет использовать mode=raw вместо mode=rs485? https://ab-log.ru/smart-house/ethernet/megad-rs485
-
Andrey_B
- Администратор
- Сообщения: 5069
- Зарегистрирован: 18 мар 2011, 12:06
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
Andrey_B » 14 июн 2022, 15:05
В настройках UART выбирать RS485.
mode=rs485 отличается от режима raw только автоматическим подсчетом/проверкой CRC (CRC16 Modbus). Больше ничем.
В режиме raw нужно самостоятельно передавать CRC в том формате, в котором это предусматривает конкретный протокол.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 08 июл 2022, 17:11
d.v.ermakov писал(а): ↑
06 июн 2022, 22:17
Например, https://aliexpress.ru/item/33029994226.html
RS485 и M-Bus имеют немного разную физическую часть. С точки зрения Меги они одинаковые (и то и другое — UART).
В предыдущую тему не вникал. Остальным простительно, M-Bus — редкость, и очень созвучен с MODBUS.
пришла это плата, пытаюсь выбрать свой счетчик согласно протоколу mbus, но ответ всегда пустой.
решил спросить у продавца, правильную ли плату я заказал. https://aliexpress.ru/item/33009939864.html там их 2: TTL to MBUS Master и TTL to MBUS Slave, я заказывал вторую. вот что он ответил:
hi . you buy our item is Slave your meter is Slave . you need buy Master mbus only the master can communicate with the table
видимо все-таки неправильную..
если заказывать другую плату, вот что там сказано по поводу подключения:
1, VIN: power input port 5V-15V, the absolute maximum voltage can not exceed 18V, or damage the module
2, GND: systematically
3,RXD: external serial port (external device) RXD, high level
4, TXD: connect to the external serial port (external device) TXD, need external high
5,OVERLOAD: Short circuit indication output, the default high, short-circuit to low, can be left open
6, TTLVCC: TTL level voltage input, can not be left floating, you must input TTL level voltage
7, M: MBUS bus interface, the initial high level bus 30 ± 1V(customizable)Note:
1,TTLVCC input 3.3V, TTL signal is 3.3V;
TTLVCC input 5V, the TTL signal is 5V; input other TTL for the input level signal.
2, TTLVCC input voltage can not exceed VIN input voltage.
Other parameters:
Input voltage VIN:Power input port 5V-15V, the absolute maximum voltage can not exceed 18V
правильно ли я понимаю, что VIN подключаем к 5 — 12В, GND — земля, RXD/TXD к Р32/33, OVERLOAD (?) можно не подключать, TTLVCC к 3.3 — 5В?
-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 09 июл 2022, 21:22
Вы правы, нужна плата master, она питает шину M-Bus. Извините, что дал вам неверную ссылку.
Подключения вы описали верно.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 18 авг 2022, 23:02
спустя полтора месяца наконец пришла плата master, но немного поврежденная:

продавец сказал, что это не должно повлиять на работоспособность. подключил к меге, пытаюсь послать запрос, и в ответ опять ничего не получаю… можно ли как-то определить, получила ли мега ответ, но пустой, или ничего не получала?
-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 21 авг 2022, 21:43
c1tru55 писал(а): ↑
18 авг 2022, 23:02
подключил к меге, пытаюсь послать запрос, и в ответ опять ничего не получаю… можно ли как-то определить, получила ли мега ответ, но пустой, или ничего не получала?
Сколотый дроссель может быть причиной неработоспособности одного из источников питания на плате.
1) Нужно проверить все питания, как на плате, так и на шине.
2) Если хотите советов — давайте фото подключений.
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 22 авг 2022, 23:16
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
2) Если хотите советов — давайте фото подключений.
подключал все так же, как и обсуждали:
c1tru55 писал(а): ↑
08 июл 2022, 17:11
правильно ли я понимаю, что VIN подключаем к 5 — 12В, GND — земля, RXD/TXD к Р32/33, OVERLOAD (?) можно не подключать, TTLVCC к 3.3 — 5В?
VIN/TTLVCC подключал к 5V, OVERLOAD не подключал.
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
осциллографа нет, да и если бы был толку нет. мультиметром подключался к выходам платы M+ M-, почему-то напряжение в состоянии покоя (т.е. никаких запросов мега не шлет) сказало до 26V при входных 5V, не знаю норма это или нет. от греха подальше отключил от счетчика. убедиться бы как-нибудь, что со счетчика реально снять показания через M-Bus, а то сначала slave платой подключался, потом возможно поврежденной master платой, мб спалил там уже встроенный интерфейс ![]()
-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 23 авг 2022, 22:33
c1tru55 писал(а): ↑
22 авг 2022, 23:16
мультиметром подключался к выходам платы M+ M-, почему-то напряжение в состоянии покоя (т.е. никаких запросов мега не шлет) сказало до 26V при входных 5V, не знаю норма это или нет. от греха подальше отключил от счетчика.
26 вольт — это нормально: https://ru.wikipedia.org/wiki/Meter-Bus
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 25 авг 2022, 20:52
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
Сколотый дроссель может быть причиной неработоспособности одного из источников питания на плате.
1) Нужно проверить все питания, как на плате, так и на шине.
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
между выходами M+ и M- 26.9V. на другом конце витой пары, которая подходит к счетчику тоже 26.9V. когда я посылаю запрос через Мегу — напряжение на мультиметре немного меняется.
также продавец переслал ответ поставщика:
Supplier Reply
First, confirm whether the interface connection is correct. There are signs on the board, especially txd—txd means txd is connected to txd; rxd—rxd is rxd connected to rxd, and cannot be crossedIn addition, ttl vcc must be connected. It should be connected according to the picture. Make sure that all the interfaces are correct. Measure whether the voltage of m+ and m- is about 28v. If so, let the customer confirm whether the two lines from the module to the meter are connected. . Check the software agreement if everything is normal
Such as communication baud rate, verification, data correctness, etc.If the customer insists that the above questions are correct. You have to use tools to troubleshoot the problem. Use an oscilloscope to connect m+ and m-. Then send data. See if there is a waveform.
In addition, the customer is soldering the socket, so make sure the screws are tightened. If the power supply line is long, the external capacitor should be connected with a capacitor of 10uf or more. Make sure that the power supply ripple is relatively small.
в общем ничего нового, единственное речь про 28V, когда у меня 26.9V. ну и про конденсатор про большой линии питания, но линия питания от Меги у меня 15 сантиметров, а витая пара до счетчика ~ метров 8.
Согласно документации я посылаю запрос
(для selection secondary address с любыми serial number/manufacturer code/identification code/medium code), в ответ ожидаю получить
от счетчика, но ответа нет. Т.е. в одной вкладке открываю урл
Код: Выделить всё
http://192.168.1.111/sec/?uart_tx=680B0B6853FD52FFFFFFFFFFFFFFFF9A16
и после этого в другой открываю
но там всегда пусто. Не знаю, что еще сделать…
-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 05 сен 2022, 17:38
26.9 или 28, думаю, не очень важно. То, что мультиметр что-то показывает — значит запрос, скорее всего, идёт. Попробуйте поменять местами M+ и M-.
Где у вас проблема, понять сложно. Я это называю приёмом родов по телефону. Поверьте, фото многое могут решить. Либо берите осциллограф и смотрите сами.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 07 сен 2022, 18:11
не знаю почему, но сейчас напряжение между контактами М+ и М- у меня 1.0 — 4.6В. что-то явно не так, хотя между VIN/TTLVCC и GND на входе 4.93В. похоже плата окончательно сдохла.
фото подключения:

-
d.v.ermakov
- Сообщения: 1988
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 12 сен 2022, 14:03
По фото ваших подключений видно, что есть проблема. VIN должно быть от 5 до 15 вольт (я бы подключил 12). TTLVCC нужно подключать к 3,3 вольтам, это уровень сигналов микроконтроллера Меги. Поэтому, вероятно, обмен и не шёл.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 04 янв 2023, 19:37
заказал новую плату, подключил все как вы сказали, на выходах M+ и M- напряжение ~28 В. но все равно результата нет. что не посылай — ответ пустой, хотя должен быть не пустой (E5).
или я что-то не понимаю в протоколе MBus, либо у меня счетчик не может с ним работать. уже не знаю, что еще придумать…
PS:
1. как долго в буфере хранится ответ по ?uart_rx=1? и как быстро его можно получать? возможно ли, что я просто не попадаю во временной интервал для его получения?
2. какие настройки должны быть у портов P32 и P33?
3. в статье «MegaD-2561 в качестве шлюза RS-485/Modbus RTU — Ethernet» сказано
RO (Output) — P32 (RX)
DI (Input) — P33 (TX)
т.е. output соединяем с receive, input с transfer (!). правильно ли я соединяю
RXD — P32 (RX)
TXD — P33 (TX)
?
Протокол обмена данными ЛГК по RS-485
(на базе универсальной гироприставки УГП-1)
Версия 1.0.2
Протокол — под этим понимается, что между всеми устройствами согласованы:
- Модель передачи данных
(как организуется логика обмена, как формируются пакеты и т.д.) - Набор команд
- Структура данных каждой из команд
Параметры RS-485 устанавливаются заранее и не переконфигурируются во время работы. По умолчанию параметры задаются:
| Параметр | Значение |
|---|---|
| Baud rate | 115200 |
| Data bits | 8 |
| Parity | none |
| Stop bits | 1 |
| Flow control | none |
Передача данных
-
Модель передачи данных — запрос-ответ между Master — Slave.
-
Мастером является заранее определенное устройство в сети RS485.
-
Мастер посылает запрос, на который всегда должен быть получен ответ.
В случае отсутствия ответа, запрос посылается повторно до тех пор, пока ответ не будет получен. -
Ответ должен быть получен по возможности без задержки по времени.
-
Таймаут получения ответа — 0.3 секунды. Подразумевается, что причина задержки не ожидание исполнения операции
(см. след. пункт). В отсутствии ответа в течении тайм-аута, команда посылается повторно. -
Долгие операции разбиваются на несколько запросов. Если запрашиваемая операция не может быть выполнена
условно мгновенно (поворот прибора, сбор данных), используется несколько запросов. Типовая последовательность:- запрос начать операцию,
- запрос статуса операции,
- запрос результата после завершения.
-
Формат сообщений одинаков для запросов и ответов.
Формат запросов
-
Запросы/ответы (фреймы) передаются в текстовом* виде в кодировке UTF-8
-
Регистр имеет значение, как правило используются заглавные буквы
-
Каждый запрос и ответ имеет общий вид:
:[кому][от кого][сообщение][crc16];- Фрейм** начинается с символа
:и заканчивается символом; - [кому][от кого] — Адрес получателя (1 байт) и адрес отправителя (1 байт). Например ‘G’, ‘M’
- [сообщение] — Непустая строка переменной длинны
- 4 символа CRC16 в шестнадцатеричном виде. Например
0FC1. - CRC16 рассчитывается для
[кому][от кого][сообщение](т.е. конверта). Тип
- Фрейм** начинается с символа
-
Адреса мастера и устройств задаются заранее:
- Адрес мастера
'M' - Адрес гирокомпаса
'G'
- Адрес мастера
Пример:
:GMS45A7;
- G — [кому] — гирокомпасу
- M — [от кого]- от мастера
- S — [сообщение] — команда выдать статус
- 45A7 — [crc16] для
GMS
* — Текстовый формат имеет очевидный недостаток в увеличении размера сообщений.
В данном случае это не критично — объем данных мал, запросы идут сравнительно редко.
Преимуществом является простота в отладке и использовании.
** — Часть
: ... [crc16];— будем называть фреймом. Часть[кому][от кого][сообщение]— будем называть конвертом.
Тогда можно сказать, что при любом запросе/ответе передается фрейм, внутри которого — конверт, а внутри конверта — сообщение.
CRC16
В качестве CRC16 используется CRC-16/CCITT-FALSE
- width=16
- poly=0x1021
- init=0xffff
- refin=false
- refout=false
- xorout=0x0000
- проверка=0x29b1 (для uint8_t* = «123456789»)
- name=»CRC-16/CCITT-FALSE»
Реализации для C и C# приведены в дополнениях. Реализация для Rust из библиотеки rust-crc1
Пример обмена данными
- Мастер посылает запрос.
:GMS45A7;
Следует читать так: от мастера(‘M’) гирокомпасу (‘G’), команда выдать статус (‘S’)
- Получает ответ:
:MGS ML TR156 L1064 ... 9671;
Мастеру (‘M’) от гирокомпаса (‘G’) , Ответ на запрос статуса (‘S’).
ML TR156 L1064 ... — данные статуса. Расшифровка приведенных данных:
- M<L> — Mode longitude — идет измерение с заданной широтой
- TR — Remaining time — рассчетное время до окончания измерений в секундах
- L — Life time — время с момента включения прибора в секундах
Правила формирования сообщений
(Из общего вида :[кому][от кого][сообщение][crc16]; данный параграф рассматривает часть — [сообщение])
-
Первый символ/байт сообщения определяет тип сообщения (команду) и дальнейшие данные, если они есть.
Сообщение может состоять из одного символа, но не может быть пустым.
Например: сообщение (‘S’) — команда выдать статус. (‘V’) — команда выдать версию -
После первого символа могут идти необходимые дополнительные данные.
Их форма определена только типом сообщения (и, разумеется, протоколом). -
Общие правила по формированию сообщений:
- 1-й символ ответа соответствует первому символу запроса (команде):
:GMS45A7; // S - запрос статуса :MGS ML TR156 L1064 ... 9671; // S - ответ с данными статуса- Если данные в сообщении содержат несколько полей, они разделяются пробелом,
а в начале каждого поля ставится символ-аббревиатура поля:
:MGS ML TR156 L1064 ... 9671; // ML, R156,... - поля. Символы M, R определяют, что это за поля- double.NaN передается, как ‘—‘ (два тире):
:MGD I0 R0 C0 TS0 MI L-- A-- IL-- IT-- E0 S087CA; // L - широта, '--' означает, что значение double.NaN
Управление ЛГК
Список запросов к ЛГК
| Команда | Расшифровка | Описание |
|---|---|---|
| V | Version | Запрос версии протокола и ПО |
| S | Status | Запрос статуса |
| M | Mode | Начать/остановить измерение |
| D | Data | Запрос последних результатов измерения |
| C | Constants | Запрос/запись корректировочного угла (и прочих констант) |
Алгоритм работы с ЛГК
-
После включения питания ЛГК, начинается опрос статуса (команда S). ЛГК начинает отвечать через 10-30с с момента подачи питания. Первоначально запрос статуса используется для опредления включения ЛГК.
(рекомендуемая частота опроса статуса — 1 раз в секунду). -
После получения первого ответа на запрос статуса, запрашивается версия протокола (команда V).
-
После включения ЛГК находится в режиме ожидания. Продолжается периодический опрос статуса.
-
По запросу оператора, посылается команда — начать измерение (команда GMML или GMMA)
-
С этого момента запрос статуса позволяет отслеживать ход измерения. Сколько осталось времени, нет ли ошибок.
-
Так же с момента запуска можно отслеживать ход измерения запрашивая данные * (команда GMD)
(рекомендуемая частота опроса данных — 1 раз в секунду). -
Когда данные готовы (или даже раньше**) используется та же команда на выдачу данных (команда GMD).
-
ЛГК находится в режиме ожидания. Продолжается периодический опрос статуса.
* Команда выдачи данных может быть вызвана в любое время (полное описание ниже). В качестве результата она возвращает последнее состояние данных. В момент начала измерения данные сбрасываются, а ID данных увеличивается на 1. После измерения (когда прибор вовзращается в режим ожидания) выдаются показания последнего измерения.
** — ЛГК начинает выдавать данные азимута и углов наклонов ДО того, как закончится измерение, с пометкой, что
данные не точны. Нет общих рекомендаций, необходимо ли выводить оператору такие данные. Для некоторых задач
бывает важно быстрее выдать данные хоть и с неполной точностью, а затем, по возможности,
ждать их сходимости. В других случаях лучше «не отвлекать оператора» данными, которые могут быть не точны.
Описание команд
Версия протокола (V)ersion
Команда — V
Ответ:
V P<major>.<minor>.<micro> F<major>.<minor>.<revision>
Пример обмена:
:GMV1502;
:MGV P1.0.0 F2.8.18 41EA;
- P — Protocol — Номер версии протокола (см. ниже описание)
- F — Firmware — Номер версии ПО
Описание:
Версия протокола состоит из 3-х цифр <major>.<minor>.<micro>, Например: 01.02.234
Общее правило версии протокола: любое изменение протокола (способа передачи данных, набора команд или структуры
данных любой из команд) должно сопровождаться какой-то сменой цифр версии протокола !
Когда изменяются major, minor и micro
<major> — Смена <major> соответcтвует ситуации, когда устройства больше не могут расшифровать
сообщения друг друга из-за изменений в протоколе обмена.
Например: Если шифрование фрейма сменится на COBS или COBS/r, должна быть изменена
<major>версия протокола.
<minor> — Соответствует общей согласованности списка команд и данных этих команд. Мастер и устройства одинаковой версии с одинаковой <major>.<minor> должны без ошибок понимать и уметь общаться друг с другом. Если это правило меняется, <minor>версия должна быть увеличена.
Например: В версии 01.02.01 оговорено, что команда ‘S’ — получить статус. В ответе 1-й символ — это флаг статуса ‘S’, время работы устройства определяется, как ‘T[время]’. Это значит, что в любой версии 01.02.xx на запрос S ответом будет статус, а данные статуса будут иметь вышеуказанный флаг и времени работы.
<micro> — Соответствует полной согласованности команд и опциональных добавок в структуры данных.
Например: В версии 01.02.01 оговорено (как и выше), что ‘S’ — команда статуса, структура ответных данных 1 символ ‘S’, ‘T[время]’ время работы. В версии 01.02.02 решено добавить в данные статуса ‘E[код]’ с кодом ошибки.
Когда: Мастер со старой версией (01.02.01) общается с устройством версии 01.02.02, он может запросить статус и декодировать данные нового устройства. Про добавленное поле с кодом ошибки он ничего не знает и пропустит его.
Когда: Мастер с новой версией (01.02.02) общается с устройством версии 01.02.01, при запросе статуса он, зная, что общается с устройством старой версии, не будет пытаться извлечь добавленный код ошибки.
Когда эти условия выполнены, может быть изменена только <micro> версия протокола.
Статус (S)tatus
Команда — S
Ответ:
S M<Mode> L<LifeTime> P<Parked> R<RemainTime> E<Error> O<Operation>
(!) Последовательность значений после начального ‘S’ в ответе может быть различной.
Т.е. принимающий парсер должен опираться на M, L, P и т.д., а не на очередность значений.
Описание:
- M — Mode — Режим работы/измерения может принимать следующие значения
- I — Idle — Прибор находится в режиме ожидания
- L — LatitudeMeasure — Прибор в режиме измерения с заданной широтой
- A — AutoMeasure — Прибор в режиме измерения с автоматическим определением широты
- T — Test — Прибор в режиме самотестирования
- L — LifeTime — Время в секундах с момента включения прибора
- P — Parked — Парковка. 1 — прибор припаркован *, 0 — не припаркован.
(!) ВАЖНО — Прибор паркуется автоматически в течении нескольких секунд (не более 10) после окончания измерения.
Пока прибор не припаркован его нельзя транспортировать. Поэтому важно дать оператору понять, когда можно отключать
и транспортировать прибор! - TR — Time Remaining — Рассчетное время до конца измренеия, если оно выполняется (иначе 0).
Реальное время измерения может отличатся. - E — Error — Ошибки (может быть несколько одновременно) и неисправности в работе прибора.
При исправности выводится ‘0’- F — Fixation error — Прибор плохо закреплен. (Для исправления ошибки перезакрепить прибор)
- H — High Noise — Плохие условия работы (внешние факторы), идет отбраковка значений из-за внешних помех. Как правило, ошибка не является признаком неисправности прибора, а служит для определния и устранения внешних факторов, приводящих к увеличению разброса показаний. Например, работа с ЛГК с незаглушенным двигателем, установка ЛГК на хлипкое основание, сильные ветровые нагрузки и т.д — могут приводить к индикации ‘H’.
- E — ERROR — Прибор имеет механическую или электрическую поломку и нуждается в ремонте
* — Парковка — механический упор, в который должен вставать лазерный гироскоп (находящийся внутри гирокомпаса)
во время транспортировки. Прибор автоматически встает в режим парковки после окончания измерений, однако ему необходимо
на это несколько секунд (до 10-и). Поэтому сразу после проведения измерений нельзя отключать прибор, не дождавшись
парковки. В противном случае прибор может разъюстироваться во время транспортировки или даже выйти из строя.
Пример обмена:
:GMS45A7;
:MGS ML TR156 L1064 P0 E0 6BC2;
Стоит читать как:
ML — прибор находится в режиме измерения с заданной широтой. TR156 — до конца измерения осталось предположительно
156 секунд. L1064 — с момента включения прибора прошло 1064 секунды.
P0 — прибор нельзя транспортировать (надо завершить измерение и дождаться парковки). E0 — ошибок нет.
:GMS45A7;
:MGS MI R0 L1064 P1 EFE C9B6;`
MI — ЛГК в режиме ожидания команд, R0 и O0 — можно игнорировать.
L1064 — с момента включения прибора прошло 1064 секунды. P1 — прибор готов к транспортировке.
EFE — есть 2 ошибки в работе: F — прибор плохо закреплен,
Е — самотестирование показывает наличие неисправимых проблем, необходим ремонт прибора.
Начало/остановка измерения (M)ode
Команда — M
Запрос:
M<Mode> T<Time> L<Latitude>
Между M и <Mode> может быть пробел.
Ответ:
M<Mode> T<Time> L<Latitude>
(!) Последовательность значений после начального ‘S’ в ответе может быть различной.
Т.е. принимающий парсер должен опираться на M, L, P и т.д., а не на очередность значений.
Описание:
-
M — Mode — Режим в который нужно перевести прибор
- I — Idle — Режим ожидание. Остановка измерения (если оно шло).
- L — LatitudeMeasure — Начать измерение с заданной широтой. В этом случае отдельно надо передать L
- A — AutoMeasure — Начать измерение с автоматическим определением широты
- T — Test — Начать режим режим самотестирования
Ниже приведены примеры запроса каждого из режимов
-
T — Time — Запрашиваемое время измерения в секундах. Если параметр не присутствует, используется 600с.
-
L — Latitude — Широта в градусах (!). Обязано задается в случае режима LatitudeMeasure (т.е. ML)
Фактически ответ всегда повторяет запрос. Это должно быть использовано для проверки корректности обмена данными
(т.е. что запрос принят правильно)
Переключение между режимами:
Каждый раз, когда приходит команда «М», текущий режим меняется или перезапускается.
-
Если во время измерения приходит команда MI (Mode Idle), измерение останавливается,
прибор уходит на парковку и переходит в режим ожидания. Т.е. Mode Idle может использоваться, как команда «СТОП».
(Если прибор уже в режиме ожидания, команда Mode Idle ничего не делает). -
Если идет измерение и приходит команда на измерение с другими настройками, измерение перезапускается с этими настройками.
-
(!) ВАЖНО — Если во время измерения приходит та же команда на проведение измерения в том же режиме с теми же
настройками — измерение перезапускается (заново!)
Примеры:
1. режим ожидания
Запрос :GMMI46F0;
Ответ :MGMIE99A;
MI — перевести прибор в режим ожидания. Если прибор в данный момент проводил измерение, оно будет остановлено.
2. режим измерения с заданной широтой
Запрос :GMML L55.751244 T300 B479;
Ответ :MGML T300 L55.751244 759C;
ML — перейти в режим измерения с заданной широтой.
L55.751244 — широта в градусах
T300 — Время измерения ~300 секунд.
Ответ подтверждает, что прибор переведен в нужный режим с заданными настройками.
3. измерение с автоматическим определением широты
Запрос :GMMA T450 0B8C;
Ответ :MGMA T450 BD50;
MA — Начать измерение с автоматическим определением широты
T450 — Время измерения ~450 секунд.
Запрос данных (D)ata
Команда — D
Ответ:
D I<Id> R<Ready> C<Completeness> TS<TimeOfStart> M<Mode> L<Latitude> A<Azimuth> IL<Incline> IT<Incline> E<Error> S<SupervisionResults>
Описание:
- I — Id — Идентификатор измерения. Увеличивается на 1 каждый новый запуск измерения.
- R — Ready — 1 — измерение завершено, данные готовы и точны. 0 — данные не точны.
- C — Completeness — Прогресс измерения в процентах. 0 — измерение начато, 100 — данные готовы
- TS — TimeOfStart — Время начала измерения в секундах (от времени жизни прибора, см. запрос статуса)
- M — Mode — Режим измерения (см. М или S)
- L — Latitude — Широта в градусах. Если измерение с заданной широтой, то заданная широта. Иначе — измеренная.
- A — Azimuth — Азимут в градусах. Измеренное значение азимута
- IL — InclinationLong. — Значение продольного угла наклона в градусах.
- IT — InclinationTrans. — Значение поперечного угла наклона в градусах.
- Е — Наличие ошибок во время измерения. Е0 — ошибки отсутствуют. Список ошибок см. запрос статуса (команда S).
- S — Результат проверки измерения на возможные неточности (см. следующий пункт)
Данные могут быть запрошены в любой момент работы прибора. Возвращаются данные последнего проводимого измерения.
Если измерений не было, то вернутся данные с Id=0 и всеми значениями ‘—‘ (аналог double.nan)
Результат проверки измерения:
После заврешения измерения, результат проходит проверку на возможные неточности.
Флаги возможных ошибок передаются в ответе на запрос данных после символа S.
S0 — ошибки отсутствуют, результаты точны.
В одном измерении может встречаться сразу несколько из перечисленных ниже проблем:
-
F — низкая частота колебаний прибора.
Возможные причины — плохое закрепление прибора или низкое напряжение источника питания.
Данная ошибка скорее всего приведет к другим ошибкам и, как следствие, к неточному результату измерения азимута. -
D — результаты измерения скорости Земли отличаются от ожидаемых. Может приводить к неверным результатам азимута.
Рекомендация — перезапуск измерения. Если ошибка часто возникает, есть основания для проведения исследования прибора. -
L — результат не прошел проверку по широте. Может возникать только в режиме измерений с заданной широтой (ML).
Рекомендации — убедиться, что широта, передаваемая пользователем при запуске измерения, соответствует реальной широте местности, на которой находится прибор. Перезапустить измерение.
При выявлении данной ошибки высока вероятность неточного результата измерения азимута (отклонение порядка 20 угловых минут или больше).
Примеры:
Запрос :GMD2771;
Ответ :MGD I3 R1 C100 TS697 ML L55.43532 A132.5433 IL0.0234 IT0.5112 E0 S0CCA8;
- I3 — Id=3, R1 — данные готовы, TS697 начало измерения на 697 секунде с начала отсчета.
- L55.43532 A132.5433 IL0.0234 IT0.5112 — Широта, азимут, продольный и поперечный углы наклона.
- E0 — Нет ошибок во время измерения.
- ML — Режим измерения — по заданной широте.
- C100 — Прогресс измерения — 100%
- S0 — результат успешно прошел проверки на возможные неточности
Запрос :GMD2771;
Ответ :MGD I0 R0 TS0 MI L-- A-- IL-- IT-- E0 S02169;
Характерный ответ, если еще не было измерений с момента включения прибора.
Запрос :GMD2771;
Ответ :MGD I4 R1 C100 TS697 ML L55.43532 A132.5433 IL0.0234 IT0.5112 E0 SDFL4B44;
- I3 — Id=3, R1 — данные готовы, TS697 начало измерения на 697 секунде с начала отсчета.
- L55.43532 A132.5433 IL0.0234 IT0.5112 — Широта, азимут, продольный и поперечный углы наклона.
- E0 — Нет ошибок во время измерения.
- ML — Режим измерения — по заданной широте.
- C60 — Прогресс измерения — 60%
- SDFL — выявлено сразу 3 потенциальных проблемы: по скорости(D), по колебаниям(F) и по широте(L). Вероятность неточности полученно азимута крайне высока.
Запрос и запись констант (C)onstants
Команда — C
Опционально с SAC<AzimuthCorrection>
Ответ:
C AC<AzimuthCorrection>
Описание:
Команда позволяет записать в ПЗУ прибора корректировочный угол. Или считать ранее записанные, используемые значения.
В случае считывания, команда посылается без дополнительных данных:
Запрос :GMC5796; //Без доп. данных команда просто запрашивает текущие константы
Ответ :MGC AC0.004 A4D3; //В настоящий момент корректировочный угол 0.004 градуса
Возвращаемые значения:
- AC — Azimuth Correction — Корректировочный угол в градусах. Установленное значение всегда прибавляется/вычитается
к измеренному значению азимута.
Для записи корректировочного угла дополнительно передается SAC<AzimuthCorrection> — Set Azimuth Correction
Запрос :GMC SAC0.005B8A1; //Записать в ПЗУ прибора корректировочный угол 0.005 градуса
Ответ :MGC AC0.005B4F2; //Записан угол 0.005 градуса
При записи, старое значение перезаписывается.
Так как данные записываются в ПЗУ прибора, данная команда не используется при автоматическом управлении ЛГК,
а только во время пуско-наладочных работах, при установке ЛГК на целевую платформы (либо при последующей коррекции).
Обработка ошибок обмена данных и исключительных ситуаций
Ошибки передачи сообщений
В общем случае, при ошибке, связанной с обменом сообщениями, ЛГК не отвечает или возвращает сообщение E<данные>
(подробнее ниже). В этих случаях необходимо заново посылать тот же запрос в ЛГК, до тех пор, пока не будет получен
правильный ответ.
Пример с точки зрения запрашивающего устройства:
Запрос :GMS45A7;
Ожидание 0.2 сек... TimeOut
Запрос повторно :GMS45A7;
Ответ :MGECRCFFD1; - ECRC = Ошибка, не сошлась контрольная сумма
Запрос повторно :GMS45A7;
Ожидаемый ответ :MGS ML R156 L1064 P0 E0 9671;
Алгоритм ответа ЛГК на ошибки передачи данных:
-
В случае, если сообщение повреждено/искажено/неправильно так, что адрес [от кого] искажен или неизвестен,
ЛГК не отвечает на запрос. Т.е. со стороны запрашивающего мастера будет TimeOut и сообщение необходимо послать повторно. -
В случае, если адрес запрашивающего устройства (мастера) не искажен и определн правильно, но само сообщение искажено
или не может быть правильно расшифровано, устройство возвращает ответ с сообщениемE<данные>, где «данные»
описывают ошибку:-
CRC — CRC16 — Контрольная сумма не сходится.
-
U — unknown command — Неизвестная команда.
-
D — Data — Ошибка в формате/задании данных команды. Как правило, дальше идет текстовое описание ошибки.
// (В запросе на измерение с заданной широтой не задана широта) Запрос :GMD0F7B; Ответ :MGED NO LATITUDE GIVEN15E0;
-
Таким образом можно составить таблицу:
| Ответ | Причина | Решение |
|---|---|---|
| Нет ответа | Сообщение не получено ЛГК или сильно искажено | Послать запрос повторно |
| Нет ответа постоянно | Прибор выключен или кабель поврежден | Включить прибор, проверить кабель |
| ECRC | Не совпадает контрольная сумма | Послать запрос повторно |
| ECRC постоянно/часто | Не совпадает контрольная сумма. Постоянно/часто искажаются данные | Проверить кабель |
| EU/ED однократно | Неправильно прочитана команда | Послать запрос повторно * |
| EU постоянно | Неизвестная команда. Возможно, неправильно реализуется протокол обмена | Проверить реализацию протокола обмена |
| ED постоянно | Ошибка в формате данных. Возможно, неправильно реализуется протокол обмена | Проверить реализацию протокола обмена |
* — CRC16 допускает возможность случайного совпадения, поэтому нельзя исключить ситуацию, когда команда передана с
ошибкой, но контрольная сумма совпала. Поэтому после однократного возникновения ошибок EU/ED можно повторно послать
команду. При постоянном появлении этой ошибки — проверить реализацию протокола.
Отслеживание перебоя питания ЛГК
В режиме ожидания — потребление ЛГК снижено (в режиме ожидания и пониженного потребления
ЛГК оказывается сразу после включения ). Только через некоторое время после начала измерения потребление ЛГК
может возрастать (в режиме ожидания потребление ~10 Вт, во время измерения пиковое потребление может быть ~30Вт)
Если при этом ЛГК подключен к сети с пониженной мощностью (разряженный аккумулятор, неправильно
выставленный регулятор силы тока), то из-за недостатка питания ЛГК может перезагрузиться. Так как ЛГК не имеет
собственных батарей, возможности самостоятельно отслеживать причину такого перезапуска не предусмотрено.
С точки зрения управляющего модуля, картина может выглядеть так:
-
ЛГК подключен с разряженному аккумулятору (или прочие причины подключения к сети с недостаточной мощностью)
-
После включения ЛГК находится в режиме ожидания с пониженным потреблением. ЛГК выходит на связь и штатно
отвечает на все запросы. -
На команду начать измерение ЛГК отвечает правильно. Некоторое время после начала измерения, он работает в штатном
режиме, правильно отвечая на запросы статуса. -
Через некоторое время, когда потребление возрастает и сеть не может это обеспечить, ЛГК выключается,
потребление снижается, ЛГК включается заново в режиме ожидания. Т.е. перезапускается. В течении ~15 секунд ЛГК
недоступен. На запросы статуса нет ответа. -
ЛГК находится в режиме ожидания после перезагрузки, отвечает на запросы статуса, но, очевидно, никакого измерения
не происходит.
Отработка такой ситуации должна быть заложена в запрашивающее устройство. Есть разные способы решения этой задачи.
Для индикации перезагрузки удобно использовать «время жизни» прибора — время в секундах с момента включения,
которое передается после запроса статуса. Так же в запросе данных есть поле — Id измерения, которое будет равно нулю,
сразу после включения (перезагрузки) прибора.
Изменение в версиях
Версия протокола 1.0.2
В ответе на запрос данных добавлена информация о проверки результатов на возможные неточности.
См. раздел Запрос данных (D)ata
Версия ПО 2.08.24
Изменения в версии ПО — Исправлены ошибки:
- Первые несколько секунд посла старта нового измерения значение выполненности измерения сохраняется из прошлого измерения.
- Команда запроса констант
GMCвозвращает правильное значение коррекционного угла только после запуска хотя бы одного измерения.
Здравствуйте!!! Проблема при работе с Moxa DE-311 при работе по ELAM протоколу. Moxa работает по широполосному беспроводному каналу по UDP протоколу. На удаленном объекте стоит контроллер Лафкин с которого необходимо выгружать конфигурационные данные, на сервере делаем процедуру upload, однако приходит ошибка CRC error, хотя отдельные регистры запрашиваются. Данные весят 1654 байта и запрашиваются одним махом. Возможна проблема в настройках Moxa, но в каких пока понять не могу. Подскажите плииз в чем может быть проблема. Чуть ниже представлены «логи» при опросе контроллера. Заранее благодарен!!!!
02.09.2009 12:43:07 Порт: 15 NodeID: test1_centrmodem
Query: F8 34 03 08 80 03 3B 60 10
02.09.2009 12:43:07 Порт: 15 NodeID: test1_centrmodem
Reply: F8 34 03 06 76 2E 18 14 A0 00 00 01 2C 00 5A 00 00 00 00 00 00 00 00 00 00 00 28 00 C8 00 64 00 00 27 10 00 00 07 D0 00 00 00 01 00 01 00 00 00 00 00 05 00 00 00 05 00 0A 00
02.09.2009 12:43:07 Порт: 15 NodeID: test1_centrmodem
Status:CRC Error
Добрый день,
Боюсь, проблему решить не удастся.
Дело в том, что DE-311 (как и другие устройства марки NPort) передают в одном Ethernet-пакете максимум 1024 символа. Более длинные сообщения разбиваются на несколько Ethernet-пакетов. Разумеется, в таком случае неизбежна пауза между пакетами, т.е. между частями сообщения. Видимо, приложение, принимающее данные с контроллера, видит эту паузу и трактует сообщение не как единое целое, а как два разных. Отсюда и ошибки в контрольной сумме.
Я подозреваю, что указанную проблему принципиально решить невозможно. Максимальный размер Ethernet-кадра 1518 байт, так что «запихать» всё сообщение в один кадр не удастся.
Topic: CRC Error with Modbus Test on RS485 against a Teco SG2-20VR-D (Read 18971 times)
0 Members and 1 Guest are viewing this topic.
I am trying to interface a Teco SG2-20VR-D (user manual here: http://www.bb-elec.com/bb-elec/literature/manuals/SG2PLR_UserManual_0707m.pdf and modbus manual here: http://www.bb-elec.com/bb-elec/literature/manuals/SG2_V-typeModbusProtocol_0807.pdf) with Mach3.
Here is what I’ve done so far:
* Configured the unit to have slave address «02» using the «LAD Version 1.9» using the RS-232 interface (separate from 485)
* Installed 120ohm resistors on the 485 line
* Configured a USB to 485 adapter to COM6
* Under the «Modbus Confugration» screen, Port Num: 6, Baud Rate: 38400 8-2-N, Do NOT use RTS for transmit, Timout of 1500ms
* Click the «Test Modbus» button
* Port Num: 6 and Baud Rate: 38400, Slave Addr: 2, Start: 100 (hex), Num Regs:1, input registers
* Click «Open» and it responds «No error»
Here are my questions:
* Why is there no option for stop, parity and data bits on the «ModBus Serial Control Monitor» page?
* Why would you need to re-enter Port Number and Baud Rate again on the monitor page if it’s on the Configuration page?
* What does the slider bar under Discrete Input(s) do?
* What is occuring when you click «Report Slave ID» and «Read Excp Stat» buttons? When clicking «Report Slave ID» mach3 returns «receive timeout».
* Why do I get «CRC Error» when I attempt to read?
* Is there a difference between slave address «1» and «01»?
* My PLC uses RTU, not ASCII — is Mach3 using RTU or ASCII? Is it configurable?
* Is there any simple way to peek at the data on the 485 serial line?
On a side note… I’ve watched the modbus videos and read everything I could find on the mach site with the word «modbus».
Thanks!

Logged
Dmoore,
I scanned thru the pdf doc on the SG2-20VR-D on controller and what I see is the modbus is used to communicate between the base and expation I/O units only
because the base unit is a master and the expation units are slave with mach and modbus mach3 has to be the master so I don’t think that it can be done thru mach

Logged
Adam
Dmoore,
did you get the SG2-MODBUS communications module for communicating modbus
also what are you using for the USB converter

Logged
Adam
did you get the SG2-MODBUS communications module for communicating modbus
also what are you using for the USB converter
I have so far tried three different USB to 485 converters — the current one is a $160 unit from B&B Electronics — if theirs doesn’t work I’d really be suprised.
I scanned thru the pdf doc on the SG2-20VR-D on controller and what I see is the modbus is used to communicate between the base and expation I/O units only
because the base unit is a master and the expation units are slave with mach and modbus mach3 has to be the master so I don’t think that it can be done thru mach
Can you tell me where in the doc’s you read that the PLC is a master? On the first page of the documentation I linked (the MODBUS protocol one), it shows a diagram with the «controller» PLC/ HMI or PC) and then shows the «SG2» (the PLC in question) as the slave. It even says in the first line «SG2 series PLC can be communication controlled by the PC or other controller with the communication protocol, Modbus RTU Mode, RS485». So I’m pretty sure that Mach3 as the master should have no problem obtaining data from the PLC. Any thoughs?

Logged
I am trying to interface a Teco SG2-20VR-D (user manual here: http://www.bb-elec.com/bb-elec/literature/manuals/SG2PLR_UserManual_0707m.pdf and modbus manual here: http://www.bb-elec.com/bb-elec/literature/manuals/SG2_V-typeModbusProtocol_0807.pdf) with Mach3.
Here is what I’ve done so far:
* Configured the unit to have slave address «02» using the «LAD Version 1.9» using the RS-232 interface (separate from 485)
* Installed 120ohm resistors on the 485 line
* Configured a USB to 485 adapter to COM6
* Under the «Modbus Confugration» screen, Port Num: 6, Baud Rate: 38400 8-2-N, Do NOT use RTS for transmit, Timout of 1500ms
* Click the «Test Modbus» button
* Port Num: 6 and Baud Rate: 38400, Slave Addr: 2, Start: 100 (hex), Num Regs:1, input registers
* Click «Open» and it responds «No error»Here are my questions:
* Why is there no option for stop, parity and data bits on the «ModBus Serial Control Monitor» page?
* Why would you need to re-enter Port Number and Baud Rate again on the monitor page if it’s on the Configuration page?
* What does the slider bar under Discrete Input(s) do?
* What is occuring when you click «Report Slave ID» and «Read Excp Stat» buttons? When clicking «Report Slave ID» mach3 returns «receive timeout».
* Why do I get «CRC Error» when I attempt to read?
* Is there a difference between slave address «1» and «01»?
* My PLC uses RTU, not ASCII — is Mach3 using RTU or ASCII? Is it configurable?
* Is there any simple way to peek at the data on the 485 serial line?On a side note… I’ve watched the modbus videos and read everything I could find on the mach site with the word «modbus».
Thanks!
Hi,
The answer to your questions;
* Why is there no option for stop, parity and data bits on the «ModBus Serial Control Monitor» page?
— It is on the previous setup page.
* Why would you need to re-enter Port Number and Baud Rate again on the monitor page if it’s on the Configuration page?
— Decause that’s the way it is.
The page is probably copied from an appication supplied by the Modbus library provider,
* What does the slider bar under Discrete Input(s) do?
— It allows you to continuously read the data, instad of having to press the read button. The further to the right it is the fast uit reads.
* What is occuring when you click «Report Slave ID» and «Read Excp Stat» buttons? When clicking «Report Slave ID» mach3 returns «receive timeout».
— It is sending the Modbus command Report Slave ID. Your device does not implement it, so it does not respond, hence the timeout.
* Why do I get «CRC Error» when I attempt to read?
— Excellent question. This is the cause of your problem most likely.
* Is there a difference between slave address «1» and «01»?
— No.
* My PLC uses RTU, not ASCII — is Mach3 using RTU or ASCII? Is it configurable?
— Mach is only RTU. Does not do ASCII
* Is there any simple way to peek at the data on the 485 serial line?
— Not really. What you could do is download the trial version of Modbus Poll and try to use that to talk to your devicce. It can display what is being received and may help in solving your problem.
Cheers,
Peter.
Cheers,
Peter.
Peter —
Thank you very much for your information — it’s been a great help!

Logged
I finally got MODBUS working with Mach3. Listed below are some of my tips for things that may not be obious if you are new to ModBus:
* First, understand what a bit, byte and word are: http://en.kioskea.net/contents/base/binaire.php3
* Second, download ModScan32 and get it working BEFORE you work with Mach3. ModScan32 allows you to see the actual input and output coming from the mobus device. It can be found in a demo version here: http://www.win-tech.com/html/modscan32.htm
* Third, within ModScan32, know that «Address» is decimal, so 0259 is 103 in hex — enter your address in decimal within ModScan32. This is also true for length which is in bytes.
* Be careful to read your modbus device’s instructions — you will be required to only request a certain amount of data from a given functiion code (say, 01 or 03) — if you get it wrong, the data will not be returned (or was the case for me)
* I like Mach3 — a great program but there are some really weird UI things that just don’t always make sense. This applies to modbus also. When you are in the «Modbus Serial Control Monitor», you have to re-enter the com port and baud rate (for reasons no one seems to know). Now, you see that «format» hex/decimal option? Has nothing to do with the slave/start/number of registers you are pulling — that is ALL entered in decimal, even if you have hex selected as the format. The format radio button is only for the output that is returned. Know that «Holding Registers» is really modbus function code 03.
Some specific information about the Teco SG2 unit:
* You NEED to get the serial cable — the unit can not be programmed via the MODBUS
* I’ve not yet found a way, out of the box, to change the baud and control, so make sure everything you intend to use can talk 38,400-n-8-2.
* Under the SG2 programming software/Operation menu bar/Module system set — The «Current ID» is the modbus slave ID. That «remote I/O» option with None/master/slave? Yea… it can be a slave even when it’s set as «none» which is it’s default setting. Better yet, set it to Slave to just be sure. Also, if you don’t have any add-on modules stuck in the side of the SG2 — I/O Num should be 0. And… make sure you are connected over serial when you read all these settings….
Best of luck!

Logged
Hi Dave,
I’m glad you finally got it working.
Cheers,
Peter.
hi Dave & peter
i’m working on Teco Modbus…
I tried pull out data from third party Modbus data- Not succesfull.
Happy that u got things right with this earlier
I want to pull the plc data to a hmi(Proface or Ge panels) , Where TECO should be slave.
Can u plz guide me in the address mapping (40001 blah blah etc) i dont find the manuals to convert DR to 40001 series at all..
i have to complete this by sunday..
help me out plz
And is it a must to use termination resistors een if we use only 1-1 connection in rs-485??
Thanks
Saran
« Last Edit: April 30, 2010, 04:13:16 PM by saran_ic »

Logged
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Здравствуйте,
имеется:
— MegaD-2561-31I15O-RTC
— MegaD-16I-XT
— Адаптер RS485-TTL-Auto
— теплосчетчик Danfoss Sonometer 500 с M-Bus (кабель с 2 проводами)
пытаюсь получить со счетчика показания, но проблема в том, что я не могу найти описание протокола M-Bus для него. в инструкции лишь сказано:
Теплосчетчик Sonometer 500 поставляется со встроенным M-bus модулем, предназначенным для подключения к распределенным сетям автоматизированного сбора данных. Передача данных осуществляется по кабелю типа медная витая пара с автоматически устанавливаемой
скоростью передачи 300 или 2400 бод.
и
Interfaces (already built-in)
— Optical: ZVEI interface as standard, for communication and testing, M-Bus protocol.
— M-Bus: Configurable telegram (via IZAR@SET software), according to EN13757. Data reading and parameterization are via two wires with polarity reversal protection.
пытался делать запросы типа
Код: Выделить всё
http://192.168.1.111/sec/?uart_tx=010300000020&mode=rs485 # получить 32 регистра с 0 адреса
но все время получаю ошибку
в чем проблема? можно ли как-то перебрать все возможные регистры/адреса? какие параметры можно менять и в каких интервалах, а какие не надо? всегда ли функциональный код должен быть 03? и SlaveId 01 (если у меня всего одно устройство)?
PS: + еще такой момент, у меня плата адаптера с обратной стороны выглядит примерно так:

как видно слева помимо А+ и В- есть еще третий контакт с иероглифами, позже выяснилось что это земля. сначала я его вообще не подключал (были ошибки CRC Error), потом подключил к тому же контакту, что и GND (и опять все те же ошибки CRC Error).
-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 06 июн 2022, 00:56
Petros писал(а): ↑
06 июн 2022, 00:36
A m-bus и modbus разве одно и то же?
Нет, не одно и то же.
Сразу не обратил внимание на фото адаптера. Адаптер RS485 не подойдёт. Нужен примерно вот такой адаптер:
- TTL-MBUS-Master-Slave-UART-MBUS.jpg_640x640.jpg (22.15 КБ) 1268 просмотров
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 06 июн 2022, 11:47
Petros писал(а): ↑
06 июн 2022, 00:36
A m-bus и modbus разве одно и то же?
что посоветовали в теме https://www.ab-log.ru/forum/viewtopic.php?t=1909 — то и заказал ![]()
d.v.ermakov писал(а): ↑
06 июн 2022, 00:56
Сразу не обратил внимание на фото адаптера. Адаптер RS485 не подойдёт. Нужен примерно вот такой адаптер:
TTL-MBUS-Master-Slave-UART-MBUS.jpg_640x640.jpg
искать на алиэкспрессе? и есть ли какая-нибудь инфа, как подключать его к меге и работать с ним?
Адаптер RS485 не подойдёт
речь о том что этот адаптер не подойдет? или о том, что другой протокол используется? просто в настройках uart меги есть только RS485…
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 14 июн 2022, 14:30
заказал вот это https://aliexpress.ru/item/33009939864.html (slave). нужен же именно slave, не master, верно?
так же раздобыл описание протокола для своего счетчика: https://disk.yandex.ru/i/Z1GXEGAx7FMOiw (на форуме, на который Вы дали ссылку, спасибо!)
d.v.ermakov писал(а): ↑
06 июн 2022, 22:17
RS485 и M-Bus имеют немного разную физическую часть. С точки зрения Меги они одинаковые (и то и другое — UART).
В предыдущую тему не вникал. Остальным простительно, M-Bus — редкость, и очень созвучен с MODBUS.
еще раз хочу повторить свой вопрос:
я к тому, что в меге в конфиге все равно надо будет указывать UART=RS485?
но для запросов надо будет использовать mode=raw вместо mode=rs485? https://ab-log.ru/smart-house/ethernet/megad-rs485
-
Andrey_B
- Администратор
- Сообщения: 5130
- Зарегистрирован: 18 мар 2011, 12:06
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
Andrey_B » 14 июн 2022, 15:05
В настройках UART выбирать RS485.
mode=rs485 отличается от режима raw только автоматическим подсчетом/проверкой CRC (CRC16 Modbus). Больше ничем.
В режиме raw нужно самостоятельно передавать CRC в том формате, в котором это предусматривает конкретный протокол.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 08 июл 2022, 17:11
d.v.ermakov писал(а): ↑
06 июн 2022, 22:17
Например, https://aliexpress.ru/item/33029994226.html
RS485 и M-Bus имеют немного разную физическую часть. С точки зрения Меги они одинаковые (и то и другое — UART).
В предыдущую тему не вникал. Остальным простительно, M-Bus — редкость, и очень созвучен с MODBUS.
пришла это плата, пытаюсь выбрать свой счетчик согласно протоколу mbus, но ответ всегда пустой.
решил спросить у продавца, правильную ли плату я заказал. https://aliexpress.ru/item/33009939864.html там их 2: TTL to MBUS Master и TTL to MBUS Slave, я заказывал вторую. вот что он ответил:
hi . you buy our item is Slave your meter is Slave . you need buy Master mbus only the master can communicate with the table
видимо все-таки неправильную..
если заказывать другую плату, вот что там сказано по поводу подключения:
1, VIN: power input port 5V-15V, the absolute maximum voltage can not exceed 18V, or damage the module
2, GND: systematically
3,RXD: external serial port (external device) RXD, high level
4, TXD: connect to the external serial port (external device) TXD, need external high
5,OVERLOAD: Short circuit indication output, the default high, short-circuit to low, can be left open
6, TTLVCC: TTL level voltage input, can not be left floating, you must input TTL level voltage
7, M: MBUS bus interface, the initial high level bus 30 ± 1V(customizable)Note:
1,TTLVCC input 3.3V, TTL signal is 3.3V;
TTLVCC input 5V, the TTL signal is 5V; input other TTL for the input level signal.
2, TTLVCC input voltage can not exceed VIN input voltage.
Other parameters:
Input voltage VIN:Power input port 5V-15V, the absolute maximum voltage can not exceed 18V
правильно ли я понимаю, что VIN подключаем к 5 — 12В, GND — земля, RXD/TXD к Р32/33, OVERLOAD (?) можно не подключать, TTLVCC к 3.3 — 5В?
-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 09 июл 2022, 21:22
Вы правы, нужна плата master, она питает шину M-Bus. Извините, что дал вам неверную ссылку.
Подключения вы описали верно.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 18 авг 2022, 23:02
спустя полтора месяца наконец пришла плата master, но немного поврежденная:

продавец сказал, что это не должно повлиять на работоспособность. подключил к меге, пытаюсь послать запрос, и в ответ опять ничего не получаю… можно ли как-то определить, получила ли мега ответ, но пустой, или ничего не получала?
-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 21 авг 2022, 21:43
c1tru55 писал(а): ↑
18 авг 2022, 23:02
подключил к меге, пытаюсь послать запрос, и в ответ опять ничего не получаю… можно ли как-то определить, получила ли мега ответ, но пустой, или ничего не получала?
Сколотый дроссель может быть причиной неработоспособности одного из источников питания на плате.
1) Нужно проверить все питания, как на плате, так и на шине.
2) Если хотите советов — давайте фото подключений.
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 22 авг 2022, 23:16
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
2) Если хотите советов — давайте фото подключений.
подключал все так же, как и обсуждали:
c1tru55 писал(а): ↑
08 июл 2022, 17:11
правильно ли я понимаю, что VIN подключаем к 5 — 12В, GND — земля, RXD/TXD к Р32/33, OVERLOAD (?) можно не подключать, TTLVCC к 3.3 — 5В?
VIN/TTLVCC подключал к 5V, OVERLOAD не подключал.
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
осциллографа нет, да и если бы был толку нет. мультиметром подключался к выходам платы M+ M-, почему-то напряжение в состоянии покоя (т.е. никаких запросов мега не шлет) сказало до 26V при входных 5V, не знаю норма это или нет. от греха подальше отключил от счетчика. убедиться бы как-нибудь, что со счетчика реально снять показания через M-Bus, а то сначала slave платой подключался, потом возможно поврежденной master платой, мб спалил там уже встроенный интерфейс ![]()
-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 23 авг 2022, 22:33
c1tru55 писал(а): ↑
22 авг 2022, 23:16
мультиметром подключался к выходам платы M+ M-, почему-то напряжение в состоянии покоя (т.е. никаких запросов мега не шлет) сказало до 26V при входных 5V, не знаю норма это или нет. от греха подальше отключил от счетчика.
26 вольт — это нормально: https://ru.wikipedia.org/wiki/Meter-Bus
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 25 авг 2022, 20:52
d.v.ermakov писал(а): ↑
21 авг 2022, 21:43
Сколотый дроссель может быть причиной неработоспособности одного из источников питания на плате.
1) Нужно проверить все питания, как на плате, так и на шине.
3) Точнее всего на ваш вопрос можно ответить, посмотрев осциллографом. Если его нет — хотя бы быстрым мультиметром посмотреть обмен.
между выходами M+ и M- 26.9V. на другом конце витой пары, которая подходит к счетчику тоже 26.9V. когда я посылаю запрос через Мегу — напряжение на мультиметре немного меняется.
также продавец переслал ответ поставщика:
Supplier Reply
First, confirm whether the interface connection is correct. There are signs on the board, especially txd—txd means txd is connected to txd; rxd—rxd is rxd connected to rxd, and cannot be crossedIn addition, ttl vcc must be connected. It should be connected according to the picture. Make sure that all the interfaces are correct. Measure whether the voltage of m+ and m- is about 28v. If so, let the customer confirm whether the two lines from the module to the meter are connected. . Check the software agreement if everything is normal
Such as communication baud rate, verification, data correctness, etc.If the customer insists that the above questions are correct. You have to use tools to troubleshoot the problem. Use an oscilloscope to connect m+ and m-. Then send data. See if there is a waveform.
In addition, the customer is soldering the socket, so make sure the screws are tightened. If the power supply line is long, the external capacitor should be connected with a capacitor of 10uf or more. Make sure that the power supply ripple is relatively small.
в общем ничего нового, единственное речь про 28V, когда у меня 26.9V. ну и про конденсатор про большой линии питания, но линия питания от Меги у меня 15 сантиметров, а витая пара до счетчика ~ метров 8.
Согласно документации я посылаю запрос
(для selection secondary address с любыми serial number/manufacturer code/identification code/medium code), в ответ ожидаю получить
от счетчика, но ответа нет. Т.е. в одной вкладке открываю урл
Код: Выделить всё
http://192.168.1.111/sec/?uart_tx=680B0B6853FD52FFFFFFFFFFFFFFFF9A16
и после этого в другой открываю
но там всегда пусто. Не знаю, что еще сделать…
-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 05 сен 2022, 17:38
26.9 или 28, думаю, не очень важно. То, что мультиметр что-то показывает — значит запрос, скорее всего, идёт. Попробуйте поменять местами M+ и M-.
Где у вас проблема, понять сложно. Я это называю приёмом родов по телефону. Поверьте, фото многое могут решить. Либо берите осциллограф и смотрите сами.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 07 сен 2022, 18:11
не знаю почему, но сейчас напряжение между контактами М+ и М- у меня 1.0 — 4.6В. что-то явно не так, хотя между VIN/TTLVCC и GND на входе 4.93В. похоже плата окончательно сдохла.
фото подключения:

-
d.v.ermakov
- Администратор
- Сообщения: 2061
- Зарегистрирован: 29 май 2015, 21:23
- Откуда: Екатеринбург, Нижний Тагил
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
d.v.ermakov » 12 сен 2022, 14:03
По фото ваших подключений видно, что есть проблема. VIN должно быть от 5 до 15 вольт (я бы подключил 12). TTLVCC нужно подключать к 3,3 вольтам, это уровень сигналов микроконтроллера Меги. Поэтому, вероятно, обмен и не шёл.
-
c1tru55
- Сообщения: 55
- Зарегистрирован: 09 янв 2022, 14:59
Re: Постоянные ошибки «CRC Error» при попытке считать данные через M-Bus с теплосчетчика Danfoss Sonometer 500
Сообщение
c1tru55 » 04 янв 2023, 19:37
заказал новую плату, подключил все как вы сказали, на выходах M+ и M- напряжение ~28 В. но все равно результата нет. что не посылай — ответ пустой, хотя должен быть не пустой (E5).
или я что-то не понимаю в протоколе MBus, либо у меня счетчик не может с ним работать. уже не знаю, что еще придумать…
PS:
1. как долго в буфере хранится ответ по ?uart_rx=1? и как быстро его можно получать? возможно ли, что я просто не попадаю во временной интервал для его получения?
2. какие настройки должны быть у портов P32 и P33?
3. в статье «MegaD-2561 в качестве шлюза RS-485/Modbus RTU — Ethernet» сказано
RO (Output) — P32 (RX)
DI (Input) — P33 (TX)
т.е. output соединяем с receive, input с transfer (!). правильно ли я соединяю
RXD — P32 (RX)
TXD — P33 (TX)
?
Hi Guys
I have my MODBUS RTU client on my BIGPIC working quite well I am receiving ALL the messages on the PIC and my PC is receiving all the messages from the PIC so all is great..
HOWEVER
Reception is done using an interrupt and every message received sets the FERR (framing error) flag. It does not matter about the size of the message I send everything else works OK, no CRC errors, no overrun errors etc but the FERR flag always gets set.
I am using the DS1487N tranceiver chip with the TX/RX logic driven from PORTC.5 on the test system I only have the one device and it is terminated with a 120 ohm resistor
The program is over 800 lines so I will not post it all but basically the tranceiver chip is always in receive mode except for when I am sending data and when I am sending data I disable the receive interrupt which is the only time it is disabled. I am running fixed 9600/8/1/N comms
The PIC setup code is
Code: Select all
procedure InitPic; // initialisation of PIC registers, timers, USART and Interrupts
begin
MEMCON.EBDIS := 1; // BIGPIC system disable external memory bus
ADCON0 := 0; // Turn of ADC
CMCON := 0x07; // turn off comparators
ADCON1 := 0x0F; // turn off analog inputs
TRISB:=0x07; // bits 0 and 1 used for INT0 and INT1, bit 7 used for TMP05 start pulse
PORTB:=0xf4; // Start pulse normally in high state to conserve TMP05 power
TRISC:=0xC0; // bits 7 and 8 used by USART, bit 5 used to control RS-485 chip tri-state
PORTC.5:=0;
USART_init(9600); // initialize USART (Takes out PORTC bits 7 & 6 !!)
RCSTA1.0:=0; // 9 bit mode disabled (no parity req, CRC much better)
TXSTA1.6:=0;
T0CON:=0xc3; // Enable 8 bit timer0 interrupt occurs every 4x256x16/Fosc Seconds (1.6384mS @ 10Mhz)
T1CON:=0x31; // Enable 16 bit timer1 with 8 bit prescale (tick every 3.2uS / overflow at 209.7152mS @ 10Mhz)
T3CON:=0x40; // turn off capture compare for timer1 (may not be required)
RCON:=$80; // ENABLE priority Interrupts - INT0/INT1 (TMP05 timing) high priority, USART1/TIMER0 (comms) low priority
PIE1 := 0x20; // enable USART1 interrupt (we do not enable TIMER1 interrupt we will just poll it for overflows)
IPR1:=0; // All peripheral interrupts are low priority (do all of them just to be sure.. bloody FERR!!)
IPR2:=0;
IPR3:=0;
INTCON2 := 0x48; // PortB pullups disabled, INT0 rising edge, INT1 trailing edge, TIMER0 low priority 01001000
INTCON3.6 := 1; // INT1 High priority
INTCON := 0xe0; // enable timer0, INT0 and Peripheral interrupts and TURN ON GLOBAL INTERRUPTS
// INT0 and INT1 enabled seperately by tmp05 routines and interupts when required
end;
the transmit code is
Code: Select all
procedure MB_Send(len:byte);
var
n,i: integer;
begin
PIE1.RC1IE:=0; // turn off receive interrupt during transmission
PORTC.5:= 1; // PULL RC5 High to initiate RS-485 transmission mode
crc := 0xFFFF;
delay_ms(1); // wait for a wee while
// calculate the CRC (modified from delphi PC routine)
for i:=1 to len do
begin
crc := crc xor word(TxBuf[i]);
for n:=1 to 8 do
begin
if (crc and 0x0001)<>0 then
crc:=(crc shr 1) xor 0xA001
else
crc:=crc shr 1;
end;
USART_Write(TxBuf[i]); // write the response byte by byte
end;
USART_Write(lo(crc)); // write crc LSB
USART_Write(hi(crc)); // write crc MSB
delay_ms(1);
PORTC.5:=0; // Drop RC.5 line to put RS-485 back into receive mode
PIR1.RC1IF:=0; // Clr any receive flags just in case
PIE1.RC1IE:=1 // turn back on receive interrupt
end;
The receive code for the interrupt is
Code: Select all
procedure interrupt_low;
begin
if PIR1.5 = 1 then // USART has received a char to process
begin
PORTB.4:=0; // OPERATE LED OFF (Will go on pretty soon so to user it will appear to flash off as data is rxd)
if (RCSTA1.1=0) AND (RCSTA1.2=0) then //no errors
begin
rxbuf[bufptr]:= RCREG1; // read the received data from USART 1 into cmd buffer
if bufptr<RxBufSize then inc(bufptr); // only interested in first 20 (well actually 7!) chars max others can be ignored
end
else // Error In Reception
begin
if RCSTA1.1=1 then // overrun error
begin
inc(MBRegister[46]);
if MBregister[46]=0 then MBregister[40].11:=1; // Overrun error word has overflowed so flag it
MBregister[40].1:=1;
end;
if RCSTA1.2=1 then // framing error
begin
inc(MBregister[45]);
if MBregister[45]=0 then MBregister[40].10:=1; // Framing error word has overflowed so flag it
MBregister[40].2:=1;
end;
BadCh:=RCREG1; // read char
RCSTA1.CREN:=0; // clear the error
RCSTA1.CREN:=1; // enable receiving again
end;
MBFrameTimeout:=0; // clear down frame timeout TIMER0 on char reception (>3.5 chars without a char is a frame timeout)
PIR1.5:=0; // ack the interrupt
end;
if INTCON.TMR0IF = 1 then // timer 0 has overflowed (1.6384mS)
begin
if MBFrameTimeout<200 then inc(MBFrameTimeout); // count goes up to 300mS but we will time the frame out in about 7mS (MODBUS Spec says 4.5mS @ 9600)
INTCON.TMR0IF:=0; // ack interrupt until next time
end;
end;
There is also a timer in the low priority interrupt but as everything works I do not suspect this, nor do I suspect INT0 or INT1 in the high priority interrupt as these are switched on only once every 20 seconds for temperature measurements while the FERR errors occur on every frame (not char) received.
I suspect it is a timing issue or an extra bit received by the USART from somewhere but my oscilloscope is all packed up as I am moving so I’m a bit stumped and I do not want to release my prototype model for production until I know whats causing the error.
I am using a MOXA Nport 5150 as the RS-485 gateway for the PC and a Delphi program to test everything.
If anyones got any ideas (including bad code!) I would be grateful ![]()
Thanks
Boz (www.boznz.com)
PS feel free to use the code
Загрузка…
Время на прочтение
8 мин
Количество просмотров 34K
Не так давно по долгу службы столкнулся с довольно интересной проблемой.
У нас имеется устройство, которое осуществляет интенсивный обмен по внутренней шине RS485, число проходящих пакетов составляет порядка нескольких тысяч в секунду, каждый пакет имеет длину в 7 байт, два из которых предназначены для хранения контрольной суммы CRC16 в ее CMS варианте (полином = 0x8005, стартовое значение = 0xFFFF). Прием осуществляется в FIFO-буфер, который сдвигается вверх с вытеснением после приема каждого последующего байта. Индикатором получения реального пакета является факт совпадения его контрольной суммы со значением, переданным в самом пакете. Никаких заголовков или дополнительных параметров.
Проблема заключалась в следующем – периодически, примерно раз в 5 минут, при передаче данных проскакивал пакет, данные которого давали выброс данных для одного из каналов, причем чаще всего выброс происходил до одного и того же значения. Сначала мы смотрели в сторону физических коллизий, но дело оказалось в другом – время от времени в буфере, где собирались полученные данные, оказывался пакет, состоящий из конца предыдущего пакета и начала следующего, причем контрольная сумма у такого комбинированного пакета оказывалась верной. То есть, налицо коллизия контрольной суммы: пакет не имеет смысла, но дает верную контрольную сумму.
Естественно, ошибка была уже на уровне проектирования системы, так как у пакетов не было никаких заголовков, введение дополнительного байта-заголовка свело количество ошибок до недетектируемого уровня, но этого мне показалось мало. Я решил проверить, насколько различные виды 16-битных контрольных сумм отличаются друг от друга в реальных условиях. Собственно, об этом и статья.
Для сравнения я выбрал несколько наиболее часто используемых 16-битных контрольных сумм с различными полиномами, стартовыми значениями и механизмом поступления битов. Выбранные мной суммы сведены в следующую таблицу:
| Обозначение | Polynomial | Init | RefIn | RefOut | XorOut |
| CMS | 0x8005 | 0xFFFF | false | false | 0x0000 |
| CCITT | 0x1021 | 0xFFFF | false | false | 0x0000 |
| AUG-CCITT | 0x1021 | 0x1D0F | false | false | 0x0000 |
| BYPASS | 0x8005 | 0x0000 | false | false | 0x0000 |
| CDMA2000 | 0xC867 | 0xFFFF | false | false | 0x0000 |
| DDS-110 | 0x8005 | 0x800D | false | false | 0x0000 |
| DECT-X | 0x0589 | 0x0000 | false | false | 0x0000 |
| EN-13757 | 0x3D65 | 0x0000 | false | false | 0xFFFF |
| Modbus | 0x8005 | 0xFFFF | true | true | 0x0000 |
| T10-DIF | 0x8BB7 | 0x0000 | false | false | 0x0000 |
| TELEDISK | 0xA097 | 0x0000 | false | false | 0x0000 |
| XMODEM | 0x1021 | 0x0000 | false | false | 0x0000 |
В данном случае:
- RefIn — порядок поступления битов из буфера данных: false — начиная со старшего значащего бита (MSB first), true – LSB first;
- RefOut – признак инвертирования порядка битов на выходе: true – инвертировать.
При эмуляции повреждения пакетов я реализовал следующие модели:
- Shuffle: заполнение случайного количества байт в пакете случайными значениями
- Bit shift: сдвиг случайных байт в пакете влево
- Roll packet: кольцевой сдвиг байт в пакете влево
- Right shift: сдвиг пакета вправо на один байт, слева дописывается 0xFF (передача идет посредством UART)
- Left shift: сдвиг пакета влево на один байт, справа дописывается 0xFF
- Fill zeros: заполнение случайного количества байт в пакете байтами 0x00 (все нули)
- Fill ones: заполнение случайного количества байт в пакете байтами 0xFF (все единицы)
- Byte injection: вставка в пакет случайного байта в случайном месте, байты за вставленным сдвигаются в направлении хвоста
- Single bit: повреждение единственного случайного бита
Затем программой были сгенерированы случайным образом 100.000.000 пакетов, над каждым из них была проведены указанные выше операции, после чего сравнивались контрольные суммы исходного и модернизированного пакета. Пакеты, которые не изменились при преобразовании, отбрасывались. Если контрольная сумма совпадала, то регистрировалась ошибка.
В итоге была получена следующая таблица с количеством ошибок:
| Обозначение | Shuffle | Bit shift | Roll packet | Right shift | Left shift | Fill zeros | Fill ones | Byte injection | Sum |
| CMS | 5101 | 3874 | 2937 | 1439 | 1688 | 3970 | 4010 | 1080 | 24099 |
| CCITT | 2012 | 1127 | 3320 | 1494 | 1486 | 1063 | 1096 | 1130 | 12728 |
| AUG-CCITT | 2012 | 1127 | 3320 | 1494 | 1486 | 1063 | 1096 | 1130 | 12728 |
| BYPASS | 5101 | 3874 | 2937 | 1439 | 1688 | 3970 | 4010 | 1080 | 24099 |
| CDMA2000 | 1368 | 1025 | 1946 | 1462 | 1678 | 1043 | 1028 | 1112 | 10662 |
| DDS-110 | 5101 | 3874 | 2937 | 1439 | 1688 | 3970 | 4010 | 1080 | 24099 |
| DECT-X | 1432 | 1189 | 5915 | 1779 | 1580 | 1215 | 1209 | 1093 | 15412 |
| EN-13757 | 1281 | 2209 | 3043 | 1520 | 1528 | 2193 | 2187 | 1039 | 15000 |
| Modbus | 5090 | 3888 | 3086 | 1282 | 1582 | 3947 | 3897 | 1073 | 23845 |
| T10-DIF | 1390 | 922 | 1424 | 1421 | 1630 | 994 | 938 | 1093 | 9812 |
| TELEDISK | 1394 | 1049 | 5398 | 1451 | 1512 | 1096 | 1066 | 1065 | 14031 |
| XMODEM | 2012 | 1127 | 3320 | 1494 | 1486 | 1063 | 1096 | 1130 | 12728 |
Очевидно, что стартовое значение алгоритма никак не влияет на полученный результат, что логично, стартовое значение дает нам лишь иное значение контрольной суммы, но сам механизм расчета никак не меняется. Поэтому эти контрольные суммы я исключил из дальнейшего рассмотрения. Точно так же не имеет смысла рассматривать ошибки в одиночных битах, все контрольные суммы справились с этим безошибочно, что, собственно, от них и требовалось при создании.
Ну и итоговая таблица качества контрольной суммы, уже без учета дублирующих алгоритмов:
| Обозначение | Number of collisions | Place |
| CMS | 24099 | 8 |
| CCITT | 12728 | 3 |
| CDMA2000 | 10662 | 2 |
| DECT-X | 15412 | 6 |
| EN-13757 | 15000 | 5 |
| Modbus | 23845 | 7 |
| T10-DIF | 9812 | 1 |
| TELEDISK | 14031 | 4 |
Остальные выводы оставляю читателям. От себя замечу лишь, что определенное влияние на результаты оказывает число единиц в полиноме контрольной суммы. Но это всего лишь мое личное субъективное мнение. Буду рад выслушать иные объяснения.
Исходный код программы приведен ниже.
Исходный код
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <time.h>
#define PACKET_LEN (7)
#define NUM_OF_CYCLES (100000)
static unsigned char reverse_table[16] =
{
0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE,
0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF
};
uint8_t reverse_bits(uint8_t byte)
{
// Reverse the top and bottom nibble then swap them.
return (reverse_table[byte & 0b1111] << 4) | reverse_table[byte >> 4];
}
uint16_t reverse_word(uint16_t word)
{
return ((reverse_bits(word & 0xFF) << 8) | reverse_bits(word >> 8));
}
uint16_t crc16_common(uint8_t *data, uint8_t len, uint16_t poly, uint16_t init,
uint16_t doXor, bool refIn, bool refOut)
{
uint8_t y;
uint16_t crc;
crc = init;
while (len--)
{
if (refIn)
crc = ((uint16_t)reverse_bits(*data++) << 8) ^ crc;
else
crc = ((uint16_t)*data++ << 8) ^ crc;
for (y = 0; y < 8; y++)
{
if (crc & 0x8000)
crc = (crc << 1) ^ poly;
else
crc = crc << 1;
}
}
if (refOut)
crc = reverse_word(crc);
return (crc ^ doXor);
}
uint16_t crc16_ccitt(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x1021, 0xFFFF, 0x0000, false, false);
}
uint16_t crc16_bypass(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x8005, 0x0000, 0x0000, false, false);
}
uint16_t crc16_xmodem(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x1021, 0x0000, 0x0000, false, false);
}
uint16_t crc16_teledisk(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0xA097, 0x0000, 0x0000, false, false);
}
uint16_t crc16_augccitt(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x1021, 0x1d0f, 0x0000, false, false);
}
uint16_t crc16_cdma2000(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0xc867, 0xffff, 0x0000, false, false);
}
uint16_t crc16_dds110(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x8005, 0x800d, 0x0000, false, false);
}
uint16_t crc16_dect(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x0589, 0x0000, 0x0000, false, false);
}
uint16_t crc16_en13757(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x3d65, 0x0000, 0xffff, false, false);
}
uint16_t crc16_t10dif(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x8bb7, 0x0000, 0x0000, false, false);
}
uint16_t crc16_cms(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x8005, 0xFFFF, 0x0000, false, false);
}
uint16_t crc16_modbus(uint8_t *data, uint8_t len)
{
return crc16_common(data, len, 0x8005, 0xFFFF, 0x0000, true, true);
}
bool compare_buf(uint8_t *buf1, uint8_t *buf2)
{
uint8_t x;
for (x = 0; x < PACKET_LEN; x++)
{
if (buf1[x] != buf2[x])
return true;
}
return false;
}
bool method_shuffle(uint8_t *buf)
{
uint8_t i, j;
uint16_t rnd;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
for (i = 0; i < PACKET_LEN; i++)
{
for (j = 0; j < 10; j++)
{
rnd = (uint16_t)rand();
if (rnd % 7 == 0)
buf[i] ^= (1 << (rnd % 8));
}
}
return compare_buf(buf, copy);
}
bool method_bitshift(uint8_t *buf)
{
uint8_t x, i, j;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
x = (uint8_t)(rand() % PACKET_LEN) + 1;
for (j = 0; j < x; j++)
{
i = (uint8_t)(rand() % PACKET_LEN);
if (buf[i] == 0)
buf[i] = 0x01;
else
buf[i] <<= 1;
}
return compare_buf(buf, copy);
}
bool method_packetroll(uint8_t *buf)
{
uint8_t x, i, j;
uint8_t temp;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
x = (uint8_t)(rand() % (PACKET_LEN - 1)) + 1;
for (j = 0; j < x; j++)
{
temp = buf[0];
for (i = 0; i < PACKET_LEN - 1; i++)
buf[i] = buf[i + 1];
buf[PACKET_LEN - 1] = temp;
}
return compare_buf(buf, copy);
}
bool method_shiftright(uint8_t *buf)
{
uint8_t i;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
for (i = 0; i < PACKET_LEN - 1; i++)
buf[i + 1] = buf[i];
buf[0] = 0xff;
return compare_buf(buf, copy);
}
bool method_shiftleft(uint8_t *buf)
{
uint8_t i;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
for (i = 0; i < PACKET_LEN - 1; i++)
buf[i] = buf[i + 1];
buf[PACKET_LEN - 1] = 0xff;
return compare_buf(buf, copy);
}
bool method_zero(uint8_t *buf)
{
uint8_t x, i, j;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
x = (uint8_t)(rand() % PACKET_LEN) + 1;
for (j = 0; j < x; j++)
{
i = (uint8_t)(rand() % PACKET_LEN);
if (buf[i] != 0x00)
buf[i] = 0x00;
else
buf[i] = 0xFF;
}
return compare_buf(buf, copy);
}
bool method_one(uint8_t *buf)
{
uint8_t x, i, j;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
x = (uint8_t)(rand() % PACKET_LEN) + 1;
for (j = 0; j < x; j++)
{
i = (uint8_t)(rand() % PACKET_LEN);
if (buf[i] != 0xFF)
buf[i] = 0xFF;
else
buf[i] = 0x00;
}
return compare_buf(buf, copy);
}
bool method_injection(uint8_t *buf)
{
uint8_t x, i;
uint8_t copy[PACKET_LEN];
memcpy(copy, buf, PACKET_LEN);
x = (uint8_t)(rand() % PACKET_LEN);
for (i = PACKET_LEN - 1; i > x; i--)
{
buf[i] = buf[i - 1];
}
buf[x] = (uint8_t)rand();
return compare_buf(buf, copy);
}
bool method_single(uint8_t *buf)
{
uint8_t x;
x = (uint8_t)(rand() % (PACKET_LEN * 8));
buf[(uint8_t)(x / 8)] ^= (1 << (x % 8));
return true;
}
typedef struct
{
uint16_t crc1;
uint16_t crc2;
uint32_t errors;
uint16_t (*fn)(uint8_t *data, uint8_t len);
char name[32];
} tCRC;
typedef struct
{
bool (*fn)(uint8_t *buf);
char name[32];
} tMethod;
static tMethod methods[] =
{
{method_shuffle, "Shuffle"},
{method_bitshift, "Bit shift"},
{method_packetroll, "Roll packet"},
{method_shiftright, "Right shift"},
{method_shiftleft, "Left shift"},
{method_zero, "Fill zeros"},
{method_one, "Fill ones"},
{method_injection, "Byte injection"},
{method_single, "Single bit"}
};
static tCRC crcs[] =
{
{0, 0, 0, crc16_cms, "CMS"},
{0, 0, 0, crc16_ccitt, "CCITT"},
{0, 0, 0, crc16_augccitt, "AUG-CCITT"},
{0, 0, 0, crc16_bypass, "BYPASS"},
{0, 0, 0, crc16_cdma2000, "CDMA2000"},
{0, 0, 0, crc16_dds110, "DDS-110"},
{0, 0, 0, crc16_dect, "DECT-X"},
{0, 0, 0, crc16_en13757, "EN-13757"},
{0, 0, 0, crc16_modbus, "Modbus"},
{0, 0, 0, crc16_t10dif, "T10-DIF"},
{0, 0, 0, crc16_teledisk, "TELEDISK"},
{0, 0, 0, crc16_xmodem, "XMODEM"}
};
int main(int argc, char * argv[])
{
uint32_t num_of_cycle;
uint32_t num_of_sums;
uint8_t packet[PACKET_LEN];
uint8_t i;
uint8_t m;
//uint8_t buf[8] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
srand(time(NULL));
printf("------------------------- CRC16 comparison -------------------------n");
num_of_sums = sizeof(crcs) / sizeof(tCRC);
for (m = 0; m < sizeof(methods) / sizeof(tMethod); m++)
{
printf("r%s:n", methods[m].name);
for (i = 0; i < num_of_sums; i++)
{
crcs[i].errors = 0;
}
for (num_of_cycle = 0; num_of_cycle < NUM_OF_CYCLES; num_of_cycle++)
{
for (i = 0; i < PACKET_LEN; i++)
packet[i] = (uint8_t)rand();
for (i = 0; i < num_of_sums; i++)
crcs[i].crc1 = crcs[i].fn(packet, PACKET_LEN);
if (!methods[m].fn(packet))
continue;
for (i = 0; i < num_of_sums; i++)
{
crcs[i].crc2 = crcs[i].fn(packet, PACKET_LEN);
if (crcs[i].crc1 == crcs[i].crc2)
crcs[i].errors++;
}
if (num_of_cycle % 1000 == 0)
printf("r%.2f%%", (float)num_of_cycle / NUM_OF_CYCLES * 100);
}
for (i = 0; i < num_of_sums; i++)
printf("r %20s: %10dn", crcs[i].name, crcs[i].errors);
}
return 0;
}
В итоге в следующей версии изделия для внутренней шины была выбрана контрольная сумма CCITT, в большей степени потому, что ее реализация была доступна в аппаратной части используемого микроконтроллера.
