I'm writing a program that listens on a Serial Port. I already have code that utilizes the VCP drivers (Virtual COM Port) to open a serial connection and then add an event handler for any time data is received. That code roughly looks like this:
public void OpenPort(string portNumber)
{
_port = new SerialPort(
portName: portNumber,
baudRate: 9600,
parity: Parity.None,
dataBits: 8,
stopBits: StopBits.One
);
_port.DataReceived += ReadData;
}
private void ReadData(object sender, SerialDataReceivedEventArgs e)
{
string data = _port.ReadExisting().Trim();
Console.WriteLine("Received: " + data);
}
This works great. It's very easy for me to understand how to set up events using the +=
notation. But I'm trying to switch over from using the VCP drivers to instead using the D2XX drivers provided by FTDI. I have most of the equivalent code that I need written, with the notable exception of being able to read data whenever a "data received" event occurs.
The D2XX driver includes one method for setting up event handlers whenever data is received, called SetEventNotification
. Here's what the method signature looks like:
SetEventNotification(UInt32 eventMask, EventWaitHandle eventHandle);
The first parameter is straight-forward enough (they have some predefined uints you can pass in to determine when the event should trigger), but I've never worked directly with EventWaitHandles before, and I found the documentation difficult to grasp, so I'm having trouble getting started.
At the end of the day... I would like to have an event listener method which performs a read task, and which I can assign using the +=
operator, as I did above with the VCP driver.
Based on what I was reading, it looks like I'll have to create a new Thread
that essentially polls continuously for the EventWaitHandle's signal? Or something like that? Any examples or sample code to get me started (or finished!) would be appreciated.
Here's what I have so far:
public void OpenPort(string portNumber)
{
_port = new FTDI();
var status = _port.OpenBySerialNumber(portNumber);
if (FTDI.FT_STATUS.FT_OK != status) throw new Exception();
status = _port.SetBaudRate((UInt32) 9600);
if (FTDI.FT_STATUS.FT_OK != status) throw new Exception();
status = _port.SetDataCharacteristics(
DataBits: FTDI.FT_DATA_BITS.FT_BITS_8,
StopBits: FTDI.FT_STOP_BITS.FT_STOP_BITS_1,
Parity: FTDI.FT_PARITY.FT_PARITY_NONE
);
if (FTDI.FT_STATUS.FT_OK != status) throw new Exception();
var evHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "");
_port.SetEventNotification(FTDI.FT_EVENTS.FT_EVENT_RXCHAR, evHandle);
// ... now what?
}
public void ReadData(object sender, EventArgs e)
{
UInt32 bytesAvailable = 0;
_port.GetRxBytesAvailable(ref bytesAvailable);
string data;
UInt32 bytesRead = 0;
_port.Read(out data, bytesAvailable, ref bytesRead);
data = data.Trim();
Console.WriteLine("Received: " + data);
}