diff --git a/include/serial.h b/include/serial.h index 56a1d65..d421100 100644 --- a/include/serial.h +++ b/include/serial.h @@ -9,137 +9,197 @@ #include #include #include +#include +#include #include "../third/serialib.h" using namespace std::literals::chrono_literals; -template -concept SupportString = requires{ - std::is_same_v; - std::is_same_v; -}; - -enum class -[[maybe_unused]] -ErrorCode{ - SUCCESS, - TIMEOUT, - SETTIMEOUTERROR, - WRITEINGERROR, - READINGERROR, -}; - -class Serial +namespace serial { -private: - serialib ser; - const char* endChar = "\r\n"; - std::function logCallBack; -public: - Serial() = default; - - std::string GetTimeNow(){ - auto now = std::chrono::system_clock::now(); - auto now_c = std::chrono::system_clock::to_time_t(now); - char buffer[32]; - ctime_s(buffer, 32, &now_c); - return std::string(buffer); - } - - template - bool OpenDevice(T PortName, unsigned int bauds) + static std::vector GetUsbPorts() { - int code; - if constexpr (std::is_same_v){ - code = ser.openDevice(PortName.c_str(), bauds); - } - else{ - code = ser.openDevice(PortName, bauds); - } - if(code == 1){ - return true; - }else{ - return false; + std::vector portArray; + std::string comname; + std::string showname; + for (int i = 0; i <= 256; i++) + { + std::format_to(std::back_inserter(comname), "\\\\.\\COM{}", i); + std::format_to(std::back_inserter(showname), "COM{}", i); + // 创建或者打开一个文件或者I/O设备,如执行成功,则返回文件句柄 INVALID_HANDLE_VALUE 表示出错 + const HANDLE m_handle = + ::CreateFileA(comname.c_str(), + static_cast(GENERIC_WRITE) | GENERIC_READ, + 0U, + nullptr, + OPEN_EXISTING, + 0U, + nullptr + ); + + if (m_handle != INVALID_HANDLE_VALUE) + { + portArray.push_back(showname); + CloseHandle(m_handle); + } + comname.clear(); + showname.clear(); } + return portArray; } - void Log(const std::string& log){ - if(logCallBack){ - auto msg = GetTimeNow() + " "+ log + "\n"; - logCallBack(msg); - } - } + template + concept SupportString = requires { + std::is_same_v; + std::is_same_v; + }; - void SetLogCallBack(std::function callBack){ - logCallBack = callBack; - } + enum class + [[maybe_unused]] ErrorCode + { + SUCCESS, + TIMEOUT, + SETTIMEOUTERROR, + WRITEINGERROR, + READINGERROR, + }; - void CloseDevice(){ - ser.closeDevice(); - } + class Serial + { + private: + serialib ser; + const char *endChar = "\r\n"; + std::function logCallBack; - ~Serial() = default; + public: + Serial() = default; + std::string GetTimeNow() + { + auto now = std::chrono::system_clock::now(); + auto now_c = std::chrono::system_clock::to_time_t(now); + char buffer[32]; + ctime_s(buffer, 32, &now_c); + return std::string(buffer); + } - template - std::optional GetAtResponse(T command, int timeout = 50){ - ser.flushReceiver(); - std::string reallyCommand; - std::string response; - if constexpr (std::is_same_v){ - reallyCommand = command + endChar; + bool IsOpen(){ + return ser.isDeviceOpen(); } - else{ - reallyCommand = std::string(command) + endChar; - } - ser.writeString(reallyCommand.c_str()); - Log("Send: " + reallyCommand); - std::this_thread::sleep_for(10ms); - // char buffer[ser.available()] = {0}; - auto availableSize = ser.available(); - char* buffer = new char[availableSize+1]; - std::memset(buffer, 0, availableSize); - auto size = ser.readBytes(buffer, availableSize, timeout); - if(size > 0){ - buffer[size] = '\0'; - response = std::string(buffer); - Log("Receive: " + response); - delete[] buffer; - return response; - } - delete[] buffer; - return std::nullopt; - } - template - bool GetAtUntil(T command, T expect = "OK",int timeout = 50){ - auto endTime = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); - ser.flushReceiver(); - std::string reallyCommand; - if constexpr (std::is_same_v){ - reallyCommand = command + endChar; - } - else{ - reallyCommand = std::string(command) + endChar; - } - ser.writeString(reallyCommand.c_str()); - Log("Send : " + reallyCommand); - while(std::chrono::system_clock::now() < endTime){ - std::this_thread::sleep_for(10ms); - auto availableSize = ser.available(); - auto buffer = new char[availableSize+1]; - auto size = ser.readBytes(buffer, availableSize, timeout); - auto str = std::string(buffer); - delete[] buffer; - if(size > 0) - Log("Receive: "+str); - if(str.find(expect) != std::string::npos){ + template + bool OpenDevice(T portName, unsigned int bauds = 115200) + { + std::string reallyPortName; + std::format_to(std::back_inserter(reallyPortName), "\\\\.\\{}", portName); + if(ser.isDeviceOpen()) return true; + int code; + code = ser.openDevice(reallyPortName.c_str(), bauds); + if (code == 1) + { return true; } + else + { + return false; + } } - return false; - } -}; + void Log(const std::string &log) + { + if (logCallBack) + { + auto msg = GetTimeNow() + " " + log + "\n"; + logCallBack(msg); + } + } + + void SetLogCallBack(std::function callBack) + { + logCallBack = callBack; + } + void CloseDevice() + { + if(!ser.isDeviceOpen()) return; + ser.closeDevice(); + } + + ~Serial() = default; + + template + std::optional DelayGetResponse(int delayTime, T command, int timeout = 50){ + std::this_thread::sleep_for(std::chrono::milliseconds(delayTime)); + return GetAtResponse(command, timeout); + } + + template + std::optional GetAtResponse(T command, int timeout = 50) + { + ser.flushReceiver(); + std::string reallyCommand; + std::string response; + if constexpr (std::is_same_v) + { + reallyCommand = command + endChar; + } + else + { + reallyCommand = std::string(command) + endChar; + } + ser.writeString(reallyCommand.c_str()); + Log("Send: " + reallyCommand); + std::this_thread::sleep_for(10ms); + auto availableSize = ser.available(); + char *buffer = new char[availableSize + 1]; + std::memset(buffer, 0, availableSize); + auto size = ser.readBytes(buffer, availableSize, timeout); + if (size > 0) + { + buffer[size] = '\0'; + response = std::string(buffer); + Log("Receive: " + response); + delete[] buffer; + return response; + } + delete[] buffer; + return std::nullopt; + } + + template + bool GetAtUntil(T command, T expect = "OK", int timeout = 50) + { + auto endTime = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout); + ser.flushReceiver(); + std::string reallyCommand; + if constexpr (std::is_same_v) + { + reallyCommand = command + endChar; + } + else + { + reallyCommand = std::string(command) + endChar; + } + ser.writeString(reallyCommand.c_str()); + Log("Send : " + reallyCommand); + while (std::chrono::system_clock::now() < endTime) + { + std::this_thread::sleep_for(10ms); + auto availableSize = ser.available(); + auto buffer = new char[availableSize + 1]; + auto size = ser.readBytes(buffer, availableSize, timeout); + buffer[size] = '\0'; + auto str = std::string(buffer); + delete[] buffer; + if (size > 0) + Log("Receive: " + str); + if (str.find(expect) != std::string::npos) + { + return true; + } + } + return false; + } + }; +} #endif // SERIAL_H