Изглежда не мога да получа отговор през com порта

Опитвам се да изпратя команда на разработчик. дъска и след това да получите отговор

E.G

(аз) set attrib=yes

(Dev. Board) OK

or

(Dev. Board) E.R.R

Но не връща нищо обратно ... нито O.K, нито E.R.R

докато платката се зарежда, ехото е включено .. така че ако изпратя командите, докато платката я зарежда, тя ще върне 'set attrib=yes' и след зареждане 'E.R.R', защото не можете да изпращате команди по време на зареждане.

най-доброто ми предположение е, че не чете отговора навреме или се опитва да го прочете твърде рано.

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
Здравей Lu Rd, благодаря за отговора. Вече имам събитие за получаване, но то не показваше данните, така че си помислих, че id трябва да се прочете отново, но сега виждам, че това беше методът, който използвах за изпращане на данните. @LU RD   -  person Studying.com    schedule 15.11.2014


Отговори (1)


Ето няколко отворени въпроса във въздуха, така че трябва да направя някои предположения, които може да са погрешни, но нека да видим.

Не знам каква библиотека за комуникационни портове използвате, така че предполагам, че е библиотеката CPort от SourceForge. Самият аз никога не съм го използвал, но прочетох, че е разпознат Unicode, така че можете да извиквате методите за запис с параметър unicodestring, който ще бъде преобразуван от библиотеката в ansistring преди изпращане. По подобен начин, когато получава ansistring от външния свят, библиотеката ще се преобразува в unicodestring за методите Read.

Поради асинхронния характер на серийната комуникация е важно да се разбере, че когато изпратите нещо, използвайки метода за запис, методът се връща незабавно, докато библиотеката и ОС изхвърлят символите един по един със скорост, определена от скоростта на предаване. В резултат на това вашият първи код никога не е получил нищо, защото вече сте се опитвали да четете от комуникационния порт, преди външното устройство дори да получи първия знак. Хубаво е да видите, че вече сте направили първата стъпка към успеха чрез внедряване на манипулатор на събития за (вероятно библиотечно събитие) OnRxChar.

OnRxChar вероятно се задейства за всеки знак (или няколко знака). Трябва да имате буфер, който е постоянен между тези събития. Локална променлива (каквато я имате сега и която е разпределена в стека) в манипулатора на събития не е постоянна, тя се губи всеки път, когато манипулаторът на събития излезе. Трябва да декларирате променливата Buffer като поле на TReaderProgrammer. Не знам защо дефинирахте буфера да бъде AnsiString, но ви предлагам да опитате с низ (реф. дискусия по-горе относно познаването на Unicode).

type
  TReaderProgrammer = class
    ..
    RxBuffer: string;
    ..
  end;

Буферът трябва да бъде изчистен, когато изпратите нова команда към външното устройство, за да е готово да получи нови данни като отговор на вашата команда.

РЕДАКТИРАНЕ: Като алтернатива можете да изчистите 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, страхотно е да видите вашите обмислени/разумни и противно четливи приноси, които се появяват тук. - 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, например comport.wirtestr (command1) if Memo.line(lastline)=ERR showmessage ERR else Comport.writestr (commands2) if Memo.line(lastline)=ERR showmessage ERR else Memo.line.add („Успешно“) изглежда, че изпраща всички команди, след което отпечатва готово и след като отпечатването е готово, отпечатва ERR или OK, ще проучвам изчистването на буфера, тъй като изглежда, че добавя всички команди заедно, например изпращане на команда 1 ... команда1. .. изпратете команда 2 .... команда 1 команда 2. трябва да бъде просто команда 2. - person Studying.com; 16.11.2014
comment
@Chewy Предполагам, че комуникирате с устройството по полудуплексен начин, тоест изпращате команда и след това чакате отговор. След това в зависимост от отговора изпращате следващата команда и отново чакате отговор. Ако това не е така, тогава трябва да изясните. Както ви казах, трябва да изчистите RxBuffer, когато изпращате нова команда, за да може RxBuffer да е готов за нов отговор. Като алтернатива можете да изчистите RxBuffer незабавно, когато получите и обработите пълен отговор. - person Tom Brunberg; 16.11.2014
comment
@TomBrunberg неговият halfduplex iv добави моя код към моя предварителен отговор. Не можах да добавя RxBuffer: string; да въведете TReaderProgrammer = клас .. RxBuffer: низ; .. край; затова го добавих под Var вместо type. изчиствам буфера, като отида на RxBuffer :='' не съм сигурен дали е най-добрият начин, но изглежда работи. Опитах се да добавя Readstr(buffer,count) след всяка writestr(command), но това не изглежда да работи. - person Studying.com; 16.11.2014
comment
@Chewy Изглежда, че сме разрешили действителния ви въпрос. Вече можете да получите отговор през комуникационен порт. Предлагам ви да гласувате както сметнете за добре и да маркирате въпроса като отговорен, след което да въведете нов въпрос как да свържете няколко предавания/отговори в серийна комуникация. - person Tom Brunberg; 16.11.2014
comment
@TomBrunberg здравей, благодаря Том, ще потърся малко в Google, преди да публикувам нови въпроси. благодаря ви за цялата помощ, вие и LU RU ми отворихте малко очите. благодаря ви момчета още веднъж - person Studying.com; 16.11.2014