Recent

Author Topic: TLazSerial : serial port component for Lazarus (windows and linux).  (Read 342167 times)

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #210 on: January 17, 2017, 07:06:54 am »
hello,
version with temp buffer :
Code: Pascal  [Select][+][-]
  1. // global variables
  2. var  CurPos : integer;
  3.   FTempStr: String;        
  4. // ========================================
  5. procedure TFMain.SerialRxData(Sender: TObject);
  6. var S,HexaS : string;
  7.     i : integer;
  8. begin
  9.     S :=  Serial.ReadData;
  10.        CurPos := Pos( Char(0) ,S);
  11.        if CurPos = 0 then begin
  12.     // Wait for end of frame ( 0x00 )
  13.     // Data put in temp String Buffer FTempStr
  14.           FTempStr := FTempStr + S;
  15.        end
  16.       else begin
  17.     // End of frame :  FTempStr contains the whole frame
  18.          FTempStr := FTempStr + Copy( S, 1, CurPos-1);
  19.     // code to display in hexa the received frame
  20.       for I := 1 to Length(FTempStr) do begin
  21.            HexaS := HexaS + InttoHex(Ord(FTempStr[I]),2)+ ' ';
  22.        end;
  23.       Memo.Lines.BeginUpdate;
  24.       Memo.Lines.Add(HexaS);
  25.       Memo.Lines.EndUpdate;
  26.       Memo.SelStart := Length(Memo.Lines.Text)-1;
  27.       Memo.SelLength:=0;
  28.       // data after the end of frame are put in the buffer
  29.       FTempStr := Copy(S,CurPos +1, Length(S) - CurPos);
  30.       end;
  31. end;                              
  32.  

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

ddimov007

  • Newbie
  • Posts: 5
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #211 on: January 20, 2017, 07:38:31 pm »
Hello guys,

I can't get the expected baud rates when using LazSerial on a Raspberry pi hardware with Jessy and with some code modification on my side.
I can't figure out what it could be wrong. Please HELP:

prerequisites:
-I am very new to programming on RPi and I haven't got too much knowledge about the actual UART hardware that is behind ttyAMA0. I am not even sure if this is released by RPi foundation.
-running RPi 3
-full and latest update of the whole system
- download and installed compiled latest Lazarus 3.1.1.
- fixed the missing coutbegin.o coutend.o links (now no warnings when compiling)
- enabled com port
- swapped and returned back the two serial ports (for some reason LazSerial only wants to talk to ttyAMA0)
- disabled console
- disabled Bluetooth to allow communication to be directed to IO port pins
- changed uart clock: "init_uart_clock=64000000"
- hooked a trusty modern 140Mpoints scope to the TX pin

 
Tested all the above with minicom:  "minicom -b 4000000 -o -D /dev/ttyAMA0"
I must say it works beautifully!

Now, my application with Lazarus: Lazarus itself works great, at least I have no doubts about the installation and compiling yet.
I modified LazSerial component to include baud rates 1000000, 2000000, 3000000 and 4000000.
The result is quite poor: I get 500Kbps when setting 1Mbit (please check the table of results below). If I initialise the port through minicom @4Mbps and only send data through my application then I get the 4Mbps out of the TX pin (for some reason both minicom and my application can share the serial port without conflicts).

I modified again LazSerial component to remove the definitions for baud rates. Now I can set any integer baud rate instead of selecting one of several populated in the ComboBox of the component.
In the process of doing that I also removed some code that was checking for out of range baud rate values.

Below is a table of what I am setting and what I get:
Set baud rate | Measured baud rate
1Mbps           |  500 Kbps
2Mbps           |  588.2 Kbps
3Mbps           |  952.4 Kbps
4Mbps           |  1Mbps

The low baud rates are also messed up.

My aim is to get the 1-4Mbps working.

I suspect there is some variable which overflows.

Has anybody got any idea where in the code of LazSerial and/or any required packaged I should look for the problem?

