I am writing an app that uses the serial port exposed by the SerialPort class in mono. What I have written so far works perfect in windows, however in linux the DataReceived event handler is never entered, so I cannot receive any data form my device. I have declared the event handler as follows:
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
Basically I am exploring good cross-platform options and this is a deal-breaker. Any advise on how to fix this or what is going on?
Edit-
I should also point out that I have tested the serial port and device on linux with other applications and all appears to be working.
mono does not support Event for serialport.
It is shown on mono's website
Maybe it has changed lastly, but as far as I know, events are not currently implemented in Mono's serial port. You have to make another thread in any flavour to read data from serial port, which happens in blocking manner. Try it and tell if it worked.
On Antanas Veiverys blog you can find two possible ways to solve it.
(2012) By adjusting the mono source code.
http://antanas.veiverys.com/enabling-serialport-datareceived-event-in-mono/
(2013) By not touching the mono source but solving the issue in a derived class.
http://antanas.veiverys.com/mono-serialport-datareceived-event-workaround-using-a-derived-class/
(2014)
However, I encourage you to read Ben Voigts blog post where he ignores using the DataReceivedEvent and instead used the BaseStream async BeginRead/EndRead functions to read data from the serial port.
http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport#comment-840
Implementing and using the given code sample works on both Windows/Unix, so I have tested. And it is more elegant than using the blocking Read() function in a threaded fashion.
I have the same problem with SerialPort.DataReceived. Konrad's advice.
using System.IO.Ports;
using System.Threading;
namespace Serial2
{
class MainClass
{
public static void Main(string[] args)
{
Thread writeThread = new Thread(new ThreadStart(WriteThread));
Thread readThread = new Thread(new ThreadStart(ReadThread));
readThread.Start();
Thread.Sleep(200); // TODO: Ugly.
writeThread.Start();
Console.ReadLine();
}
private static void WriteThread()
{ // get port names with dmesg | grep -i tty
SerialPort sp2 = new SerialPort("/dev/ttyS5", 115200, Parity.None, 8, StopBits.One);
sp2.Open();
if(sp2.IsOpen)
Console.WriteLine("WriteThread(), sp2 is open.");
else
Console.WriteLine("WriteThread(), sp2 is open.");
sp2.Write(" This string has been sent over an serial 0-modem cable.\n"); // \n Needed (buffering?).
sp2.Close();
}
private static void ReadThread()
{
SerialPort sp = new SerialPort("/dev/ttyS4", 115200, Parity.None, 8, StopBits.One);
sp.Open();
if(sp.IsOpen)
Console.WriteLine("ReadThread(), sp Opened.");
else
Console.WriteLine("ReadThread(), sp is not open.");
while(true)
{
Thread.Sleep(200);
if(sp.BytesToRead > 0)
{
Console.WriteLine(sp.ReadLine());
}
}
}
}
}