Recent

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

six1

  • Jr. Member
  • **
  • Posts: 76
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #285 on: February 18, 2019, 07:01:28 am »
maybe the problem occours only by compiling in debug mode?
Did you try to compile in release mode?

best, michael

BeaglePi

  • New Member
  • *
  • Posts: 29
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #286 on: February 18, 2019, 07:44:41 am »
I did try that some time ago - but it could be worth another try!

I'd wondered whether I could set active to false after using the component and then set it to true again before the next read, but it doesn't work.  The component then fails at the Application.processMessages line.

BeaglePi

  • New Member
  • *
  • Posts: 29
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #287 on: February 18, 2019, 11:09:16 am »
But looking at the code I see that it processes messages while waiting for the thread to terminate.  Maybe I should just have a small delay after closing it.

BeaglePi

  • New Member
  • *
  • Posts: 29
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #288 on: February 18, 2019, 09:00:17 pm »
Given that the problem often occurs between my calls to DataAvailable , i.e. when I am not knowingly using the component, it must be that the software running to trigger the RX event is competing for a resource.  Can I tell it only to run when I request DataAvailable and not to trigger the RX event?

JoeJ

  • Newbie
  • Posts: 1
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #289 on: February 22, 2019, 06:05:42 pm »
Hi,

the package LazSerial Version 0.2 can't be compiled under Raspian Stretch. Reason: The file "lazsynaser.pas" in lines 252..262 references undefined constants. They should be defined in file 'termios.inc'. In other operating systems and/or Lazarus versions they are, but not in Lazarus 2.0 under Raspbian Stretch, Nov 2018 edition.

As a quick and very dirty intermediate fix I replaced the constants in these lines with literal expressions. This worked, but of course that's no tidy solution.


Regards --  Joe


Thaddy

  • Hero Member
  • *****
  • Posts: 9293
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #290 on: February 22, 2019, 06:25:35 pm »
I did the same and reported it. But anyway: components are not the way to go here, simply use synaser in a non-visual manner. That would skip any incompatibilities caused by the component author and is much easier in the end. No "sleur en pleur" (dutch) or "drag and dump" "programming" involved. Keep components to the visual parts of your application is my personal opinion. Always has been.

It's an opinion, so feel free do digress...
« Last Edit: February 22, 2019, 06:29:24 pm by Thaddy »
also related to equus asinus.

BeaglePi

  • New Member
  • *
  • Posts: 29
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #291 on: February 23, 2019, 04:09:41 am »
Problem reconnecting to Arduino - I'm desperate!

OK, so I reduced myself to one Lazserial component by connecting an Arduino Mega and hooking up to the extra serial channels to that.

The problem is that when I fire up the Lazarus program it has difficulty connecting to the Arduino.  The receive light on the Arduino flashes to show that I am interrogating it but the transmit light stays off.  And LazSerial states that no data are available.  Even when I program the Arduino to echo every char.

On the other hand I do NOT have that problem when I interrogate it from the Arduino monitor - it responds immediately and correctly.

So it looks as though LazSerial may not be turning on Rx?

I could really use some help here!  I'm ready to burn it.

BeaglePi

  • New Member
  • *
  • Posts: 29
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #292 on: February 23, 2019, 09:32:30 am »
I'll try to post some code and see if that inspires any interest:

Sorry that it's not properly formatted.

Here's the Arduino:

void loop()
//Code borrowed and modified from Robin 2 on Arduino forum.
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '@';
    char endMarker = '!';
    char rc;
 
    while (Serial.available() > 0 && newData == false)
    {
        rc = Serial.read();

       //Serial.write (rc) ;

        if (recvInProgress == true)
        {
         if (rc != endMarker)
          {
           receivedChars[ndx] = rc;
           ndx++;
           if (ndx >= MAXSTRLEN)
            {
             ndx = MAXSTRLEN - 1;
            }
          }
            else
            {
             receivedChars[ndx] = '\0'; // terminate the string
             recvInProgress = false;
             ndx = 0;
             newData = false;
          //   Serial.println (receivedChars) ;
             translateSerialRequest () ;
            // memset (receivedChars, '\0', MAXSTRLEN) ;
            }
        }

        else if (rc == startMarker)
         {
          recvInProgress = true;
         }
    }
}

It eventually falls through into a command parser.  When the echo is turned on, nothing comes back after connection .

