0

Im trying to send a command to a dev. board and then receive a reply

E.G

(me) set attrib=yes

(Dev. Board) O.K

or

(Dev. Board) E.R.R

But it doesn't bounce back anything ... not an O.K or an E.R.R

while the board is booting echo is on .. so if I send the commands while the board is booting it it will bounce back an 'set attrib=yes' and once booted an 'E.R.R' because you cant send commands while booting.

my best guess is that it isn't reading the reply in time or trying to read it too soon.

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;
Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
Studying.com
  • 109
  • 1
  • 4
  • 10
  • 1
    You can't read the reply in your send method. Get the data in the receive event (you have to use a global buffer) and when enough amounts of data is received (or #10 character), interpret the answer. You can also add a timer to get a timeout notification if the answer is not received in time. – LU RD Nov 15 '14 at 14:15
  • Hi Lu Rd , thanks for the reply. I already have a Receive event but it wasn't displaying the data so thought id have to read again but I see now it was the method I was using to send the data. @LU RD – Studying.com Nov 15 '14 at 16:41

1 Answers1

3

Here are several open questions in the air, so I have to make some assumptions that might be wrong, but let's see.

I don't know what comm port library you are using, so I'm assuming it is the CPort library from SourceForge. I have never used it myself, but I have read that it is made Unicode aware, such that you can call the write methods with a unicodestring parameter which will be converted by the library to ansistring before sending. Similarily when receiving ansistring from the outer world, the library will convert to unicodestring for the Read methods.

Due to the asynchronous nature of serial communication, it is important to understand that when you send something using the write method, the method returns immediately while the library and OS spit out the characters one at at time at a pace defined by the baud rate. As a result your first code never received anything, because you were already attempting to read from the comm port before the external device even received the first character. It is good to see that you have now taken the first step to success by implementing an event handler for (presumably library event) OnRxChar.

The OnRxChar probably fires for each character (or couple of characters). You need to have a buffer that is persistent between these events. A local var (as you have it now and which is allocated on the stack) in the event handler is not persistent, it is lost every time the event handler exits. You should declare the Buffer variable as a field of TReaderProgrammer. I don't know why you defined the buffer to be AnsiString, but I suggest you try with string (ref discussion above regarding Unicode awareness).

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

The buffer needs to be cleared when you send a new command to the external device in order for it to be ready to receive new data as a response to your command.

EDIT: Alternatively you can clear the RxBuffer immediately when you have received and processed a full response.

The TReaderProgrammer.ComPort1RxChar should look like this sofar:

procedure TReaderProgrammer.ComPort1RxChar(Sender: TObject; Count: Integer);
var
  RxData : string;
begin
  (Sender as TComPort).ReadStr(RxData,Count);
  RxBuffer := RxBuffer + Rxdata;
  ...
end;

The rest of the event handler is, I guess, probably just to see progress of reception, so nothing more about that.

Tom Brunberg
  • 20,312
  • 8
  • 37
  • 54
  • 1
    +1. Assuming you're the TB from the Borland/CodeGear/[...] NGs, it's great to see your thoughtful/sensible & v. readable contributions appearing here. – MartynA Nov 15 '14 at 20:29
  • 1
    I see thanks but what's the difference between your RxBuffer and my Buffer other than yours being global and mine being AnsiString. sorry im very new to programming so I want to understand why I make the changes. what dose (sender as Tcomport) vs ComPort1. change ? thank you for taking the time to answer my previse question. you are correct it is CPort library from SourceForge and that was an amazing answer. Vote up from me but don't have 15 rep ... @TomBrunberg – Studying.com Nov 15 '14 at 21:13
  • @Chewy RxBuffer as a field of the TReaderProgrammer class is not global as you claim, but it is persistant between the calls of the OnRxChar event handler. (Sender as TComPort) vs. ComPort1 is probably not really important in your case if you have only one instance of TComPort. (sneder as TComPort) is valid for any instance firing the event in situations where you have several. – Tom Brunberg Nov 15 '14 at 21:37
  • Hi TomBrunberg , after adding the buffer. I cant seem to send any if commands E.G 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('Succesfull') it seems to send all the commands then print done and after printing done print the ERR or OK im going to looking into clearing the Buffer since it seems to add all the commands together E.G send command 1 ... command1 ... send command 2 .... command 1 command 2. should be just command 2. – Studying.com Nov 15 '14 at 21:43
  • 1
    @Chewy I am assuming you are communicating with the device in halfduplex manner, that is, you send a command and then wait for a reponse. Then depending on the response, you send next command and wait for a respnse again. If that is not the case, then you need to clarify. As I told you, you need to clear the RxBuffer when you send a new command in order for the RxBuffer to be ready for a new response. Alternatively you can clear the RxBuffer immediately when you have received and processed a full reponse. – Tom Brunberg Nov 15 '14 at 22:01
  • @TomBrunberg its halfduplex iv added my code to my previse answer. I couldn't add RxBuffer: string; to type TReaderProgrammer = class .. RxBuffer: string; .. end; so I added it under Var instead of type. im clearing the buffer by going RxBuffer :='' not sure if its the best way but it seems to work. I tried adding a Readstr(buffer,count) after each writestr(command) but that didn't seem to work. – Studying.com Nov 16 '14 at 08:58
  • 1
    @Chewy It seems we have sorted out your actual question. You can now receive a reply via a comm port. I suggest you vote as you see fit and mark the question as answered, then enter a new question how to chain several transmissions/responses in a serial communication. – Tom Brunberg Nov 16 '14 at 10:01
  • @TomBrunberg hi thanks tom I will do some googleing before I post any new questions. thank you for all the help you and LU RU have opened my eyes a little. thank you guys once again – Studying.com Nov 16 '14 at 17:39