Some of the code I came across was written by "Jurassic Pork".
Jurassic Pork, do you have any ideas?

I will be happy to share the code if required. Just let me know.

Many thanks in advance!

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #212 on: January 21, 2017, 11:25:52 am »
hello,
there is a new version of TLazSerial    :
Quote
V 0.2  01/2017 : BaudRates for UNIX fixed - synaser files units renamed (with laz prefix)
 scan port for linux improved

TLazserial is now in Github    here
the 0.2 version is the master version (in progress)

Be careful ! someone (zbyna) has created another version of TLazserial in github with the version 0.1 of TLazserial . It is not the official version !!!!

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

ddimov007

  • Newbie
  • Posts: 5
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #213 on: January 22, 2017, 09:39:20 am »
Thanks 10x JP!
I will test this first thing on Monday.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #214 on: January 22, 2017, 04:25:39 pm »
-running RPi 3
- enabled com port
- swapped and returned back the two serial ports (for some reason LazSerial only wants to talk to ttyAMA0)
- disabled console
- disabled Bluetooth to allow communication to be directed to IO port pins
- changed uart clock: "init_uart_clock=64000000"
RPi 3 behaves different then RPi 1 and 2. If you have older Pi available then test if it works. Read this: http://www.briandorey.com/post/Raspberry-Pi-3-UART-Overlay-Workaround. If you search the net for "Raspberry Pi 3B UART BT problems" you will see that there are a lot of problems, especially that UART speed is tied to clock which can change dynamically. Try to have some low fixed speed and turn off all power savings. Old Pi had UART0 as serial interface, but in Pi3 UART0 is used for Bluetooth so without a workaround UART1 on GPIO14 & 15 should be used. The reason why this was changed is that UART0 was influenced by the core_freq and that's important for BT. However nothing stops you to try some other Linux flavor like Arch or TinyCore, or bare metal like Ultibo, and see if something is different or fixed. See also http://raspberrypi.stackexchange.com/questions/45570/how-do-i-make-serial-work-on-the-raspberry-pi3 and http://raspberrypi.stackexchange.com/questions/45143/how-to-disable-dma-when-using-uart-on-the-raspberry-pi-2.

Quote
- hooked a trusty modern 140Mpoints scope to the TX pin
Are you measuring directly on Pi header pin or later from some RS232 voltage levels? Do you send a single char or thousands in your tests (FIFO is just 8 bytes)?

Quote
Tested all the above with minicom:  "minicom -b 4000000 -o -D /dev/ttyAMA0"
I must say it works beautifully!
Can you try to send some big file with nothing else but thousands of 'U' characters directly to port with redirection from command line without using minicom and report if you still find that it works as good as in minicom. Then try to send the same file from minicom and report if it behaves exactly the same. Btw, are your tests from Pi booted to console, or you are running some desktop and window manager? Can you retest your Lazarus application just from console, before any desktop is booted?

Quote
I modified LazSerial component to include baud rates 1000000, 2000000, 3000000 and 4000000.
The result is quite poor: I get 500Kbps when setting 1Mbit (please check the table of results below). If I initialise the port through minicom @4Mbps and only send data through my application then I get the 4Mbps out of the TX pin (for some reason both minicom and my application can share the serial port without conflicts).
Can you take a look into minicom sources to see how it does the port setup? Can you show the simplest code you use for testing? How do you initialize port from LazSerial? Maybe your modifications are not enough. You can try some other serial library like Platform eXtended Library (PXL), or directly latest trunk version of Synapse SynaSer. You can also try to setup port from command line before use in your application. If that works then you can call script or external sh process from your application.

Additional info you might be interested in:
https://www.raspberrypi.org/forums/viewtopic.php?t=57845&p=438417
https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=17559
https://github.com/hzeller/rpi-gpio-dma-demo
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

ddimov007

  • Newbie
  • Posts: 5
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #215 on: January 23, 2017, 05:40:52 pm »
JP,