and a tiny part of the Pascal code:

 procedure LazWrites(StringOut: string);
   begin
    Form1.Timer1.Enabled:= false ;//Drive query and screen update
    Form1.LazSerialArduino.WriteData (stringOut) ;
    form1.LblQueryOut.Caption := stringOut ;
    RegisterStateConstant (CS_ARDUINOQUERYSENDING, false ) ;
    sleep(30) ;

    LazReads ;

    ClearAnswers ; //Checks for unanswered questions
   end;

  //Read from LazSerial and process the answer, then delete it from the stack
  //Only called when ArduinoQueryActive but not ArduinoQuerySending
  procedure LazReads;
   var
    readStr,
    workStr   : string ;
    Ido,
    Counter,
    endPos   : integer ;
   begin
     try

    form1.timer1.Enabled:= true ;

    if form1.LazSerialArduino.DataAvailable then
      readStr := form1.LazSerialArduino.ReadData else exit ;
      holdStr := holdStr + readStr ;   


LazWrites accepts a string that was popped from the query stack.  It might look like:
@V233!       -     rotate the valve to position 3.  Check in as query 23.  @ and! are start and end characters.

So this is running on Serial3 on the Mega at 9600 Baud.

@E34! queries the laser on Serial2 which returns a string of info 112 characters long, etc.

The point is, that if I send @V235! from the Arduino monitor, there is a buzz and the valve switches to position 5 and returns @V|23|Valve to pos 5|0!

When I start the Lazarus program and send the same command, nothing happens.  The Rx light on the Arduino flashes but there is no flash of Tx or a return.  It never sees data available and exits after
 if form1.LazSerialArduino.DataAvailable then ...

If I put a break point on that line and the two following and step through them repeatedly, then eventually the serial starts up and everything flows.

Any help very gratefully received!

FedCo

  • Newbie
  • Posts: 3
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #293 on: June 15, 2019, 02:07:46 pm »
Hello.

