Recent

Author Topic: TLazSerial: reading and displaying multiple characters  (Read 26792 times)

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
TLazSerial: reading and displaying multiple characters
« on: April 15, 2017, 11:40:54 pm »
I am new to Lazarus and TLazSerial. I have experience with Delphi 4 Pro and SerialNG and ComDrv32, but I have had problems with communication in Win10 and I am looking at other serial port components. I have built a very simple application using Lazarus and TLazSerial, and I can send a Ctrl-T character to my USB serial port device, which then sends a string of 240 character pairs (480 total) of "00010203...0>0?101112...>0>1..>?". I use a memo, which adds text upon the RxData event, but the memo shows only: 00<CRLF>01<CRLF>02. The CRLFs seem to be added by TLazSerial, and the remaining characters are missing.

I might need to use some of the functions in LazSynaSer such as RecvBufferEx() but I don't know how to access them. My code is very simple:

Code: [Select]
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  LazSerial;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Label1: TLabel;
    LazSerial1: TLazSerial;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure LazSerial1RxData(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

const
  Ctrl_T = 20;
implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);
begin
  LazSerial1.ShowSetupDialog;
  LazSerial1.Open;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  LazSerial1.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
var command: string;
begin
  command := char(Ctrl_T) + char(0);
  LazSerial1.WriteData(command);
end;

procedure TForm1.LazSerial1RxData(Sender: TObject);
var       RecvData: String;
begin
  RecvData := LazSerial1.ReadData;
  Memo1.Lines.AddText(RecvData);
end;

end.

I thought it best to start a new topic rather than add to the long thread on TLazSerial. My question may be answered there but it's too hard to search through so many pages. Is there a user document for TLazSerial? Or is the documentation in the code?

It would be helpful to have a simple terminal demo rather than the specialized GPS project.

Also, how does one show images? I tried [ img] tags on my URL with no luck, and my image was 300k so I could not upload it.
« Last Edit: April 16, 2017, 12:41:22 am by PStechPaul »

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #1 on: April 15, 2017, 11:58:49 pm »
I was able to (almost) achieve success with this:
Code: [Select]
procedure TForm1.LazSerial1RxData(Sender: TObject);
var       RecvData: array[0..255] of char;
begin
  LazSerial1.synser.RecvBufferEx(@RecvData,250,10);
  Memo1.Lines.AddText(RecvData);
end;

The contents of the memo:
Code: [Select]
000102030405060708090:0;0<0=0>0?101112131415161718191:1;1<1=1>1?202122232425262728292:2;2<2=2>2?303132333435363738393:3;3<3=3>3?404142434445464748494:4;4<4=4>4?505152535455565758595:5;5<5=5>5?606162636465666768696:6;6<6=6>6?707172737475767778797:7;A
7<7=7>7?808182838485868788898:8;8<8=8>8?909192939495969798999:9;9<9=9>9?:0:1:2:3:4:5:6:7:8:9:::;:<:=:>:?;0;1;2;3;4;5;6;7;8;9;:;;;<;=;>;?<0<1<2<3<4<5<6<7<8<9<:<;<<<=<><?=0=1=2=3=4=5=6=7=8=9=:=;=<===>=?>0>1>2>3>4>5>6>7>8>9>:>;><>=>>>?
C
There seem to be some CRLFs and a few extra characters. Close, but no cigar!

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #2 on: April 16, 2017, 01:18:26 am »
I added a counter for Characters Received, and changed a few things, resulting in better (but not quite perfect) performance:
Code: [Select]
procedure TForm1.LazSerial1RxData(Sender: TObject);
var       RecvData: array[0..499] of char;
          i: integer;
begin
  LazSerial1.synser.RecvBufferEx(@RecvData,500,200);
  Memo1.Lines.AddText(RecvData);
  i := 0;
  while( RecvData[i] <> char(0) ) do begin
    CharCount := CharCount + 1;
    inc(i);
    end;
  eCharCount.Text:= IntToStr(CharCount);