Can you share your definitions for thermios.inc?




hello,
there is a new version of TLazSerial    :
Quote
V 0.2  01/2017 : BaudRates for UNIX fixed - synaser files units renamed (with laz prefix)
 scan port for linux improved

TLazserial is now in Github    here
the 0.2 version is the master version (in progress)

Be careful ! someone (zbyna) has created another version of TLazserial in github with the version 0.1 of TLazserial . It is not the official version !!!!




Friendly, J.P

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #216 on: January 24, 2017, 06:16:24 am »
Hello,
JP,
Can you share your definitions for thermios.inc?

Why ? I haven't changed the file termios.inc
The file termios.inc for linux is in the folder  Lazarus/fpc/3.0.0/source/rtl/linux

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

ddimov007

  • Newbie
  • Posts: 5
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #217 on: January 24, 2017, 10:45:41 am »
Hi JP,

My termios.inc doesn't have the definitions for the baud rates, used in the latest version of  Lazserial V0.2 (B2000000, B4000000...).
At least I don't have the correct one on my system. Without the constant definitions in termios.inc Lazserial would not compile without modifications.

However, because I only need one baud rate I figured by testing and guesswork what the constant is for 4Mbps and now it works well for that baud rate.
Others would probably benefit from having termios.inc too.


I take the opportunity to thank you for your help and also Avra: Apologies I didn't reply to Avra - there was a lot of food for though in his post and plenty of resources to look at.


Many thanks!

Hello,
JP,
Can you share your definitions for thermios.inc?

Why ? I haven't changed the file termios.inc
The file termios.inc for linux is in the folder  Lazarus/fpc/3.0.0/source/rtl/linux

Friendly, J.P

Migrant

  • Newbie
  • Posts: 4
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #218 on: February 11, 2017, 04:29:56 pm »
Dear Antico Porco,

Many thanks for updating this essential package, which should be part of the standard Lazarus distribution.

I used the original spdoserial code, with some difficulty.

However, using your ReadData function, lines greater than 64 characters have a CR/CRLF inserted, which corrupts my incoming packets.
--------------------------------
($.A539738020202020000FC1800009C40ED44C7CE257812BD3B0002010100098
DF237)
--------------------------------

I have added the RecvTerminated function into your LazSerial.pas file, from the original sdposerial.pas.

---------------------------------------
function TLazSerial.RecvTerminated(timeout: integer; const EndTerm: ansistring): string;
begin
  result:='';
  if FSynSer.Handle=INVALID_HANDLE_VALUE then
    ComException('can not read from a closed port.');
  result:=FSynSer.RecvTerminated(timeout,EndTerm);
end;
---------------------------------------

This now works beautifully; would you consider adding this function into your release package please?

Thanks again for your efforts.

Migrant
 

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #219 on: February 12, 2017, 05:14:25 am »
hello,
Migrant i can add your function in TLazSerial  component but before i want to understand why you have a problem with readdata function.

1 - What is your serial port baudRate ?
2 - What is your Terminator String ?
3 - What is your data frame length ?
4 - When you use Readdata , do you use a temp Buffer like this ? :
Code: Pascal  [Select][+][-]
  1.  procedure TFMain.SerialRxData(Sender: TObject);    
  2. var Str : string;
  3. begin
  4.   Str :=  Serial.ReadData;
  5.   CurPos := Pos( Char(10) ,Str);
  6.   if CurPos = 0 then begin
  7.     FTempStr := FTempStr + Str;
  8.   end
  9.   else begin
  10.     FTempStr := FTempStr + Copy( Str, 1, CurPos-1);
  11.     Memo.Lines.BeginUpdate;
  12.     Memo.Lines.Add(FtempStr);
  13.      Memo.Lines.EndUpdate;
  14.     Memo.SelStart := Length(Memo.Lines.Text)-1;
  15.     Memo.SelLength:=0;
  16.     AnalyseTrames(FtempStr);
  17.     FTempStr := Copy(Str,CurPos +1, Length(Str) - CurPos);
  18.   end;    
  19.  end;

 I have tried to use the RecvTerminated function like this :
 
