Click to See Complete Forum and Search --> : [RESOLVED] Serial Port Reading problem (timeout)
bluebarca
April 8th, 2009, 03:55 PM
1 - I have a problem with the serial port, i wrote a simple program to chat betwen 2 PC and it worked perfectly. Now I'm trying to connect to an "Advanced ID ST500 RFID Reader" the program sends the data normally and it is recieved by the reader correctly but when receiving the program throws a Timeout exception even for timeouts of 10 seconds. The problem the serialMonitor rogram for the serial port detects and reads the data correctly, so why isn't the program.
2 - Also how can i make the reading take place automatically without requiring me to invoke readline() every time, i mean to make the availability of data to be read invoke an event handler?
Here is my code:
----------------------
SerialPort sp = new SerialPort();
sp.BaudRate = 38400;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.PortName = "COM1";
sp.WriteLine("Any Text Here");
richTextBox4.Text = sp2.ReadLine();
// this always gives Timeout exception when talking with the reader when infact there is data recieved and it was read by a Serial Port monitor !!!
How Can i solve the Timeout Problem ?
How Can i make the read process automatic without the need to invoke readline manytime() ?
krose
April 8th, 2009, 06:25 PM
There's no reason to run a loop to recover data from the serial port. Subscribe to the SerialDataReceivedEvent and Windows will trigger that event when something arrives at the port.
//Subscribe to serial data received event to trigger event when data arrives on the port
sp.DataReceived += new SerialDataReceivedEventHandler(ProcessReceivedData);
//Handler as indicatted above will be run when the event is triggered.
private void ProcessReceivedData(object sender, SerialDataReceivedEventArgs e)
{
byte[2048] ReceiveBuffer;
int offset = 0;
int toRead = sp.BytesToRead;
sp.Read(ReceiveBuffer, offset, toRead);
offset += toRead;
//Received data will be in placed into ReceiveBuffer at location offset.
//You will have to handle buffer overflow conditions and clean up the
//buffer when the data when you are finished recovering the data.
}
Note: The event will be triggered when the first byte arrives. If you have not created a recognizable data packet to determine if data has been completely recovered, you may not have all the data. Be prepared for additional events or even the posibility that not all the data will be received. In serial communications, it's the designers responsibility to handle data errors, incomplete data, and multiple messages in one receive events.
Hope that helps. Good luck!
eclipsed4utoo
April 9th, 2009, 05:55 AM
along with what krose said, if you know the data is going to be appended with a carriage return at the end, you can use the "ReadLine()" method instead. If there is not going to be a carriage return at the end, then you will need to use the "Read()" method as krose specified.
bluebarca
April 11th, 2009, 05:45 PM
thanks everybody for the reply/help
i've tried the SerialDataReceivedEventHandler thing but i've got the following error:
Error-> Cross thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on
can anybody help me in solving this problem ?
eclipsed4utoo
April 12th, 2009, 04:56 AM
thanks everybody for the reply/help
i've tried the SerialDataReceivedEventHandler thing but i've got the following error:
Error-> Cross thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on
can anybody help me in solving this problem ?
here is an example of receiving data from a serial port and outputting it to a textbox. This is probably what you are trying to do.
http://www.dreamincode.net/code/snippet2764.htm
bluebarca
April 13th, 2009, 12:03 PM
hey i've tried the code but i'm facing some problems
all types of the read mathods (readline,read,...etc) throws a timeout exception. only ReadExisting works but it doesnt read the entire data sent, it sometimes reads a charecter, two or a collection but not the whole + it always ignores the first charecter sent if by chance it read the whole string.
here is the 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;
namespace serialPort
{
public partial class Form1 : Form
{
SerialPort sp2 = new SerialPort();
private delegate void SetTextDeleg(string text);
public Form1()
{
InitializeComponent();
sp2.BaudRate = 38400;
sp2.Parity = Parity.None;
sp2.DataBits = 8;
sp2.StopBits = StopBits.One;
sp2.PortName = "COM2";
sp2.Handshake = Handshake.None;
}
private void Form1_Load(object sender, EventArgs e)
{
sp2.Open();
sp2.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
}
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string data = sp2.ReadExisting();
this.BeginInvoke(new SetTextDeleg(si_DataReceived), new object[] { data });
}
private void si_DataReceived(string data)
{
richTextBox3.Text = data.Trim();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
sp2.WriteLine(richTextBox1.Text.ToString());
label1.Text = "Sent: " + richTextBox1.Text;
richTextBox4.Text = sp2.ReadExisting().Trim();
}
catch(System.Exception ex){
label1.Text = "The Following Exception Took Place\n"+ex.Message;
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
sp2.WriteLine(richTextBox2.Text.ToString());
label2.Text = "Sent: " + richTextBox2.Text;
richTextBox4.Text = sp2.ReadExisting().Trim();
label8.Text = "RTS Enable " + sp2.RtsEnable.ToString() + "\n" + "Clear To Send " + sp2.CtsHolding.ToString() + "\n" + "Read Buffer Size " + sp2.ReadBufferSize.ToString() + "\n" + "Bytes To Read " + sp2.BytesToRead.ToString() + "\n" + "Encoding " + sp2.Encoding.ToString();
}
catch (System.Exception ex)
{
label1.Text = "The Following Exception Took Place\n" + ex.Message;
}
}
}
}
xander_tan
April 14th, 2009, 05:49 AM
hey i've tried the code but i'm facing some problems
all types of the read mathods (readline,read,...etc) throws a timeout exception. only ReadExisting works but it doesnt read the entire data sent, it sometimes reads a charecter, two or a collection but not the whole + it always ignores the first charecter sent if by chance it read the whole string.
...
I am currently exploring this SerialPort class. I believe that I am using ReadExisting, but I tried ReadLine before, and it seems to work fine.
Have you tried to perform this following lines?
serialPort.ReadTimeout = 500
serialPort.WriteTimeout = 500
I am, in fact, working on an open source project:
http://sourceforge.net/projects/tanjungpriok/
Currently the software accessing the serialport using polling, I am trying to subscribe to SerialPort Event too.
Feel free to dig into my code through the SVN server.
bluebarca
May 1st, 2009, 01:45 PM
strangely the only thing that works without Throwing a timeout exception of dropping charecters or all the other problems is ReadTo("\r"), i can't say why this only works while all the others don't but i'm glad that the problem is solved!
Thank you all for your help
Best Regards
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.