end;
I attached a screen shot but don't see it in the preview.
[edit]Now I see it. I also got it to receive all 480 characters properly (I think) by using this:
Code: [Select]
procedure TForm1.LazSerial1RxData(Sender: TObject);
var       RecvData: array[0..499] of char;
          i: integer;
begin
//  LazSerial1.synser.RecvBufferEx(@RecvData,500,200);
  RecvData := LazSerial1.synser.Recvstring(200);
  Memo1.Lines.AddText(RecvData);
  i := 0;
  while( RecvData[i] <> char(0) ) do begin
    CharCount := CharCount + 1;
    inc(i);
    end;
  eCharCount.Text:= IntToStr(CharCount);
end;
For my end application I will need to receive a continuous stream of character pairs at 2400 pairs (4800 characters) per second, using 57600 baud. The characters are sent at precise intervals of 2400 per second, rather than bursts, and there is no flow control. I will probably need to use RecvByte or perhaps RecvPacket with packet size 2.

The character pairs are formatted such that they comprise 12 bits of ADC data and a 4 bit counter so that software can detect a missing byte. I used several circular queues to read raw characters and store them as integers and then further process them. I suppose that would be the next step to try.
« Last Edit: April 16, 2017, 01:36:57 am by PStechPaul »

Thaddy

  • Hero Member
  • *****
  • Posts: 14169
  • Probably until I exterminate Putin.
Re: TLazSerial: reading and displaying multiple characters
« Reply #3 on: April 16, 2017, 12:35:54 pm »
Characters are not C chars and they can have different meaning depending on string type used.
I do not understand why you do not use byte instead of char. After all, you are handling byte streams. (Not Ansi, UTF8, UTF16 char streams)
Things will get confusing and buggy at some point... Specifically when you use Lazarus UTF8 string system.
Plz use byte, not char, if you mean byte,

Specialize a type, not a var.

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #4 on: April 16, 2017, 07:18:13 pm »
At this point I am more accustomed to using C for PIC microcontroller projects, and my Delphi is rather "rusty". I made some changes and additions as follows:
Code: [Select]
unit SerialTestMain;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, LazSerial;

