25 myfCTSFlowControl(true),
26 myInputBufferLength( 0 )
35 if (atoi(
port.c_str()) < 10)
36 myPortNumber =
"COM" +
port;
38 myPortNumber =
"\\\\.\\COM" +
port;
65 myfCTSFlowControl = f;
85 DCB dcbSerialParams = {0};
90 controlString.c_str(),
95 dcbSerialParams.fOutxCtsFlow = myfCTSFlowControl;
97 SetCommState(myCOMHandle, &dcbSerialParams);
103 DCB dcbSerialParams = {0};
104 dcbSerialParams.DCBlength =
sizeof(dcbSerialParams);
105 GetCommState(myCOMHandle, &dcbSerialParams);
106 dcbSerialParams.BaudRate = rate;
107 dcbSerialParams.fOutxCtsFlow = 0;
108 SetCommState(myCOMHandle, &dcbSerialParams);
116 myInputBufferLength = length;
121 const std::string &portNumber()
const
129 DCB dcbSerialParams = {0};
130 dcbSerialParams.DCBlength =
sizeof(dcbSerialParams);
131 GetCommState(myCOMHandle, &dcbSerialParams);
132 return dcbSerialParams.BaudRate;
137 return myCOMHandle != 0;
144 std::stringstream ss;
147 ss <<
"COM not connected\n";
151 ss <<
"overlapped\n";
153 ss <<
"not overlapped\n";
156 DWORD sz =
sizeof(cfg);
162 ss <<
"GetCommConfig FAILED\n";
166 ss <<
"\nBaudRate " << dcb.BaudRate
167 <<
"\nfBinary " << dcb.fBinary
168 <<
"\nfParity " << dcb.fParity
169 <<
"\nfOutxCtsFlow " << dcb.fOutxCtsFlow
170 <<
"\nfOutxDsrFlow " << dcb.fOutxDsrFlow
171 <<
"\nfDtrControl " << dcb.fDtrControl
172 <<
"\nfDsrSensitivity " << dcb.fDsrSensitivity
173 <<
"\nfTXContinueOnXoff " << dcb.fTXContinueOnXoff
174 <<
"\nfOutX " << dcb.fOutX
175 <<
"\nfInX " << dcb.fInX
176 <<
"\nfErrorChar " << dcb.fErrorChar
177 <<
"\nfBinary " << dcb.fNull
178 <<
"\nfNull " << dcb.fRtsControl
179 <<
"\nfAbortOnError " << dcb.fAbortOnError
180 <<
"\nXonLim " << dcb.XonLim
181 <<
"\nXoffLim " << dcb.XoffLim
182 <<
"\nByteSize " << dcb.ByteSize
183 <<
"\nParity " << dcb.Parity
184 <<
"\nStopBits " << dcb.StopBits
185 <<
"\nXonChar " << dcb.XonChar
186 <<
"\nXoffChar " << dcb.XoffChar
187 <<
"\nErrorChar " << dcb.ErrorChar
188 <<
"\nEofChar " << dcb.EofChar
189 <<
"\nEvtChar " << dcb.EvtChar <<
"\n";
192 std::string &errorMsg()
210 if (!myPortNumber.length())
213 DWORD dwFlagsAndAttributes = 0;
215 dwFlagsAndAttributes = FILE_FLAG_OVERLAPPED;
217 myCOMHandle = CreateFile(
218 myPortNumber.c_str(),
219 GENERIC_READ | GENERIC_WRITE,
223 dwFlagsAndAttributes,
227 if (myCOMHandle == INVALID_HANDLE_VALUE)
229 DWORD dw = GetLastError();
233 FORMAT_MESSAGE_ALLOCATE_BUFFER |
234 FORMAT_MESSAGE_FROM_SYSTEM |
235 FORMAT_MESSAGE_IGNORE_INSERTS,
238 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
241 std::cout << (
char *)lpMsgBuf;
243 std::cout <<
"Cannot open COM at "
244 << myPortNumber <<
" error " << myPortNumber <<
"\n";
245 myError = myPortNumber;
249 myError +=
" There seems to be no device connected to this port";
252 myError +=
" This port seems to be in use by another application";
255 myError +=
" Driver reports device is not ready";
258 myError +=
" This port will not open, error " + std::to_string(dw);
270 "baud=9600 parity=N data=8 stop=1 octs=off");
273 PurgeComm(myCOMHandle, PURGE_RXCLEAR);
275 if (myInputBufferLength > 0)
279 GetCommProperties(myCOMHandle, &CommProp);
283 CommProp.dwCurrentRxQueue))
284 myError +=
" Input buffer resize failed";
294 CloseHandle(myCOMHandle);
310 int totalBytesRead = 0;
314 myRcvbuffer.resize(needed);
320 int waiting = waitForData();
326 myRcvbuffer.resize(needed);
328 else if (waiting >= needed)
341 memset(&over, 0,
sizeof(over));
344 myRcvbuffer.data() + totalBytesRead,
350 throw std::runtime_error(
"windex com read block failed " + std::to_string(GetLastError()));
354 totalBytesRead += chunk;
358 }
while (needed > 0);
362 std::vector<unsigned char>
388 myFuture = std::async(
395 myThread =
new std::thread(read_sync_wait,
this);
406 int write(
const std::vector<unsigned char> &buffer)
412 memset(&over, 0,
sizeof(over));
413 DWORD dNoOfBytesWritten;
414 bool ret = WriteFile(
422 int syserrno = GetLastError();
423 std::cout <<
"write failed " << syserrno <<
"\n";
427 std::cout <<
"polling ..." << std::endl;
430 HasOverlappedIoCompleted(&over);
431 if (over.Internal != STATUS_PENDING)
440 std::cout <<
"async write timed out\n";
444 std::cout <<
" ." << std::endl;
449 std::cout <<
"async write completed\n";
450 return buffer.size();
454 return dNoOfBytesWritten;
460 std::vector<unsigned char> buffer(msg.size());
461 memcpy(buffer.data(), msg.data(), msg.size());
462 return write(buffer);
466 std::string myPortNumber;
468 std::future<void> myFuture;
469 std::thread *myThread;
470 std::vector<unsigned char> myRcvbuffer;
471 int myInputBufferLength;
474 bool myfCTSFlowControl;
490 int waiting = comstat.cbInQue;
495 SetCommMask(myCOMHandle, EV_RXCHAR);
496 WaitCommEvent(myCOMHandle, &dwEventMask, NULL);
499 void read_sync_wait()
502 const int check_interval_msecs = 50;
503 while (myFuture.wait_for(std::chrono::milliseconds(check_interval_msecs)) == std::future_status::timeout)
read / write to COM serial port
Definition: com.h:16
std::vector< unsigned char > readData()
get reference to buffer containg data that was read
Definition: com.h:363
com(gui *parent)
CTOR.
Definition: com.h:21
void read(int needed)
blocking read from COM port
Definition: com.h:305
void read_async(int bytes)
non-blocking read from COM port
Definition: com.h:382
void port(const std::string &port)
Set port number to which connection will be made.
Definition: com.h:33
std::string configText()
Get human readable port configuration.
Definition: com.h:142
void overlapped(bool f=true)
Enable/Disable open connection overlapped.
Definition: com.h:50
int write(const std::string &msg)
Write string of data to the COM port.
Definition: com.h:458
bool open()
Open connection to port.
Definition: com.h:208
void CTSFlowControl(bool f=true)
Enable/Disable CTS flow control.
Definition: com.h:63
void deviceInputBuffer(int length)
set device input buffer length
Definition: com.h:114
void DeviceControlString(const std::string &controlString)
Configure device.
Definition: com.h:80
bool isOpen()
true if connected
Definition: com.h:135
int write(const std::vector< unsigned char > &buffer)
Write buffer of data to the COM port.
Definition: com.h:406
The base class for all windex gui elements.
Definition: wex.h:824
HWND handle()
get window handle
Definition: wex.h:1655