Home All Groups Group Topic Archive Search About

Possible bug with SerialPort Parity.None and/or ParityReplace

Author
31 Mar 2006 2:51 AM
David Creel
I am developing some firmware that needs to send binary data to a .NET app
via rs232.  I have created a test .NET app that uses the SerialPort class to
read the data, however it is erroneously doing a replacement on the value
0xFF to be 0x3F (the default ParityReplace character).  I am specifically
setting Parity to None and ParityReplace = 0 to stop this, however it
continues to replace the character.

I believe this might be a bug in the SerialPort class itself, because I can
use DOS or hyperterminal to view the incoming data, and neither appears to
replace the 0xFF with 0x3F (which is '?').

Here is the code I am testing with.  Hook up a serial cable from COM1 to
COM2, run the app, press the buttin, and send some 0xFFs from COM1->COM2 to
test.  Other characters appear to work fine.

//***************************************

using System;
using System.Windows.Forms;
using System.IO.Ports;

namespace WindowsApplication1
{
    public partial class Form2 : Form
    {
        private SerialPort _port;

        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (_port == null)
            {
                _port = new SerialPort("COM2", 19200, Parity.None, 8,
StopBits.One);
                _port.ParityReplace = (byte)'\0';
                _port.ReadTimeout = 500;
                _port.DataReceived += new
SerialDataReceivedEventHandler(_port_DataReceived);

                _port.Open();
            }
            else
            {
                _port.Close();
                _port.Dispose();
                _port = null;
            }
        }

        void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            this.Invoke(new Action<int>(handleData), 0);
        }

        private void handleData(int dummy)
        {
            char[] c = new char[_port.BytesToRead];
            _port.Read(c, 0, c.Length);

            for (int i = 0; i < c.Length; i++)
            {
                textBox1.Text += ((int)c[i]).ToString("x") + " " + c[i] +
"\r\n";
            }
        }
    }
}
--
===>DavidC

Author
31 Mar 2006 6:07 PM
Dick Grier
Hi David,

I don't know, but I will take a look later today.  Of course, if there is a
bug I cannot fix it (and a fix will be a while coming, I suspect).  However,
if I verify the problem I will submit it.

In the meantime, you can download DesktopSerialIO from my homepage to get
you going.

--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
Author
31 Mar 2006 6:32 PM
Dick Grier
David,

BTW, post the syntax that you are using to read the data (just in case).

Dick

--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
Author
31 Mar 2006 7:07 PM
David Creel
Hi Dick,

thanks for looking into it.  I believe I have found more information which
might be valuable.  It seems to read correctly if I use the Read(byte[]...)
instead of Read(char[]...).  It seems the Read with char[] ignores the
ParityReplace or something.  I might take a peek in SerialPort with reflector
later and see if I see the problem (if it's not off in native land).

The code I posted is everything I have (other than the firmware that sends
the data).  All I do is send the hex value and char value to a textbox, and
the value is 3F instead of FF.  I have progressed beyond this since I
realized the byte[] overload worked.

--
===>DavidC


Show quote
"Dick Grier" wrote:

> David,
>
> BTW, post the syntax that you are using to read the data (just in case).
>
> Dick
>
> --
> Richard Grier, MVP
> Hard & Software
> Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
> Edition,
> ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
> 2006.
> See www.hardandsoftware.net for details and contact information.
>
>
>
Author
31 Mar 2006 8:00 PM
Dick Grier
I wrote the following as a test (modified the code for the simple terminal
program on my web site):

Dim Count As Integer = SerialPort.BytesToRead

Dim Buffer(0 To Count - 1) As Byte

Dim Text2Display As String

SerialPort.Read(Buffer, 0, Count)

For I As Integer = 0 To Buffer.GetUpperBound(0)

Text2Display += Hex(Buffer(I)) & " "

Next

Debug.WriteLine(Text2Display)

If Text2Display IsNot Nothing Then _

DefInstance.txtTerm.BeginInvoke(New DisplayData(AddressOf Display), New
Object() {Text2Display})

This works fine, with no error, nor any incorrect data displayed.  All hex
characters are shown.  As you see it uses the Read method.

--
Richard Grier, MVP
Hard & Software
Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
Edition,
ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
2006.
See www.hardandsoftware.net for details and contact information.
Author
4 Apr 2006 5:07 PM
David Creel
Dick,

please try your sample using a char[] instead of byte[].

Here is the simplest example code I could derive which shows the problem. 
Just connect a serial cable between COM1 and COM2, run the code, and double
click the form.  You will see 0x3f  :  ?  when you should see 0xFF  :


Here is the code:
using System;
using System.Windows.Forms;
using System.IO.Ports;

public class Test : Form
{
    static void Main()
    {
        Application.Run(new Test());
    }

    private SerialPort _port;
    public Test()
    {
        this.DoubleClick += new System.EventHandler(this.Test_DoubleClick);

        _port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One);
        _port.DataReceived += new
SerialDataReceivedEventHandler(_port_DataReceived);
        _port.ParityReplace = (byte)'\0';

        _port.Open();
    }

    void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        this.Invoke(new Action<int>(handleData), 0);
    }

    void handleData(int dummy)
    {
        char[] buf = new char[1];

        _port.Read(buf, 0, 1);

        MessageBox.Show("0x" + ((int)buf[0]).ToString("x") + "  :  " +
buf[0]);
    }

    private void Test_DoubleClick(object sender, EventArgs e)
    {
        SerialPort p = new SerialPort("COM1", 9600, Parity.None, 8,
StopBits.One);
        p.ParityReplace = (byte)'\0';
        p.Open();

        char[] buf = new char[] { (char)0xFF };
        p.Write(buf, 0, 1);

        p.Close();
        p.Dispose();
        p = null;
    }
}
--
===>DavidC


Show quote
"Dick Grier" wrote:

> I wrote the following as a test (modified the code for the simple terminal
> program on my web site):
>
> Dim Count As Integer = SerialPort.BytesToRead
>
> Dim Buffer(0 To Count - 1) As Byte
>
> Dim Text2Display As String
>
> SerialPort.Read(Buffer, 0, Count)
>
> For I As Integer = 0 To Buffer.GetUpperBound(0)
>
> Text2Display += Hex(Buffer(I)) & " "
>
> Next
>
> Debug.WriteLine(Text2Display)
>
> If Text2Display IsNot Nothing Then _
>
> DefInstance.txtTerm.BeginInvoke(New DisplayData(AddressOf Display), New
> Object() {Text2Display})
>
> This works fine, with no error, nor any incorrect data displayed.  All hex
> characters are shown.  As you see it uses the Read method.
>
> --
> Richard Grier, MVP
> Hard & Software
> Author of Visual Basic Programmer's Guide to Serial Communications, Fourth
> Edition,
> ISBN 1-890422-28-2 (391 pages, includes CD-ROM). July 2004, Revised March
> 2006.
> See www.hardandsoftware.net for details and contact information.
>
>
>

AddThis Social Bookmark Button