Не могу получить ответ через порт vir com

Я пытаюсь отправить команду разработчику. доска, а затем получить ответ

E.G

(я) установить атрибут = да

(Совет разработчиков) ОК

or

(Совет разработчиков) ERR

Но это ничего не возвращает... ни OK, ни E.R.R.

пока плата загружается, эхо включено ... поэтому, если я отправлю команды во время загрузки платы, она вернет «set attrib = yes» и после загрузки «ERR», потому что вы не можете отправлять команды во время загрузки.

я думаю, что он не читает ответ вовремя или пытается прочитать его слишком рано.

procedure TReaderProgrammer.Button2Click(Sender: TObject);
Var 
  Buffer: AnsiString; 
  RxData: string; 
  Count : integer;
begin
  if ComPort1.Connected then
  begin
    ComPort1.WriteStr(edtSendText.Text+#13);
    comport1.ReadStr(RxData,Count);
    Buffer := Buffer + Rxdata;
    memoRxData.Text := memoRxData.Text+Buffer+#13+#10;
  end;
end;

person Studying.com    schedule 15.11.2014    source источник
comment
Вы не можете прочитать ответ в своем методе отправки. Получите данные в событии приема (вы должны использовать глобальный буфер) и, когда будет получено достаточное количество данных (или символ #10), интерпретируйте ответ. Вы также можете добавить таймер, чтобы получать уведомление об истечении времени ожидания, если ответ не получен вовремя.   -  person LU RD    schedule 15.11.2014
comment
Привет Лу Рд, спасибо за ответ. У меня уже есть событие Receive, но оно не отображает данные, поэтому я подумал, что id должен прочитать снова, но теперь я вижу, что это был метод, который я использовал для отправки данных. @LU РД   -  person Studying.com    schedule 15.11.2014


Ответы (1)


Вот несколько открытых вопросов, поэтому я должен сделать некоторые предположения, которые могут быть неверными, но давайте посмотрим.

Я не знаю, какую библиотеку коммуникационных портов вы используете, поэтому я предполагаю, что это библиотека 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
comment
+1. Предполагая, что вы являетесь TB из Borland/CodeGear/[...] NG, приятно видеть здесь ваши вдумчивые/разумные и v. удобочитаемые вклады. - person MartynA; 15.11.2014
comment
Я вижу, спасибо, но в чем разница между вашим RxBuffer и моим буфером, кроме вашего глобального и моего AnsiString. извините, я очень новичок в программировании, поэтому я хочу понять, почему я вношу изменения. какая доза (отправитель как Tcomport) по сравнению с ComPort1. сдача ? спасибо, что нашли время ответить на мой предварительный вопрос. вы правы, это библиотека CPort от SourceForge, и это был потрясающий ответ. Голосуйте за меня, но у вас нет 15 представителей ... @TomBrunberg - person Studying.com; 16.11.2014
comment
@Chewy RxBuffer как поле класса TReaderProgrammer не является глобальным, как вы утверждаете, но сохраняется между вызовами обработчика событий OnRxChar. (Отправитель как TComPort) и ComPort1, вероятно, не очень важны в вашем случае, если у вас есть только один экземпляр TComPort. (sneder как TComPort) действителен для любого экземпляра, запускающего событие в ситуациях, когда их несколько. - person Tom Brunberg; 16.11.2014
comment
Привет TomBrunberg, после добавления буфера. Кажется, я не могу отправить какие-либо команды if EG comport.wirtestr (command1), если Memo.line(lastline)=ERR showmessage ERR else Comport.writestr (commands2), если Memo.line(lastline)=ERR showmessage ERR else Memo.line.add ('Succesfull') кажется, что он отправляет все команды, затем печатает выполнено, а после завершения печати печатает ERR или OK, я собираюсь изучить очистку буфера, поскольку он, кажется, добавляет все команды вместе, например, send command 1 ... command1 . .. отправить команду 2 .... команду 1 команду 2. должно быть просто командой 2. - person Studying.com; 16.11.2014
comment
@Chewy Я предполагаю, что вы общаетесь с устройством в полудуплексном режиме, то есть вы отправляете команду и ждете ответа. Затем, в зависимости от ответа, вы отправляете следующую команду и снова ждете ответа. Если это не так, то нужно уточнить. Как я уже говорил, вам нужно очищать RxBuffer при отправке новой команды, чтобы RxBuffer был готов к новому ответу. В качестве альтернативы вы можете очистить RxBuffer сразу после получения и обработки полного ответа. - person Tom Brunberg; 16.11.2014
comment
@TomBrunberg своим полудуплексом iv добавил мой код к моему предварительному ответу. Я не мог добавить RxBuffer: string; ввести TReaderProgrammer = class .. RxBuffer: string; .. конец; поэтому я добавил его под Var вместо типа. я очищаю буфер, выбрав RxBuffer := '' не уверен, что это лучший способ, но, похоже, он работает. Я попытался добавить Readstr(buffer,count) после каждой writestr(command), но это не сработало. - person Studying.com; 16.11.2014
comment
@Chewy Кажется, мы разобрались с вашим актуальным вопросом. Теперь вы можете получить ответ через коммуникационный порт. Я предлагаю вам проголосовать за то, что вы считаете нужным, и отметить вопрос как отвеченный, а затем ввести новый вопрос, как связать несколько передач/ответов в последовательном сообщении. - person Tom Brunberg; 16.11.2014
comment
@TomBrunberg, привет, спасибо, Том. Я погуглю, прежде чем публиковать новые вопросы. спасибо за всю помощь, которую вы и LU RU немного открыли мне глаза. спасибо, ребята, еще раз - person Studying.com; 16.11.2014