Комментарии 10
Первая — отсутствие преамбулы. Точнее она есть, это задержка в 3.5 символа. Если же вы пытаетесь прочитать дамп Modbus/RTU данных из файла, или получаете их из ненадёжного по задержкам канала, или используете какие-то преобразователи типа 485 over TCP/IP, то эти 3.5 вы не найдёте. Или найдёте посередине половины пакетов. В итоге приходится как-то умно детектить границы пакетов по номеру устройства и CRC, что неприятно.
Вторая — отсутствие стандарта на Modbus\UDP, который на самом деле существует, но не стандартизирован.
А в остальном — хороший удобный протокол.
tcgetattr(fserial, &options); // Получить текущие настройки порта
cfsetispeed(&options, BaudRate); // Установить скорость входящего потока
cfsetospeed(&options, BaudRate); // Установить скорость исходящего потока
if(ParityOdd)
options.c_cflag |= PARENB | PARODD; // Включить проверку четности (неч)
else if(ParityEven)
options.c_cflag |= PARENB & ~PARODD;// Включить проверку четности (чет)
options.c_cflag &= ~CSTOPB; // 1 стоп бит
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8 | CREAD | CLOCAL; // 8 бит, включить приемник
if(bCTS)
options.c_cflag |= CRTSCTS; // включить аппаратный контроль потока
else
options.c_cflag &= ~CRTSCTS; // отключить аппаратный контроль потока
// Вместо ниже приведенных установок можно использовать
// int cfmakeraw(struct termios *termios_p) для настройки необрабатываемого
// драйвером последовательного порта ввода/вывода
// Raw Input - ввод не обрабатывается драйвером порта
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
// Raw Output
options.c_oflag &= ~OPOST;
options.c_iflag = IGNBRK; // Ignore Break Condition (без этого работало
// некорректно: CRC/Timeout errors)
// Настройка таймаутов порта
options.c_cc[VMIN] = 0; // Минимальное количество символов
options.c_cc[VTIME]= Timeout/100; // Таймаут ожидания каждого
// символа *10 сек
tcsetattr(fserial, TCSANOW, &options); // Записать новые настройки
// (немедленно)
if(MDebug > 1){
cout << "Serial port options:" << endl;
cout << "c_cflag: " << options.c_cflag << endl;
cout << "c_lflag: " << options.c_lflag << endl;
cout << "c_iflag: " << options.c_iflag << endl;
cout << "c_oflag: " << options.c_oflag << endl;
cout << "c_cc: " << options.c_cc << endl;
cout << "c_ispeed: " << options.c_ispeed << endl;
cout << "c_ospeed: " << options.c_ospeed << endl;
}
Что за задержка? Не было такого.
https://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf раздел 2.5.1.1
Детектить по ID и структуре пакета легко, когда у вас известен ID и надёжный канал связи, в котором не теряются и не искажаются куски пакетов. Хотя в таком канале и на задержки не стоило бы надеяться.
RTU варианте поверх работы с Serial портом, или 485 интерфейса насколько это встречалось в моей практике.
RS485 — тоже serial интерфейс, противопоставление некорректно. Modbus RTU (и ASCII, который вы не упомянули) может работать по произвольному последовательному интерфейсу (RS232, RS422, RS485, UART, как примеры).
Сама же статья непонятно о чём. Вы научились писать/читать из serial интерфейса и считать crc16 с помощью внешней функции? Хорошо.
Вы ничего не написали про структуру фрейма, коды операций, структуру адресного пространства устройства (отличия discrete input, coil, input register, holding register, независимость адресации), два варианта адресации в клиентских библиотеках (десятичная запись адреса часто смещена на 1) и кучу других базовых аспектов.
Читайте спецификации на официальном сайте протокола.Тогда зачем вообще этот пост? Показать что Вы наконец-то разобрались с довольно простым протоколом? Хотя бы ссылку на «официальный сайт протокола» привели бы что-ли.
непонятно какие цели преследует автор.
Абсолютно вырванные из контекста куски кода
crc.i = CRC16((unsigned char *)request, reqsize-2);
request[reqsize-2] = crc.ch[1];
request[reqsize-1] = crc.ch[0];
что за crc.i — что это за структура?
что за request откуда взялся, как объявлен?
какие еще функции в MB протоколе существуют?
какие есть коды ошибок и как их обрабатывать?
какая особенность расчета контрольной суммы именно для MB протокола?
отсылка к оф. докам, это не серьезно
После прочтения статьи образуется еще больше вопросов и это не следствие осознание проблемы.
Знакомство с Modbus