I'm trying to write a simple c# console application to read/write from a serial port that communicates to an Arduino that I have hooked up. The problem that I'm running into is that I can write to the Arduino no problem, but I am unable to receive any data back. My serial port's SerialDataReceivedEventHandler isn't ever being fired either, but I'm guessing those two issues are related.
I know it isn't my Arduino that is causing the problem because when using the Arduino IDE I am able to receive data without any problems. Here is what I've got code wise for now:
SerialPort sPort = new SerialPort();
sPort.PortName = SerialPort.GetPortNames()[0];
sPort.BaudRate = 9600;
sPort.Parity = Parity.None;
sPort.DataBits = 8;
sPort.StopBits = StopBits.One;
sPort.RtsEnable = false;
sPort.Handshake = Handshake.None;
sPort.DataReceived += new SerialDataReceivedEventHandler(sPort_dataReceived);
sPort.ErrorReceived += new SerialErrorReceivedEventHandler(sPort_ErrorReceived);
sPort.Open();
Console.Read();
sPort.Write("tt_calib");
while (true)
{
if (sPort.ReadExisting() != string.Empty)
Console.WriteLine(sPort.ReadExisting());
}
I am aware that I don't close the port in this code, that is not the issue as I am able to rerun and open it every time. This code is also not in its final form, I'm attempting to get the read event working so that I can react to various messages differently. I've read what seems like every question but no solution I've found seems to do the trick.
This is a C# .NET 4.5 console application running on Windows 8.1
It ended up being a stupid simple issue. Instead of sPort.RtsEnable = false; it should be true. All events now trigger and I am able to read.
With C# in VS2019 available cross-platform, I ran into the same issue on my VM (Parallels+Windows10) and my host machine (MacOS).
Setting DTR to true did the trick
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
private static void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
I had the exact same issue and finally realized that my hardware flow control setting is bios configurable and my setting was DISABLED! doh
We are trying to read data written by an external device (weighing scale in this case) connected to serial port using .Net serial port class.
First we initialize the serial port as below:
InitializeSerialPort()
{
if ((serialPort != null) && (serialPort.IsOpen))
{
serialPort.Close();
serialPort.Dispose();
serialPort = null;
}
serialPort = new SerialPort("COM2", 9600, Parity.None, 8,
StopBits.One) { Handshake = Handshake.None };
serialPort.DataReceived += serialPort_DataReceived;
serialPort.NewLine = "\r";
}
We are using background worker thread to poll the device on continuous interval by sending a command(understood by the weighing scale) on the serial port. As soon as we send the command the device connected to serial port reacts with a response output. We call ReadLine API of SerialPort class to get the data present on the serial port written by the device in the DataReceived event as shown in the code snippet below :
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
data = serialPort.ReadLine();
}
catch(System.IO.IOException ex)
{
//since serial port reading threw an error so there is no value to be parsed hence exit the function.
return;
}
//if no error then parse the data received
}
I'm using System.IO.Ports.SerialPort class of .Net framework 4.0. I can see a number of people posting this issue on other forums but with no specific resolution. Some of them terming .Net Serial port class as buggy which has not been fixed by Microsoft till date. One of the forums where this error is mentioned is here
I also tried the solution posted here but of no help. I need some input if any one else has come across this issue or its resolution.
We were able to solve this problem by locking the code inside serialPort_DataReceived method.
Object lockObject = new Object();
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
lock(lockObject)
{
try
{
data = serialPort.ReadLine();
}
catch(System.IO.IOException ex)
{
//since serial port reading threw an error so there is no value to be parsed hence exit the function.
return;
}
}
//if no error then parse the data received
}
We had set the polling interval to poll the device connected on serial port as 10 seconds. Possibly the entire code present inside serialPort_DataReceived method was sometimes taking more than 10 seconds. We were not able to exactly establish this fact as it was not happening every time may be.
So we locked the entire piece of code inside serialPort_DataReceived method using lock keyword in C# to ensure that the new execution for new data received from serial port doesn't start unless the older reading hasn't finished. The issue got resolved after implementing this code on trial and error basis. Hope this helps others as well if they come across such an issue.
I need to connect to a sensor through a serial port and read some data off it. I connect to it and send the command, but nothing is returned from the device, instead a Timeout exception is thrown. Similar questions here on stackoverflow use the OnDataReceived event, i tried that and it did not work. The parameters i used to initialize and the command i send work as expected on Putty.
-- what am i missing here
void Read()
{
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
try
{
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Encoding = new ASCIIEncoding();
serialPort.ReadTimeout = 1000;
serialPort.WriteTimeout = 900;
serialPort.Open();
serialPort.WriteLine("TEMP");
MessageBox.Show("Reading");
MessageBox.Show(serialPort.ReadLine());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
serialPort.Close();
}
}
Thank you
serialPort.Handshake = Handshake.XOnXOff;
Maybe that's correct, it is pretty unusual. But real devices almost always pay attention to the hardware handshake signals, in addition to an Xon/Xoff flow control protocol. The DTR (Data Terminal Ready) and RTS (Ready To Send) signals have to be turned on before the device is convinced that it is connected to a real computer. A program like Putty will always turn them on, your program does not.
Add these two required lines:
serialPort.RtsEnable = true;
serialPort.DtrEnable = true;
And ensure that the serialPort.NewLine property correctly matches the end-of-message character used by the device. Temporarily use ReadExisting() instead to avoid getting bitten by that detail, don't leave it that way.
I would suggest that the problem is with the encoding you're using. To check if that's the problem use a sniffer of your choice to see that the bytes transferred on your application are the same as on putty.
Only be sure that you're actually trying to read the bytes when using a sniffer because if you don't they won't be shown on the output.
If that doesn't show you anything you can try to change your ReadLine() method to ReadByte() to ensure that there's no problem with the reading type that you're using.
Serial port sniffers
http://www.serialmon.com/
virtual-serial-port.org/products/serialmonitor/?gclid=CInI2ZPL_bsCFaxr7Aod8S4A8w
www.hhdsoftware.com/device-monitoring-studio
I need to write a program, that will listen to communication in ModBus network through RS485.
I am connected to the network with RS485 <> USB dongle.
I can read some data using SerialPort.DataReceived event, but it gives strange results.
Data is often split, when it should come in one piece. (Modbus Master transmits every 100ms).
class Serial
{
private SerialPort port;
Queue<byte[]> buffer;
public Serial()
{
buffer = new Queue<byte[]>();
port = new SerialPort("COM3", 19200, Parity.Even, 8, StopBits.One);
port.DataReceived += port_DataReceived;
}
public void Open()
{
if (port.IsOpen)
{
port.Close();
}
port.Open();
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] buff = new byte[port.BytesToRead];
port.Read(buff, 0, port.BytesToRead);
buffer.Enqueue(buff);
}
}
I don't have any start sign in transmission.
Delay between frames is min. 3.5 chars, and max delay between chars is 1.5 chars.
This is entirely normal, serial ports are very slow devices. The DataReceived event is fired as soon as one byte was received. You'll need to call Read() and pay attention to the value it returns, the number of bytes it was able to retrieve from the input buffer. Which might be more than one but is only very rarely equal to the number of bytes in a "packet", that could only happen if the machine got very slow for some reason.
Beware that the debugger is one way to make it that slow, a breakpoint or single-stepping the event handler code gives the driver enough time to receive all the bytes in a packet. So that the Read() call returns them all. But that stops working as soon as you stop debugging that code.
You could use the ReceivedBytesThreshold property to delay the event but that can only work when a packet has a fixed size. Simply append the bytes you get into byte[], using the 2nd argument of the Read() call. And don't process the packet until you have them all.
I've been fighting with this issue for a day and I can't find answer for it.
I am trying to read data from GPS device trough COM port in Compact Framework C#. I am using SerialPort class (actually my own ComPort class boxing SerialPort, but it adds only two fields I need, nothing special).
Anyway, I am running while loop in a separate thread which reads line from the port, analyze NMEA data, print them, catch all exceptions and then I Sleep(200) the thread, because I need CPU for other threads... Without Sleep it works fine, but uses 100% CPU.. When I don't use Sleep after few minutes the output from COM port looks like this:
GPGSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
GSA,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
A,A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,18,12,271,24,24,05,020,24,14,04,326,25,11,03,023,*76
A,3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
3,09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
09,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
,12,22,17,15,27,,,,,,,2.6,1.6,2.1*3F
as you can see the same message is read few times but cut.
I wonder what I'm doing wrong...
My port configuration:
port.ReadBufferSize = 4096;
port.BaudRate = 4800;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.NewLine = "\r\n";
port.ReadTimeout = 1000;
port.ReceivedBytesThreshold = 100000;
And my reading function:
private void processGps(){
while (!closing)
{
//reconnect if needed
try
{
string sentence = port.ReadLine();
//here print the sentence
//analyze the sentence (this takes some time 50-100ms)
}
catch (TimeoutException)
{
Thread.Sleep(0);
}
catch (IOException ioex)
{
//handling IO exception (some info on the screen)
}
Thread.Sleep(200);
}
}
There is some more stuff in this function like reconnection if the device is lost etc., but it is not called when the GPS is connected properly. I was trying
port.DiscardInBuffer();
after some blocks of code (in TimeoutException, after read.)
Did anyone had similar problem? I really dont know what I'm doing wrong.. The only way to get rig of it is removing the last Sleep.
For all those who have similar problem. The first issue was about overflowing the buffer. I had 4096 size of buffer and the data was just flowing trough it so I was reading corrupted sentences. Now I read all buffer at once and analyze it. First sentence is sometimes corrupted, but the rest is ok.
The second thing was the device issue. Tom Tom MkII sometimes loses connection with the device. I had to restart the GPS and find it again in Bt devices list.
Regards
There's nothing in your post to say how you are doing handshaking.
Normally you would use software (XON/XOFF) or hardware (e.g. RTS/CTS) handshaking so that the serial port will tell the transmitting to stop when it is unable to receive more data. The handshaking configuration must (of course) match the configuration of the transmitting device.
If you fail to configure handshaking correctly, you may get away with it as long as you are processing the data fast enough - but when you have a Sleep, data may be lost.