Code: Pascal  [Select][+][-]
  1. procedure TFMain.SerialRxData2(Sender: TObject);      
  2.  var Str : string;
  3. begin
  4.   Str :=  Serial.RecvTerminated(1000,Chr(13)+Chr(10));
  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;  

it's OK but if you receive data without terminator string the program can freeze. 

Readdata use recvpacket function of synaser :
 
Quote
Read all available data and return it in the function result string.
 
never freeze the program.

Friendly, J.P
« Last Edit: February 12, 2017, 05:17:02 am by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Thaddy

  • Hero Member
  • *****
  • Posts: 14157
  • Probably until I exterminate Putin.
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #220 on: February 12, 2017, 08:28:53 am »
Hm yes, that nasty terminator. On raw data you can avoid it easily by using RcvStreamSize procedure  and WaitingData function. No string terminator.
« Last Edit: February 12, 2017, 08:30:47 am by Thaddy »
Specialize a type, not a var.

Migrant

  • Newbie
  • Posts: 4
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #221 on: February 12, 2017, 11:41:31 am »
Dear JP,
Thanks for your swift response.

1 - What is your serial port baudRate ?  115200baud
2 - What is your Terminator String ?       STARTC='('; ENDC=')'
3 - What is your data frame length ?      Variable
4 - When you use Readdata , do you use a temp Buffer like this ? : See below

Code: Pascal  [Select][+][-]
  1. procedure TConsole.LazSerial1RxData(Sender: TObject);
  2. var
  3.   indata : string;
  4.   data   : string;
  5.   x,l    : integer;
  6. begin
  7.   if (LazSerial1.Active=TRUE) and (LazSerial1.DataAvailable=TRUE) then
  8.   begin
  9. //    LazSerial1.WriteData(XOFF);  //Stall for time....
  10. //    indata:=LazSerial1.ReadData;
  11.     indata:=LazSerial1.RecvTerminated(0,ENDC);
  12.     l:=Length(indata);
  13.     if (MAXPKTSIZE>l) then
  14.     begin
  15.       if (l>1) then
  16.       begin
  17.         x:=pos(STARTC,indata);
  18.         data:=Copy(indata, x, l);
  19.         if (data[1]=STARTC) then
  20.         begin
  21.             PktRdy:=true;
  22.           Console.mRx.Lines.Add(data+ENDC);
  23.           Console.ImageList1.GetBitmap(GRNLED,Console.RxLED.Picture.Bitmap);
  24.           Console.RxLEDTimer.Enabled:=FALSE;
  25.           Console.RxLEDTimer.Interval:=100;
  26.           Console.RxLEDTimer.Enabled:=true;
  27.           Packets.BreakPkt(data);
  28.         end;
  29.       end;
  30.     end;
  31.     LazSerial1.WriteData(XON);
  32.   end;
  33. end;  
  34.  


Migrant
« Last Edit: February 12, 2017, 11:57:11 am by Migrant »

Jurassic Pork

  • Hero Member
  • *****
  • Posts: 1228
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #222 on: February 12, 2017, 04:54:55 pm »
hello,
i have tried to simulate data like you  have  and  using readdata to read the data with a temp Buffer. It seems to be OK  (at speed 9600 and 115200) .

Data send  every 2 seconds :
Quote
(00112233445566778899abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ)
Global variable :
Code: Pascal  [Select][+][-]
  1.  CurPos : integer;
  2.   FTempStr: String;

the procedure   