I ask for help.
In my program, there are delays of 30 seconds, sometimes often, sometimes rarely. Delays occur only when the program is connected to the COM port. after the hang, the program continues to work normally.
I use the LazSerial library.
The duration of delays is always the same.
Why do these delays occur? How to fix that they were not?
Code: Pascal  [Select]
  1. unit TenU;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, LazSerial, Forms,StdCtrls, ExtCtrls, LazSynaSer,dos;
  9.  
  10. type
  11.  
  12.   { TForm1 }
  13.  
  14.   { TTenesi_Creator }
  15.  
  16.   TTenesi_Creator = class(TForm)
  17.     ConBut: TButton;
  18.     deviceList: TComboBox;
  19.     Label1: TLabel;
  20.     Label10: TLabel;
  21.     Label13: TLabel;
  22.     Label14: TLabel;
  23.     Label15: TLabel;
  24.     Label16: TLabel;
  25.     Label2: TLabel;
  26.     Label3: TLabel;
  27.     Label4: TLabel;
  28.     Label5: TLabel;
  29.     Label6: TLabel;
  30.     Label7: TLabel;
  31.     Label9: TLabel;
  32.     Tenesi: TLazSerial;
  33.     Timer1: TTimer;
  34.     Timer2: TTimer;
  35.     procedure ConButClick(Sender: TObject);
  36.     procedure deviceListDropDown(Sender: TObject);
  37.     procedure FormCreate(Sender: TObject);
  38.     procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  39.     procedure Timer1Timer(Sender: TObject);
  40.     procedure Timer2Timer(Sender: TObject);
  41.  
  42.   private
  43.  
  44.   public
  45.  
  46.   end;
  47.  
  48. var
  49.   Tenesi_Creator: TTenesi_Creator;
  50.   ModeFly:byte;
  51.   Bat,Lat,Lon,Alt,AltG,Cog,GPSVSI,Sat,Speed,VSI,Curs:double;
  52.   Pitch,Roll:integer;
  53.  
  54.  
  55. implementation
  56.  
  57. {$R *.lfm}
  58.  
  59. { TForm1 }
  60.  
  61. procedure TTenesi_Creator.deviceListDropDown(Sender: TObject);
  62. begin
  63.  deviceList.Items.CommaText:=LazSynaSer.GetSerialPortNames;
  64. end;
  65.  
  66. procedure TTenesi_Creator.FormCreate(Sender: TObject);
  67. begin
  68. end;
  69.  
  70. procedure TTenesi_Creator.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  71. begin
  72.  If Tenesi.Active then Tenesi.Close;
  73. end;
  74.  
  75. procedure TTenesi_Creator.Timer1Timer(Sender: TObject);
  76. Var comanda,s:string;
  77. begin
  78.  if Bat<21 then Bat:=25.2
  79.            else bat:=bat-0.1;
  80.  if Curs>360 then Curs:=Curs-360
  81.              else Curs:=Curs+1;
  82.  Lat:=56.1234567;
  83.  Lon:=35.7654321;
  84.  if alt>1000 then alt:=-100
  85.              else alt:=alt+0.3;
  86.  ModeFly:=2;
  87.  VSI:=435.67;
  88.  
  89.  str(Pitch:4,s);          Label2.Caption:= 'Pit '+s;
  90.  str(Roll:4,s);           Label9.Caption:= 'Rol '+s;
  91.  str(Bat:2:2,s);          Label10.Caption:='Bat '+s;
  92.  str(Lat:3:7,s);          Label6.Caption:= 'Lat '+s;
  93.  str(Lon:3:7,s);          Label13.Caption:='Lon '+s;
  94.  str(AltG:5:2,s);         Label5.Caption:= 'AlG '+s;
  95.  str(Alt:5:2,s);          Label14.Caption:='Alt '+s;
  96.  str(Curs:4:2,s);         Label15.Caption:='Crs '+s;
  97.  str(Speed:4:2,s);        Label3.Caption:= 'Spe '+s;
  98.  Label16.Caption:='Модель ПК A2';
  99.  Label4.Caption:='Fly Mode GPS';
  100.  
  101.  Label1.Caption:='111111111111';
  102.  if Tenesi.Active
  103.   then
  104.    begin
  105.     Label1.Caption:='222222222222';
  106.     Comanda:='PK_A2,';
  107.     comanda:=comanda+'Mode: ';
  108.     case ModeFly of
  109.      0:comanda:=comanda+' MAN,';
  110.      1:comanda:=comanda+' ATT,';
  111.      2:comanda:=comanda+' GPS,';
  112.     end;
  113.     str(Bat:2:2,s);      comanda:=comanda+' Bat: '+s+#13#10;
  114.     Tenesi.WriteData(Comanda);
  115.     str(Lat:2:7,s);      comanda:='Lat: '+s+',';
  116.     str(Lon:2:7,s);      comanda:=comanda+' Lon: '+s+',';
  117.     str(AltG:4:2,s);     comanda:=comanda+'GPS alt: '+s+',';
  118.     str(Cog:3:2,s);      comanda:=comanda+'COG: '+s+',';
  119.     str(Speed:2:2,s);    comanda:=comanda+'Speed: '+s+',';
  120.     str(GPSVSI:3:2,s);   comanda:=comanda+'GPS VSI: '+s+',';
  121.     str(Sat:2:2,s);      comanda:=comanda+'Sat: '+s+#13#10;
  122.     Tenesi.WriteData(Comanda);
  123.     str(Alt:3:2,s);      comanda:='Alt: '+s+',';
  124.     //str(VSI:3:0,s);      comanda:=comanda+'VSI: '+s+',';
  125.     str(Curs:3:2,s);     comanda:=comanda+' Heading: '+s+#13#10;
  126.     Label1.Caption:='333333333333';
  127.     Tenesi.WriteData(Comanda);
  128.     Label1.Caption:='444444444444';
  129.    end;
  130.  Label1.Caption:='555555555555';
  131. end;
  132.  
  133. procedure TTenesi_Creator.Timer2Timer(Sender: TObject);
  134. Var HH,MM,CC,KK:word;
  135.     s,Comand:string;
  136. begin
  137.  Label1.Caption:='66666666666';
  138.  GetTime(HH,MM,CC,KK);
  139.  str(HH:2,s);
  140.  Comand:='Date/Time: 05.07.19 '+s+':';
  141.  Label7.Caption:=Comand;
  142.  str(MM:2,s);Comand:=Comand+s+':';
  143.  str(CC:2,s);Comand:=Comand+s;
  144.  Label7.Caption:=Comand;
  145.  Comand:=Comand+#13#10;
  146.  Label1.Caption:='77777777777';
  147.  If Tenesi.Active then Tenesi.WriteData(Comand);
  148.  Label1.Caption:='88888888888';
  149. end;
  150.  
  151. //Выполняется по нажатию на кнопку Подключение Устройства 1
  152. procedure TTenesi_Creator.ConButClick(Sender: TObject);
  153. begin
  154.  Tenesi.Device := deviceList.Text;
  155.  Tenesi.BaudRate:= LazSerial.br115200;
  156.  if Not Tenesi.Active  then Tenesi.Open
  157.                     else Tenesi.Close;
  158.  if Tenesi.Active
  159.   then ConBut.Caption:='Отключить'
  160.   Else ConBut.Caption:='Подключить';
  161. end;
  162.  
  163. end.  
  164.  
« Last Edit: June 15, 2019, 02:14:16 pm by FedCo »