type

  { TfmSerialTest }

  TfmSerialTest = class(TForm)
    btStart: TButton;
    btStop: TButton;
    Button1: TButton;
    Button2: TButton;
    btTest: TButton;
    eCharCount: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    LazSerial1: TLazSerial;
    Memo1: TMemo;
    Timer1: TTimer;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure btStartClick(Sender: TObject);
    procedure btStopClick(Sender: TObject);
    procedure btTestClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure LazSerial1RxData(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

const
  Ctrl_A = 01;
  Ctrl_D = 04;
  Ctrl_T = 20;
  Ctrl_Z = 26;
  MAXBUFF = 5000;
var
  fmSerialTest: TfmSerialTest;
  CharCount: longint;
  CommBuffer: Array[0..MAXBUFF+1] of byte;
  CommBufferPtr, LastCommBufferPtr: longint;
implementation

{$R *.lfm}

{ TfmSerialTest }

procedure TfmSerialTest.Button1Click(Sender: TObject);
begin
  LazSerial1.ShowSetupDialog;
  LazSerial1.Open;
end;

procedure TfmSerialTest.Button2Click(Sender: TObject);
begin
  LazSerial1.Close;
end;

procedure TfmSerialTest.btStartClick(Sender: TObject);
begin
  LazSerial1.SynSer.SendInteger(Ctrl_A); //WriteData(command);
end;

procedure TfmSerialTest.btStopClick(Sender: TObject);
begin
  LazSerial1.SynSer.SendInteger(Ctrl_D);
end;

procedure TfmSerialTest.btTestClick(Sender: TObject);
begin
  LazSerial1.SynSer.SendInteger(Ctrl_T);
end;

procedure TfmSerialTest.FormCreate(Sender: TObject);
begin
  LazSerial1.BaudRate := br_57600;
  CommBufferPtr := 0;
  LastCommBufferPtr := 0;
  try
  CharCount := 0;
  LazSerial1.Device:='COM6';
  LazSerial1.Open;
  //LazSerial1.SynSer.SendInteger(Ctrl_Z);
  LazSerial1.SynSer.SendInteger(Ctrl_D);
  finally
  end;
end;

procedure TfmSerialTest.LazSerial1RxData(Sender: TObject);

begin
  CommBuffer[CommBufferPtr] := LazSerial1.synser.RecvByte(0);
  if CommBufferPtr < MAXBUFF then
    inc( CommBufferPtr )
  else
    CommBufferPtr := 0;
  inc(CharCount);
end;

procedure TfmSerialTest.Timer1Timer(Sender: TObject);
var       BufferPtr: longint;
begin
  eCharCount.Text:= IntToStr(CharCount);
  BufferPtr := LastCommBufferPtr;
  while BufferPtr <> CommBufferPtr do begin
    Memo1.Lines.Text := Memo1.Lines.Text + char(CommBuffer[BufferPtr]); //strData;
    if BufferPtr < MAXBUFF then
      inc(BufferPtr)
    else
      BufferPtr := 0;
  end;
  LastCommBufferPtr := BufferPtr;
end;

end.
The "Test" button sends a Ctrl-T character to which the device responds with a string of 480 characters (true in this case, but actually bytes), but the CharCount variable consistently reads 484. If I copy and paste the contents of the memo into Notepad++, it shows 5 lines and 488 characters as file size. It appears that the memo adds CR+LF, and when I delete the newlines, it shows 480 characters and one line.

The "Start" button sends Ctrl-A and the device responds with a stream of byte pairs at 4800 bytes per second, and the "Stop" button sends Ctrl-D which stops transmission. I clicked Start and then quickly clicked Stop, and the CharCount showed about 1400 bytes. But the CharCount continued to increment to over 4000. Apparently LazSerial1.RxData continues to fire the OnRxData event, even though nothing more is being transmitted.

[edit] I verified with a scope that there is no activity on the serial connection. I was able to close and then re-open the port, and the spurious firing of the RxData event no longer occurred. At that point the CharCount showed 7040, and the form controls seemed active. Before closing and opening, the form controls were very sluggish - apparently the RxData event was hogging most of the resources.
« Last Edit: April 16, 2017, 07:39:05 pm by PStechPaul »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial: reading and displaying multiple characters
« Reply #5 on: April 17, 2017, 02:02:38 am »
hello,
if you have a terminal char in your frames ( may be the ? char in your case), you can try to synchronize the serial receive event with it using the RecvTerminated function like this for example :
Code: Pascal  [Select][+][-]
  1. procedure TFMain.SerialRxData3(Sender: TObject);
  2.   var Str : string;
  3. begin
  4.   Str :=  Serial.RecvTerminated(150,'?');
  5.   if Serial.SynSer.LastError = 0 then
  6.   begin
  7.     Memo.Lines.BeginUpdate;
  8.     Memo.Lines.Add(Str);
  9.      Memo.Lines.EndUpdate;
  10.     Memo.SelStart := Length(Memo.Lines.Text)-1;
  11.     Memo.SelLength:=0;
  12.   end
  13.   Else
  14.     begin
  15.        Memo.Lines.Add('Error : ' + Serial.SynSer.LastErrorDesc);
  16.     end;
  17.   end;

Result in attachment

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #6 on: April 17, 2017, 02:22:48 am »
There are no special characters in the stream of bytes transmitted by the device to the USB serial port. The Ctrl-T command causes transmission of a stream of exactly 240 characters, and my application checks the port by using the CharCount. In actual operation, the bytes are transmitted continuously until a STOP command (Ctrl-D) is received.

Does TLazSerial support overlapped communication? It needs to be able to respond quickly to a button click that sends a command byte while receiving the stream of data.

Thanks.

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial: reading and displaying multiple characters
« Reply #7 on: April 17, 2017, 02:34:28 am »
There are no special characters in the stream of bytes transmitted by the device to the USB serial port.

Strange   %) because in the frame that you show us , the character ? seems to be always at the end of a sequence of char. Is it a real frame ? if not  can you show us a real frame ?
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #8 on: April 17, 2017, 02:47:49 am »
Here is one "frame" of 480 characters as copied from the Memo, excluding whitespace ahead and behind the block of characters:
Code: [Select]
000102030405060708090:0;0<0=0>0?101112131415161718191:1;1<1=1>1?202122232425262728292:2;2<2=2>2?303132333435363738393:3;3<3=3>3?404142434445464748494:4;4<4=4>4?505152535455565758595:5;5<5=5>5?606162636465666768696:6;6<6=6>6?707172737475767778797:7;7<7=7>7?808182838485868788898:8;8<8=8>8?909192939495969798999:9;9<9=9>9?:0:1:2:3:4:5:6:7:8:9:::;:<:=:>:?;0;1;2;3;4;5;6;7;8;9;:;;;<;=;>;?<0<1<2<3<4<5<6<7<8<9<:<;<<<=<><?=0=1=2=3=4=5=6=7=8=9=:=;=<===>=?>0>1>2>3>4>5>6>7>8>9>:>;><>=>>>?Here is the assembly code for the PIC18F2420 device that sends the stream:
Code: [Select]
test:
bsf flg10,START ;indicate start test mode
movff timer2,temp ;timer2,temp
swapf temp,W ;Get high nibble
andlw B'00001111' ;clear high nibble
addlw '0'
rcall PutTxBuffer
movf timer2,W ;timer2,W
andlw B'00001111' ;clear high nibble
addlw '0'
rcall PutTxBuffer
movlw D'239'
cpfseq timer2 ;finish test if end of sequence
bra tm2isr99

