KRModbusMaster.pas

KRModbusMaster - клиентская части протокола Modbus. Формирует пакет набора стандартных функций протокола с последующей отправкой на Slave-устройство. Полученный ответ проверяет на наличие ошибок и разбивает на составные части.

Типы данных

  • TMBMError – ошибка обработчика
  • TMBMCallBack – процедура обратного вызова при получении ответа от сервера

Константы

Коды ошибок:
  • mbmeNotConnector – не подключен модуль передачи данных
  • mbmeIncorrectID – неверный идентификатор пакета
  • mbmeIncorrectPackageLength – неверная длинна пакета
  • mbmeCRC – ошибка контрольной суммы
  • mbmeIncorrectFunction – неверный номер функции
  • mbmeIncorrectMBPackageLength – неверная длинна Modbus пакета
  • mbmeIncorrectDataLength – неверная длинна данных
  • mbmeQueueOverflowed – очередь переполнена
  • mbmeTimeOut – тайм аут
  • mbmeRealTimeError – ошибка времени выполнения
  • mbmeModbusNotActive – обработчик протокола Modbus выключен
  • mbmeClientNotActive – Modbus клиент выключен
  • MB_PARSER_ERRORS_MSG – список сообщений о ошибках

Классы

TKRModbusMaster - клиент протокола Modbus

Свойства
Методы

Преобразование кода ошибки в соответствующее сообщение

  • AError - код ошибки
  • ALevel - исходящая переменная, содержит сообщение о типа ошибки
  • Result - сообщение о ошибке

Отправляет запрос на выполнение функции чтение состояния группы дискретных регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartCoil - начальный дискретный регистр
  • ACount - количество дискретных регистров
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции чтение состояния группы дискретных входов

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartInput - начальный дискретный вход
  • ACount - количество дискретных входов
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции чтение значения регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный регистр
  • ACount - количество регистров
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции чтение значения входящих регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный входящий регистр
  • ACount - количество входящих регистров
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение пользовательской функции

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AFunc - код функции
  • AData - указатель на буфер данных
  • ADataLen - количество байт данных в буфере
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции записи состояния дискретного регистра

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • ACoilNum - адрес дискретного регистра
  • AData - новый статус
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции записи состояния группы дискретных регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartCoil - начальный дискретный регистр
  • ACount - количество дискретных регистров
  • AData - новые статусы регистров
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции записи значения в регистр

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - адрес регистра
  • AData - новое значение регистра
  • ACallBack - функция, которая будет вызвана после обработки запроса

Отправляет запрос на выполнение функции записи данных в группу регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный регистр
  • ACount - количество регистров
  • AData - новые значения регистров
  • ACallBack - функция, которая будет вызвана после обработки запроса

Добавление пакета в очередь на отправке

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AFunc - код функции
  • APPack - указатель на буфер
  • APkLen - количество байт данных в буфере
  • ACallBack - функция, которая будет вызвана после обработки запроса
  • ARecvLen - длинна ответа. Если длинна ответа не постоянна, то устанавливается ноль

Формирование пакета функции чтение состояния группы дискретных регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartCoil - начальный дискретный регистр
  • ACount - количество дискретных регистров
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции чтение состояния группы дискретных входов

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartInput - начальный дискретный вход
  • ACount - количество дискретных входов
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции чтение значения регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный регистр
  • ACount - количество регистров
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции чтение значения входящих регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный входящий регистр
  • ACount - количество входящих регистров
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета пользовательской функции

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AFunc - код функции
  • AData - указатель на буфер данных
  • ADataLen - количество байт данных в буфере
  • APPack - указатель на буфер в который будет записан пакет функции
  • Result - длина пакета

Формирование пакета функции записи состояния дискретного регистра

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • ACoilNum - адрес дискретного регистра
  • AData - новый статус
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции записи состояния группы дискретных регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartCoil - начальный дискретный регистр
  • ACount - количество дискретных регистров
  • AData - новые статусы регистров
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции записи значения в регистр

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - адрес регистра
  • AData - новое значение регистра
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета

Формирование пакета функции записи данных в группу регистров

  • AMBType - тип протокола (mbtRTU, mbtTCP, mbtASCII)
  • AAddres - адрес устройства
  • AStartReg - начальный регистр
  • ACount - количество регистров
  • AData - новые значения регистров
  • APPack - указатель на буфер в который будет записан пакет функции
  • ARecvLen - исходящая переменная, в которую записывается длинна ответа
  • Result - длина пакета
События

Примеры:

 
Поделиться:
0
Дмитрий Левин
20.03.2019 01:32
 
