![]() |
|
|
Регистрация Восстановить пароль |
Повторная активизация e-mail |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Новичок
Джуниор
Регистрация: 29.12.2021
Сообщений: 2
|
![]()
Добрый день, прошу помочь людей с опытом работы с COM портом на Delphi.
Разрабатываю программу на Delphi 10.4 для связи с цифровым манометром через протокол RS-232. Физически связь осуществляется ПК - USB преобразователь RS-232 - витая пара UTP 4P - цифровой манометр. скорость обмена данными 9600 б/с количество бит данных 8 без проверки на четность количество стоп-бит – 1 Программа через таймер каждую секунду шлёт запрос, на что цифровой манометр отвечает, отправляя значение одного параметра (давления) формируя ответ согласно своего протокола, пример байт в HEX формате: FF 00 FF FF 86 FF FF FF FF 04 01 05 00 00 01 3D 6E 7F 28 83 из них самый последний байт является контрольной суммой сообщения, а перед ним 4 байта - значение в формате IEEE754(Float) Для работы с COM портом использую библиотеку ComPort Library v4.11, сообщение через COM порт приходит не сразу, а частями (причём длина частей не постоянна), поэтому перед запросом я очищаю буфер, а по мере прихода частей собираю пакет (буфер) через глобальную переменную проблема заключается в следующем, в результате получения ответов и сборки их в пакет (буфер) я получаю неправильный результат (неправильное значение параметра (давления) и неверную контрольную сумму), но только стоит мне добавить лишнее ненужное действие (например вывод промежуточных результатов в Memo1) происходит следующее, при добавлении строк в Memo1 происходить прокручивание Memo1 вниз (через ScrollBars) и обратное поднятие вверх, программа как бы замедляется и в результате я получаю правильный пакет (буфер), у которого верное значение и контрольная сумма. что самое для меня непонятное, приведу пример, сначала я запускаю родную программу от манометра, и запрашиваю к примеру 20 раз значение манометра и все 20 раз приходит правильное значение параметра, закрываю программу, открываю свою программу, делаю запрос и вывод без лишних действий, сколько бы я не отправлял запрос, ответ приходит неправильный, стоит включить лишние действия (вывод в Memo1), всё становится нормально, результат и контрольная сумма правильная. так же есть интересный эффект, после нескольких запросов с лишними действиями, при отключении лишних действий, начинают приходить правильные ответы даже без лишних действий, что вообще не поддаётся моей логике. у меня есть несколько вариантов (возможно вы предложите свой, более правильный): 0) другой алгоритм сборки пакета (может быть ошибка в нём) 1) специальное замедление программы (выполнение каких-то лишних действий) 2) замедление программы через функции Sleep, Delay (подскажите как правильно сделать? какое значение задержки? или пример кода) 3) формирование пакета (буфера) не в ручную, а через TComDataPacket, как только его правильно настроить? есть параметр StartString, но мне нужно начало пакета определять не по стартовой строке, а по 4-ом стартовым байтам (пакет начинается с FF 00 FF FF, просто FF может повторяться в сообщении) 4) выставление временных задержек COM-port'а, сейчас значения стоят по умолчанию Timeouts.ReadIntervalTimeout:=-1; Timeouts.ReadTotalTimeoutConstant:= 0; Timeouts.ReadTotalTimeoutMultiplier :=0; Timeouts.WriteTotalTimeoutConstant: =1000; Timeouts.WriteTotalTimeoutMultiplie r:=100; пробовал выставить следующие значения: Timeouts.ReadIntervalTimeout:=50; Timeouts.ReadTotalTimeoutConstant:= 100; Timeouts.ReadTotalTimeoutMultiplier :=70; Timeouts.WriteTotalTimeoutConstant: =100; Timeouts.WriteTotalTimeoutMultiplie r:=60; результат тот же, приходит не верный ответ так же есть родная программа от манометра, в которой заданы временные интервалы (смотреть прилагаемые картинки), но какие задать мне значения Timeouts исходя из параметров родной программы (может кто-то подскажет верные)? так же в целом прошу проверить код, может опытные люди найдут ошибки или предложат оптимизировать процедуру? код получения и сборки пакета: Код:
Последний раз редактировалось Serje88; 29.12.2021 в 13:59. |
![]() |
![]() |
![]() |
#2 |
фрилансер
Форумчанин
Регистрация: 11.10.2019
Сообщений: 852
|
![]()
Serje88, для начала выведи в лог всё, что прочиталось из порта, и всё, что записалось в порт (с точностью до мс.)
(запись для лога необходимо формировать непосредственно сразу после функции записи/чтения, чтобы время в логе можно более точнее соответствовало реальности) |
![]() |
![]() |
![]() |
#3 |
Новичок
Джуниор
Регистрация: 29.12.2021
Сообщений: 2
|
![]()
спасибо за помощь, ошибка была элементарная, вместо "for i:=0 to Count" должно быть "for i:=0 to Count-1", всё работает отлично с таймаутами по умолчанию
|
![]() |
![]() |
![]() |
Опции темы | Поиск в этой теме |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Работа с com портом | Shadowfirst | Общие вопросы C/C++ | 0 | 01.07.2016 15:51 |
Работа с COM портом | SDevel | C# (си шарп) | 6 | 05.01.2013 12:16 |
Работа с com портом | Валера777 | Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM | 4 | 05.12.2009 00:06 |
Работа с COM портом | hoba | Общие вопросы Delphi | 3 | 20.11.2008 03:39 |