![]() |
|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
![]() Здравствуйте.
Подтолкните в правильном направлении для решения следующей задачи: Есть некоторое устройство общающееся с PC посредством com-порта. Протокол у этого устройства ModbusRTU. Написал тестовую программу обмена с этим устройством без использования классов. Данные принимаю и отправляю в виде массива Byte. Все работает (т.е. значения из регистров я получаю и вывожу на форму). Теперь встала задача оформить это все в виде класса. Почитал книги по ООП , но до конца так и не понял как это реализовать. Из всего протокола Modbus RTU меня интересует пока только 2 функции это- 3 ( Read holding registers) и 6 (Preset Holding registers). Вот начало как я это вижу. Родитель Код:
TModbus =class (TObject) private FID:Byte; // адрес устройства используется при запросе и ответе FCodeFunction:Byte; // номер функции используется при запросе и ответе FRegistr: Byte; // адрес регистра используется при запросе FSizeDataField:Byte // Размер поля данных используется при запросе и ответе FCRC: Word; // Контрольная сумма используется при запросе и ответе Сейчас без класса обмен происходит так: для записи из edit_ов берется значение ID,функции (3 или 6), адрес регистра, размер поля и загоняется в глобальные переменные, а потом в процедуре собирается в массив array of byte к которому прикручиваются 2 байта CRC и отправляется в порт. Далее в отдельном потоке при приходе данных в буфер проверяется CRC пакета если рассчитанное значение совпадает с значением в пакете то передается в главный модуль. Далее они анализируется на ошибку следующим образом: проверяется адрес устройства, проверяется код функции в ответе если они совпадают с отправленными то пакет передается по ссылке в процедуру определения из какого регистра были получены данные ( сравнение по номеру запроса) эта процедура отправляет пакет еще в одну процедуру где происходит извлечения из пакета значения регистра, его расшифровка и выводится на форму в edit. Собственно почему и хочу переделать под класс из за наличия кучи глобальных переменных . Заранее благодарен всем кто откликнется. С уважением Юрий. Последний раз редактировалось Jury_yamal, 21.11.2014 в 14:00. |
#2
|
||||
|
||||
![]() Этот набор бутово-вордных переменных больше похож на запись (TModbus = record)
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
||||
|
||||
![]() Цитата:
Из текущего же описания я пока увидел лишь общую функцию отправки данных с несколькими параметрами. То есть, можно обойтись и без класса, но только если тело функции не представляет один большой case или набор if-ов, под каждую команду делающих свою обработку. Не стоит путать форумы с богадельнями. © Bargest |
#4
|
|||
|
|||
![]() Вот пример того что я пытаюсь сделать.
И да тело функций приема и отправки выглядят как большой case.Если не считать запись в регистры (что в основ используется только в начале), то циклы запроса и ответа выглядят так: 1. Послать запрос на чтение из регистра текущего напряжения на канале 1 (значение Float32). запрос выглядит как (const Channel: array of byte, ReguestN:byte) где Reguest - номер запроса (используется в case для определения номера запроса), увеличивается на 1 при отправке. 2. Запустить таймер (если за отведеное время нет ответа от ком порта повторить 10 раз эту же команду после чего отключить ком порт и выдать ошибку в окно ). 3 При приеме проверяется СRC в принятом пакете и код функции если рассчитанное СRC не совпадает с значение в пакете или код функции =80 (последняя цифра это сообщение какая именно ошибка) то повторяется пункт 2. 4. Если принятый пакет (read: array of byte, ReguestN:byte) проходит соответствующую проверку то он отправляется в процедуру получения значения в (по номеру Reguest в case) свою переменную Single и вывода на форму. 5. То же самое проходит для 3 других каналов и цикл повторяется. Дело в том что в протоколе Modbus не передается значение из какого регистра были получены данные поэтому использую Reguest (номер запроса ни как не меняется в потоке опроса порта). Т.е. например если Reguest=1 в принятом пакете то это значение 1 канала в Flaot32, если 2 то соответственно 2 и т.д. Последний раз редактировалось Jury_yamal, 24.11.2014 в 10:57. |
#5
|
|||
|
|||
![]() Если по простому, то приведу пример, как мы работали с сетью CAN. У библиотеки dll были функции. Для отправки сообщения создайте функцию Write (или SendMessage). Если приходит сообщение к вам, то вызывается ваш обработчик. Предварительно вы указываете эту функцию, а она вызывается асинхронно. Как только она вызовется, внутри надо прочитать сообщение какой-нибудь функцией Read (а может, уже в обработчик будет доставлены байты сообщения). Если нужно данные от прочтения визуализировать, то нужна будет синхронизация с главным процессом.
|
#6
|
||||
|
||||
![]() Цитата:
А в архиве оказались не исходники. ![]() Не стоит путать форумы с богадельнями. © Bargest |