Здравствуйте Руслан!
Я начал изучать вопросы написания прогамы опроса устройства по протоколу Modbus TCP, в качестве основных компонентов опроса решил использовать Ваши компоненты.
За основу взял, Ваш пример опроса Овеновского устройства переделав его на TCP/
Устройство с которым, я работаю имеет большое количество регистров, потому решил в таймере, опрашивать сразу целый массив регистров начиная с регистра 100 по 160.
Для этого в таймере я вызываю функцию ReadHoldingRegisters:
Опрос проводится со скоростью 100мс. Все бы ничего, но спустя очень короткое время (от 4сек до нескольких минут) вылетает ошибка access violation at address XXXX in module..
после чего компилятор меня переносит в модуль KRModbusMaster, (строка 2380) на метод

procedure TKRMBThread._CallBack(AError: integer; APack: PKRBuffer;

конкретно сюда:
В чем может быть причина этой ошибки, или что я не доделал так чтобы решить задачу чтения регистров??
Спасибо за внимание!
С уважением Дмитрий!
Показать полностью
5
Руслан Кандирал
20.03.2019 10:26
Дмитрий Левин
 
Процедура
Procedure TForm1.CallBack(AError: integer; AData: Pointer);
вызывается не из основного потока. По этому нужно соблюсти правила синхронизации потоков. Из параллельного потока нельзя обращаться к визуальным компонентам. В вашем случае скорее всего ошибку вызвала строка
StatusBar1.Panels[1].Text := MB_PARSER_ERRORS_MSG[AError];

Я думаю тут подошла бы синхронизация через сообщения Windows. Плюс, желательно останавливать таймер на время выполнения запроса, так как если вдруг получится так, что время обработки запроса будет больше времени срабатывания таймера, то будет переполняться очередь запросов. Я бы сделал это так:
Показать полностью
0
Дмитрий Левин
26.03.2019 22:58
Руслан Кандирал
 
Прежде всего благодарю за развернутый и быстрый ответ, и прошу прощения за запоздалый ответ (не имел возможностей вдумчиво ответить).
Надо будет както более глубоко изучить Ваш труд и поучаствовать в написании примеров и справки к Вашим компонентам.
Как я понял из вашего примера идея такая:
1. Вначале, из любого удобного места приложения, по мере надобности передаем запрос на чтение, необходимой группы регистров - командой ReadHoldingRegisters.
2. В пользовательской функции обратного вызова CallBack, мы принимаем и дешифруем данные с группы регистров. При этом действия функции CallBack происходят в пределах другого потока, и для того чтобы сообщить основному приложению о завершении этой работы, мы посылаем ему сообщение WM_MBCALLBACK.
3.В предварительно прописанном методе WMMBCallback, производим обработку полученных данных, например вывод на пользовательский интерфейс.

Т.е. требуется опрос Modbus устройства оформить в трех фазах.

Еще раз благодарю за внимание и оперативные ответы, и прошу прощения за не своевременный ответ.
Показать полностью
5
Руслан Кандирал
26.03.2019 23:36
Дмитрий Левин
 
1. Да. Желательно поставить опрос хотя бы одного регистра в цикл для поддержания коннекта, а остальные уже опрашивать по мере необходимости.
2. Да, CallBack вызывается из другого потока. С помощью SendMessage мы приостанавливаем этот поток пока окно которому принадлежит Handle не обработает запрос.
3. Да.

Ещё можно сделать так

Показать полностью
0
Валентин Викторович
29.12.2017 06:17
 
Так работать не хочет, ошибки не выводятся в listbox. Сделал немного по другому. Обрабатываю непосредственно ошибки тэгов.

Показать полностью
0
Валентин Викторович
28.12.2017 07:57
 
Добрый день, подскажите пожалуйста, Каким образом вытащить сообщения об ошибке и передать их в listbox. Спасибо
Показать полностью
5
Руслан Кандирал
28.12.2017 09:18
Валентин Викторович
 
Для начала вам нужно получить код ошибки, он приходит в callback функции. Пример:
Код ошибки передаем в заранее созданную переменную. Из callback функции обращаться к визуальным компонентам нельзя, так как она вызывается не из основного потока.

Затем с помощью таймера можно сделать так:
Показать полностью

Новости сайта

06.02.2018 15:53
Добавлена программа SimpleADB
Программа SimpleADB разработана в среде Delphi XE для отладки Android устройств через утилиту adb
07.10.2017 23:57
Оптимизация библиотек Modbus для контроллеров Arduino
Сделал оптимизированный вариант библиотек Modbus под Arduino, с целью снизить размер занимаемой памяти для скетча
28.03.2017 23:51
Modbus Slave RTU/ASCII для микроконтроллеров Arduino
Реализация клиентской части протокола Modbus RTU и Modbus ASCII для контроллеров Arduino и пример использования с видео обзором

Популярные статьи

Modbus Slave на Arduino
Реализация клиентской части протокола Modbus RTU и Modbus ASCII для контроллеров Arduino
Пример передачи данных по протоколу Modbus на Delphi
Пример передачи данных с контроллера ОВЕН ПЛК100 в программу на Delphi по протоколу Modbus
Набор компонентов для Delphi
Набор компонентов для Delphi включает в себя компонент для работы с файловой системой, сетью, автоматизацией и другие.