Вот несколько открытых вопросов, поэтому я должен сделать некоторые предположения, которые могут быть неверными, но давайте посмотрим.
Я не знаю, какую библиотеку коммуникационных портов вы используете, поэтому я предполагаю, что это библиотека CPort от SourceForge. Я никогда не использовал его сам, но я читал, что он поддерживает Unicode, так что вы можете вызывать методы записи с параметром unicodestring, который будет преобразован библиотекой в ansistring перед отправкой. Точно так же при получении строки из внешнего мира библиотека преобразует строку в юникод для методов чтения.
Из-за асинхронного характера последовательной связи важно понимать, что когда вы отправляете что-то с помощью метода записи, метод возвращается немедленно, в то время как библиотека и ОС выдают символы по одному за раз со скоростью, определяемой скоростью передачи данных. В результате ваш первый код так ничего и не получил, потому что вы уже пытались прочитать из коммуникационного порта еще до того, как внешнее устройство получило первый символ. Приятно видеть, что вы сделали первый шаг к успеху, реализовав обработчик событий для (предположительно библиотечного события) OnRxChar.
OnRxChar, вероятно, срабатывает для каждого символа (или пары символов). Вам нужно иметь постоянный буфер между этими событиями. Локальная переменная (как она у вас сейчас и которая выделена в стеке) в обработчике событий не сохраняется, она теряется каждый раз, когда обработчик событий выходит. Вы должны объявить переменную Buffer как поле TReaderProgrammer. Я не знаю, почему вы определили буфер как AnsiString, но я предлагаю вам попробовать строку (ссылка на обсуждение выше относительно поддержки Unicode).
type
TReaderProgrammer = class
..
RxBuffer: string;
..
end;
Буфер необходимо очищать при отправке новой команды на внешнее устройство, чтобы оно было готово к приему новых данных в ответ на вашу команду.
EDIT: В качестве альтернативы вы можете очистить RxBuffer сразу после получения и обработки полного ответа.
TReaderProgrammer.ComPort1RxChar должен выглядеть следующим образом:
procedure TReaderProgrammer.ComPort1RxChar(Sender: TObject; Count: Integer);
var
RxData : string;
begin
(Sender as TComPort).ReadStr(RxData,Count);
RxBuffer := RxBuffer + Rxdata;
...
end;
Остальная часть обработчика событий, я думаю, просто для наблюдения за ходом приема, так что больше об этом нечего.
person
Tom Brunberg
schedule
15.11.2014