Recent

Author Topic: LazSerial + Arduino UNO connection problem  (Read 1205 times)

xaviermdq

  • Newbie
  • Posts: 4
LazSerial + Arduino UNO connection problem
« on: May 29, 2022, 02:45:27 am »
Hi,

I'm using Lazarus with LazSerial 0.5. I want to connect to an Arduino UNO board.
The Arduino board currently has a program that expects a text (command) from the serial port and responds with a text (which varies depending on the text received).
Using the serial monitor included with the Arduino IDE, everything works perfectly. When I try from Lazarus, the text is sent but I don't get a response. Thinking about the handshake configuration, speed, frame format, etc, I started trying all the variants and there was no case. I even tried receiving through an event (in the version I show here, I wait to receive the data with a timeout).
Then, I made the same program but using AutoIt3 scripting language with CommAPI library and it works perfect.
Using a serial port monitor, I captured the connection made by the Arduino IDE, AutoIt3 and Lazarus (knowing that the first 2 work fine). I don't understand much about the serial port parameters but I think the differences between the versions that worked and the one that didn't, was only in the IOCTL_SERIAL_SET_TIMEOUTS structure. How can I configure this structure from LazSerial? Or do I have to modify the source code?

The fragment of Lazarus code I'm using is:

Code: Pascal  [Select][+][-]
  1. function Look(sPort : String) : Boolean
  2. var
  3.     sResponse : String;
  4.     bError : Boolean;
  5.     t0 : UInt64;
  6. begin
  7.     Result := False;
  8.     sResponse := '';
  9.     bError := False;
  10.     //I configured LazSerial control to 9600,8N1,FlowControl None (and tested with Hardware and XonXoff also), RcvLineCRLF=false, rest to default
  11.     frmMain.Serial.Device := sPort;
  12.     try
  13.       frmMain.Serial.Open;
  14.     except
  15.       bError := True;
  16.     end;
  17.     if not bError then
  18.     begin
  19.       Sleep(500); //in a first version, I don't put this delay. I get the same result.
  20.       frmMain.Serial.WriteData('V' + #10);
  21.       t0 := GetTickCount64();
  22.       repeat
  23.         if frmMain.Serial.DataAvailable then sResponse := sResponse + frmMain.Serial.ReadData;
  24.       until (GetTickCount64() - t0) > 1000;
  25.       if sResponse = ('OK'+#10) then Result := True;
  26.       frmMain.Serial.Close;
  27.     end;
  28. end;
  29.  

Here is the captured data in each case:


AutoIt3 w/CommAPI library:
--------------------------
IOCTL_SERIAL_SET_BAUD_RATE: Retrieve Baud Rate
   · Baud Rate      = 9600
IOCTL_SERIAL_CLR_RTS: Clear RTS
IOCTL_SERIAL_CLR_DTR: Clear DTR
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
   · Stop bits      = 1
   · Parity         = No
   · Data bits      = 8
IOCTL_SERIAL_SET_CHARS: Set special characters
   · EOF        = 0
   · Error      = 0
   · Break      = 0
   · Event      = 0
   · XON        = 0
   · XOFF       = 0
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
   · Control lines      = 0
   · Flow control       = 0
   · Xon Limit          = 0
   · Xoff Limit         = 0
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
   · Read interval               = 0
   · Read total multiplier       = 1
   · Read total constant         = 0
   · Write total multiplier      = 1
   · Write total constant        = 0
IOCTL_SERIAL_PURGE: Purge requests
   · Mask      = SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT | SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR (0xf)
Data 0x56 0x0A sent
Data response ok
The port has been closed

Arduino IDE Serial Monitor:
---------------------------
IOCTL_SERIAL_SET_BAUD_RATE: Retrieve Baud Rate
   · Baud Rate      = 9600
IOCTL_SERIAL_SET_RTS: Set RTS
IOCTL_SERIAL_SET_DTR: Set DTR
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
   · Stop bits      = 1
   · Parity         = No
   · Data bits      = 8
IOCTL_SERIAL_SET_CHARS: Set special characters
   · EOF        = 0xcc
   · Error      = 0x5c
   · Break      = 0x5c
   · Event      = 0x89
   · XON        = 0x11
   · XOFF       = 0x13
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
   · Control lines      = SERIAL_DTR_CONTROL (0x1)
   · Flow control       = SERIAL_RTS_CONTROL | SERIAL_XOFF_CONTINUE (0x80000040)
   · Xon Limit          = 2048
   · Xoff Limit         = 512
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
   · Read interval               = 0
   · Read total multiplier       = 0
   · Read total constant         = 0
   · Write total multiplier      = 0
   · Write total constant        = 0
IOCTL_SERIAL_SET_WAIT_MASK: Set wait mask
   · Wait Mask      = SERIAL_EV_RXCHAR (0x1)
Data 0x56 0x0A sent
Data response ok
The port has been closed

LazSerial with FlowControl=fcNone:
--------------------------------------
IOCTL_SERIAL_SET_WAIT_MASK: Set wait mask
   · Wait Mask      = 0
IOCTL_SERIAL_SET_QUEUE_SIZE: Set queue size
   · Input       = 4096
   · Output      = 0
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
   · Read interval               = 65535
   · Read total multiplier       = 0
   · Read total constant         = 0
   · Write total multiplier      = 0
   · Write total constant        = 0
IOCTL_SERIAL_SET_RTS: Set RTS
IOCTL_SERIAL_SET_DTR: Set DTR
IOCTL_SERIAL_PURGE: Purge requests
   · Mask      = SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT | SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR (0xf)
IOCTL_SERIAL_SET_BAUD_RATE: Retrieve Baud Rate
   · Baud Rate      = 9600
IOCTL_SERIAL_SET_RTS: Set RTS
IOCTL_SERIAL_SET_DTR: Set DTR
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
   · Stop bits      = 1
   · Parity         = No
   · Data bits      = 8
IOCTL_SERIAL_SET_CHARS: Set special characters
   · EOF        = 0xe5
   · Error      = 0xc5
   · Break      = 0xc5
   · Event      = 0
   · XON        = 0x11
   · XOFF       = 0x13
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
   · Control lines      = SERIAL_DTR_CONTROL (0x1)
   · Flow control       = SERIAL_RTS_CONTROL (0x40)
   · Xon Limit          = 1024
   · Xoff Limit         = 1024
A lot of IOCTL_SERIAL_GET_COMMSTATUS and IOCTL_SERIAL_SET_WAIT_MASK with the data 0x56 0x0A sent.
IOCTL_SERIAL_CLR_RTS: Clear RTS
IOCTL_SERIAL_CLR_DTR: Clear DTR
The port has been closed

LazSerial with FlowControl=fcXonXoff:
-------------------------------------
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
   · Control lines      = SERIAL_DTR_CONTROL (0x1)
   · Flow control       = SERIAL_AUTO_TRANSMIT | SERIAL_AUTO_RECEIVE | SERIAL_RTS_CONTROL (0x43)
   · Xon Limit          = 1024
   · Xoff Limit         = 1024

LazSerial with FlowControl=fcHardware:
--------------------------------------
IOCTL_SERIAL_SET_WAIT_MASK: Set wait mask
   · Wait Mask      = 0
IOCTL_SERIAL_SET_QUEUE_SIZE: Set queue size
   · Input       = 4096
   · Output      = 0
IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
   · Read interval               = 65535
   · Read total multiplier       = 0
   · Read total constant         = 0
   · Write total multiplier      = 0
   · Write total constant        = 0
IOCTL_SERIAL_SET_RTS: Set RTS
IOCTL_SERIAL_SET_DTR: Set DTR
IOCTL_SERIAL_PURGE: Purge requests
   · Mask      = SERIAL_PURGE_TXABORT | SERIAL_PURGE_RXABORT | SERIAL_PURGE_TXCLEAR | SERIAL_PURGE_RXCLEAR (0xf)
IOCTL_SERIAL_SET_BAUD_RATE: Retrieve Baud Rate
   · Baud Rate      = 9600
IOCTL_SERIAL_SET_DTR: Set DTR
IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
   · Stop bits      = 1
   · Parity         = No
   · Data bits      = 8
IOCTL_SERIAL_SET_CHARS: Set special characters
   · EOF        = 0xe5
   · Error      = 0xc5
   · Break      = 0xc5
   · Event      = 0
   · XON        = 0x11
   · XOFF       = 0x13
IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
   · Control lines      = SERIAL_DTR_CONTROL | SERIAL_CTS_HANDSHAKE (0x9)
   · Flow control       = SERIAL_RTS_HANDSHAKE (0x80)
   · Xon Limit          = 1024
   · Xoff Limit         = 1024
A lot of IOCTL_SERIAL_GET_COMMSTATUS and IOCTL_SERIAL_SET_WAIT_MASK with the dta 0x56 0x0A sent.
IOCTL_SERIAL_CLR_RTS: Clear RTS
IOCTL_SERIAL_CLR_DTR: Clear DTR
The port has been closed

« Last Edit: May 29, 2022, 02:34:27 pm by xaviermdq »

af0815

  • Hero Member
  • *****
  • Posts: 1289
Re: LazSerial + Arduino UNO connection problem
« Reply #1 on: May 29, 2022, 09:20:33 am »
Open and close are not in the same Form. So this are Differential objects.
regards
Andreas

tetrastes

  • Sr. Member
  • ****
  • Posts: 473
Re: LazSerial + Arduino UNO connection problem
« Reply #2 on: May 29, 2022, 12:54:44 pm »
Using a serial port monitor, I captured the connection made by the Arduino IDE, AutoIt3 and Lazarus (knowing that the first 2 work fine). I don't understand much about the serial port parameters but I think the differences between the versions that worked and the one that didn't, was only in the IOCTL_SERIAL_SET_TIMEOUTS structure. How can I configure this structure from LazSerial? Or do I have to modify the source code?
I would advice to modify the source code. The value 65535 for Read interval is rather senseless, I think that this is typo in synaser.pas (MAXWORD instead of MAXDWORD).
But I think that your problem is not in this.

xaviermdq

  • Newbie
  • Posts: 4
Re: LazSerial + Arduino UNO connection problem
« Reply #3 on: May 29, 2022, 01:08:13 pm »
Open and close are not in the same Form. So this are Differential objects.
Sorry, there was a typo. I corrected the post to reflect that the port is closed at the end.

avra

  • Hero Member
  • *****
  • Posts: 2514
    • Additional info
Re: LazSerial + Arduino UNO connection problem
« Reply #4 on: May 29, 2022, 01:29:07 pm »
Your problems reminds me of this one:
https://forum.lazarus.freepascal.org/index.php/topic,59433.0.html

You can try suggestions listed there...
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

xaviermdq

  • Newbie
  • Posts: 4
Re: LazSerial + Arduino UNO connection problem
« Reply #5 on: May 29, 2022, 01:56:07 pm »
I would advice to modify the source code. The value 65535 for Read interval is rather senseless, I think that this is typo in synaser.pas (MAXWORD instead of MAXDWORD).
But I think that your problem is not in this.

You are right! According to MS documentation ("A value of MAXDWORD, combined with zero values for both the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier members, specifies that the read operation is to return immediately with the bytes that have already been received, even if no bytes have been received."), the correct value is MAXDWORD. And also you are right that this isn't the problem. Also tried a read interval of 0 with no success.

xaviermdq

  • Newbie
  • Posts: 4
Re: LazSerial + Arduino UNO connection problem
« Reply #6 on: May 29, 2022, 02:22:39 pm »
Your problems reminds me of this one:
https://forum.lazarus.freepascal.org/index.php/topic,59433.0.html

You can try suggestions listed there...

Hi avra!
I tested with the event driven version that you suggest to crisares (defining a global Response variable and OnRxData that only fills Response using ReadData method) with no success. I think if it was the problem, I should at least get the response on the serial port monitor, right?
Also with other software (Serial Monitor from Arduino IDE, Putty, and a program made in AutoIt3 that is also not event driven) works ok.
I'll try with synaser alone and with LazSerial in event driven version with the corrections to the read interval value.

PD:
I resist to use the event driven version because my application is very simple: send 2 bytes (a 1 byte command and a EOL character) and wait (up to 500 to 1000ms) an OK + EOL response. This is for looking up that my hardware is connected to PC.

 

TinyPortal © 2005-2018