Recent

Author Topic: Serial port parity not working  (Read 427 times)

engine32

  • New Member
  • *
  • Posts: 24
Serial port parity not working
« on: October 16, 2025, 07:26:13 pm »
  Hi there,

  I am writing a Modbus analyzer on a serial port. Everything good except that no matter what parity I set for the com port data gets through. I would like data not to get through if there is a parity mismatch.

  Here is my serial port config:
Code: Pascal  [Select][+][-]
  1.   hSer0 := CreateFileA(PChar(strComPortNamePrologue), //port name
  2.                       (GENERIC_READ or GENERIC_WRITE), //Read/Write
  3.                       0,                            // No Sharing
  4.                       nil,                         // No Security
  5.                       OPEN_EXISTING,// Open existing port only
  6.                       FILE_FLAG_OVERLAPPED,            // Overlapped I/O
  7.                       0);        // Null for Comm Devices
  8.  
  9.   if not(hSer0 = INVALID_HANDLE_VALUE) then begin
  10.     booResult := GetCommState(hSer0, dcbSer);
  11.     dcbSer.ByteSize := 8;
  12.     dcbSer.BaudRate := u32ComPortBaud;
  13.     dcbSer.flags := (1 shl 0) or (1 shl 1) or (1 shl 10); // fBinary, fParity and fErrorChar set;
  14. //    dcbSer.ErrorChar := CHR(0);
  15.     dcbSer.Parity := 1; // even;
  16.     booResult := SetCommState(hSer0, dcbSer);
  17.     if booResult then begin
  18.       frmMain.memTxt.Lines.Add('Serial port config OK');
  19.     end
  20.     else begin
  21.       frmMain.memTxt.Lines.Add('Serial port config NOT OK');
  22.     end;
  23.     ctoS0.ReadIntervalTimeout := 10;
  24.     ctoS0.ReadTotalTimeoutMultiplier := 0;
  25.     ctoS0.ReadTotalTimeoutConstant := 0;
  26.     ctoS0.WriteTotalTimeoutMultiplier := 0;
  27.     ctoS0.WriteTotalTimeoutConstant := 0;
  28.     booResult := SetCommTimeouts(hSer0, ctoS0);
  29.   end
  30.   else begin
  31.     ShowMessage(strComPortName + ' not found');
  32.     frmMain.Close;
  33.   end;
  34.  
  35.  

  Thank you.

serbod

  • Full Member
  • ***
  • Posts: 145
Re: Serial port parity not working
« Reply #1 on: October 16, 2025, 07:44:28 pm »
Try to set fParity flag:

Code: Pascal  [Select][+][-]
  1. dcbSer.fParity := 1; // If this member is TRUE, parity checking is performed and errors are reported.

Also, if your UART adapter based on FTDI or CP210 chip, use code examples from chipmaker

engine32

  • New Member
  • *
  • Posts: 24
Re: Serial port parity not working
« Reply #2 on: October 16, 2025, 08:07:21 pm »
  There is no fParity member. All flags are grouped in a DWORD "flags" member (see attached picture).

  Update: currently the master polls four devices, where only one device is actually connected to the bus. The master uses no parity setting. When the serial port is set as no parity, I see all four queries, and only one reply from the device connected. If I set the parity EVEN or ODD, two of the queries (to two of the devices) is coming through despite the CRC check which is working properly. So, there is some effect, and I see the CRC failing for the other two queries.
  What I think it is happening the first stop bit is read as the parity bit and in some cases it matches. A query is 8 bytes long including the CRC. It can be seen how poor is this parity check.
  I would like the bytes where the parity check fails to be replaced by a specific char so the CRC would always fail, or not to be received at all.

  Thank you.


LeP

  • Jr. Member
  • **
  • Posts: 57
Re: Serial port parity not working
« Reply #3 on: October 16, 2025, 10:24:17 pm »
I used to set property via BuilCommDCB: https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-buildcommdcbW

It sets everything in the DCB. beacuse this changed over the time ... now the fParity field exists.
« Last Edit: October 16, 2025, 10:28:35 pm by LeP »

mas steindorff

  • Hero Member
  • *****
  • Posts: 560
Re: Serial port parity not working
« Reply #4 on: October 17, 2025, 09:23:26 pm »

  Update: currently the master polls four devices, where only one device is actually connected to the bus. The master uses no parity setting. When the serial port is set as no parity, I see all four queries, and only one reply from the device connected. If I set the parity EVEN or ODD, two of the queries (to two of the devices) is coming through despite the CRC check which is working properly. So, there is some effect, and I see the CRC failing for the other two queries.
 
I believe serial parts are a one to one connection unless you are using them in addressable mode (a feature of the devise). if you are, then the port settings of all on the same bus must match.
CRC is also not a low level feature of the serial port, it's an add on feature of one side or the other (or both) that (from what I understand), is not supported at the "file/hardware" level.
That said, I believe you need to use a flush/".purge" option on every level up to your CRC handling to get rid of any trash that the devise may have passed to your host during the connection process.
MAS
windows 10 &11, Ubuntu 21+ IDE 3.4 general releases

 

TinyPortal © 2005-2018