Code: Pascal  [Select][+][-]
  1. procedure TFMain.SerialRxData2(Sender: TObject);
  2. var Str : string;
  3. begin
  4. Str := Serial.Readdata;
  5. CurPos := Pos(')' ,Str);
  6.   if CurPos = 0 then begin
  7.      // put data in buffer string if no terminator
  8.      FTempStr := FTempStr + Str;
  9.    end
  10.   else
  11.   begin
  12.     FTempStr := FTempStr + Copy( Str, 1, CurPos-1);
  13.     ;
  14.     if FtempStr[1] = '(' then
  15.          begin
  16.            // remove first chr  
  17.            delete(FtempStr,1,1);
  18.            // display data in a memo
  19.            Memo.Lines.BeginUpdate
  20.            Memo.Lines.Add(FtempStr);
  21.            Memo.Lines.EndUpdate;
  22.            //scroll
  23.            Memo.SelStart := Length(Memo.Lines.Text)-1;
  24.            Memo.SelLength:=0;
  25.          end;    
  26.       FTempStr := Copy(Str,CurPos + 1, Length(Str) - CurPos);
  27.   end;
  28.   end;  

Result in attachment

Friendly, J.P

« Last Edit: February 12, 2017, 04:57:21 pm by Jurassic Pork »
Jurassic computer : Sinclair ZX81 - Zilog Z80A à 3,25 MHz - RAM 1 Ko - ROM 8 Ko

Migrant

  • Newbie
  • Posts: 4
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #223 on: February 12, 2017, 06:39:35 pm »
Dear JP,

I incorporated your code and I still get a wrapped line; see ReadData.png
The Rx memo is directly displaying the buffer from ReadData.

Code: Pascal  [Select][+][-]
  1. procedure TConsole.LazSerial1RxData(Sender: TObject);
  2. var Str : string;
  3. begin
  4. Str := LazSerial1.Readdata;
  5. Console.mRx.Lines.Add(Str);  
  6.  
  7.  

The correct handling is shewn in RecvTerminated.png

The next thing to do is to OutHex the buffer contents to find the inserted character(s).

BTW, I'm developing under 64-bit Windows-7 and porting to a Raspberry Pi 3 target.
« Last Edit: February 12, 2017, 06:45:30 pm by Migrant »

Migrant

  • Newbie
  • Posts: 4
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #224 on: February 12, 2017, 09:51:31 pm »
Okay, I've dumped the same packet using both methods; the one labelled "BAD" is the ReadData method.
There are two bytes in error, should be $91, but is instead $FB
I'm rightly getting checksum errors and therefore no data!


 (  $  .  A  5  3| E  8| 3  8| 0  5| 0  5| 0  5| 0  2| F  B| E  D| 0  0| 0  0  0  0  0  0  0  3  E  8  E  B  8  5  C  7  A  F  0  0  6  4  0  0  0  A  0  8  0  2  0  5  0  1  0  1  0  0  0  9  A  D  F  2  2  3  )
28/24/2E/41/35/33/45/38/33/38/30/35/30/35/30/35/30/32/46/42/45/44/30/30/30/30/30/30/30/30/30/33/45/38/45/42/38/35/43/37/41/46/30/30/36/34/30/30/30/41/30/38/30/32/30/35/30/31/30/31/30/30/30/39/41/44/46/32/32/33/29/BAD
28/24/2E/41/35/33/45/30/33/38/30/35/30/35/30/35/30/32/39/31/45/44/30/30/30/30/30/30/30/30/30/33/45/38/45/42/38/35/43/37/41/46/30/30/36/34/30/30/30/41/30/38/30/32/30/35/30/31/30/31/30/30/30/39/31/37/46/32/36/36/29/GOOD
 (  $  .  A  5  3| E  0| 3  8| 0  5| 0  5| 0  5  0  2  9  1  E  D  0  0  0  0  0  0  0  0  0  3  E  8  E  B  8  5  C  7  A  F  0  0  6  4  0  0  0  A  0  8  0  2  0  5  0  1  0  1  0  0  0  9  1  7  F  2  6  6  )
                                                       ^  ^
                                                       91 is correct


Time for a beer.
« Last Edit: February 13, 2017, 09:08:20 am by Migrant »

 

TinyPortal © 2005-2018