Reputation: 21999
How to check CTS
line value of opened SerialPort
? Idea is to set this value from device on other side while using 3-wire serial interface without handshaking.
Here is some code to start discussion (adapted msdn example):
[DllImport("kernel32.dll")]
static extern bool SetCommMask(IntPtr hFile, uint dwEvtMask);
[DllImport("kernel32.dll")]
static extern bool WaitCommEvent(IntPtr hFile, out uint lpEvtMask, IntPtr lpOverlapped);
SerialPort _port = null;
bool _exit;
public Form1()
{
InitializeComponent();
_port = new SerialPort("COM2");
_port.Open();
// getting handle is tricky
var handle = ((SafeFileHandle)_port.BaseStream.GetType().GetField("_handle", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(_port.BaseStream)).DangerousGetHandle();
// set mask to listen to change of CTS signal
if (!SetCommMask(handle, 0x0008)) // EV_CTS
throw ...
// start listener
Task.Run(() =>
{
while (!_exit)
{
uint mask = 0;
if (WaitCommEvent(handle, out mask, IntPtr.Zero))
if ((mask & 0x0008) != 0)
Task.Run(() => MessageBox.Show("smth happenz"));
});
_port.Close();
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
_exit = true;
}
This code can tell me if there is a change of signal on CTS
line, but can't figure out how to get actual value (is it high or low?).
Apart from that there are strange issues. WaitCommEvent
returns false
immediately (with Marshal.GetLastError() = 0
) unless CTS
is set to opposite to what it was when com-port was opened. Moreover, I see MessageBox
for values which are equal to what it was when com-port was opened. This is really weird, because I can't figure out a value by using this approach.
Another thing is what WaitCommEvent
blocks. I can close form and application terminates without visible (yet?) issues, but I'd really enjoy having non-blocking polling here.
Upvotes: 0
Views: 1934
Reputation: 61993
A 3-wire serial interface does not include the CTS signal, so you cannot use it.
As for reading the value of CTS, the documentation is here: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363194%28v=vs.85%29.aspx you want to look at GetCommMask()
and GetCommModemStatus()
.
Upvotes: 3
Reputation: 6145
You need to use GetCommModemStatus
to retrieve status of CTS.
You can use WaitCommEvent
in non-blocking mode with overlapped IO. That is, opening the port as overlapped and providing the 3rd parameter of WaitCommEvent
.
Upvotes: 2