avra

  • Hero Member
  • *****
  • Posts: 1736
    • Additional info
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #294 on: June 15, 2019, 02:35:10 pm »
Why do these delays occur? How to fix that they were not?
Your application does everything in the main thread, including message processing. When that main thread is blocked with something as slow as serial communication, windows messages do not get processed and your application is not responding looking frozen until communication is finished. Sometimes when chunks of communication are not that long you can fix this by putting Application.ProcessMessages in comm loops or by putting it right after one serial communication and before next one is started. More often you need to do it the proper way, by introducing separate communication thread and synchronizing that with your application and GUI. To do that you need a lot of learning. Search the docs, forum and wiki on the topic.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

FedCo

  • Newbie
  • Posts: 3
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #295 on: June 15, 2019, 03:33:38 pm »
The solution was found !!!!
In the inspector of the objects of the library Lazserial there is a parameter Device. SynSer. DeadlocktimeOut, which is not updated in the inspector of objects, it must be registered in the program itself. The default value is 30000, you need to set it to the value you need, I set 100 for myself. Everything worked without any hangs.

Device. SynSer. DeadlocktimeOut:=100;
Write this line after opening the port.

Thank you all for your help !!! ))))))))).
« Last Edit: June 15, 2019, 03:35:18 pm by FedCo »

avra

  • Hero Member
  • *****
  • Posts: 1736
    • Additional info
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #296 on: June 15, 2019, 03:58:33 pm »
In the inspector of the objects of the library Lazserial there is a parameter Device. SynSer. DeadlocktimeOut, which is not updated in the inspector of objects, it must be registered in the program itself. The default value is 30000, you need to set it to the value you need, I set 100 for myself.
Synapse SynaSer is the father of TLazSerial and for DeadlockTimeout property documentation at http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html#DeadlockTimeout says:
Quote
This timeout value is used as deadlock protection when trying to send data to (or receive data from) a device that stopped communicating during data transmission (e.g. by physically disconnecting the device). The timeout value is in milliseconds. The default value is 30,000 (30 seconds).
It smells like you have communication issues on a physical wire level or with device it self. Your application might behave better, but source of the problem still exists. If you use RS485 then check for proper resistor termination on both ends of the cable. If you use RS232/422/485 then check for proper shielding. If you use RS232 then max cable length for 9600bps in ideal conditions should not exceed 30m, in less ideal conditions even less. With 115200 do not go over 10m if you want stable communication. You can use oscilloscope to see how clean your signal is. Avoid energetic cables whenever you can with your communication cable, especially if heavy consumers and motors are powered by them. Keep distance of at least 30cm from them, and if you must cross them then cross at 90 degree angle (even when having a proper distance). Check grounding on both sides. Find shortest possible communication cable and let your laptop be the only master to your device, disconnecting other devices if there are any. If problems go away, wiring is guilty. If they persist then device is guilty. If device allows then lowering communication speed can help sometimes.
« Last Edit: June 15, 2019, 04:01:51 pm by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

FedCo

  • Newbie
  • Posts: 3
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #297 on: June 15, 2019, 04:06:16 pm »
There are no devices.
Made virtual connected com ports.
And after I changed the value of 30,000 to 100, everything began to work fine. No data loss was noticed, the program was already running for more than an hour and there were no stops.
Before changing the parameter, the stops occurred 10-20 times in 5 minutes.
After changing the parameter, I even reduced the execution time of the program procedure twice, and still everything works fine!
« Last Edit: June 15, 2019, 04:08:33 pm by FedCo »

avra

  • Hero Member
  • *****
  • Posts: 1736
    • Additional info
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #298 on: June 15, 2019, 04:31:53 pm »
There are no devices.
Made virtual connected com ports.
And after I changed the value of 30,000 to 100, everything began to work fine. No data loss was noticed, the program was already running for more than an hour and there were no stops.
Stops are still there. They just now last 100ms instead of 30s so it is harder to notice them. There are many virtual comm port implementations, and some are buggy. You should try another one.
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

PaulRowntree

  • Jr. Member
  • **
  • Posts: 76
    • Paul Rowntree
Re: TLazSerial : serial port component for Lazarus (windows and linux).
« Reply #299 on: September 13, 2019, 11:31:19 pm »
Thank you to avra and FedCo for giving solid tips on my own 30 sec freeze problem!
Here is another issue : my Win10 machine, with 64 compilation on Laz 1.8 uses the {$H+} option which should (I think) force AnsiStrings throughout the code.  However, my received messages in LazSerial were getting clipped to 255 characters.  The problem was solved by adding {$H+} to the LazSerial unit, as well as my own units that subclassed the base component to my wn needs.
Is this the expected behaviour?  I assumed that the {$H+} in the Options dialog would cover everything ..
Thanks again avra & FedCo!
Paul Rowntree
- coding for instrument control, data acquisition & analysis, CNC systems