#ifndef SERIAL_H #define SERIAL_H #include #include #include #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 { 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) { 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; } } void Log(const std::string& log){ if(logCallBack){ auto msg = GetTimeNow() + " "+ log + "\n"; logCallBack(msg); } } void SetLogCallBack(std::function callBack){ logCallBack = callBack; } void CloseDevice(){ ser.closeDevice(); } ~Serial() = default; 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); // 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){ return true; } } return false; } }; #endif // SERIAL_H