movlw CR ;End of test data
rcall PutTxBuffer
movlw LF
rcall PutTxBuffer
; clrf txmode
bcf flg10,START ;Sequence ended
bcf flg10,TEST ;end test mode
bra tm2isr99
[edit] Looking at that code, it appears that a CrLf is added after the 480 characters have been sent. But it appears that the Memo has two CrLf pairs ahead of and behind the block. When I copy and paste into Notepad++ it shows five lines and size of 488. When I strip the CrLfs it is the correct 480 characters.
« Last Edit: April 17, 2017, 03:07:52 am by PStechPaul »

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #9 on: April 17, 2017, 03:31:43 am »
Based on that, I modified my code as follows:
Code: [Select]
const
  Ctrl_A = 01;
  Ctrl_D = 04;
  Ctrl_T = 20;
  Ctrl_Z = 26;
  LF = 10;
  CR = 13;
  MAXBUFF = 5000;

procedure TfmSerialTest.LazSerial1RxData(Sender: TObject);
var       RecvData: byte;
begin
  RecvData := LazSerial1.synser.RecvByte(0);
  if RecvData > CR then begin
    CommBuffer[CommBufferPtr] := RecvData;
    if CommBufferPtr < MAXBUFF then
      inc( CommBufferPtr )
    else
      CommBufferPtr := 0;
    inc(CharCount);
  end;
end;   

I have attached a screenshot:

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #10 on: April 27, 2017, 04:11:40 am »
I have returned to this project and I made several improvements. I am also using it now with a different serial device that answers a "?" with a set of ID strings, and all others with "Error". It works OK but if I close the COM port in the program or by cutting power to the device, the program hangs up. It seems to be stuck in the following:
Code: [Select]
function TBlockSerial.CanEvent(Event: dword; Timeout: integer): boolean;
var
  ex: DWord;
  y: Integer;
  Overlapped: TOverlapped;
begin
  FillChar(Overlapped, Sizeof(Overlapped), 0);
  Overlapped.hEvent := CreateEvent(nil, True, False, nil);
  try
    SetCommMask(FHandle, Event);
    SetSynaError(sOK);
    if (Event = EV_RXCHAR) and (Waitingdata > 0) then
      Result := True
    else
    begin
      y := 0;
      if not WaitCommEvent(FHandle, ex, @Overlapped) then
        y := GetLastError;
      if y = ERROR_IO_PENDING then
      begin
        //timedout
        WaitForSingleObject(Overlapped.hEvent, Timeout);
        SetCommMask(FHandle, 0);
        GetOverlappedResult(FHandle, Overlapped, DWord(y), True);
      end;
      Result := (ex and Event) = Event;
    end;
  finally
    SetCommMask(FHandle, 0);
    CloseHandle(Overlapped.hEvent);
  end;
