Problem with serial port in C# 2.0

G

Guest

Hi everybody,

I have a big problem. I am trying to use serial communication in C# 2. The
problem is that the event DataReceived is never fired. I have tried on two
computers and it does not work at all. I have tried also in C++ .NET 2005 and
also does not work.

I did not find any useful information on the net.

Do you have a small working C# program about how to setup and use the COM1
port and the DataReceived event?

Thank you.
 
G

Guest

Sorry for this reply, but I forgot to mention that my problem is only with a
GUI program. The DataReceived works perfect in a console program.

What is wrong with a GUI program? Or I am missing something?

I would like to see a simple GUI program which works with DataReceived event
and to see what is wrong with my program.

Thank you.
 
J

Janiek Buysrogge

Hi,

Try this code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace SerialTest
{
public partial class Form1 : Form
{
SerialPort m_comPort;

public Form1()
{
InitializeComponent();

m_cmbPortName.Items.Clear();
foreach (string s in SerialPort.GetPortNames())
{
m_cmbPortName.Items.Add(s);
}

m_cmbStopbits.DataSource =
System.Enum.GetValues(typeof(StopBits));
m_cmbParity.DataSource =
System.Enum.GetValues(typeof(Parity));
}

private void button1_Click(object sender, EventArgs e)
{
Send();
}

private void Send()
{
try
{
if (m_comPort.IsOpen)
{
int delay = Int32.Parse(m_txtDelay.Text);
if (delay > 0)
{
string cmd = m_txtSend.Text;
for (int i = 0; i < cmd.Length; i++)
{
m_comPort.Write(cmd.ToString());
Thread.Sleep(delay);
}
}
else
{
m_comPort.Write(m_txtSend.Text);
}
}
}
catch (Exception ex)
{
MessageBox.Show("Exception while writing to COM: " +
ex.Message);
}
}

private void m_txtSend_TextChanged(object sender, EventArgs e)
{
//Send();
//m_txtSend.Clear();
}

private void m_btnOpen_Click(object sender, EventArgs e)
{
try
{
if (m_comPort != null)
{
if (m_comPort.IsOpen)
{
m_comPort.Close();
}
}
else
{
m_comPort = new SerialPort();
}

m_comPort.DataReceived += new
SerialDataReceivedEventHandler(port_DataReceived);

/// Port Name
m_comPort.PortName = m_cmbPortName.Text;
/// Baud Rate
m_comPort.BaudRate = Int32.Parse(m_txtBaud.Text);
/// Stop Bits
m_comPort.StopBits =
(StopBits)Enum.Parse(typeof(StopBits), m_cmbStopbits.Text);
/// Parity
m_comPort.Parity = (Parity)Enum.Parse(typeof(Parity),
m_cmbParity.Text);
/// Data Bits
m_comPort.DataBits = Int32.Parse(m_txtDatabits.Text);
/// Flow Control
m_comPort.Handshake = Handshake.RequestToSend;
m_comPort.RtsEnable = true;

//m_comPort.Encoding = Encoding.UTF8;

m_comPort.Open();

Log("Port successfully opened");
}
catch (Exception ex)
{
Log("Error while opening " + m_cmbPortName.Text + ": "
+ ex.Message);
}
}

private void Log(string s)
{
m_txtLog.Invoke(new EventHandler(delegate
{
m_txtLog.Text += Environment.NewLine + s;
}));
}

private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
string data = "";
while (m_comPort.BytesToRead > 0)
{
data += Convert.ToChar(m_comPort.ReadByte());
}

Log(data);
}

private void m_btnClose_Click(object sender, EventArgs e)
{
try
{
if (m_comPort.IsOpen)
{
m_comPort.Close();

Log("Port successfully closed");
}
}
catch (Exception ex)
{
Log("Could not close port: " + ex.Message);
}
}
}
}


Note: Send command supports sending chars with delay between them.

Janiek
 
C

# Cyrille37 #

Mircea a écrit :
Sorry for this reply, but I forgot to mention that my problem is only with a
GUI program. The DataReceived works perfect in a console program.

What is wrong with a GUI program? Or I am missing something?

Hello,
just a idea :

Access to GUI stuff from an event has to be done via a BeginInvoke( someDelegate )

good luke
cyrille
 
G

Guest

I face with another problem with serial port. I read string bytes of
different lenghts. If the incoming string has up to 8 bytes, everything is
fine. If the incoming string has more than 8 bytes, there is a problem. For
example, I read a byte string from the serial port which is 11 bytes long.
The function read returns only the first 8 bytes and I have to perform a
second read for the other 3. This behavoiur is exactly like a TCP port. This
time I know how many bytes I expect, but there are cases when I don't know
how many bytes I get.

Is tihs the behaviour of the serial port in C# 2, or I miss something?

I use the function Read(byte[], offset, length) and doesn't matter what I
use as lenght, either BytesToRead, or length of the byte array, which is
large enough. If the expected input is more than 8 bytes, BytesToRead is
always 8 and I need some more readings.

All this happens in DataAvailable function.

Thank you.
 
G

Guest

Bob said:
Hi Mircea,
Suggest you check your 'ReceivedBytesThreshold' property.
regards
Bob
Hi Bob,

Thank you for your reply. The value of 'ReceivedBytesThreshold' property is
1. Is this the right value to be, or I miss something?
 
H

Helge Jensen

Mircea said:
I face with another problem with serial port. I read string bytes of
different lenghts. If the incoming string has up to 8 bytes, everything is
fine. If the incoming string has more than 8 bytes, there is a problem. For
example, I read a byte string from the serial port which is 11 bytes long.
The function read returns only the first 8 bytes and I have to perform a
second read for the other 3. This behavoiur is exactly like a TCP port. This
time I know how many bytes I expect, but there are cases when I don't know
how many bytes I get.

Yes, it is exactly a Stream, you are not guaranteed that the buffer you
pass is filled, only that at least one byte is written, or that the
stream is closed, in which case 0 bytes are returned.
Is tihs the behaviour of the serial port in C# 2, or I miss something?

How can the serial-port guess how many bytes you need to read? should it
always block untill your buffer is filled?

In the special-case of a serial-port stream, you can set a
timeout-value, s.t. Read will return if no data is not recieved within a
certain time-limit.
I use the function Read(byte[], offset, length) and doesn't matter what I
use as lenght, either BytesToRead, or length of the byte array, which is
large enough. If the expected input is more than 8 bytes, BytesToRead is
always 8 and I need some more readings.

if you wish to remain blocked while reading any amount of data, use a
helper function:

public static void FillBuffer(
Stream s, byte[] buffer, int offset, int count)
{
for ( int r = 0, i = 0; i < count; i += r )
{
r = s.Read(buffer, offset+i, count-i);
if ( r <= 0 )
throw new EndOfStreamException(
string.Format("EOS while reading {0} bytes, only got {1}",
count, i));
}
}
...
byte[] buf = ...;
FillBuffer(s, buf, 0, buf.Length);

If you have more complex requirements, you will need to encode the data
that you transmit in a protocol which you can parse chunk-by-chunk.
 
G

Guest

Thank you Helge, I have figured out how to do it. The problem is now solved and
everything works fine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top