Я пишу программу, которая прослушивает последовательный порт. У меня уже есть код, который использует драйверы VCP (Virtual COM Port), чтобы открыть последовательное соединение, а затем добавить обработчик событий для получения любых данных времени. Этот код выглядит примерно так:Как я могу использовать EventWaitHandle для создания события?
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);
}
Это прекрасно работает. Мне очень легко понять, как настроить события, используя нотацию +=
. Но я пытаюсь переключиться с использования драйверов VCP вместо этого, используя D2XX drivers, предоставленный FTDI. У меня есть большая часть эквивалентного кода, который мне нужно написать, за исключением того, что он может читать данные всякий раз, когда происходит событие, полученное «данные».
Драйвер D2XX включает в себя один способ настройки обработчиков событий при получении данных, который называется SetEventNotification
. Вот что сигнатура метода выглядит следующим образом:
SetEventNotification(UInt32 eventMask, EventWaitHandle eventHandle);
Первый параметр достаточно прямолинейно (у них есть некоторые предопределенные uints вы можете пройти, чтобы определить, когда событие должно вызвать), но я никогда не работал непосредственно с EventWaitHandles раньше, и я обнаружил, что the documentation сложно понять, так что мне трудно начать работу.
В конце дня ... Я хотел бы иметь метод прослушивателя событий, который выполняет задачу чтения, и которую я могу назначить с помощью оператора +=
, как это было выше с драйвером VCP.
Основываясь на том, что я читал, похоже, что мне нужно будет создать новый Thread
, который, по существу, непрерывно проверяет сигнал EventWaitHandle? Или что-то типа того? Любые примеры или пример кода, чтобы начать меня (или закончил!), Будут оценены.
Вот что я до сих пор:
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);
}
Большое вам спасибо! Это прекрасно и дает мне достаточно, чтобы написать остальные. (Я бы не ожидал, что кто-нибудь сможет проскочить через этот неясный PDF-файл!) Чтобы решить ваши проблемы, нет, я фактически не отправляю данные по стандарту COM-порта, а вместо этого использую кабель USB-последовательный (эффективно эмулируя последовательная связь). Есть несколько документированных недостатков в использовании драйверов VCP, потому что, хотя они имеют более удобный интерфейс программирования, они могут фактически вызывать исключения на уровне структуры, которые вы не можете поймать, и тому подобное. Методы FTDI, как правило, более надежны. – SoaperGEM