end;

Here is my code:
Code: [Select]
const
  Ctrl_A = 01;
  Ctrl_D = 04;
  Ctrl_T = 20;
  Ctrl_Z = 26;
  LF = 10;
  CR = 13;
  MAXBUFF = 5000;
var
  fmSerialTest: TfmSerialTest;
  CharCount: longint;
  CommBuffer: Array[0..MAXBUFF+1] of byte;
  CommBufferPtr, LastCommBufferPtr: longint;
  Test: boolean = FALSE;
implementation

{$R *.lfm}

{ TfmSerialTest }

procedure TfmSerialTest.Button1Click(Sender: TObject);
begin
  LazSerial1.ShowSetupDialog;
  LazSerial1.Open;
end;

procedure TfmSerialTest.Button2Click(Sender: TObject);
begin
  LazSerial1.Close;
end;

procedure TfmSerialTest.btStartClick(Sender: TObject);
begin
  Test := FALSE;
  LazSerial1.SynSer.SendByte(Ctrl_A);
end;

procedure TfmSerialTest.btStopClick(Sender: TObject);
begin
  LazSerial1.SynSer.SendByte(Ctrl_D);
end;

procedure TfmSerialTest.btTestClick(Sender: TObject);
begin
  Test := TRUE;
  LazSerial1.SynSer.SendByte(Ctrl_T);
end;

procedure TfmSerialTest.FormCreate(Sender: TObject);
begin
  LazSerial1.BaudRate := br_57600;
  CommBufferPtr := 0;
  LastCommBufferPtr := 0;
  try
  CharCount := 0;
  LazSerial1.Device:='COM21';
  LazSerial1.Open;
  LazSerial1.SynSer.SendByte(Ctrl_D);
  except
    MessageDlg('Error','Error opening default port',mtConfirmation,[mbOK],'');
  end;
end;

procedure TfmSerialTest.LazSerial1RxData(Sender: TObject);
var       RecvData: byte;
begin
  RecvData := LazSerial1.synser.RecvByte(0);
  if (not Test) or (RecvData > CR) then begin
    CommBuffer[CommBufferPtr] := RecvData;
    if CommBufferPtr < MAXBUFF then
      inc( CommBufferPtr )
    else
      CommBufferPtr := 0;
    inc(CharCount);
  end;
end;

procedure TfmSerialTest.Memo1KeyPress(Sender: TObject; var Key: char);
begin
  LazSerial1.SynSer.SendByte(byte(Key));
end;

procedure TfmSerialTest.Timer1Timer(Sender: TObject);
var       BufferPtr: longint;
begin
  Memo1.SetFocus;
  eCharCount.Text:= IntToStr(CharCount);
  BufferPtr := LastCommBufferPtr;
  while BufferPtr <> CommBufferPtr do begin
    Memo1.Lines.Text := Memo1.Lines.Text + char(CommBuffer[BufferPtr]); //strData;
      Memo1.SelStart:= Length(Memo1.Lines.Text);
    if BufferPtr < MAXBUFF then
      inc(BufferPtr)
    else
      BufferPtr := 0;
  end;
  LastCommBufferPtr := BufferPtr;
end;
I thought the  "LazSerial1.Close;" would work, but the button for "Open" does not enter the OnClick handler:

  LazSerial1.ShowSetupDialog;
  LazSerial1.Open;

Actually, after a long time (several minutes), it does work. Perhaps there is a very long timeout?

[edit]If there is no communication activity, the open and close buttons are responsive. But once communication occurs, the buttons need to be clicked several times before they respond. It's as if the button click message gets ignored until a brief window opens so the system can respond.

I can see that even without any activity on the COM port, the following line is repeatedly executed:
Code: [Select]
        WaitForSingleObject(Overlapped.hEvent, Timeout);
So that means GetLastError = ERROR_IO_PENDING.
« Last Edit: April 27, 2017, 05:31:01 am by PStechPaul »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

