What might affect the values ​​returned by Serialport.Read ()

I wrote a simple C # 2.0 application using the .Net Framework 2.0 Serialport class to communicate with the controller card through COM1.

Recently, there has been a problem with invalid bytes returned by the Read method. It returned the correct number of bytes, only the values ​​were incorrect. A similar application written in Delphi still returned the correct values.

I used Portmon to record activity on the serial port of both applications, comparing the two logs and where some (apparently) slight different settings, and I tried to emulate the Delphi application as close as possible, but to no avail.

So what can affect the byte values ​​returned by the Read method?

Most settings between the two applications are identical.

Here is a list of lines that differed in the Portmon log:

Delphi app:

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF: dc ERR: 0 BRK: 0 EVT: 0 XON: 11 XOFF: 13
IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 0 Replace: 0 XonLimit: 256 XoffLimit: 256 IOCTL_SERIAL_SET_TIMEUUTS Serial0 SUCCESS RI: -1 RM: 100 RC: 1000 WM: 100 WC: 1000 IOCTL_SERALIALS RIALXSTIAL RJTSIALS RIALXSMIALSTRIALSSTIAL_SERIAL_STRIAL_SERIAL_TRIAL_STERIAL_SERIAL_TRIAL_STERIAL_SERIAL_TRIAL_STERIAL_STRIAL_STERIAL_STERIAL_STRIAL_STERIAL_STERIAL_STERIAL_STERIAL_TRIAL_STERIAL_STERIAL_STERIAL_STERIAL_STERIAL_STRIAL_STERIAL_STERIAL_STERIAL_STERIAL_STRIAL_STERIAL_TRIAL_STERIAL_TRIAL_STERIAL_STERIAL_TRIAL_STERIAL_STERIAL_LESS

C # application:

IOCTL_SERIAL_SET_CHAR Serial0 SUCCESS EOF: 1a ERR: 0 BRK: 0 EVT: 1a XON: 11 XOFF: 13 IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 0 Replace: 0 XonLimit: 1024 XoffLimit_SERIAL_TIMEITIAL_TIMEITIAL_ITIAL_TECIALTITIALTECIALTIMEIT WM: 0 WC: 1000 IOCTL_SERIAL_SET_WAIT_MASK Serial0 SUCCESS Mask: RXCHAR RXFLAG CTS DSR RLSD BRK ERR RING

UPDATE:

The correct bytes returned were: 91, 1, 1, 3, 48, 48, 50, 69, 66, 51, 70, 55, 52, 93 (14 bytes). The last value is a simple checksum.

Incorrect return values: 91, 241, 254, 252, 242, 146, 42, 201, 51, 70, 55, 52, 93 (13 bytes).

As you can see, the first and last five bytes are returned.

The ErrorReceived event indicates that a framing error has occurred that may explain incorrect values. But the question is, why does SerialPort encounter a cropping error when the Delphi application does not seem to do?

+4
source share
4 answers

Well, it looks like the problem has been resolved (at least for now).

Apparently, the framing error led to the return of incorrect values. I wrote a VB6 application using the MSComm control, which worked fine and compared the log files created by Portmon.

I understood the following differences

Application VB6:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 1 Replace: 0 XonLimit: 256 XoffLimit: 256

C # application:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 0 Replace: 0 XonLimit: 1024 XoffLimit: 1024

While playing with the settings, I found that if I set _serialPort.DtrEnable = true , the C # application generates the following log entry:

IOCTL_SERIAL_SET_HANDFLOW Serial0 SUCCESS Shake: 1 Replace: 0 XonLimit: 1024 XoffLimit: 1024

This seemed to prevent the cropping error, and the application seems to be working fine.

+2
source

Have you checked the settings for the number of data bits, stop bits and parity?

The parity bit is a kind of error detection mechanism. For example: if you send using 7 data bits and one parity bit, the eighth bit will be used to detect bit inversion errors. If the receiver expects 8 data bits and a parity bit, the result will be distorted.

0
source

Unfortunately, you did not indicate exactly what differences you get. Is this a random character that is different or is all of your input data distorted? Please note that characters read through the SerialPort.Read function may be changed by the system due to the setting of the SerialPort.Encoding property. This parameter affects the interpretation of the incoming text, because it was text in ASCII, Unicode, UTF8, or any other encoding scheme. Windows uses "raw byte (s)" to "readable text" to convert.

0
source

If you are reading into an array of bytes (for example: SerialPort.Read), you should get exactly the bytes that you see on PortMon.

If you convert to characters (SerialPort.ReadLine or SerialPort.ReadChar), then the data will be encoded using the current encoding (property SerialPort.Encoding), which explains the differences that you see.

If you want to see characters with the same binary values ​​as bytes on the wire, a good encoding for use is Latin-1, as described in this post .

Example:

 SerialPort.Encoding = Encoding.GetEncoding("Latin1") 
0
source

Source: https://habr.com/ru/post/1277046/


All Articles