better error handling, mctor and cctor
This commit is contained in:
+51
-14
@@ -2,13 +2,14 @@
|
||||
#include <iostream>
|
||||
|
||||
#ifdef WINDOWS
|
||||
OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
||||
OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate) noexcept:
|
||||
comPort(comPort),
|
||||
baudRate(baudRate)
|
||||
{
|
||||
serialHandle = CreateFile(normalizePort(comPort).c_str(), GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (!serialHandle) {
|
||||
std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"!" << std::endl;
|
||||
serialHandle = CreateFileW(normalizePort(comPort).c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (serialHandle == INVALID_HANDLE_VALUE) {
|
||||
DWORD err = GetLastError();
|
||||
std::wcerr << L"Unable to open serial port file " << normalizePort(comPort) << L"! Error: " << (int)err << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,14 +17,28 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
||||
serialParams.DCBlength = sizeof(serialParams);
|
||||
|
||||
if (!GetCommState(serialHandle, &serialParams)) {
|
||||
std::wcerr << L"Unable to get comm state of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
||||
DWORD err = GetLastError();
|
||||
std::wcerr << L"Unable to get comm state of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
serialParams.BaudRate = baudRate;
|
||||
serialParams.ByteSize = 8;
|
||||
serialParams.Parity = NOPARITY;
|
||||
serialParams.StopBits = ONESTOPBIT;
|
||||
serialParams.fParity = FALSE;
|
||||
serialParams.fBinary = TRUE;
|
||||
serialParams.fOutxCtsFlow = FALSE;
|
||||
serialParams.fOutxDsrFlow = FALSE;
|
||||
serialParams.fOutX = FALSE;
|
||||
serialParams.fInX = FALSE;
|
||||
serialParams.fRtsControl = RTS_CONTROL_DISABLE;
|
||||
serialParams.fDtrControl = DTR_CONTROL_DISABLE;
|
||||
|
||||
if (!SetCommState(serialHandle, &serialParams)) {
|
||||
std::wcerr << L"Unable to set comm state of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
||||
DWORD err = GetLastError();
|
||||
std::wcerr << L"Unable to set comm state of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,24 +50,38 @@ OSerialBus::OSerialBus(const std::wstring& comPort, int baudRate):
|
||||
timeouts.WriteTotalTimeoutMultiplier = 10;
|
||||
|
||||
if (!SetCommTimeouts(serialHandle, &timeouts)) {
|
||||
std::wcerr << L"Unable to set comm timeouts of port " << normalizePort(comPort) << L"! Is the port busy?" << std::endl;
|
||||
DWORD err = GetLastError();
|
||||
std::wcerr << L"Unable to set comm timeouts of port " << normalizePort(comPort) << L"! Is the port busy? Error: " << (int)err << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
open = true;
|
||||
}
|
||||
|
||||
bool OSerialBus::isOpen() const
|
||||
OSerialBus::OSerialBus(OSerialBus&& other) noexcept:
|
||||
comPort(other.comPort),
|
||||
baudRate(other.baudRate),
|
||||
serialHandle(other.serialHandle),
|
||||
open(other.open)
|
||||
{
|
||||
other.serialHandle = INVALID_HANDLE_VALUE;
|
||||
other.open = false;
|
||||
}
|
||||
|
||||
bool OSerialBus::isOpen() const noexcept
|
||||
{
|
||||
return open;
|
||||
}
|
||||
|
||||
bool OSerialBus::close()
|
||||
bool OSerialBus::close() noexcept
|
||||
{
|
||||
if (!isOpen()) {
|
||||
return true;
|
||||
}
|
||||
return CloseHandle(serialHandle);
|
||||
}
|
||||
|
||||
bool OSerialBus::send(const std::string& line)
|
||||
bool OSerialBus::send(const std::string& line) noexcept
|
||||
{
|
||||
// Important: this relies on chartype of line being 1 byte long!
|
||||
const char* data = line.data();
|
||||
@@ -75,7 +104,7 @@ bool OSerialBus::send(const std::string& line)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSerialBus::sendl(const std::string& line)
|
||||
bool OSerialBus::sendl(const std::string& line) noexcept
|
||||
{
|
||||
if (!send(line)) {
|
||||
return false;
|
||||
@@ -83,17 +112,25 @@ bool OSerialBus::sendl(const std::string& line)
|
||||
return send("\n");
|
||||
}
|
||||
|
||||
int OSerialBus::getBaudRate() const
|
||||
int OSerialBus::getBaudRate() const noexcept
|
||||
{
|
||||
return baudRate;
|
||||
}
|
||||
|
||||
const std::wstring& OSerialBus::getComPort() const
|
||||
const std::wstring& OSerialBus::getComPort() const noexcept
|
||||
{
|
||||
return comPort;
|
||||
}
|
||||
|
||||
std::wstring OSerialBus::normalizePort(const std::wstring& port)
|
||||
OSerialBus& OSerialBus::operator<<(const std::string& in)
|
||||
{
|
||||
if (!send(in)) {
|
||||
throw std::runtime_error("Failed to write to COM port!");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::wstring OSerialBus::normalizePort(const std::wstring& port) noexcept
|
||||
{
|
||||
// If port string already includes prefix, return as-is
|
||||
if (port == L"\\\\.\\") {
|
||||
|
||||
+15
-9
@@ -6,20 +6,26 @@ class OSerialBus
|
||||
{
|
||||
#ifdef WINDOWS
|
||||
public:
|
||||
OSerialBus(const std::wstring& comPort, int baudRate = 9600);
|
||||
OSerialBus(const std::wstring& comPort, int baudRate = 9600) noexcept;
|
||||
OSerialBus(const OSerialBus& other) = delete;
|
||||
OSerialBus(OSerialBus&& other) noexcept;
|
||||
OSerialBus& operator=(const OSerialBus& other) = delete;
|
||||
|
||||
bool isOpen() const;
|
||||
bool close();
|
||||
bool send(const std::string& line);
|
||||
bool sendl(const std::string& line);
|
||||
bool isOpen() const noexcept;
|
||||
bool close() noexcept;
|
||||
bool send(const std::string& line) noexcept;
|
||||
bool sendl(const std::string& line) noexcept;
|
||||
|
||||
int getBaudRate() const;
|
||||
const std::wstring& getComPort() const;
|
||||
int getBaudRate() const noexcept;
|
||||
const std::wstring& getComPort() const noexcept;
|
||||
|
||||
// Alias for send()
|
||||
OSerialBus& operator<<(const std::string& in);
|
||||
|
||||
private:
|
||||
static std::wstring normalizePort(const std::wstring& port);
|
||||
static std::wstring normalizePort(const std::wstring& port) noexcept;
|
||||
|
||||
const std::wstring& comPort;
|
||||
const std::wstring comPort;
|
||||
const int baudRate = 0;
|
||||
HANDLE serialHandle;
|
||||
bool open = false;
|
||||
|
||||
+6
-1
@@ -9,7 +9,12 @@ int main()
|
||||
std::cerr << "Serial bus is not open! Is the COM port busy?" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
bus.sendl("MA 1 120");
|
||||
|
||||
if (!bus.send("MA 1 60\n")) {
|
||||
std::cerr << "Could not send command!" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
bus.close();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user