PStechPaul

  • Jr. Member
  • **
  • Posts: 76
    • P S Technology, Inc.
Re: TLazSerial: reading and displaying multiple characters
« Reply #12 on: April 27, 2017, 07:02:19 pm »
That is not quite what I am concerned about. I am using the "onRxData" event to respond quickly anytime data is received. I need to do other things when no data is available. But if I set a breakpoint in the function:
Code: [Select]
function TBlockSerial.CanEvent(Event: dword; Timeout: integer): boolean;while no data is being received, it shows it is being called regularly. While data is being received, the "LazSerial1RxData" function is called as expected from the event, and it executes this part of the function:
Code: [Select]
    if (Event = EV_RXCHAR) and (Waitingdata > 0) then
      Result := True
But once all characters have been received, the function is being called regularly (I don't know how quickly, but the timeout is 100), where it executes this code:
Code: [Select]
      begin
        //timedout
        WaitForSingleObject(Overlapped.hEvent, Timeout);
        SetCommMask(FHandle, 0);
        GetOverlappedResult(FHandle, Overlapped, DWord(y), True);
      end;
      Result := (ex and Event) = Event;
When it is in this state, the buttons on the form are very sluggish and don't respond except after multiple taps. Once the port is closed, the buttons act immediately, and the CanEvent code is no longer being called. This is a serious problem that renders the component unusable in my application. I have supplied my complete code. Can you duplicate the problem?
« Last Edit: April 27, 2017, 07:06:45 pm by PStechPaul »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial: reading and displaying multiple characters
« Reply #13 on: April 27, 2017, 11:49:49 pm »
hello,
i don't think that you are in a good way with your code.
Your timer is an application killer. When i try to execute your code with no port COM21 available . I have a frozen exception message dialog.

Friendly, J.P
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial: reading and displaying multiple characters
« Reply #14 on: April 28, 2017, 12:28:23 am »
with no timer and this code in your SerialTestMain.pas  :
Code: Pascal  [Select][+][-]
  1. procedure TfmSerialTest.LazSerial1RxData(Sender: TObject);
  2. var Str : string;
  3. begin
  4. Str :=  LazSerial1.RecvTerminated(150,'?');
  5. if LazSerial1.SynSer.LastError = 0 then
  6. begin
  7.   Str := Str + '?';
  8.   Memo1.Lines.BeginUpdate;
  9.   Memo1.Lines.Add(Str);
  10.   CharCount := CharCount + Length(Str);
  11.   eCharCount.Text:= IntToStr(CharCount);
  12.   Memo1.Lines.EndUpdate;
  13.   Memo1.SelStart := Length(Memo1.Lines.Text)-1;
  14.   Memo1.SelLength:=0;
  15. end
  16. Else
  17.   begin
  18.      Memo1.Lines.Add('Error : ' + LazSerial1.SynSer.LastErrorDesc);
  19.   end;
  20.  
  21. end;                  

sending this packet in the serial port :
Code: Pascal  [Select][+][-]
  1. Str := '000102030405060708090:0;0<0=0>0?101112131415161718191:1;1<1=1>1?202122232425262728292:2;2<2=2>2?' +
  2.         '303132333435363738393:3;3<3=3>3?404142434445464748494:4;4<4=4>4?505152535455565758595:5;5<5=5>5?' +
  3.         '606162636465666768696:6;6<6=6>6?707172737475767778797:7;7<7=7>7?808182838485868788898:8;8<8=8>8?' +
  4.         '909192939495969798999:9;9<9=9>9?:0:1:2:3:4:5:6:7:8:9:::;:<:=:>:?;0;1;2;3;4;5;6;7;8;9;:;;;<;=;>;?' +
  5.         '<0<1<2<3<4<5<6<7<8<9<:<;<<<=<><?=0=1=2=3=4=5=6=7=8=9=:=;=<===>=?>0>1>2>3>4>5>6>7>8>9>:>;><>=>>>?';

i get what you can see in the attachment
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

 

TinyPortal © 2005-2018