Document/VID ±í¸ñ.zipBinary files differ
SourceCode/Bond/MELSECSDK/include/Mdfunc.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,392 @@ #ifndef WINAPI #define WINAPI #endif #ifdef __cplusplus extern "C" { #endif SHORT WINAPI mdOpen( SHORT, SHORT, LPLONG ); SHORT WINAPI mdClose( LONG ); SHORT WINAPI mdSend( LONG, SHORT, SHORT, SHORT, PSHORT, LPVOID ); SHORT WINAPI mdReceive( LONG, SHORT, SHORT, SHORT, PSHORT, LPVOID ); SHORT WINAPI mdDevSet( LONG, SHORT, SHORT, SHORT ); SHORT WINAPI mdDevRst( LONG, SHORT, SHORT, SHORT ); SHORT WINAPI mdRandW( LONG, SHORT, LPVOID, LPVOID, SHORT ); SHORT WINAPI mdRandR( LONG, SHORT, LPVOID, LPVOID, SHORT ); SHORT WINAPI mdControl( LONG, SHORT, SHORT ); SHORT WINAPI mdTypeRead( LONG, SHORT, PSHORT ); SHORT WINAPI mdBdLedRead( LONG, PSHORT ); SHORT WINAPI mdBdModRead( LONG, PSHORT ); SHORT WINAPI mdBdModSet( LONG, SHORT ); SHORT WINAPI mdBdRst( LONG ); SHORT WINAPI mdBdSwRead( LONG, PSHORT ); SHORT WINAPI mdBdVerRead( LONG, PSHORT ); SHORT WINAPI mdInit( LONG ); SHORT WINAPI mdWaitBdEvent( LONG, PSHORT, LONG, PSHORT, PSHORT ); LONG WINAPI mdSendEx( LONG, LONG, LONG, LONG, LONG, LPLONG, LPVOID ); LONG WINAPI mdReceiveEx( LONG, LONG, LONG, LONG, LONG, LPLONG, LPVOID ); LONG WINAPI mdDevSetEx( LONG, LONG, LONG, LONG, LONG ); LONG WINAPI mdDevRstEx( LONG, LONG, LONG, LONG, LONG ); LONG WINAPI mdRandWEx( LONG, LONG, LONG, LPVOID, LPVOID, LONG ); LONG WINAPI mdRandREx( LONG, LONG, LONG, LPVOID, LPVOID, LONG ); LONG WINAPI mdRemBufWriteEx( LONG, LONG, LONG, LONG, LPLONG, LPVOID ); LONG WINAPI mdRemBufReadEx( LONG, LONG, LONG, LONG, LPLONG, LPVOID ); LONG WINAPI mdRemBufWriteIPEx( LONG, LONG, LONG, LPLONG, LPVOID ); LONG WINAPI mdRemBufReadIPEx( LONG, LONG, LONG, LPLONG, LPVOID ); #ifdef __cplusplus } #endif #define mdopen mdOpen #define mdclose mdClose #define mdsend mdSend #define mdreceive mdReceive #define mddevset mdDevSet #define mddevrst mdDevRst #define mdrandw mdRandW #define mdrandr mdRandR #define mdcontrol mdControl #define mdtyperead mdTypeRead #define mdsendex mdSendEx #define mdreceiveex mdReceiveEx #define mddevsetex mdDevSetEx #define mddevrstex mdDevRstEx #define mdrandwex mdRandWEx #define mdrandrex mdRandREx #define DevX (1) #define DevLX(x) (DevX*1000+(x)) #define DevY (2) #define DevLY(x) (DevY*1000+(x)) #define DevL (3) #define DevM (4) #define DevSM (5) #define DevF (6) #define DevTT (7) #define DevTC (8) #define DevCT (9) #define DevCC (10) #define DevTN (11) #define DevCN (12) #define DevD (13) #define DevSD (14) #define DevTM (15) #define DevTS (16) #define DevTS2 (16002) #define DevTS3 (16003) #define DevCM (17) #define DevCS (18) #define DevCS2 (18002) #define DevCS3 (18003) #define DevA (19) #define DevZ (20) #define DevV (21) #define DevR (22) #define DevZR (220) #define DevB (23) #define DevLB(x) (DevB*1000+(x)) #define DevW (24) #define DevLW(x) (DevW*1000+(x)) #define DevQSB (25) #define DevLSB(x) (DevQSB*1000+(x)) #define DevSTT (26) #define DevSTC (27) #define DevQSW (28) #define DevLSW(x) (DevQSW*1000+(x)) #define DevSPG(x) (29*1000+(x)) #define DevQV (30) #define DevMRB (33) #define DevMAB (34) #define DevSTN (35) #define DevWw (36) #define DevWr (37) #define DevLZ (38) #define DevRD (39) #define DevFS (40) #define DevLTT (41) #define DevLTC (42) #define DevLTN (43) #define DevLCT (44) #define DevLCC (45) #define DevLCN (46) #define DevLSTT (47) #define DevLSTC (48) #define DevLSTN (49) #define DevSPB (50) #define DevSPB1 (501) #define DevSPB2 (502) #define DevSPB3 (503) #define DevSPB4 (504) #define DevSPX (51) #define DevSPY (52) #define DevUSER (100) #define DevMAIL (101) #define DevMAILNC (102) #define DevER0 (22000) #define DevER1 (22001) #define DevER2 (22002) #define DevER3 (22003) #define DevER4 (22004) #define DevER5 (22005) #define DevER6 (22006) #define DevER7 (22007) #define DevER8 (22008) #define DevER9 (22009) #define DevER10 (22010) #define DevER11 (22011) #define DevER12 (22012) #define DevER13 (22013) #define DevER14 (22014) #define DevER15 (22015) #define DevER16 (22016) #define DevER17 (22017) #define DevER18 (22018) #define DevER19 (22019) #define DevER20 (22020) #define DevER21 (22021) #define DevER22 (22022) #define DevER23 (22023) #define DevER24 (22024) #define DevER25 (22025) #define DevER26 (22026) #define DevER27 (22027) #define DevER28 (22028) #define DevER29 (22029) #define DevER30 (22030) #define DevER31 (22031) #define DevER32 (22032) #define DevER33 (22033) #define DevER34 (22034) #define DevER35 (22035) #define DevER36 (22036) #define DevER37 (22037) #define DevER38 (22038) #define DevER39 (22039) #define DevER40 (22040) #define DevER41 (22041) #define DevER42 (22042) #define DevER43 (22043) #define DevER44 (22044) #define DevER45 (22045) #define DevER46 (22046) #define DevER47 (22047) #define DevER48 (22048) #define DevER49 (22049) #define DevER50 (22050) #define DevER51 (22051) #define DevER52 (22052) #define DevER53 (22053) #define DevER54 (22054) #define DevER55 (22055) #define DevER56 (22056) #define DevER57 (22057) #define DevER58 (22058) #define DevER59 (22059) #define DevER60 (22060) #define DevER61 (22061) #define DevER62 (22062) #define DevER63 (22063) #define DevER64 (22064) #define DevER65 (22065) #define DevER66 (22066) #define DevER67 (22067) #define DevER68 (22068) #define DevER69 (22069) #define DevER70 (22070) #define DevER71 (22071) #define DevER72 (22072) #define DevER73 (22073) #define DevER74 (22074) #define DevER75 (22075) #define DevER76 (22076) #define DevER77 (22077) #define DevER78 (22078) #define DevER79 (22079) #define DevER80 (22080) #define DevER81 (22081) #define DevER82 (22082) #define DevER83 (22083) #define DevER84 (22084) #define DevER85 (22085) #define DevER86 (22086) #define DevER87 (22087) #define DevER88 (22088) #define DevER89 (22089) #define DevER90 (22090) #define DevER91 (22091) #define DevER92 (22092) #define DevER93 (22093) #define DevER94 (22094) #define DevER95 (22095) #define DevER96 (22096) #define DevER97 (22097) #define DevER98 (22098) #define DevER99 (22099) #define DevER100 (22100) #define DevER101 (22101) #define DevER102 (22102) #define DevER103 (22103) #define DevER104 (22104) #define DevER105 (22105) #define DevER106 (22106) #define DevER107 (22107) #define DevER108 (22108) #define DevER109 (22109) #define DevER110 (22110) #define DevER111 (22111) #define DevER112 (22112) #define DevER113 (22113) #define DevER114 (22114) #define DevER115 (22115) #define DevER116 (22116) #define DevER117 (22117) #define DevER118 (22118) #define DevER119 (22119) #define DevER120 (22120) #define DevER121 (22121) #define DevER122 (22122) #define DevER123 (22123) #define DevER124 (22124) #define DevER125 (22125) #define DevER126 (22126) #define DevER127 (22127) #define DevER128 (22128) #define DevER129 (22129) #define DevER130 (22130) #define DevER131 (22131) #define DevER132 (22132) #define DevER133 (22133) #define DevER134 (22134) #define DevER135 (22135) #define DevER136 (22136) #define DevER137 (22137) #define DevER138 (22138) #define DevER139 (22139) #define DevER140 (22140) #define DevER141 (22141) #define DevER142 (22142) #define DevER143 (22143) #define DevER144 (22144) #define DevER145 (22145) #define DevER146 (22146) #define DevER147 (22147) #define DevER148 (22148) #define DevER149 (22149) #define DevER150 (22150) #define DevER151 (22151) #define DevER152 (22152) #define DevER153 (22153) #define DevER154 (22154) #define DevER155 (22155) #define DevER156 (22156) #define DevER157 (22157) #define DevER158 (22158) #define DevER159 (22159) #define DevER160 (22160) #define DevER161 (22161) #define DevER162 (22162) #define DevER163 (22163) #define DevER164 (22164) #define DevER165 (22165) #define DevER166 (22166) #define DevER167 (22167) #define DevER168 (22168) #define DevER169 (22169) #define DevER170 (22170) #define DevER171 (22171) #define DevER172 (22172) #define DevER173 (22173) #define DevER174 (22174) #define DevER175 (22175) #define DevER176 (22176) #define DevER177 (22177) #define DevER178 (22178) #define DevER179 (22179) #define DevER180 (22180) #define DevER181 (22181) #define DevER182 (22182) #define DevER183 (22183) #define DevER184 (22184) #define DevER185 (22185) #define DevER186 (22186) #define DevER187 (22187) #define DevER188 (22188) #define DevER189 (22189) #define DevER190 (22190) #define DevER191 (22191) #define DevER192 (22192) #define DevER193 (22193) #define DevER194 (22194) #define DevER195 (22195) #define DevER196 (22196) #define DevER197 (22197) #define DevER198 (22198) #define DevER199 (22199) #define DevER200 (22200) #define DevER201 (22201) #define DevER202 (22202) #define DevER203 (22203) #define DevER204 (22204) #define DevER205 (22205) #define DevER206 (22206) #define DevER207 (22207) #define DevER208 (22208) #define DevER209 (22209) #define DevER210 (22210) #define DevER211 (22211) #define DevER212 (22212) #define DevER213 (22213) #define DevER214 (22214) #define DevER215 (22215) #define DevER216 (22216) #define DevER217 (22217) #define DevER218 (22218) #define DevER219 (22219) #define DevER220 (22220) #define DevER221 (22221) #define DevER222 (22222) #define DevER223 (22223) #define DevER224 (22224) #define DevER225 (22225) #define DevER226 (22226) #define DevER227 (22227) #define DevER228 (22228) #define DevER229 (22229) #define DevER230 (22230) #define DevER231 (22231) #define DevER232 (22232) #define DevER233 (22233) #define DevER234 (22234) #define DevER235 (22235) #define DevER236 (22236) #define DevER237 (22237) #define DevER238 (22238) #define DevER239 (22239) #define DevER240 (22240) #define DevER241 (22241) #define DevER242 (22242) #define DevER243 (22243) #define DevER244 (22244) #define DevER245 (22245) #define DevER246 (22246) #define DevER247 (22247) #define DevER248 (22248) #define DevER249 (22249) #define DevER250 (22250) #define DevER251 (22251) #define DevER252 (22252) #define DevER253 (22253) #define DevER254 (22254) #define DevER255 (22255) #define DevER256 (22256) #define DevRBM (-32768) #define DevRAB (-32736) #define DevRX (-32735) #define DevRY (-32734) #define DevRW (-32732) #define DevARB (-32704) #define DevSB (-32669) #define DevSW (-32668) #define DevEM(x) (31*1000+(x)) #define DevED(x) (32*1000+(x)) SourceCode/Bond/MELSECSDK/lib/MdFunc32.libBinary files differ
SourceCode/Bond/Servo/CCLinkPerformance/CCLinkIEControl.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,81 @@ #include "stdafx.h" #include "CCLinkIEControl.h" CCCLinkIEControl::CCCLinkIEControl() : CPerformanceMelsec(BoardType::CC_LINK_IE_CONTROL) {} CCCLinkIEControl::~CCCLinkIEControl() = default; int CCCLinkIEControl::SetBoardModeEx(CCLinkIEControlMode mode) { return SetBoardMode(static_cast<short>(mode)); } CCLinkIEControlMode CCCLinkIEControl::GetBoardModeEx() { short nMode = 0; const int nResult = GetBoardMode(nMode); if (nResult != 0) { return CCLinkIEControlMode::UNKNOWN; } return ConvertToCCLinkIEControlMode(nMode); } int CCCLinkIEControl::GetBoardStatusEx(BoardStatus& status) { const int nResult = GetBoardStatus(status); if (nResult != 0) { return nResult; } return ValidateBoardStatus(status); } int CCCLinkIEControl::ReadLedStatus(LedStatus& outLedStatus) { std::vector<short> vecLedBuffer; const int nRet = ReadBoardLed(vecLedBuffer); if (nRet != 0) { return nRet; } if (vecLedBuffer.empty()) { UpdateLastError(ERROR_CODE_INVALID_DATA); return ERROR_CODE_INVALID_DATA; } // è§£æåä½ç¶æ const short nBuffer = vecLedBuffer[0]; outLedStatus.bExtPw = (nBuffer & (1 << 15)) != 0; outLedStatus.bRd = (nBuffer & (1 << 6)) != 0; outLedStatus.bDLnk = (nBuffer & (1 << 5)) != 0; outLedStatus.bPrm = (nBuffer & (1 << 4)) != 0; outLedStatus.bErr = (nBuffer & (1 << 3)) != 0; outLedStatus.bSd = (nBuffer & (1 << 2)) != 0; outLedStatus.bMode = (nBuffer & (1 << 1)) != 0; outLedStatus.bRun = (nBuffer & (1 << 0)) != 0; return 0; } CCLinkIEControlMode CCCLinkIEControl::ConvertToCCLinkIEControlMode(const short nMode) { switch (static_cast<CCLinkIEControlMode>(nMode)) { case CCLinkIEControlMode::ONLINE: return CCLinkIEControlMode::ONLINE; // å¨çº¿ case CCLinkIEControlMode::OFFLINE: return CCLinkIEControlMode::OFFLINE; // 离线 case CCLinkIEControlMode::INTER_STATION_TEST: return CCLinkIEControlMode::INTER_STATION_TEST; // ç«é´æµè¯ case CCLinkIEControlMode::LINE_TEST: return CCLinkIEControlMode::LINE_TEST; // 线路æµè¯ case CCLinkIEControlMode::LOOPBACK_TEST: return CCLinkIEControlMode::LOOPBACK_TEST; // èªåéæµè¯ case CCLinkIEControlMode::HW_TEST: return CCLinkIEControlMode::HW_TEST; // H/Wæµè¯ case CCLinkIEControlMode::BUS_IF_TEST: return CCLinkIEControlMode::BUS_IF_TEST; // æ»çº¿I/Fæµè¯ default: return CCLinkIEControlMode::UNKNOWN; } } int CCCLinkIEControl::ValidateBoardStatus(const BoardStatus& status) { if (status.nStationValue < 1 || status.nStationValue > 120) { return ERROR_CODE_STATION_OUT_OF_RANGE; // ç«å·è¶ åºèå´ } if (status.nGroupValue < 0 || status.nGroupValue > 32) { return ERROR_CODE_GROUP_OUT_OF_RANGE; // ç»è¶ åºèå´ } if (status.nNetworkValue < 1 || status.nNetworkValue > 239) { return ERROR_CODE_NETWORK_OUT_OF_RANGE; // ç½ç»å·è¶ åºèå´ } return 0; // æ ¡éªéè¿ } SourceCode/Bond/Servo/CCLinkPerformance/CCLinkIEControl.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,68 @@ #ifndef CCLINKIECONTROL_H #define CCLINKIECONTROL_H #include "PerformanceMelsec.h" enum class CCLinkIEControlMode : short { UNKNOWN = 0x0194, // æªç¥ ONLINE = 0x0000, // å¨çº¿ OFFLINE = 0x0002, // 离线 INTER_STATION_TEST = 0x0005, // ç«é´æµè¯ LINE_TEST = 0x0006, // 线路æµè¯ LOOPBACK_TEST = 0x0007, // èªåéæµè¯ HW_TEST = 0x0009, // H/Wæµè¯ BUS_IF_TEST = 0x000E // æ»çº¿I/Fæµè¯ }; class CCCLinkIEControl final : public CPerformanceMelsec { public: CCCLinkIEControl(); ~CCCLinkIEControl() override; struct LedStatus { bool bExtPw; // å¤é¨çµæºç¶æ (b15) bool bRd; // æ°æ®æ¥æ¶ç¶æ (b6) bool bDLnk; // æ°æ®é¾æ¥ç¶æ (b5) bool bPrm; // 管çåè½ç¶æ (b4) bool bErr; // éè¯¯ç¶æ (b3) bool bSd; // æ°æ®åéç¶æ (b2) bool bMode; // å¨ä½æ¨¡å¼ (b1) bool bRun; // è¿è¡ç¶æ (b0) // 转æ¢ä¸ºå符串ï¼ç¨äºè°è¯ std::string ToString() const { std::ostringstream oss; oss << "CC-Link IE Control Network LED Status: {" << "\n Ext Power: " << (bExtPw ? "ON" : "OFF") << "\n Receive Data: " << (bRd ? "Receiving" : "Not Receiving") << "\n Data Link: " << (bDLnk ? "Linked" : "Not Linked") << "\n Management: " << (bPrm ? "Managing" : "Not Managing") << "\n Error: " << (bErr ? "Error Detected" : "No Error") << "\n Send Data: " << (bSd ? "Sending" : "Not Sending") << "\n Mode: " << (bMode ? "Executing" : "Not Executing") << "\n Run: " << (bRun ? "Running" : "Stopped") << "\n}"; return oss.str(); } }; // 读åç®æ ç«ç¹CPUç±»å // short ReadCPUCodeEx(const StationIdentifier& station, short& nCPUCode); // æ¿æ¨¡å¼è·å/设置 int SetBoardModeEx(CCLinkIEControlMode mode); CCLinkIEControlMode GetBoardModeEx(); // è·åæ¿ç¶æ int GetBoardStatusEx(BoardStatus& status); // 读åLEDç¶æ int ReadLedStatus(LedStatus& outLedStatus); private: static CCLinkIEControlMode ConvertToCCLinkIEControlMode(short nMode); static int ValidateBoardStatus(const BoardStatus& status); }; #endif //CCLINKIECONTROL_H SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,1355 @@ // PerformanceMelsec.cpp: implementation of the CPerformanceMelsec class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "PerformanceMelsec.h" #include <windows.h> #include <iostream> #include <fstream> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif #ifdef _DEBUG #define LOG_ERROR(msg) \ std::cerr << "[ERROR] " << __FILE__ << ":" << __LINE__ << " (" << __FUNCTION__ << ") - " << msg << std::endl; #define LOG_DEBUG(msg) \ std::cout << "[DEBUG] " << __FILE__ << ":" << __LINE__ << " (" << __FUNCTION__ << ") - " << msg << std::endl; #else #define LOG_ERROR(msg) #define LOG_DEBUG(msg) #endif // åå§åéææååé std::unordered_map<int, std::string> CPerformanceMelsec::m_mapError = { // æ¿åSDKé误ç {0, "No error, communication successful."}, {1, "Driver not started. The driver is not running."}, {2, "Timeout error (board response error). Request not completed within timeout."}, {66, "Already OPEN error. The specified channel is OPEN."}, {68, "Path error. The specified path is invalid."}, {69, "Unsupported function execution error."}, {70, "Station number error. The specified station number is invalid."}, {71, "No received data error (during RECV function)."}, {77, "Memory allocation error / insufficient memory resources."}, {85, "SEND/RECV channel number error."}, {100, "Board H/W resource busy."}, {101, "Routing exception."}, {102, "Board driver I/F error: Failed to send request data to the board driver."}, {103, "Board driver I/F error: Failed to receive response data from the board driver."}, {130, "Initial software component No. Error."}, {131, "Capacity error."}, {133, "Parameter error."}, {16385, "Specified target station number does not exist."}, {16386, "Received a request that the target station cannot process."}, {16418, "Failed to create the event history file."}, {16420, "Failed to access the event history file."}, {16421, "Another board driver is using the event history file."}, {16432, "The specified soft component type does not exist."}, {16433, "Soft component specification error: Out of range or invalid start I/O or block number."}, {16512, "Request data exception: Invalid data or unsupported module."}, {16685, "File association error: Failed to create the event history file."}, {16837, "File association error: Event history file does not exist."}, {18944, "Link association error: Network does not exist, unsupported CPU, or incorrect network No./station number."}, {-1, "Invalid path. The specified function is not supported for this path."}, {-2, "Start component No. error. The specified component is out of range."}, {-3, "Capacity error. The capacity exceeds the component range."}, {-6, "Component type error. The specified type during write is invalid."}, {-8, "Channel No. error. The channel specified is invalid."}, {-12, "Target path error. The specified path points to an invalid target."}, {-13, "Write protection area error. The specified range is protected."}, {-16, "Target path conflict. The path conflicts with write protection settings."}, {-17, "Device not found or target not responding."}, {-18, "Invalid target. The device does not support the operation."}, {-19, "Invalid path operation. An unsupported path operation was executed."}, {-31, "DLL library call failed or path not initialized."}, {-32, "Resource timeout error. Communication timed out or exceeded resource limits."}, {-33, "Communication timeout error. The target is not responding or timed out."}, {-34, "Unsupported communication target error. The specified network No. or station No. points to an unsupported model."}, {-35, "Registry access error."}, {-36, "Registry access error."}, {-37, "Communication initialization error. The settings for initializing the communication path are invalid."}, {-42, "Key information error. Authentication failed."}, {-43, "Marking event error. TC waiting event write was executed on the CPU."}, {-61, "Marking event error. TC waiting event write was executed on the CPU."}, {-62, "Event waiting timeout. The specified external event waiting timed out."}, {-63, "Timeout value is out of range."}, {-64, "Timeout value is out of range."}, {-65, "Event waiting timeout. The specified external event waiting timed out."}, {-66, "Timeout-induced resource shortage."}, {-67, "Irrelevant file access execution error."}, {-69, "Operation executed, but the module does not support the function."}, {-70, "The target event processing module returned a rejection."}, {-71, "The remote station did not return data correctly."}, {-72, "Pointer error. The specified pointer value is invalid."}, {-73, "Specified address error."}, {-2174, "Buffer data queue exception occurred. Read/write exception to device."}, {-7656, "Buffer data queue exception. Read/write exception to the device."}, {-7672, "Buffer data queue exception. Read/write exception to the device."}, {-11683, "Buffer data transfer error."}, {-11717, "Network No. error."}, {-11746, "Station No. error."}, {-12128, "Buffer data send/response error."}, {-18560, "Module mode setting error."}, {-18572, "Communication method error."}, {-25056, "Processor error."}, {-26334, "Duplicate program call or illegal CPU operation."}, {-26336, "Routing request error to a station without routing function support."}, {-27902, "Event register timeout error."}, {-28079, "Communication No. read error."}, {-28080, "Communication No. incorrect error."}, {-28136, "Unsupported function in fast mode error."}, {-28139, "Link disconnection error."}, {-28140, "Incorrect mode setting error."}, {-28141, "System reboot error."}, {-28142, "Mode error."}, {-28143, "Hardware self-diagnosis error."}, {-28144, "Hardware self-diagnosis error."}, {-28150, "Data reception interruption at remote station error."}, {-28151, "Data reception interruption at remote station error."}, {-28153, "Data reception interruption at remote station error."}, {-28154, "Abnormal data reception error."}, {-28158, "Driver WDT error."}, {-28160, "Hardware resource error."}, {-28622, "Dedicated instruction channel in-use error."}, {-28634, "Hardware self-diagnosis error."}, {-28636, "Hardware self-diagnosis error."}, // èªå®ä¹é误ç {ERROR_CODE_UNKNOWN, "Error: Unknown error code."}, {ERROR_CODE_NOT_CONNECTED, "Error: Not connected to the device."}, {ERROR_CODE_INVALID_PARAM, "Error: Invalid parameter."}, {ERROR_CODE_INVALID_DATA, "Error: Invalid data provided."}, {ERROR_CODE_STATION_OUT_OF_RANGE, "Error: Station number is out of range."}, {ERROR_CODE_GROUP_OUT_OF_RANGE, "Error: Group number is out of range."}, {ERROR_CODE_NETWORK_OUT_OF_RANGE, "Error: Network number is out of range."} }; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CPerformanceMelsec::CPerformanceMelsec(const BoardType enBoardType) { m_nPath = 0; m_enBoardType = enBoardType; m_bConnected.store(false); } // ææå½æ° CPerformanceMelsec::~CPerformanceMelsec() { Disconnect(); } // è·åæè¿çéè¯¯ä¿¡æ¯ std::string CPerformanceMelsec::GetLastError() const { return m_strLastError; } // ä¿åéè¯¯ä¿¡æ¯ bool CPerformanceMelsec::SaveErrorInfoToFile(const std::string& filename) { // æå¼æä»¶ std::ofstream file(filename); if (!file.is_open()) { std::cerr << "Failed to open file for saving: " << filename << std::endl; return false; } // éåéææååé m_mapError å¹¶å°æ¯ä¸ªé误信æ¯åå ¥æä»¶ for (const auto& entry : m_mapError) { const int nCode = entry.first; const std::string& strMessage = entry.second; file << nCode << "|" << strMessage << "\n"; } file.close(); return true; } // å è½½éè¯¯ä¿¡æ¯ bool CPerformanceMelsec::LoadErrorInfoFromFile(const std::string& filename) { std::ifstream inFile(filename); if (!inFile.is_open()) { std::cerr << "Failed to open file for loading: " << filename << std::endl; return false; } m_mapError.clear(); std::string line; while (std::getline(inFile, line)) { std::istringstream iss(line); int nCode = 0; std::string strToken; std::string strMessage; // 使ç¨åé符 "|" è§£ææ¯ä¸è¡ if (std::getline(iss, strToken, '|')) { nCode = std::stoi(strToken); } if (std::getline(iss, strToken)) { strMessage = strToken; } if (!strMessage.empty()) { m_mapError[nCode] = strMessage; } } return true; } // è¿æ¥å°PLC int CPerformanceMelsec::Connect(const short nChannel, const short nMode) { std::lock_guard<std::mutex> lock(m_mtx); if (m_bConnected.load()) { return 0; } const BoardType enBoardType = FindBoardTypeByChannel(nChannel); if (enBoardType == BoardType::UNKNOWN || enBoardType != m_enBoardType) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } // è¿æ¥PLCï¼æ¾å¼ç±»å转æ¢ä»¥å¹é mdOpen çç¾å const short nRet = mdOpen(nChannel, nMode, &m_nPath); if (nRet == 0) { m_bConnected.store(true); m_enBoardType = enBoardType; } else { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æå¼è¿æ¥ int CPerformanceMelsec::Disconnect() { std::lock_guard<std::mutex> lock(m_mtx); short nRet = 0; if (m_bConnected.load()) { nRet = mdClose(m_nPath); m_bConnected.store(false); m_nPath = 0; } UpdateLastError(nRet); LOG_DEBUG("Close connect."); return nRet; } // å¯ç¼ç¨æ§å¶å¨è½¯å ä»¶ä¿¡æ¯è¡¨çåå§å int CPerformanceMelsec::InitializeController() { std::lock_guard<std::mutex> lock(m_mtx); if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } const short nRet = mdInit(m_nPath); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // è·åçæ¬ä¿¡æ¯ int CPerformanceMelsec::GetBoardVersion(BoardVersion& version) { if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } // è·åçæ¬ä¿¡æ¯ short buf[32] = {0}; const short nRet = mdBdVerRead(m_nPath, buf); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); return nRet; } // å¡«å çæ¬ä¿¡æ¯å°ç»æä½ version.fixedValue[0] = static_cast<char>(buf[0] & 0xFF); version.fixedValue[1] = static_cast<char>((buf[0] >> 8) & 0xFF); version.checksum[0] = static_cast<char>(buf[1] & 0xFF); version.checksum[1] = static_cast<char>((buf[1] >> 8) & 0xFF); version.swVersion[0] = static_cast<char>(buf[2] & 0xFF); version.swVersion[1] = static_cast<char>((buf[2] >> 8) & 0xFF); std::memcpy(version.date, &buf[3], 6); version.reserved = static_cast<uint32_t>(buf[6]) | (static_cast<uint32_t>(buf[7]) << 16); std::memcpy(version.swModel, &buf[8], 16); std::memcpy(version.hwModel, &buf[16], 16); version.twoPortMemory[0] = static_cast<char>(buf[18] & 0xFF); version.twoPortMemory[1] = static_cast<char>((buf[18] >> 8) & 0xFF); version.twoPortAttribute[0] = static_cast<char>(buf[19] & 0xFF); version.twoPortAttribute[1] = static_cast<char>((buf[19] >> 8) & 0xFF); version.availableBias[0] = static_cast<char>(buf[20] & 0xFF); version.availableBias[1] = static_cast<char>((buf[20] >> 8) & 0xFF); std::memcpy(version.moduleType, &buf[21], 10); return nRet; } // 读åç®æ ç«ç¹CPUç±»å int CPerformanceMelsec::ReadCPUCode(const StationIdentifier& station, short& nCPUCode) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { nCPUCode = 0; std::lock_guard<std::mutex> lock(m_mtx); nRet = mdTypeRead(m_nPath, CombineStation(station), &nCPUCode); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ¿æ¨¡å¼è®¾ç½® int CPerformanceMelsec::SetBoardMode(const short nMode) { // æ£æ¥æ¯å¦å·²ç»è¿æ¥ if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ short nRet = 0; { std::lock_guard<std::mutex> lock(m_mtx); nRet = mdBdModSet(m_nPath, nMode); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // è·åæ¿æ¨¡å¼ int CPerformanceMelsec::GetBoardMode(short& nMode) { // æ£æ¥æ¯å¦å·²ç»è¿æ¥ if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } short nRet = 0; { nMode = 0; std::lock_guard<std::mutex> lock(m_mtx); nRet = mdBdModRead(m_nPath, &nMode); } if (nRet != 0) { UpdateLastError(nRet); LOG_DEBUG("Raw Mode: " << nMode); LOG_ERROR(m_strLastError); } return 0; } // æ¿å¤ä½ int CPerformanceMelsec::BoardReset() { std::lock_guard<std::mutex> lock(m_mtx); if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } const short nRet = mdBdRst(m_nPath); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ¿LED读å int CPerformanceMelsec::ReadBoardLed(std::vector<short>& vecLedBuffer) { std::lock_guard<std::mutex> lock(m_mtx); if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } // æ¸ ç©º LED ç¼å²åº vecLedBuffer.clear(); vecLedBuffer.resize(16, 0); // è°ç¨ SDK 彿°è¯»å LED æ°æ® const short nRet = mdBdLedRead(m_nPath, vecLedBuffer.data()); if (nRet != 0) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); LOG_ERROR("Error reading board LED, ErrorCode: " << nRet); LOG_ERROR(m_strLastError); } return nRet; } // è·åæ¿ç¶æ int CPerformanceMelsec::GetBoardStatus(BoardStatus& status) { std::lock_guard<std::mutex> lock(m_mtx); if (!m_bConnected) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } short buf[6] = {0}; const short nRet = mdBdSwRead(m_nPath, buf); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } // å° buf æ å°å°ç»æä½ status = BoardStatus::fromBuffer(buf); return 0; } // éç¨è¯»æ°æ® int CPerformanceMelsec::ReadData(const StationIdentifier& station, const short nDevType, const short nDevNo, short nSize, std::vector<short>& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStationAndSize(station, nSize); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // åå§å读åç¼å²åº vecData.clear(); vecData.resize(nSize); // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { std::lock_guard<std::mutex> lock(m_mtx); short* pData = vecData.data(); nRet = mdReceive(m_nPath, CombineStation(station), nDevType, nDevNo, &nSize, pData); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } if (nRet != 0) { vecData.clear(); // å¦æè¯»åå¤±è´¥ï¼æ¸ 空ç¼å²åº } return nRet; } // 读å使°æ® int CPerformanceMelsec::ReadBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nBitCount, BitContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStationAndSize(station, nBitCount); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // 计ç®éè¦è¯»åçåè大å°ï¼æä½å¯¹é½ä¸ºåèæ°ï¼ const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>((nBitCount + 7) / 8); // åä¸åæ´ std::vector<short> vecTempBuffer((nSize + 1) / 2, 0); // 临æ¶ç¼å²åºï¼åèå¯¹é½ nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer); if (nRet == 0) { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertShortToUint8(vecTempBuffer, vecData); } return nRet; } // 读ååæ°æ® int CPerformanceMelsec::ReadWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nWordCount, WordContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStationAndSize(station, nWordCount); if (nRet != 0) { UpdateLastError(nRet); return nRet; } const short nDevType = CalculateDeviceType(station, enDevType); std::vector<short> vecTempBuffer(nWordCount, 0); nRet = ReadData(station, nDevType, nDevNo, nWordCount, vecTempBuffer); if (nRet == 0) { vecData.clear(); vecData.assign(vecTempBuffer.begin(), vecTempBuffer.end()); } return nRet; } // 读åååæ°æ® int CPerformanceMelsec::ReadDWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const short nDWordCount, DWordContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStationAndSize(station, nDWordCount); if (nRet != 0) { UpdateLastError(nRet); return nRet; } const auto nSize = static_cast<short>(nDWordCount * 2); // æ¯ä¸ªååå 两个åï¼æ¯ä¸ªååå 4 åèï¼ const short nDevType = CalculateDeviceType(station, enDevType); std::vector<short> vecTempBuffer(nSize, 0); nRet = ReadData(station, nDevType, nDevNo, nSize, vecTempBuffer); if (nRet == 0) { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertShortToUint32(vecTempBuffer, vecData); } return nRet; } // éç¨åæ°æ® int CPerformanceMelsec::WriteData(const StationIdentifier& station, const short nDevType, const short nDevNo, short nSize, short* pData) { // éªè¯ç«ç¹åæ° int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // æ°æ®æææ§ if (nSize < 0 || pData == nullptr) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { std::lock_guard<std::mutex> lock(m_mtx); nRet = mdSend(m_nPath, CombineStation(station), nDevType, nDevNo, &nSize, pData); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // å使°æ® int CPerformanceMelsec::WriteBitData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const BitContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ const int nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // 计ç®éè¦åå ¥çåèæ°ï¼ä½æ°æ®éè¦æ 8 ä½å¯¹é½ä¸ºåèæ°ï¼ const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>((vecData.size() + 7) / 8); std::vector<short> vecBuffer(vecData.size() / 2 + vecData.size() % 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertUint8ToShort(vecData, vecBuffer); } return WriteData(station, nDevType, nDevNo, nSize, vecBuffer.data()); } // ååæ°æ® int CPerformanceMelsec::WriteWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const WordContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ const int nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // 计ç®éè¦åå ¥çåèæ°ï¼æ¯ä¸ªåå 2 åèï¼ const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>(vecData.size() * sizeof(uint16_t)); const auto pData = const_cast<short*>(reinterpret_cast<const short*>(vecData.data())); return WriteData(station, nDevType, nDevNo, nSize, pData); } // åååæ°æ® int CPerformanceMelsec::WriteDWordData(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo, const DWordContainer& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ const int nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // 计ç®éè¦åå ¥çåèæ°ï¼æ¯ä¸ªååå 4 åèï¼ const short nDevType = CalculateDeviceType(station, enDevType); const auto nSize = static_cast<short>(vecData.size() * sizeof(uint32_t)); std::vector<short> vecBuffer(vecData.size() * 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertUint32ToShort(vecData, vecBuffer); } return WriteData(station, nDevType, nDevNo, nSize, vecBuffer.data()); } // æ©å±è¯»æ°æ® long CPerformanceMelsec::ReadDataEx(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<char>& vecData) { // éªè¯ç«ç¹åæ°å读å大尿¯å¦ææ long nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } if (nSize < 0) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } vecData.resize(nSize); long nActualSize = (nSize + 1) / 2; std::vector<short> vecBuffer(nActualSize, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ nRet = mdReceiveEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nActualSize, vecBuffer.data()); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } else { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertShortToChar(vecBuffer, vecData); } return 0; } // æ©å±åæ°æ® long CPerformanceMelsec::WriteDataEx(const StationIdentifier& station, long nDevType, long nDevNo, const std::vector<char>& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ long nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // å° vecData 转æ¢ä¸º short ç±»åçç¼å²åº long nSize = static_cast<long>(vecData.size()); std::vector<short> vecBuffer((nSize + 1) / 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertCharToShort(vecData, vecBuffer); nRet = mdSendEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo, &nSize, vecBuffer.data()); } // é误å¤ç忥å¿è®°å½ if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ©å±è½¯å ä»¶éæºè¯»å long CPerformanceMelsec::ReadRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, std::vector<char>& vecData) { if (vecSoftElements.empty()) { UpdateLastError(ERROR_INVALID_PARAMETER); LOG_ERROR("Invalid parameters: soft elements are empty."); return ERROR_INVALID_PARAMETER; } // åå¤ dev æ°æ® std::vector<short> devBuffer(vecSoftElements.size() * 3 + 1, 0); // æ¯ä¸ªè½¯å ä»¶éè¦ 3 个 shortï¼å¤å ä¸ä¸ªè®¡æ°å¨ devBuffer[0] = static_cast<short>(vecSoftElements.size()); // 第ä¸ä¸ªå ç´ æ¯è½¯å ä»¶æ°é for (size_t i = 0; i < vecSoftElements.size(); ++i) { const SoftElement& element = vecSoftElements[i]; devBuffer[i * 3 + 1] = element.nType; // 软å ä»¶ç±»å devBuffer[i * 3 + 2] = static_cast<short>(element.nStartNo); // èµ·å§è½¯å ä»¶ç¼å· devBuffer[i * 3 + 3] = element.nElementCount; // ç¹æ° } // 计ç®è¯»åæ°æ®æéç¼å²åºå¤§å° long nBufferSize = 0; for (const auto& element : vecSoftElements) { nBufferSize += element.nElementCount * 2; // æ¯ä¸ªç¹å ç¨ 2 个åè } // éä¿æ¤åè°ç¨ mdRandREx long nRet = 0; std::vector<short> vecBuffer(nBufferSize / 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // ç¡®ä¿çº¿ç¨å®å ¨ nRet = mdRandREx(m_nPath, station.nNetNo, station.nStNo, devBuffer.data(), vecBuffer.data(), nBufferSize); } // é误å¤ç忥å¿è®°å½ if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); return nRet; } // å°è¯»åå°ç short æ°æ®è½¬æ¢ä¸º char æ°æ® vecData.resize(nBufferSize); for (size_t i = 0; i < vecBuffer.size(); ++i) { vecData[i * 2] = static_cast<char>(vecBuffer[i] & 0xFF); // ä½åè vecData[i * 2 + 1] = static_cast<char>((vecBuffer[i] >> 8) & 0xFF); // é«åè } return nRet; } // æ©å±è½¯å ä»¶éæºåå ¥ï¼æ¯æå¤ä¸ªè½¯å ä»¶ï¼ long CPerformanceMelsec::WriteRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, const std::vector<char>& vecData) { if (vecSoftElements.empty() || vecData.empty()) { UpdateLastError(ERROR_INVALID_PARAMETER); LOG_ERROR("Invalid parameters: soft elements or data is empty."); return ERROR_INVALID_PARAMETER; } // åå¤ dev æ°æ® std::vector<long> devBuffer(vecSoftElements.size() * 3 + 1, 0); // æ¯ä¸ªè½¯å ä»¶éè¦ 3 个 longï¼å¤å ä¸ä¸ªè®¡æ°å¨ devBuffer[0] = static_cast<long>(vecSoftElements.size()); // 第ä¸ä¸ªå ç´ æ¯è½¯å ä»¶æ°é for (size_t i = 0; i < vecSoftElements.size(); ++i) { const SoftElement& element = vecSoftElements[i]; devBuffer[i * 3 + 1] = static_cast<long>(element.nType); // 软å ä»¶ç±»å devBuffer[i * 3 + 2] = element.nStartNo; // èµ·å§è½¯å ä»¶ç¼å·ï¼å·²ç»æ¯ long ç±»åï¼æ é转æ¢ï¼ devBuffer[i * 3 + 3] = static_cast<long>(element.nElementCount); // ç¹æ° } // éä¿æ¤åè°ç¨ mdRandWEx long nRet = 0; std::vector<short> vecBuffer(vecData.size() / 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // ç¡®ä¿çº¿ç¨å®å ¨ ConvertCharToShort(vecData, vecBuffer); nRet = mdRandWEx(m_nPath, station.nNetNo, station.nStNo, devBuffer.data(), vecBuffer.data(), static_cast<long>(vecBuffer.size())); } // é误å¤ç忥å¿è®°å½ if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // è¿ç¨è®¾å¤ç«/è¿ç¨ç«çç¼å²åå¨å¨è¯»å long CPerformanceMelsec::ReadRemoteBuffer(const StationIdentifier& station, long nOffset, long nSize, std::vector<char>& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } if (nSize < 0) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } long nActualSize = (nSize + 1) / 2; std::vector<short> vecBuffer(nActualSize, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ nRet = mdRemBufReadEx(m_nPath, station.nNetNo, station.nStNo, nOffset, &nActualSize, vecBuffer.data()); } if (nRet != 0) { UpdateLastError(nRet); // æ´æ°é误ç LOG_ERROR(m_strLastError); } else { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertShortToChar(vecBuffer, vecData); } return nRet; } // è¿ç¨è®¾å¤ç«/è¿ç¨ç«çç¼å²åå¨å¨åå ¥ long CPerformanceMelsec::WriteRemoteBuffer(const StationIdentifier& station, long nOffset, const std::vector<char>& vecData) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ long nRet = ValidateStationAndData(station, vecData); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // å° vecData 转æ¢ä¸º short ç±»åçç¼å²åº long nSize = static_cast<long>(vecData.size()); std::vector<short> vecBuffer((nSize + 1) / 2, 0); { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertCharToShort(vecData, vecBuffer); nRet = mdRemBufWriteEx(m_nPath, station.nNetNo, station.nStNo, nOffset, &nSize, vecBuffer.data()); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // è¿ç¨ç«çç¼å²åå¨å¨è¯»å 对象ç«IPå°åæå® long CPerformanceMelsec::ReadRemoteBufferByIp(const std::string& strIP, long nOffset, long nSize, std::vector<char>& vecData) { uint32_t nAddress = 0; if (nSize < 0 || !ConvertIpStringToUint32(strIP, nAddress)) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } // å°ç¼å²åºå¤§å°è°æ´ä¸º nSize vecData.resize(nSize, 0); std::vector<short> vecBuffer((nSize + 1) / 2, 0); // 转æ¢ä¸º short ç±»å // è°ç¨åºå± SDK long nRet = 0; { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ nRet = mdRemBufReadIPEx(m_nPath, static_cast<long>(nAddress), nOffset, &nSize, vecBuffer.data()); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } else { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ä¿æ¤ ConvertShortToChar(vecBuffer, vecData); } return nRet; } // è¿ç¨ç«çç¼å²åå¨å¨åå ¥ 对象ç«IPå°åæå® long CPerformanceMelsec::WriteRemoteBufferByIp(const std::string& strIP, long nOffset, const std::vector<char>& vecData) { uint32_t nAddress = 0; if (vecData.empty() || !ConvertIpStringToUint32(strIP, nAddress)) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } // è½¬æ¢ vecData 为 short ç±»åçç¼å²åº long nSize = static_cast<long>(vecData.size()); std::vector<short> vecBuffer((nSize + 1) / 2, 0); long nRet = 0; { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ ConvertCharToShort(vecData, vecBuffer); nRet = mdRemBufWriteIPEx(m_nPath, static_cast<long>(nAddress), nOffset, &nSize, vecBuffer.data()); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // 设置(ON)对象ç«çæå®ä½è½¯å ä»¶ int CPerformanceMelsec::SetBitDevice(const StationIdentifier& station, const DeviceType enDevType, const short nDevNo) { // éªè¯ç«ç¹åæ° int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { std::lock_guard<std::mutex> lock(m_mtx); // 线ç¨å®å ¨ const short nDevType = CalculateDeviceType(station, enDevType); nRet = mdDevSet(m_nPath, CombineStation(station), nDevType, nDevNo); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // å¤ä½(OFF)对象ç«çæå®ä½è½¯å ä»¶ int CPerformanceMelsec::ResetBitDevice(const StationIdentifier& station, const DeviceType enDevType, const short enDevNo) { // éªè¯ç«ç¹åæ° int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { std::lock_guard<std::mutex> lock(m_mtx); const short nDevType = CalculateDeviceType(station, enDevType); nRet = mdDevRst(m_nPath, CombineStation(station), nDevType, enDevNo); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ©å±ä½è½¯å 件设置 long CPerformanceMelsec::SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) { std::lock_guard<std::mutex> lock(m_mtx); // æ£æ¥åæ°æææ§ long nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } nRet = mdDevSetEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ©å±ä½è½¯å ä»¶å¤ä½ long CPerformanceMelsec::ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo) { std::lock_guard<std::mutex> lock(m_mtx); // æ£æ¥åæ°æææ§ long nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } nRet = mdDevRstEx(m_nPath, station.nNetNo, station.nStNo, nDevType, nDevNo); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // æ§è¡å¯¹è±¡ç«çCPU int CPerformanceMelsec::ControlCPU(const StationIdentifier& station, ControlCode enControlCode) { // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int nRet = ValidateStation(station); if (nRet != 0) { UpdateLastError(nRet); return nRet; } // éªè¯æ§å¶ç æ¯å¦åæ³ const auto nControlCode = static_cast<short>(enControlCode); if (nControlCode < 0 || nControlCode > 2) { UpdateLastError(ERROR_CODE_INVALID_PARAM); // åæ°é误 return ERROR_CODE_INVALID_PARAM; } // ç¡®ä¿çº¿ç¨å®å ¨çæå°éå®èå´ { std::lock_guard<std::mutex> lock(m_mtx); nRet = mdControl(m_nPath, CombineStation(station), nControlCode); } if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } // äºä»¶çå¾ int CPerformanceMelsec::WaitForBoardEvent(std::vector<short> vecEventNumbers, const int nTimeoutMs, EventDetails& details) { std::lock_guard<std::mutex> lock(m_mtx); if (!m_bConnected.load()) { UpdateLastError(ERROR_CODE_NOT_CONNECTED); return ERROR_CODE_NOT_CONNECTED; } if (vecEventNumbers.empty() || vecEventNumbers.size() > 64) { UpdateLastError(ERROR_CODE_INVALID_PARAM); return ERROR_CODE_INVALID_PARAM; } // 第 0 个å ç´ å卿°éï¼æå¤§æ¯æ 64 个äºä»¶ std::array<short, 65> eventno = {0}; eventno[0] = static_cast<short>(vecEventNumbers.size()); std::copy(vecEventNumbers.begin(), vecEventNumbers.end(), eventno.begin() + 1); // åå§åè¾åºåæ° details.nEventNo = 0; details.details.fill(0); const int nRet = mdWaitBdEvent(m_nPath, eventno.data(), nTimeoutMs, &details.nEventNo, details.details.data()); if (nRet != 0) { UpdateLastError(nRet); LOG_ERROR(m_strLastError); } return nRet; } //============================================è¾ å©å½æ°======================================================= // æ´æ°æè¿çéè¯¯ä¿¡æ¯ void CPerformanceMelsec::UpdateLastError(const int nCode) { if (nCode == 0) { return; } // æ£æ¥éè¯¯ç æ¯å¦åå¨äºæ å°è¡¨ä¸ const auto it = m_mapError.find(nCode); if (it != m_mapError.end()) { // 妿æ¾å°ï¼ç´æ¥è¿å对åºè¯è¨çéè¯¯ä¿¡æ¯ m_strLastError = it->second; } else { // å¦ææªæ¾å°ï¼å¤çç¹æ®èå´ m_strLastError = "Unknown error."; if (nCode == -28611 || nCode == -28612) { // ç³»ç»åºé m_strLastError = "System error."; } if (nCode >= -20480 && nCode <= -16384) { // CC-Link ç³»ç»æ£æµåºçé误 m_strLastError = "Error detected in the CC-Link system."; } if (nCode >= -12288 && nCode <= -8193) { // CC-Link IE TSN ç³»ç»æ£æµåºçé误 m_strLastError = "Error detected in the CC-Link IE TSN system."; } if (nCode >= -8192 && nCode <= -4097) { // CC-Link IE æ§å¶ç½ç»ç³»ç»æ£æµåºçé误 m_strLastError = "Error detected in the CC-Link IE control network system."; } if (nCode >= -4096 && nCode <= -257) { // MELSECNET/10 æ MELSECNET/ç½ç»ç³»ç»é误èå´ m_strLastError = "Errors detected in MELSECNET/10 or MELSECNET/network system."; } if (nCode >= 4096 && nCode <= 16383) { // MELSEC æ°æ®é¾æ¥åºèå´ m_strLastError = "Internal error detected by MELSEC Data Link Library."; } if (nCode == 18944 || nCode == 18945) { // 龿¥å ³èåºé m_strLastError = "Link association error: Network does not exist, unsupported CPU, or incorrect network No./station number."; } if (nCode >= 16384 && nCode <= 20479) { // PLC CPU æ£æµèå´ m_strLastError = "Errors detected by the programmable controller CPU in the target station."; } if (nCode >= 28416 && nCode <= 28671) { // åä½åè½æ¨¡åèå´ m_strLastError = "Error detected in the redundancy module of the target station."; } } } // æ£æ¥è¿æ¥ç¶æåç«ç¹åæ°æææ§ int CPerformanceMelsec::ValidateStation(const StationIdentifier& station) const { // æ£æ¥æ¯å¦å·²è¿æ¥ if (!m_bConnected.load()) { return ERROR_CODE_NOT_CONNECTED; } // æ£æ¥ç½ç»å·åç«ç¹å·èå´ if (station.nNetNo < 0 || station.nNetNo > 239 || station.nStNo < 0 || station.nStNo > 255) { return ERROR_CODE_INVALID_PARAM; } return 0; // åæ°ææ } // éªè¯ç«ç¹åæ°åæ°æ®æææ§ int CPerformanceMelsec::ValidateStationAndSize(const StationIdentifier& station, const short nCount) const { // éªè¯ç«ç¹åæ° const int nRet = ValidateStation(station); if (nRet != 0) { return nRet; // 妿ç«ç¹éªè¯å¤±è´¥ï¼è¿å对åºé误ç } if (nCount <= 0) { return ERROR_CODE_INVALID_PARAM; } return 0; // éªè¯éè¿ } // IPå符串转uint32_t bool CPerformanceMelsec::ConvertIpStringToUint32(const std::string& strIP, uint32_t& nIP) { nIP = 0; std::stringstream ss(strIP); std::string strSegment; int nShift = 24; while (std::getline(ss, strSegment, '.')) { const auto nByte = static_cast<uint32_t>(std::stoi(strSegment)); if (nByte > 255) { return false; } nIP |= (nByte << nShift); nShift -= 8; } return true; } //============================================éæè¾ å©å½æ°==================================================== // å»¶æ¶ï¼å¹¶ä¸è½¬åçªå£æ¶æ¯ void CPerformanceMelsec::Delay(const unsigned int nDelayMs) { MSG message; // å¦æå»¶è¿æ¶é´ä¸º 0ï¼ä» å¤ç䏿¬¡æ¶æ¯éå if (nDelayMs == 0) { // éé»å¡çæ£æ¥æ¶æ¯éå if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&message); // å°æ¶æ¯è½¬å为ææççªå£æ¶æ¯ DispatchMessage(&message); // æ´¾åæ¶æ¯ç»ç¸åºççªå£è¿ç¨ } return; } DWORD finish; const DWORD start = GetTickCount(); // è·åå½åçæ¶é´æ³ï¼ä»ç³»ç»å¯å¨ä»¥æ¥çæ¯«ç§æ°ï¼ do { if (PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&message); // è½¬æ¢æ¶æ¯ DispatchMessage(&message); // å¤çæ¶æ¯ } Sleep(1); // æå 1 毫ç§ï¼é²æ¢è¿åº¦å ç¨ CPU finish = GetTickCount(); // è·åå½åçæ¶é´æ³ } while ((finish - start) < nDelayMs); // 循ç¯ç´å°ç»è¿çæ¶é´å¤§äºæå®çå»¶è¿æ¶é´ } BoardType CPerformanceMelsec::FindBoardTypeByChannel(const int nChannel) { if (nChannel >= MELSECNET_CHANNEL(1) && nChannel <= MELSECNET_CHANNEL(4)) { return BoardType::MELSECNET_H; } else if (nChannel >= CC_LINK_CHANNEL(1) && nChannel <= CC_LINK_CHANNEL(4)) { return BoardType::CC_LINK_VER_2; } else if (nChannel >= CC_LINK_IE_CONTROL_CHANNEL(1) && nChannel <= CC_LINK_IE_CONTROL_CHANNEL(4)) { return BoardType::CC_LINK_IE_CONTROL; } else if (nChannel >= CC_LINK_IE_FIELD_CHANNEL(1) && nChannel <= CC_LINK_IE_FIELD_CHANNEL(4)) { return BoardType::CC_LINK_IE_FIELD; } else if (nChannel >= CC_LINK_IE_TSN_CHANNEL(1) && nChannel <= CC_LINK_IE_TSN_CHANNEL(4)) { return BoardType::CC_LINK_IE_TSN; } return BoardType::UNKNOWN; } // åå¹¶ç½ç»å·åç«ç¹å· short CPerformanceMelsec::CombineStation(const StationIdentifier& station) { return static_cast<short>(station.nStNo | ((station.nNetNo << 8) & 0xFF00)); } // 计ç®è½¯å ä»¶ç±»å short CPerformanceMelsec::CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType) { int nDevType = static_cast<int>(enDevType); // æ ¹æ®è½¯å ä»¶ç±»åçç¹å®è§åè¿è¡è®¡ç® if (enDevType == DeviceType::LX || enDevType == DeviceType::LY || enDevType == DeviceType::LB || enDevType == DeviceType::LW || enDevType == DeviceType::LSB || enDevType == DeviceType::LSW) { // ç½ç»å·å åç§» nDevType += station.nNetNo; } else if (enDevType == DeviceType::ER) { // æä»¶å¯åå¨çåå·å åç§» nDevType += 0; } else if (enDevType == DeviceType::SPG) { // èµ·å§ I/O No. ÷ 16 çå¼ nDevType += 0 / 16; } return static_cast<short>(nDevType); } // std::vector<char>转æ¢ä¸ºstd::vector<short> void CPerformanceMelsec::ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort) { vecShort.resize((vecChar.size() + 1) / 2, 0); // è°æ´ short 容å¨å¤§å° for (size_t i = 0; i < vecChar.size(); i++) { if (i % 2 == 0) { vecShort[i / 2] = static_cast<unsigned char>(vecChar[i]); // ä½åè } else { vecShort[i / 2] |= static_cast<unsigned char>(vecChar[i]) << 8; // é«åè } } } // std::vector<short>转æ¢ä¸ºstd::vector<char> void CPerformanceMelsec::ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>& vecChar) { vecChar.resize(vecShort.size() * 2); // è°æ´ char 容å¨å¤§å° for (size_t i = 0; i < vecShort.size(); i++) { vecChar[i * 2] = static_cast<char>(vecShort[i] & 0xFF); // ä½åè vecChar[i * 2 + 1] = static_cast<char>((vecShort[i] >> 8) & 0xFF); // é«åè } } // std::vector<uint8_t>转æ¢ä¸ºstd::vector<short> void CPerformanceMelsec::ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort) { vecShort.resize((vecUint8.size() + 1) / 2, 0); // è°æ´ short 容å¨å¤§å° for (size_t i = 0; i < vecUint8.size(); i++) { if (i % 2 == 0) { vecShort[i / 2] = static_cast<short>(vecUint8[i]); // ä½åè } else { vecShort[i / 2] |= static_cast<short>(vecUint8[i] << 8); // é«åè } } } // std::vector<short>转æ¢ä¸ºstd::vector<uint8_t> void CPerformanceMelsec::ConvertShortToUint8(const std::vector<short>& vecShort, std::vector<uint8_t>& vecUint8) { vecUint8.resize(vecShort.size() * 2); // è°æ´ uint8_t 容å¨å¤§å° for (size_t i = 0; i < vecShort.size(); i++) { vecUint8[i * 2] = static_cast<uint8_t>(vecShort[i] & 0xFF); // ä½åè vecUint8[i * 2 + 1] = static_cast<uint8_t>((vecShort[i] >> 8) & 0xFF); // é«åè } } // std::vector<uint32_t>转æ¢ä¸ºstd::vector<short> void CPerformanceMelsec::ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort) { vecShort.resize(vecUint32.size() * 2); // æ¯ä¸ª uint32_t 转æ¢ä¸ºä¸¤ä¸ª short for (size_t i = 0; i < vecUint32.size(); i++) { vecShort[i * 2] = static_cast<short>(vecUint32[i] & 0xFFFF); // ä½16ä½ vecShort[i * 2 + 1] = static_cast<short>((vecUint32[i] >> 16) & 0xFFFF); // é«16ä½ } } // std::vector<short>转æ¢ä¸ºstd::vector<uint32_t> void CPerformanceMelsec::ConvertShortToUint32(const std::vector<short>& vecShort, std::vector<uint32_t>& vecUint32) { vecUint32.resize((vecShort.size() + 1) / 2, 0); // æ¯ä¸¤ä¸ª short å并为ä¸ä¸ª uint32_t for (size_t i = 0; i < vecUint32.size(); i++) { vecUint32[i] = (static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2 + 1])) << 16) | // é«16ä½ static_cast<uint32_t>(static_cast<uint16_t>(vecShort[i * 2])); // ä½16ä½ } } //============================================模æ¿è¾ å©å½æ°==================================================== // éªè¯ç«ç¹åæ°åæ°æ®æææ§ template <typename T> int CPerformanceMelsec::ValidateStationAndData(const StationIdentifier& station, const std::vector<T>& vecData) { // éªè¯ç«ç¹åæ° const int nRet = ValidateStation(station); if (nRet != 0) { return nRet; // 妿ç«ç¹éªè¯å¤±è´¥ï¼è¿å对åºé误ç } // éªè¯æ°æ®æ¯å¦ä¸ºç©º if (vecData.empty()) { return ERROR_CODE_INVALID_PARAM; } return 0; // éªè¯éè¿ } // ç±ä½è½¬é«å®¹å¨ç模æ¿ï¼æ´åï¼ template <typename T, typename U> void CPerformanceMelsec::ConvertLowToHigh(const std::vector<T>& vecLow, std::vector<U>& vecHigh) { static_assert(std::is_integral<T>::value && std::is_integral<U>::value, "T and U must be integral types"); // èªå¨è®¡ç® nGroupSize constexpr size_t nGroupSize = sizeof(U) / sizeof(T); // 妿 T å U ç大å°ç¸çï¼ç´æ¥è½¬æ¢ if (sizeof(T) == sizeof(U)) { vecHigh.assign(vecLow.begin(), vecLow.end()); return; } // 妿 U ç大尿¯ T çåæ°ï¼æ£å¸¸ç»å static_assert(sizeof(U) > sizeof(T), "Size of U must be greater than or equal to size of T"); // 计ç®å®æ´ç»çæ°é size_t nHighSize = (vecLow.size() + nGroupSize - 1) / nGroupSize; // åä¸åæ´ vecHigh.resize(nHighSize, 0); // åå¹¶ä½ä½æ°æ®å°é«ä½æ°æ® for (size_t i = 0; i < vecLow.size(); i++) { vecHigh[i / nGroupSize] |= (static_cast<U>(vecLow[i]) << ((i % nGroupSize) * CHAR_BIT * sizeof(T))); } return vecHigh; } // ç±é«è½¬ä½å®¹å¨ç模æ¿ï¼æ´åï¼ template <typename T, typename U> void CPerformanceMelsec::ConvertHighToLow(const std::vector<T>& vecHigh, std::vector<U>& vecLow) { static_assert(std::is_integral<T>::value && std::is_integral<U>::value, "T and U must be integral types"); // èªå¨è®¡ç® nGroupSize constexpr size_t nGroupSize = sizeof(T) / sizeof(U); // 妿 T å U ç大å°ç¸çï¼ç´æ¥è½¬æ¢ if (sizeof(T) == sizeof(U)) { vecLow.assign(vecHigh.begin(), vecHigh.end()); return; } // 妿 T ç大尿¯ U çåæ°ï¼æ£å¸¸åè§£ static_assert(sizeof(T) > sizeof(U), "Size of T must be greater than or equal to size of U"); size_t nLowSize = vecHigh.size() * nGroupSize; // ä½å®¹å¨çå¤§å° vecLow.resize(nLowSize, 0); // åè§£é«ä½æ°æ®å°ä½ä½æ°æ® for (size_t i = 0; i < vecHigh.size(); i++) { for (size_t j = 0; j < nGroupSize; j++) { vecLow[i * nGroupSize + j] = static_cast<U>((vecHigh[i] >> (j * CHAR_BIT * sizeof(U))) & ((1ULL << (CHAR_BIT * sizeof(U))) - 1)); } } return vecLow; } SourceCode/Bond/Servo/CCLinkPerformance/PerformanceMelsec.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,465 @@ #ifndef PERFORMANCE_MELSEC_H #define PERFORMANCE_MELSEC_H #include <map> #include <array> #include <mutex> #include <string> #include <vector> #include <atomic> #include <sstream> #include <unordered_map> // è¿æ¥åæ° #define PLC_MAX_RETRY 3 // æå¤§éè¯æ¬¡æ°ï¼å¨ä¸PLCéä¿¡æ¶ï¼å¦æåçéä¿¡é误ï¼å°æå¤éè¯3次 #define PLC_TIMEOUT 500 // è¶ æ¶æ¶é´ï¼æ¯«ç§ï¼ï¼æ¯æ¬¡éä¿¡æä½çè¶ æ¶çå¾ æ¶é´ä¸º500æ¯«ç§ /* * ç½ç»ééï¼æå®éä¿¡æä½¿ç¨çç½ç»ééå·ï¼é常å¨å¤éééä¿¡ä¸è®¾ç½® * 51 å° 54 æ¯ MELSECNET/H ç 1-4 éé * 81 å° 84 æ¯ CC-Link ç 1-4 éé * 151 å° 154 æ¯ CC-Link IE æ§å¶å¨ç½ç»ç 1-4 éé * 181 å° 184 æ¯ CC-Link IE ç°åºç½ç»ç 1-4 éé * 281 å° 284 æ¯ CC-Link IE TSN ç½ç»ç 1-4 éé **/ #define MELSECNET_CHANNEL(x) (50 + (x)) // x èå´ï¼1~4 #define CC_LINK_CHANNEL(x) (80 + (x)) // x èå´ï¼1~4 #define CC_LINK_IE_CONTROL_CHANNEL(x) (150 + (x)) // x èå´ï¼1~4 #define CC_LINK_IE_FIELD_CHANNEL(x) (180 + (x)) // x èå´ï¼1~4 #define CC_LINK_IE_TSN_CHANNEL(x) (280 + (x)) // x èå´ï¼1~4 // èªå®ä¹é误ç #define ERROR_CODE_UNKNOWN 0x00010000 // æªç¥ #define ERROR_CODE_NOT_CONNECTED 0x00020000 // æªè¿æ¥ #define ERROR_CODE_INVALID_PARAM 0x00030000 // åæ°æ æ #define ERROR_CODE_INVALID_DATA 0x00040000 // æ°æ®æ æ #define ERROR_CODE_STATION_OUT_OF_RANGE 0x00050000 // ç«å·è¶ åºèå´ #define ERROR_CODE_GROUP_OUT_OF_RANGE 0x00060000 // ç»å·è¶ åºèå´ #define ERROR_CODE_NETWORK_OUT_OF_RANGE 0x00070000 // ç½ç»å·è¶ åºèå´ // æ¿åç±»å enum class BoardType { UNKNOWN = -1, // æªç¥ç±»å MELSECNET_H = MELSECNET_CHANNEL(1), // MELSECNET/H CC_LINK_VER_2 = CC_LINK_CHANNEL(1), // CC-Link Ver. 2 CC_LINK_IE_CONTROL = CC_LINK_IE_CONTROL_CHANNEL(1), // CC-Link IE æ§å¶ç½ç» CC_LINK_IE_FIELD = CC_LINK_IE_FIELD_CHANNEL(1), // CC-Link IE ç°åºç½ç» CC_LINK_IE_TSN = CC_LINK_IE_TSN_CHANNEL(1) // CC-Link IE TSN }; // 软å ä»¶ç±»åæä¸¾ enum class DeviceType { /* * ERãLXãLYãLBãLWãLSBãLSWåSPG软å 件齿¯èå´å * ERï¼DevER0ï½256 * LXï¼DevLX1ï½255ï¼DevLX(x) (DevX*1000+(x)) * LYï¼DevLY1ï½255ï¼DevLY(x) (DevY*1000+(x)) * LBï¼DevLB1ï½255ï¼DevLB(x) (DevB*1000+(x)) * LWï¼DevLW1ï½255ï¼DevLW(x) (DevW*1000+(x)) * LSBï¼DevLSB1ï½255ï¼DevLSB(x) (DevQSB*1000+(x)) * LSWï¼DevLSW1ï½255ï¼DevLSW(x) (DevQSW*1000+(x)) * SPGï¼DevSPG0ï½255ï¼DevSPG(x) (29*1000+(x)) * æ©å±æä»¶å¯åå¨ä»£ç æå®(10è¿å¶æ°)çå3使°å软å ä»¶åæå®çæ°å¼ä¸ï¼åºæå®åNo.(0ï½256) * 龿¥ç´æ¥è½¯å ä»¶ä»£ç æå®(10è¿å¶æ°)çå3使°å软å ä»¶åæå®çæ°å¼ä¸ï¼åºæå®ç½ç»No.(1ï½255) * æºè½åè½æ¨¡å软å ä»¶ä»£ç æå®(10è¿å¶æ°)çå3使°å软å ä»¶åæå®çæ°å¼ä¸ï¼åºæå®(èµ·å§I/ONo.÷16)çå¼ * æ©å±æä»¶å¯åå¨å龿¥ç´æ¥è½¯å ä»¶å¨éæºè¯»å(mdRandRãmdRandREx)彿°ä¸ï¼å³ä½¿æå®å®é ä¸åå¨ç软å 件乿å¯è½æ£å¸¸ç»æ * MAILåMAILMCå¨SENDåè½åRECVåè½ä¸ï¼ä¸è½¯å 件访é®ä¸æ ·ï¼æå®ååè½å¯¹åºç软å ä»¶ç±»åï¼è¿è¡æ°æ®çåé(mdSendãmdSendEx)ææ°æ®ç读å(mdReceiveãmdReceiveEx) **/ X = 0x0001, // è¾å ¥ (ä½) Y = 0x0002, // è¾åº (ä½) L = 0x0003, // éåç»§çµå¨ (ä½) M = 0x0004, // å é¨ç»§çµå¨ (ä½) SM = 0x0005, // ç¹æ®ç»§çµå¨ (ä½) F = 0x0006, // æ¥è¦å¨ (ä½) TT = 0x0007, // 宿¶å¨ (触ç¹) (ä½) TC = 0x0008, // 计æ°å¨ (线å) (ä½) CT = 0x0009, // 计æ°å¨ (触ç¹) (ä½) CC = 0x000A, // 计æ°å¨ (线å) (å) TN = 0x000B, // 宿¶å¨ (å½åå¼) (å) CN = 0x000C, // 计æ°å¨ (å½åå¼) (å) D = 0x000D, // æ°æ®å¯åå¨ (å) SD = 0x000E, // ç¹æ®å¯åå¨ (å) TM = 0x000F, // 宿¶å¨ (设置å¼ä¸») (å) TS = 0x0010, // 宿¶å¨ (设置å¼ä¸»1) (å) TS2 = 0x3E82, // 宿¶å¨ (设置å¼ä¸»2) (å) TS3 = 0x3E83, // 宿¶å¨ (设置å¼ä¸»3) (å) CM = 0x0011, // 计æ°å¨ (设置å¼ä¸») (å) CS = 0x0012, // 计æ°å¨ (设置å¼ä¸»1) (å) CS2 = 0x4652, // 计æ°å¨ (设置å¼ä¸»2) (å) CS3 = 0x4653, // 计æ°å¨ (设置å¼ä¸»3) (å) A = 0x0013, // ç´¯å å¨ (å) Z = 0x0014, // ååå¯åå¨ (å) V = 0x0015, // ååå¯åå¨ (å) R = 0x0016, // æä»¶å¯åå¨ (å忢æ¹å¼) (å) ER = 0x55F0, // æ©å±æä»¶å¯åå¨ (å忢æ¹å¼) (0x55F0ï½0x56F0) (å) (å¨éæºè¯»å(mdRandRãmdRandREx)彿°ä¸ï¼å³ä½¿æå®å®é ä¸åå¨ç软å 件乿å¯è½æ£å¸¸ç»æã(è¯»åæ°æ®ä¸æ£ç¡®ã)) ZR = 0x00DC, // æä»¶å¯åå¨ (è¿å·è®¿é®æ¹å¼) (å) B = 0x0017, // 龿¥ç»§çµå¨ (ä½) W = 0x0018, // 龿¥å¯åå¨ (å) QSB = 0x0019, // 龿¥ç¹æ®ç»§çµå¨ (ä½) STT = 0x001A, // ç´¯è®¡å®æ¶å¨ (触ç¹) (ä½) STC = 0x001B, // ç´¯è®¡å®æ¶å¨ (线å) (ä½) QSW = 0x001C, // 龿¥ç¹æ®å¯åå¨ (å) QV = 0x001E, // ååç»§çµå¨ (ä½) MRB = 0x0021, // éæºè®¿é®ç¼å² (å) STN = 0x0023, // ç´¯è®¡å®æ¶å¨ (å½åå¼) (å) LZ = 0x0026, // è¶ é¿ååå¯åå¨ (åå) RD = 0x0027, // å·æ°æ°æ®å¯åå¨ (å) LTT = 0x0029, // è¶ é¿å®æ¶å¨ (触ç¹) (ä½) LTC = 0x002A, // è¶ é¿å®æ¶å¨ (线å) (ä½) LTN = 0x002B, // è¶ é¿å®æ¶å¨ (å½åå¼) (åå) LCT = 0x002C, // è¶ é¿è®¡æ°å¨ (触ç¹) (ä½) LCC = 0x002D, // è¶ é¿è®¡æ°å¨ (线å) (ä½) LCN = 0x002E, // è¶ é¿è®¡æ°å¨ (å½åå¼) (åå) LSTT = 0x002F, // è¶ é¿ç´¯è®¡å®æ¶å¨ (触ç¹) (ä½) LSTC = 0x0030, // è¶ é¿ç´¯è®¡å®æ¶å¨ (线å) (ä½) LSTN = 0x0031, // è¶ é¿ç´¯è®¡å®æ¶å¨ (å½åå¼) (åå) SPB = 0x0032, // ç¼å²åå¨å¨ (å) MAIL = 0x0065, // ç¹æ®è½¯å ä»¶ç±»åï¼é®ä»¶ç±»å (10è¿å¶ 101) MAILMC = 0x0066, // ç¹æ®è½¯å ä»¶ç±»åï¼æ 确认é®ä»¶ (10è¿å¶ 102) LX = 0x03E9, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥è¾å ¥) (0x03E9ï½0x04E7) (ä½) LY = 0x07D1, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥è¾åº) (0x07D1ï½0x08CF) (ä½) LB = 0x59D9, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥ç»§çµå¨) (0x59D9ï½0x5AD7) (ä½) LW = 0x5DC1, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥å¯åå¨) (0x5DC1ï½0x5EBF) (å) LSB = 0x61A9, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥ç¹æ®ç»§çµå¨) (0x61A9ï½0x62A7) (ä½) LSW = 0x6D61, // 龿¥ç´æ¥è½¯å ä»¶ (龿¥ç¹æ®å¯åå¨) (0x6D61ï½0x6E5F) (å) SPG = 0x7148, // æºè½åè½æ¨¡å软å ä»¶ (0x7148ï½0x7247) (å) }; // æ°æ®ç±»å enum class DataType { BIT = 1, // ä½ (1ä½) WORD = 2, // å (16ä½) DWORD =4 // åå (32ä½) }; // æ§å¶ä»£ç enum class ControlCode { RUN = 0, // è¿ç¨ RUN STOP = 1, // è¿ç¨ STOP PAUSE = 2 // è¿ç¨ PAUSE }; // çæ¬ä¿¡æ¯ struct BoardVersion { char fixedValue[2]; // åºå®å¼ char checksum[2]; // æ ¡éªå char swVersion[2]; // è½¯ä»¶çæ¬ char date[6]; // æ¥æ (æ ¼å¼ YYMMDD) uint32_t reserved; // ä¿çåºå (4 åè) char swModel[16]; // 软件åå· char hwModel[16]; // 硬件åå· char twoPortMemory[2]; // 两端å£åå¨å¨å ç¨å®¹é char twoPortAttribute[2]; // 两端å£å±æ§ char availableBias[2]; // å¯ä½¿ç¨åç½® char moduleType[10]; // æºåç±»å // è¾åºç»æä½å 容为å符串 (便äºè°è¯) std::string toString() const { std::ostringstream oss; oss << "Fixed Value: " << fixedValue[0] << fixedValue[1] << "\n" << "Checksum: " << checksum[0] << checksum[1] << "\n" << "SW Version: " << swVersion[0] << swVersion[1] << "\n" << "Date: " << std::string(date, 6) << "\n" << "Reserved: " << reserved << "\n" << "SW Model: " << std::string(swModel, 16) << "\n" << "HW Model: " << std::string(hwModel, 16) << "\n" << "Two Port Memory: " << twoPortMemory[0] << twoPortMemory[1] << "\n" << "Two Port Attribute: " << twoPortAttribute[0] << twoPortAttribute[1] << "\n" << "Available Bias: " << availableBias[0] << availableBias[1] << "\n" << "Module Type: " << std::string(moduleType, 10) << "\n"; return oss.str(); } }; // ç«ç¹æ è¯ç¬¦ï¼é»è®¤ä½¿ç¨æ¬ç« struct StationIdentifier { /* * [Network No.] * 0 表示æ¬ç« * 1~239 表示æ®éç½ç»å· **/ /* * [Station No.] * MELSECNET/Hï¼1~64 è¡¨ç¤ºå ¶ä»ç«ç¹ï¼255 表示æ¬ç« * CC-Link ç³»åç½ç»çèå´ç±»ä¼¼ï¼åºå«å¨äºç«å·çåå¼èå´ * MELSECNET/H : 1~64(Other stations),255(Own station) * CC-Link : 0~63(Other stations),255(Own station) * CC-Link IE Controller : 1~120(Other stations),255(Own station) * CC-Link IE Field : 0~120(Other stations),255(Own station) * CC-Link IE TSN : 0~120(Other stations),255(Own station) **/ /* * é« 8 ä½ï¼ç½ç»å·ï¼ï¼ æå®è®¾å¤æå±çç½ç» * ä½ 8 ä½ï¼ç«ç¹å·ï¼ï¼ æå®è®¾å¤å¨ç½ç»ä¸çç¼å· * ç¨ä¸ä¸ªåæ°ä¼ é设å¤çç½ç»å·åç«ç¹å·æ¶: nSt = station.nStNo | ((station.nNetNo << 8) & 0xFF00); **/ short nNetNo = 0; // ç½ç»ç¼å·ï¼PLCæè¿æ¥çç½ç»ç¼å·ï¼0表示é»è®¤ç½ç» short nStNo = 255; // ç«ç¹ç¼å·ï¼æå®ä¸PLCè¿æ¥çç«ç¹ç¼å·ï¼255éå¸¸è¡¨ç¤ºå¹¿ææææç«ç¹ // èªå®ä¹æé 彿°ï¼è¦çé»è®¤å¼ explicit StationIdentifier(const short net, const short st) : nNetNo(net), nStNo(st) {} // å°âç½ç»å·âåâç«ç¹å·âç»åæä¸ä¸ªæç»ç¼ç short StationIdentifier::toNetworkStationCode() const { return static_cast<short>(nStNo | ((nNetNo << 8) & 0xFF00)); } // éè½½ < è¿ç®ç¬¦ï¼ç¨äºæåºææ¯è¾ï¼é常ç¨äº map æ set ä¸ä½ä¸º keyï¼ bool operator<(const StationIdentifier& other) const { return std::tie(nNetNo, nStNo) < std::tie(other.nNetNo, other.nStNo); } // éè½½ == è¿ç®ç¬¦ï¼ç¨äºç¸çæ¯è¾ï¼ bool operator==(const StationIdentifier& other) const { return std::tie(nNetNo, nStNo) == std::tie(other.nNetNo, other.nStNo); } // éè½½ = è¿ç®ç¬¦ï¼ç¨äºèµå¼ï¼ StationIdentifier& operator=(const StationIdentifier& other) { if (this != &other) { nNetNo = other.nNetNo; nStNo = other.nStNo; } return *this; } }; // æ¿ç¶æ struct BoardStatus { short nStationValue = 0; // ç«å·ç设å¤å¼ (buf[0]) short nGroupValue = 0; // ç» No. ç设å¤å¼ (buf[1]) short nNetworkValue = 0; // ç½ç» No. ç设å¤å¼ (buf[2]) short nReserved1 = 0; // ä¿çåæ®µ (buf[3]) short nReserved2 = 0; // ä¿çåæ®µ (buf[4]) short nReserved3 = 0; // ä¿çåæ®µ (buf[5]) // å°æ°ç»æ å°å°ç»æä½ static BoardStatus fromBuffer(const short buf[6]) { return { buf[0], buf[1], buf[2], buf[3], buf[4], buf[5] }; } // å°ç»æä½å 容æ å°å°æ°ç» void toBuffer(short buf[6]) const { buf[0] = nStationValue; buf[1] = nGroupValue; buf[2] = nNetworkValue; buf[3] = nReserved1; buf[4] = nReserved2; buf[5] = nReserved3; } // è°è¯è¾åº std::string toString() const { std::ostringstream oss; oss << "Station Value: " << nStationValue << "\n" << "Group Value: " << nGroupValue << "\n" << "Network Value: " << nNetworkValue << "\n" << "Reserved1: " << nReserved1 << "\n" << "Reserved2: " << nReserved2 << "\n" << "Reserved3: " << nReserved3 << "\n"; return oss.str(); } }; // äºä»¶è¯¦æ struct EventDetails { short nEventNo; // åççäºä»¶å· std::array<short, 4> details; // åå¨äºä»¶è¯¦æ ä¿¡æ¯ // è§£æäºä»¶è¯¦æ ï¼è¿åæ ¼å¼åå符串 std::string toString() const { std::ostringstream oss; oss << "Details[0]: " << details[0] << ", " << "Details[1]: " << details[1] << ", " << "Details[2]: " << details[2] << ", " << "Details[3]: " << details[3]; return oss.str(); } }; // SoftElement ç»æä½å®ä¹ struct SoftElement { short nType; // 软å ä»¶ç±»å short nElementCount; // ç¹æ° long nStartNo; // èµ·å§è½¯å ä»¶ç¼å· }; // éè¯¯ä¿¡æ¯ struct ErrorInfo { int nErrorCode = 0; // é误ç std::string strErrorMessageCn; // 䏿æè¿° std::string strErrorMessageEn; // è±ææè¿° // å°ç»æä½åºåå为å符串 std::string toString() const { std::ostringstream oss; oss << nErrorCode << "|" << strErrorMessageCn << "|" << strErrorMessageEn; return oss.str(); } // ä»å符串ååºååä¸ºç»æä½ static ErrorInfo fromString(const std::string& line) { ErrorInfo info; std::istringstream iss(line); std::string token; // 使ç¨åé符 "|" è§£æå符串 std::getline(iss, token, '|'); info.nErrorCode = std::stoi(token); std::getline(iss, token, '|'); info.strErrorMessageCn = token; std::getline(iss, token, '|'); info.strErrorMessageEn = token; return info; } }; using BitContainer = std::vector<uint8_t>; // æ¯ä¸ªå ç´ åå¨ 8 ä¸ªä½ using WordContainer = std::vector<uint16_t>; // æ¯ä¸ªå ç´ åå¨ 16 ä½ using DWordContainer = std::vector<uint32_t>; // æ¯ä¸ªå ç´ åå¨ 32 ä½ // CPerformanceMelsec 类声æ class CPerformanceMelsec { public: // è·åæè¿çéè¯¯ä¿¡æ¯ std::string GetLastError() const; // é误信æ¯å è½½ä¸ä¿åæ¥å£ static bool LoadErrorInfoFromFile(const std::string& filename); // 仿件å è½½éè¯¯ä¿¡æ¯ static bool SaveErrorInfoToFile(const std::string& filename); // ä¿åé误信æ¯å°æä»¶ // è¿æ¥/æå¼ int Connect(short nChannel, short nMode = -1); int Disconnect(); // åå§åå¯ç¼ç¨æ§å¶å¨è½¯å ä»¶ä¿¡æ¯è¡¨ int InitializeController(); // è·åçæ¬ä¿¡æ¯ int GetBoardVersion(BoardVersion& version); // æ¿å¤ä½ int BoardReset(); // æ¿LED读å int ReadBoardLed(std::vector<short>& vecLedBuffer); // 读åç®æ ç«ç¹CPUç±»å int ReadCPUCode(const StationIdentifier& station, short& nCPUCode); // æ¿æ¨¡å¼è·å/设置 int SetBoardMode(short nMode); int GetBoardMode(short& nMode); // è·åæ¿ç¶æ int GetBoardStatus(BoardStatus& status); // è¯»åæ°æ® int ReadData(const StationIdentifier& station, short nDevType, short nDevNo, short nSize, std::vector<short>& vecData); int ReadBitData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nBitCount, BitContainer& vecData); int ReadWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nWordCount, WordContainer& vecData); int ReadDWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, short nDWordCount, DWordContainer& vecData); int WriteData(const StationIdentifier& station, short nDevType, short nDevNo, short nSize, short* pData); int WriteBitData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const BitContainer& vecData); int WriteWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const WordContainer& vecData); int WriteDWordData(const StationIdentifier& station, DeviceType enDevType, short nDevNo, const DWordContainer& vecData); // æ©å±è¯»åæ°æ® long ReadDataEx(const StationIdentifier& station, long nDevType, long nDevNo, long nSize, std::vector<char>& vecData); long WriteDataEx(const StationIdentifier& station, long nDevType, long nDevNo, const std::vector<char>& vecData); // æ©å±è½¯å ä»¶éæºè¯»åï¼æ¯æå¤ä¸ªè½¯å ä»¶ï¼ long ReadRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, std::vector<char>& vecData); long WriteRandomDataEx(const StationIdentifier& station, const std::vector<SoftElement>& vecSoftElements, const std::vector<char>& vecData); // è¿ç¨è®¾å¤ç«/è¿ç¨ç«çç¼å²åå¨å¨è¯»å long ReadRemoteBuffer(const StationIdentifier& station, long nOffset, long nSize, std::vector<char>& vecData); long WriteRemoteBuffer(const StationIdentifier& station, long nOffset, const std::vector<char>& vecData); long ReadRemoteBufferByIp(const std::string& strIP, long nOffset, long nSize, std::vector<char>& vecData); long WriteRemoteBufferByIp(const std::string& strIP, long nOffset, const std::vector<char>& vecData); // 设置/å¤ä½å¯¹è±¡ç«çæå®ä½è½¯å ä»¶ int SetBitDevice(const StationIdentifier& station, DeviceType enDevType, short nDevNo); int ResetBitDevice(const StationIdentifier& station, DeviceType enDevType, short enDevNo); // æ©å±è®¾ç½®/å¤ä½å¯¹è±¡ç«çæå®ä½è½¯å ä»¶ long SetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo); long ResetBitDeviceEx(const StationIdentifier& station, long nDevType, long nDevNo); // æ§è¡å¯¹è±¡ç«çCPU int ControlCPU(const StationIdentifier& station, ControlCode enControlCode); // äºä»¶çå¾ ï¼vecEventNumbers[0, 64]ï¼nTimeoutMs[-1, 2147483647] // åæ¶åçäºå¤ä¸ªäºä»¶çæ åµä¸ï¼é¦å æ£æµåºå ¶ä¸ä¸ä¸ªäºä»¶ã 忬¡æ§è¡äºæ¬å½æ°çæ åµä¸æ£æµåºå ¶å®äºä»¶ã int WaitForBoardEvent(std::vector<short> vecEventNumbers, int nTimeoutMs, EventDetails& details); private: // éå®ä¸è§£éï¼å¤çº¿ç¨åæ¥ä¿æ¤ï¼ void Lock() { m_mtx.lock(); } void Unlock() { m_mtx.unlock(); } protected: // æé 彿°/ææå½æ° explicit CPerformanceMelsec(BoardType enBoardType); virtual ~CPerformanceMelsec(); // è¾ å©å½æ° void UpdateLastError(int nCode); // æ´æ°æè¿çéè¯¯ä¿¡æ¯ int ValidateStation(const StationIdentifier& station) const; // æ£æ¥è¿æ¥ç¶æåç«ç¹åæ°æææ§ int ValidateStationAndSize(const StationIdentifier& station, short nCount) const; // éæè¾ å©å½æ° static void Delay(unsigned int nDelayMs); // å»¶æ¶ï¼å¹¶ä¸è½¬åçªå£æ¶æ¯ static BoardType FindBoardTypeByChannel(int nChannel); // æ¥æ¾æ¿åç±»å static short CombineStation(const StationIdentifier& station); // åå¹¶ç½ç»å·åç«ç¹å· static short CalculateDeviceType(const StationIdentifier& station, DeviceType enDevType); // 计ç®è½¯å ä»¶ç±»å // IPè½¬æ¢ static bool ConvertIpStringToUint32(const std::string& strIP, uint32_t& nIP); // 容å¨è½¬æ¢ static void ConvertCharToShort(const std::vector<char>& vecChar, std::vector<short>& vecShort); static void ConvertShortToChar(const std::vector<short>& vecShort, std::vector<char>&vecChar); static void ConvertUint8ToShort(const std::vector<uint8_t>& vecUint8, std::vector<short>& vecShort); static void ConvertShortToUint8(const std::vector<short>& vecShort, std::vector<uint8_t>& vecUint8); static void ConvertUint32ToShort(const std::vector<uint32_t>& vecUint32, std::vector<short>& vecShort); static void ConvertShortToUint32(const std::vector<short>& vecShort, std::vector<uint32_t>& vecUint32); // 模æ¿è¾ å©å½æ° template <typename T> int ValidateStationAndData(const StationIdentifier& station, const std::vector<T>& vecData); template <typename T, typename U> void ConvertLowToHigh(const std::vector<T>& vecLow, std::vector<U>& vecHigh); template <typename T, typename U> void ConvertHighToLow(const std::vector<T>& vecHigh, std::vector<U>& vecLow); // æååé std::mutex m_mtx; // äºæ¥éä¿æ¤ BoardType m_enBoardType; // æ¿åç±»å long m_nPath; // éä¿¡è·¯å¾ std::atomic<bool> m_bConnected; // æ¯å¦å·²è¿æ¥ std::string m_strLastError; // æè¿ä¸æ¬¡éè¯¯ä¿¡æ¯ // éææååé static std::unordered_map<int, std::string> m_mapError; // éè¯¯ç æ å°è¡¨ }; #endif // PERFORMANCE_MELSEC_H SourceCode/Bond/Servo/SECSRuntimeManager.cpp
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,682 @@ #include "stdafx.h" #include "SECSRuntimeManager.h" // 常é const std::string DATABASE_FILE = R"(SECSDataManager.db)"; // éææååå§å std::mutex SECSRuntimeManager::m_mutex; // è·ååä¾å®ä¾ SECSRuntimeManager& SECSRuntimeManager::getInstance() { static SECSRuntimeManager instance; return instance; } // æé 彿° SECSRuntimeManager::SECSRuntimeManager() { m_pDB = new BL::SQLiteDatabase(); } // ææå½æ° SECSRuntimeManager::~SECSRuntimeManager() { termRuntimeSetting(); if (m_pDB != nullptr) { delete m_pDB; m_pDB = nullptr; } } // 仿°æ®åºä¸è·åæ´æ° int SECSRuntimeManager::getIntFromDB(const std::string& query) { auto results = m_pDB->fetchResults(query); if (!results.empty() && !results[0].empty()) { // 转æ¢ç¬¬ä¸ä¸ªæ¥è¯¢ç»æä¸ºæ´æ° return std::stoi(results[0][0]); } return 0; } // 夿VIDæ¯å¦éå¤ bool SECSRuntimeManager::isIDDuplicate(int nID) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return false; } // å®ä¹è¦æ£æ¥ç表 std::vector<std::string> tables = { "SystemSV", "EqpSV", "SystemDV", "EqpDV", "SystemEC", "EqpEC" }; // éåè¡¨ï¼æ£æ¥æ¯å¦æéå¤ç ID for (const auto& table : tables) { // å建 SQL æ¥è¯¢ std::string checkSQL = "SELECT COUNT(*) FROM " + table + " WHERE ID = " + std::to_string(nID) + ";"; // æ§è¡æ¥è¯¢ auto results = m_pDB->fetchResults(checkSQL); int count = (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0; // 妿æ¾å°äºéå¤ç IDï¼åè¿å true if (count > 0) { return true; } } // å¦ææ²¡æéå¤ï¼è¿å false return false; } // 夿åç§°æ¯å¦éå¤ bool SECSRuntimeManager::isNameDuplicate(const std::string& sName) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return false; } // å®ä¹è¦æ£æ¥ç表 std::vector<std::string> tables = { "SystemSV", "EqpSV", "SystemDV", "EqpDV", "SystemEC", "EqpEC" }; // éåè¡¨ï¼æ£æ¥æ¯å¦æéå¤ç Name for (const auto& table : tables) { // å建 SQL æ¥è¯¢ std::string checkSQL = "SELECT COUNT(*) FROM " + table + " WHERE Name = '" + sName + "';"; // æ§è¡æ¥è¯¢ auto results = m_pDB->fetchResults(checkSQL); int count = (!results.empty() && !results[0].empty()) ? std::stoi(results[0][0]) : 0; // 妿æ¾å°äºéå¤ç Nameï¼åè¿å true if (count > 0) { return true; } } // å¦ææ²¡æéå¤ï¼è¿å false return false; } // è®¾ç½®æ°æ®åºè¿æ¥ void SECSRuntimeManager::setDatabase(BL::Database* db) { std::lock_guard<std::mutex> lock(m_mutex); m_pDB = db; } // åå§åSECS设置管çåº bool SECSRuntimeManager::initRuntimeSetting() { char path[MAX_PATH]; GetModuleFileName(NULL, path, MAX_PATH); std::string exePath(path); std::string dbFileDir = exePath.substr(0, exePath.find_last_of("\\/")) + "\\DB"; if (!CreateDirectory(dbFileDir.c_str(), NULL) && ERROR_ALREADY_EXISTS != GetLastError()) { throw std::runtime_error("Failed to create database directory."); } std::string dbFilePath = dbFileDir + "\\" + DATABASE_FILE; if (!m_pDB->connect(dbFilePath, true)) { return false; } // åå§å SystemSV 表 initSystemSVTable(); // åå§å EqpSV 表 initEqpSVTable(); // åå§å SystemDV 表 initSystemDVTable(); // åå§å EqpDV 表 initEqpDVTable(); // åå§å SystemEC 表 initSystemECTable(); // åå§å EqpEC 表 initEqpECTable(); // åå§å SystemECID 表 initSystemEventTable(); // åå§å EqpECID 表 initEqpEventTable(); // åå§å SystemEventLink 表 initEventLinkTable(); // åå§å PPID 表 initPPIDTable(); // åå§å RPTID 表 initRPTIDTable(); return true; } // 鿝SECS设置管çåº void SECSRuntimeManager::termRuntimeSetting() { if (m_pDB != nullptr) { m_pDB->disconnect(); } } // åå§å SystemSV 表 void SECSRuntimeManager::initSystemSVTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 SystemSV 表ï¼å¦æä¸åå¨ï¼ std::string createTableSQL = "CREATE TABLE IF NOT EXISTS SystemSV (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "Length INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SystemID INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create SystemSV table."); } // é¢å®ä¹ç SV æ°æ® std::vector<std::tuple<int, std::string, std::string, int, std::string, std::string, int>> svData = { {1, "SYS_LICENSE_CODE", "ASCII", 0, "NULL", "License code (Formal; Evaluation; NoLicense)", 1}, {2, "SYS_LICENSE_STATUS", "UINT_1", 0, "NULL", "License status(0:Unauthorized; 1:Authorized; 2:Evaluation; 3:Evaluation Expiring; 4:Trial; 5:Trial End)", 2}, {3, "GEM_CLOCK", "ASCII", 0, "NULL", "System Clock", 3}, {4, "SYS_SECS_COMM_MODE", "UINT_1", 0, "NULL", "SECS Communication Mode(0:HSMS Mode; 1:SECSI Mode)", 4}, {5, "SYS_SECS_DRIVER_CONNECT_STATE", "UINT_1", 0, "NULL", "Initial SECS Driver Connect State(0:Stop; 1:Start)", 5} }; for (const auto& entry : svData) { int nID, nLength, nSystemID; std::string sName, sDataType, sRemark, sUnit; std::tie(nID, sName, sDataType, nLength, sUnit, sRemark, nSystemID) = entry; // æ£æ¥ Name æ¯å¦å·²åå¨ int count = getIntFromDB("SELECT COUNT(*) FROM SystemSV WHERE Name = '" + sName + "';"); if (count == 0) { // æå ¥æ°æ® std::string insertSQL = "INSERT INTO SystemSV (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" + std::to_string(nID) + ", '" + sName + "', '" + sDataType + "', " + (nLength > 0 ? std::to_string(nLength) : "NULL") + ", " + ((sUnit == "NULL") ? "NULL" : "'" + sUnit + "'") + ", '" + sRemark + "', " + std::to_string(nSystemID) + ");"; if (!m_pDB->executeQuery(insertSQL)) { throw std::runtime_error("Failed to insert SystemSV data."); } } } } // æ·»å SystemSV æ°æ® int SECSRuntimeManager::addSystemSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } if (isIDDuplicate(nID)) { return 2; } if (isNameDuplicate(sName)) { return 3; } // 妿 Unit æ¯ "NULL" å符串æè 为空ï¼åæå ¥ NULL å¼ std::string insertSQL = "INSERT INTO SystemSV (ID, Name, DataType, Length, Unit, Remark, SystemID) VALUES (" + std::to_string(nID) + ", '" + sName + "', '" + sDataType + "', " + (nLength > 0 ? std::to_string(nLength) : "NULL") + ", " + ((sUnit == "NULL" || sUnit.empty()) ? "NULL" : "'" + sUnit + "'") + ", '" + sRemark + "', " + std::to_string(nSystemID) + ");"; if (!m_pDB->executeQuery(insertSQL)) { return 4; } return 0; } // æ´æ°æå® ID ç SystemSV æ°æ® int SECSRuntimeManager::updateIDSystemSV(int nID, int sNewID) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } // æ£æ¥æ¯å¦åå¨è¯¥ ID if (!isIDDuplicate(nID)) { return 2; } if (isIDDuplicate(sNewID)) { return 3; } // æå»ºæ´æ°ç SQL è¯å¥ std::string updateSQL = "UPDATE SystemSV SET ID = " + std::to_string(sNewID) + " WHERE ID = " + std::to_string(nID) + ";"; if (!m_pDB->executeQuery(updateSQL)) { return 4; } return 0; } // æ´æ°ææ SystemSV æ°æ® int SECSRuntimeManager::updateAllSystemSV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } // æ£æ¥æ¯å¦åå¨è¯¥ ID if (!isIDDuplicate(nID)) { return 2; } // æ£æ¥æ°ç ID æ¯å¦å·²åå¨ï¼å¦æå·²åå¨ï¼åè¿åé误代ç 3ã if (isIDDuplicate(sNewID)) { return 3; } // æå»ºæ´æ°ç SQL è¯å¥ std::string updateSQL = "UPDATE SystemSV SET "; bool firstField = true; // 妿æ°ç ID 被æä¾ï¼æ´æ° ID if (sNewID > 0) { if (!firstField) { updateSQL += ", "; } updateSQL += "ID = " + std::to_string(sNewID); firstField = false; } // æ´æ° Name if (!sName.empty()) { if (!firstField) { updateSQL += ", "; } updateSQL += "Name = '" + sName + "'"; firstField = false; } // æ´æ° DataType if (!sDataType.empty()) { if (!firstField) { updateSQL += ", "; } updateSQL += "DataType = '" + sDataType + "'"; firstField = false; } // æ´æ° Length if (nLength > 0) { if (!firstField) { updateSQL += ", "; } updateSQL += "Length = " + std::to_string(nLength); firstField = false; } // æ´æ° Unit if (sUnit != "NULL" && !sUnit.empty()) { if (!firstField) { updateSQL += ", "; } updateSQL += "Unit = '" + sUnit + "'"; firstField = false; } else if (sUnit == "NULL") { if (!firstField) { updateSQL += ", "; } updateSQL += "Unit = NULL"; firstField = false; } // æ´æ° Remark if (!sRemark.empty()) { if (!firstField) { updateSQL += ", "; } updateSQL += "Remark = '" + sRemark + "'"; firstField = false; } // æ´æ° SystemID if (nSystemID > 0) { if (!firstField) { updateSQL += ", "; } updateSQL += "SystemID = " + std::to_string(nSystemID); } // æ·»å WHERE å奿¥æå®æ´æ°åªä¸ªè®°å½ updateSQL += " WHERE ID = " + std::to_string(nID) + ";"; // æ§è¡æ´æ°æä½ if (!m_pDB->executeQuery(updateSQL)) { return 4; } return 0; } // å é¤æå® ID ç SystemSV æ°æ® int SECSRuntimeManager::deleteSystemSVByID(int nID) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } // æ£æ¥æ¯å¦åå¨è¯¥ ID if (!isIDDuplicate(nID)) { return 2; } // æå»ºå é¤ç SQL è¯å¥ std::string deleteSQL = "DELETE FROM SystemSV WHERE ID = " + std::to_string(nID) + ";"; if (!m_pDB->executeQuery(deleteSQL)) { return 3; } return 0; } int SECSRuntimeManager::deleteAllSystemSV() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } // æå»ºå é¤æææ°æ®ç SQL è¯å¥ std::string deleteSQL = "DELETE FROM SystemSV;"; if (!m_pDB->executeQuery(deleteSQL)) { return 2; } return 0; // å 餿åï¼è¿å 0 表示æä½æå宿ã } // åå§å EqpSV 表 void SECSRuntimeManager::initEqpSVTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EqpSV 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS EqpSV (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "Length INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SeqNo INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create EqpSV table."); } } // æ·»å EqpSV æ°æ® int SECSRuntimeManager::addEqpSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo) { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { return 1; } if (isIDDuplicate(nID)) { return 2; } if (isNameDuplicate(sName)) { return 3; } // æå»º SQL æå ¥è¯å¥ï¼æå ¥æ°æ®å° EqpSV 表ä¸ã std::string insertSQL = "INSERT INTO EqpSV (ID, Name, DataType, Length, Unit, Remark, SeqNo) VALUES (" + std::to_string(nID) + ", '" + sName + "', '" + sDataType + "', " + ((nLength <= 0) ? "NULL" : std::to_string(nLength))+", " + ((sUnit == "NULL" || sUnit.empty()) ? "NULL" : "'" + sUnit + "'")+", '" + sRemark + "', " + std::to_string(nSeqNo) + ");"; // æ§è¡æå ¥æä½ï¼è¥å¤±è´¥åæåºå¼å¸¸ã if (!m_pDB->executeQuery(insertSQL)) { return 4; } return 0; // æå ¥æåï¼è¿å 0 表示æä½æå宿ã } // åå§å SystemDV 表 void SECSRuntimeManager::initSystemDVTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 SystemDV 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS SystemDV (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "Length INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SystemID INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create SystemDV table."); } } // åå§å EqpDV 表 void SECSRuntimeManager::initEqpDVTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EqpDV 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS EqpDV (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "Length INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SeqNo INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create EqpDV table."); } } // åå§å SystemEC 表 void SECSRuntimeManager::initSystemECTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 SystemEC 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS SystemEC (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "MinValue INTEGER NULL, " "MaxValue INTEGER NULL, " "DefaultVal INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SystemID INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create SystemEC table."); } } // åå§å EqpEC 表 void SECSRuntimeManager::initEqpECTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EqpEC 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS EqpEC (" "ID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "DataType TEXT NOT NULL, " "MinValue INTEGER NULL, " "MaxValue INTEGER NULL, " "DefaultValue INTEGER NULL, " "Unit TEXT NULL, " "Remark TEXT, " "SeqNo INTEGER NOT NULL, " "Length INTEGER NOT NULL, " "CanUpdateByHost INTEGER NOT NULL);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create EqpEC table."); } } // åå§å SystemEvent 表 void SECSRuntimeManager::initSystemEventTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 SystemEvent 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS SystemEvent (" "CEID INTEGER PRIMARY KEY, " "Name TEXT UNIQUE NOT NULL, " "Remark TEXT, " "SystemID INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create SystemEvent table."); } } // åå§å EqpEvent 表 void SECSRuntimeManager::initEqpEventTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EqpEvent 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS EqpEvent (" "CEID INTEGER PRIMARY KEY AUTOINCREMENT, " "Name TEXT UNIQUE NOT NULL, " "Remark TEXT, " "BitNo INTEGER);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create EqpEvent table."); } } // åå§å EventLink 表 void SECSRuntimeManager::initEventLinkTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EventLink 表 std::string createEventLinkSQL = "CREATE TABLE IF NOT EXISTS EventLink (" "CEID INTEGER, " "RPTID INTEGER, " "FOREIGN KEY (CEID) REFERENCES EqpEvent(CEID));"; if (!m_pDB->executeQuery(createEventLinkSQL)) { throw std::runtime_error("Failed to create EventLink table."); } } // åå§å PPID 表 void SECSRuntimeManager::initPPIDTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 EqpPPID 表 std::string createTableSQL = "CREATE TABLE IF NOT EXISTS EqpPPID (" "BitNo INTEGER PRIMARY KEY AUTOINCREMENT, " "PPID INTEGER NULL);"; if (!m_pDB->executeQuery(createTableSQL)) { throw std::runtime_error("Failed to create EqpPPID table."); } // å æ£æ¥è¡¨æ¯å¦ä¸ºç©º int nCount = getIntFromDB("SELECT COUNT(*) FROM EqpPPID;"); if (nCount == 0) { // æå ¥åå§æ°æ®ï¼512 è¡ï¼ for (int nBitNo = 0; nBitNo < 512; ++nBitNo) { std::string insertSQL = "INSERT INTO EqpPPID (BitNo) VALUES (" + std::to_string(nBitNo) + ");"; if (!m_pDB->executeQuery(insertSQL)) { throw std::runtime_error("Failed to insert data into EqpPPID table."); } } } } // åå§å RPTID 表 void SECSRuntimeManager::initRPTIDTable() { std::lock_guard<std::mutex> lock(m_mutex); if (m_pDB == nullptr) { throw std::runtime_error("Database not connected."); } // å建 RPTID ç¸å ³è¡¨ std::string createReportTableSQL = "CREATE TABLE IF NOT EXISTS Report (" "RPTID INTEGER PRIMARY KEY);"; std::string createReportVIDsTableSQL = "CREATE TABLE IF NOT EXISTS ReportVIDs (" "ID INTEGER PRIMARY KEY AUTOINCREMENT, " "RPTID INTEGER NOT NULL, " "VID INTEGER NOT NULL, " "FOREIGN KEY (RPTID) REFERENCES Report(RPTID));"; if (!m_pDB->executeQuery(createReportTableSQL)) { throw std::runtime_error("Failed to create Report table."); } if (!m_pDB->executeQuery(createReportVIDsTableSQL)) { throw std::runtime_error("Failed to create ReportVIDs table."); } } SourceCode/Bond/Servo/SECSRuntimeManager.h
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,221 @@ #ifndef SECS_RUNTIME_MANAGER_H #define SECS_RUNTIME_MANAGER_H #include <string> #include <vector> #include <mutex> #include "Database.h" class SECSRuntimeManager { public: /** * è·ååä¾å®ä¾ * @return SECSRuntimeManagerå®ä¾çå¼ç¨ */ static SECSRuntimeManager& getInstance(); /** * è®¾ç½®æ°æ®åºè¿æ¥ * @param db æ°æ®åºè¿æ¥çæé */ void setDatabase(BL::Database* db); /** * åå§åSECSè¿è¡è®¾ç½®ç®¡çåº * @return æåè¿åtrueï¼å¤±è´¥è¿åfalse */ bool initRuntimeSetting(); /** * 鿝SECSè¿è¡è®¾ç½®ç®¡çåº */ void termRuntimeSetting(); /** * åå§åSystemSV表 */ void initSystemSVTable(); /** * æ·»å SystemSV æ°æ® * @param nID: éè¦æ·»å ç SystemSV ç IDï¼å¿ é¡»æ¯å¯ä¸çã * @param sName: éè¦æ·»å ç SystemSV çåç§°ï¼å¿ é¡»æ¯å¯ä¸çã * @param sDataType: æ°æ®ç±»åï¼è¡¨ç¤ºè¯¥ç³»ç»å¼çç±»åï¼ä¾å¦ "ASCII"ã"UINT_1" çã * @param nLength: ç³»ç»å¼çæ°æ®é¿åº¦ï¼é常为ä¸ä¸ªæ£æ´æ°ï¼ç¨äºè¡¨ç¤ºè¯¥æ°æ®çé¿åº¦ã * @param sUnit: ç³»ç»å¼çåä½ãå¦æä¸ºç©ºæè 为 "NULL"ï¼åæå ¥æ°æ®åºä¸ç NULL å¼ã * @param sRemark: 夿³¨ä¿¡æ¯ï¼æè¿°è¯¥ç³»ç»å¼çå ¶ä»ä¿¡æ¯ï¼å¯ç¨äºè¯´æè¯¥å段çç¨éæç¹æ§ã * @param nSystemID: è¯¥æ°æ®æå±çç³»ç» IDï¼ç¨äºä¸å ¶ä»è¡¨è¿è¡å ³èã * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: ID éå¤ï¼æ æ³æå ¥æ°æ®ã * @return 3: Name éå¤ï¼æ æ³æå ¥æ°æ®ã * @return 4: æå ¥æ°æ®å¤±è´¥ã * @return 0: æå ¥æåï¼æ°æ®å·²æ·»å å° SystemSV 表ä¸ã * * æ¤å½æ°ç¨äºå°ä¸æ¡æ°çæ°æ®æå ¥å° SystemSV 表ä¸ãå®é¦å 伿£æ¥ä¼ å ¥ç `ID` å `Name` æ¯å¦å·²åå¨äºè¡¨ä¸ï¼ * 妿åå¨åè¿åç¸åºçé误代ç ã妿 `Unit` åæ°ä¸º "NULL" æè 为空ï¼å½æ°ä¼å°å ¶è½¬æ¢ä¸ºæ°æ®åºä¸ç NULL å¼ã * ç¶åï¼æé ä¸ä¸ª SQL æå ¥è¯å¥å¹¶æ§è¡æå ¥æä½ã妿æå ¥å¤±è´¥ï¼åæåºå¼å¸¸ã * 妿ä¸å顺å©ï¼è¿å 0 è¡¨ç¤ºæ°æ®æåæå ¥ã */ int addSystemSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); /** * æ´æ°æå® ID ç SystemSV æ°æ® * @param nID: éè¦æ´æ°ç SystemSV çå½å IDã * @param sNewID: è¦æ´æ°ä¸ºçæ° IDã * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: æªæ¾å°æå®ç IDã * @return 3: æ°ç ID å·²ç»åå¨ï¼æ æ³æ´æ°ã * @return 4: æ´æ°æä½å¤±è´¥ã * @return 0: æ´æ°æåã * * æ¤å½æ°ç¨äºæ´æ° `SystemSV` è¡¨ä¸æå® `nID` çè®°å½ï¼å°å ¶ `ID` åæ®µæ´æ°ä¸º `sNewID`ã * 卿§è¡æ´æ°åï¼å½æ°ä¼æ£æ¥ï¼ * 1. å½åç `nID` æ¯å¦åå¨äºè¡¨ä¸ã * 2. æ°ç `sNewID` æ¯å¦å·²ç»åå¨äºè¡¨ä¸ï¼å¦æåå¨ï¼åæ æ³è¿è¡æ´æ°ã * * 妿 `nID` ä¸åå¨ï¼åè¿åé误代ç 2ã妿 `sNewID` å·²ç»åå¨ï¼åè¿åé误代ç 3ã * å¦ææ°æ®åºæ´æ°å¤±è´¥ï¼åè¿åé误代ç 4ãæåæ¶ï¼è¿å 0 表示æä½æåã */ int updateIDSystemSV(int nID, int sNewID); /** * æ´æ°ææ SystemSV æ°æ® * @param nID: éè¦æ´æ°ç SystemSV çå½å IDã * @param sNewID: è¦æ´æ°ä¸ºçæ° IDï¼å¦æä¸ºç©ºæä¸º -1ï¼å䏿´æ° IDã * @param sName: æ°çåç§°ï¼å¦æä¸ºç©ºï¼å䏿´æ°ã * @param sDataType: æ°çæ°æ®ç±»åï¼å¦æä¸ºç©ºï¼å䏿´æ°ã * @param nLength: æ°çæ°æ®é¿åº¦ï¼å¦æä¸ºè´å¼æé¶ï¼å䏿´æ°ã * @param sUnit: æ°çåä½ï¼å¦æä¸ºç©ºæ "NULL"ï¼å䏿´æ°ã * @param sRemark: æ°ç夿³¨ï¼å¦æä¸ºç©ºï¼å䏿´æ°ã * @param nSystemID: æ°çç³»ç» IDï¼å¦æä¸ºè´å¼ï¼å䏿´æ°ã * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: æ²¡ææ¾å°è¯¥ ID 对åºçè®°å½ã * @return 3: æ°ç ID å·²ç»åå¨ï¼æ æ³æ´æ°ã * @return 4: æ´æ°æä½å¤±è´¥ã * @return 0: æ´æ°æåã * * æ¤å½æ°ç¨äºæ´æ°æå® `ID` ç `SystemSV` æ°æ®ã妿æä¸ªå段为空ï¼åè·³è¿è¯¥åæ®µçæ´æ°ã * 妿ç»å®ç `ID` ä¸åå¨ï¼åè¿åé误代ç 2ã妿æ°ç `ID` å·²ç»åå¨ï¼åè¿åé误代ç 3ã * * 妿忮µä¸ºç©ºï¼è·³è¿è¯¥åæ®µçæ´æ°ã */ int updateAllSystemSV(int nID, int sNewID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSystemID); /** * å é¤æå® ID ç SystemSV æ°æ® * @param nID: éè¦å é¤ç SystemSV ç IDã * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: æªæ¾å°æå®ç ID 对åºçè®°å½ã * @return 3: å 餿ä½å¤±è´¥ã * @return 0: å 餿åã * * æ¤å½æ°ç¨äºå é¤ `SystemSV` è¡¨ä¸æå® `nID` çè®°å½ã妿ç»å®ç `nID` ä¸åå¨ï¼åè¿åé误代ç 2ã * å 餿使ååï¼è¿å 0 表示å 餿åã */ int deleteSystemSVByID(int nID); /** * å 餿æ SystemSV æ°æ® * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: å 餿ä½å¤±è´¥ã * @return 0: å 餿åã * * æ¤å½æ°ç¨äºå é¤ `SystemSV` 表ä¸çææè®°å½ãå¦ææ°æ®åºæªè¿æ¥ï¼åè¿åé误代ç 1ã * 妿å 餿ä½å¤±è´¥ï¼åè¿åé误代ç 2ãå 餿ååï¼è¿å 0 表示å 餿åã */ int deleteAllSystemSV(); /** * åå§åEqp表 */ void initEqpSVTable(); /** * æ·»å EqpSV æ°æ® * @param nID: éè¦æ·»å ç EqpSV ç IDï¼å¿ é¡»æ¯å¯ä¸çã * @param sName: éè¦æ·»å ç EqpSV çåç§°ï¼å¿ é¡»æ¯å¯ä¸çã * @param sDataType: æ°æ®ç±»åï¼è¡¨ç¤ºè¯¥è®¾å¤å¼çç±»åï¼ä¾å¦ "ASCII"ã"UINT_1" çã * @param nLength: 设å¤å¼çæ°æ®é¿åº¦ï¼é常为ä¸ä¸ªæ£æ´æ°ï¼ç¨äºè¡¨ç¤ºè¯¥æ°æ®çé¿åº¦ã * @param sUnit: 设å¤å¼çåä½ãå¦æä¸ºç©ºæè 为 "NULL"ï¼åæå ¥æ°æ®åºä¸ç NULL å¼ã * @param sRemark: 夿³¨ä¿¡æ¯ï¼æè¿°è¯¥è®¾å¤å¼çå ¶ä»ä¿¡æ¯ï¼å¯ç¨äºè¯´æè¯¥å段çç¨éæç¹æ§ã * @param nSeqNo: è¯¥æ°æ®çåºå·ï¼ç¨äºæåºã * @return 1: æ°æ®åºæªè¿æ¥ã * @return 2: ID éå¤ï¼æ æ³æå ¥æ°æ®ã * @return 3: Name éå¤ï¼æ æ³æå ¥æ°æ®ã * @return 4: æå ¥æ°æ®å¤±è´¥ã * @return 0: æå ¥æåï¼æ°æ®å·²æ·»å å° EqpSV 表ä¸ã * * æ¤å½æ°ç¨äºå°ä¸æ¡æ°çæ°æ®æå ¥å° EqpSV 表ä¸ãå®é¦å 伿£æ¥ä¼ å ¥ç `ID` å `Name` æ¯å¦å·²åå¨äºè¡¨ä¸ï¼ * 妿åå¨åè¿åç¸åºçé误代ç ã妿 `Unit` åæ°ä¸º "NULL" æè 为空ï¼å½æ°ä¼å°å ¶è½¬æ¢ä¸ºæ°æ®åºä¸ç NULL å¼ã * ç¶åï¼æé ä¸ä¸ª SQL æå ¥è¯å¥å¹¶æ§è¡æå ¥æä½ã妿æå ¥å¤±è´¥ï¼åæåºå¼å¸¸ã * 妿ä¸å顺å©ï¼è¿å 0 è¡¨ç¤ºæ°æ®æåæå ¥ã */ int addEqpSV(int nID, const std::string& sName, const std::string& sDataType, int nLength, const std::string& sUnit, const std::string& sRemark, int nSeqNo); /** * åå§åSystemDV表 */ void initSystemDVTable(); /** * åå§åEqpDV表 */ void initEqpDVTable(); /** * åå§åSystemEC表 */ void initSystemECTable(); /** * åå§åEqpEC表 */ void initEqpECTable(); /** * åå§åSystemEvent表 */ void initSystemEventTable(); /** * åå§åEqpEvent表 */ void initEqpEventTable(); /** * åå§åEventLink表 */ void initEventLinkTable(); /** * åå§åPPID表 */ void initPPIDTable(); /** * åå§åRPTID表 */ void initRPTIDTable(); private: SECSRuntimeManager(); ~SECSRuntimeManager(); // ç¦æ¢æ·è´åèµå¼ SECSRuntimeManager(const SECSRuntimeManager&) = delete; SECSRuntimeManager& operator=(const SECSRuntimeManager&) = delete; // 仿°æ®åºä¸è·åæ´æ° int getIntFromDB(const std::string& query); // 夿VIDæ¯å¦éå¤ bool isIDDuplicate(int nID); // 夿åç§°æ¯å¦éå¤ bool isNameDuplicate(const std::string& sName); BL::Database* m_pDB; static std::mutex m_mutex; }; #endif // SECS_RUNTIME_MANAGER_H SourceCode/Bond/Servo/Servo.cpp
@@ -7,6 +7,7 @@ #include "ServoDlg.h" #include "ServoGraph.h" #include "AlarmManager.h" #include "SECSRuntimeManager.h" // 声æå ¨å±åéï¼ç¨äºç®¡ç GDI+ åå§å ULONG_PTR g_diplusToken; @@ -117,6 +118,21 @@ } // åå§åSECSè¿è¡è®¾ç½®ç®¡çåº try { if (!SECSRuntimeManager::getInstance().initRuntimeSetting()) { AfxMessageBox("åå§åSECSè¿è¡è®¾ç½®å¤±è´¥ï¼"); return FALSE; } } catch (const std::exception& ex) { CString errorMsg; errorMsg.Format(_T("åå§åSECSè¿è¡è®¾ç½®å¤±è´¥ï¼%s"), CString(ex.what())); AfxMessageBox(errorMsg, MB_ICONERROR); return FALSE; } CServoDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); @@ -159,6 +175,9 @@ // 鿝æ¥è¦è¡¨ AlarmManager::getInstance().termAlarmTable(); // 鿝SECSè¿è¡è®¾ç½®ç®¡çåº SECSRuntimeManager::getInstance().termRuntimeSetting(); return CWinApp::ExitInstance(); } SourceCode/Bond/Servo/Servo.vcxproj
@@ -21,7 +21,7 @@ <PropertyGroup Label="Globals"> <ProjectGuid>{66ADACE5-3166-4D1F-B30B-DE5E01FB01A2}</ProjectGuid> <RootNamespace>Servo</RootNamespace> <WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <Keyword>MFCProj</Keyword> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> @@ -115,7 +115,7 @@ <Optimization>Disabled</Optimization> <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <SDLCheck>true</SDLCheck> <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;..\MELSECSDK\include;.\CCLinkPerformance;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -169,7 +169,7 @@ <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <SDLCheck>true</SDLCheck> <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;..;..\DatabaseSDK\include;..\MELSECSDK\include;.\CCLinkPerformance;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Windows</SubSystem> @@ -194,6 +194,8 @@ <ItemGroup> <ClInclude Include="AlarmManager.h" /> <ClInclude Include="BlButton.h" /> <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h" /> <ClInclude Include="CCLinkPerformance\PerformanceMelsec.h" /> <ClInclude Include="Common.h" /> <ClInclude Include="Configuration.h" /> <ClInclude Include="Context.h" /> @@ -204,6 +206,7 @@ <ClInclude Include="LogEdit.h" /> <ClInclude Include="Model.h" /> <ClInclude Include="Resource.h" /> <ClInclude Include="SECSRuntimeManager.h" /> <ClInclude Include="SecsTestDlg.h" /> <ClInclude Include="Servo.h" /> <ClInclude Include="ServoDlg.h" /> @@ -215,6 +218,8 @@ <ItemGroup> <ClCompile Include="AlarmManager.cpp" /> <ClCompile Include="BlButton.cpp" /> <ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp" /> <ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp" /> <ClCompile Include="Configuration.cpp" /> <ClCompile Include="Context.cpp" /> <ClCompile Include="HsmsAction.cpp" /> @@ -223,6 +228,7 @@ <ClCompile Include="LogDlg.cpp" /> <ClCompile Include="LogEdit.cpp" /> <ClCompile Include="Model.cpp" /> <ClCompile Include="SECSRuntimeManager.cpp" /> <ClCompile Include="SecsTestDlg.cpp" /> <ClCompile Include="Servo.cpp" /> <ClCompile Include="ServoDlg.cpp" /> SourceCode/Bond/Servo/Servo.vcxproj.filters
@@ -1,144 +1,80 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Filter Include="æºæä»¶"> <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> </Filter> <Filter Include="头æä»¶"> <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> </Filter> <Filter Include="èµæºæä»¶"> <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> </Filter> <Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" /> </ItemGroup> <ItemGroup> <Manifest Include="res\application.exe.manifest" /> </ItemGroup> <ItemGroup> <ClCompile Include="AlarmManager.cpp" /> <ClCompile Include="BlButton.cpp" /> <ClCompile Include="Configuration.cpp" /> <ClCompile Include="Context.cpp" /> <ClCompile Include="HsmsAction.cpp" /> <ClCompile Include="HsmsPassive.cpp" /> <ClCompile Include="Log.cpp" /> <ClCompile Include="LogDlg.cpp" /> <ClCompile Include="LogEdit.cpp" /> <ClCompile Include="Model.cpp" /> <ClCompile Include="SecsTestDlg.cpp" /> <ClCompile Include="Servo.cpp" /> <ClCompile Include="ServoDlg.cpp" /> <ClCompile Include="ServoGraph.cpp" /> <ClCompile Include="stdafx.cpp" /> <ClCompile Include="TerminalDisplayDlg.cpp" /> <ClCompile Include="SECSRuntimeManager.cpp" /> <ClCompile Include="CCLinkPerformance\CCLinkIEControl.cpp"> <Filter>CCLinkPerformance</Filter> </ClCompile> <ClCompile Include="CCLinkPerformance\PerformanceMelsec.cpp"> <Filter>CCLinkPerformance</Filter> </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="AlarmManager.h" /> <ClInclude Include="BlButton.h" /> <ClInclude Include="Common.h" /> <ClInclude Include="Configuration.h" /> <ClInclude Include="Context.h" /> <ClInclude Include="HsmsAction.h" /> <ClInclude Include="HsmsPassive.h" /> <ClInclude Include="Log.h" /> <ClInclude Include="LogDlg.h" /> <ClInclude Include="LogEdit.h" /> <ClInclude Include="Model.h" /> <ClInclude Include="Resource.h" /> <ClInclude Include="SecsTestDlg.h" /> <ClInclude Include="Servo.h" /> <ClInclude Include="ServoDlg.h" /> <ClInclude Include="ServoGraph.h" /> <ClInclude Include="stdafx.h" /> <ClInclude Include="targetver.h" /> <ClInclude Include="TerminalDisplayDlg.h" /> <ClInclude Include="SECSRuntimeManager.h" /> <ClInclude Include="CCLinkPerformance\CCLinkIEControl.h"> <Filter>CCLinkPerformance</Filter> </ClInclude> <ClInclude Include="CCLinkPerformance\PerformanceMelsec.h"> <Filter>CCLinkPerformance</Filter> </ClInclude> </ItemGroup> <ItemGroup> <ResourceCompile Include="Servo.rc" /> </ItemGroup> <ItemGroup> <Image Include="res\Servo.ico" /> </ItemGroup> <ItemGroup> <None Include="packages.config" /> <None Include="res\Servo.rc2" /> </ItemGroup> <ItemGroup> <Text Include="ReadMe.txt" /> </ItemGroup> <ItemGroup> <ClInclude Include="Servo.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="ServoDlg.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="stdafx.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="targetver.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Resource.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="ServoGraph.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Model.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="BlButton.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Common.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="LogDlg.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="LogEdit.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Configuration.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Log.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="HsmsPassive.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="HsmsAction.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="Context.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="SecsTestDlg.h"> <Filter>头æä»¶</Filter> </ClInclude> <ClInclude Include="TerminalDisplayDlg.h"> <ClInclude Include="AlarmManager.h"> <Filter>头æä»¶</Filter> </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="Servo.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="ServoDlg.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="stdafx.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="ServoGraph.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="Model.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="BlButton.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="LogDlg.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="LogEdit.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="Configuration.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="Log.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="HsmsPassive.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="HsmsAction.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="Context.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="SecsTestDlg.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> <ClCompile Include="TerminalDisplayDlg.cpp"> <ClCompile Include="AlarmManager.cpp"> <Filter>æºæä»¶</Filter> </ClCompile> </ItemGroup> <ItemGroup> <ResourceCompile Include="Servo.rc"> <Filter>èµæºæä»¶</Filter> </ResourceCompile> </ItemGroup> <ItemGroup> <None Include="res\Servo.rc2"> <Filter>èµæºæä»¶</Filter> </None> <None Include="packages.config" /> </ItemGroup> <ItemGroup> <Image Include="res\Servo.ico"> <Filter>èµæºæä»¶</Filter> </Image> </ItemGroup> <ItemGroup> <Manifest Include="res\application.exe.manifest" /> <Filter Include="CCLinkPerformance"> <UniqueIdentifier>{77338295-9841-4706-8816-a958b1b5c465}</UniqueIdentifier> </Filter> </ItemGroup> </Project> SourceCode/Bond/Servo/ServoDlg.cpp
@@ -9,7 +9,6 @@ #include "Common.h" #include "Log.h" #include "SecsTestDlg.h" #include "AlarmManager.h" #include <chrono> #include <thread> #include <cmath> SourceCode/Bond/Servo/stdafx.h
@@ -38,6 +38,9 @@ #include <gdiplus.h> using namespace Gdiplus; // CC-LINK模å #include "..\MELSECSDK\include\Mdfunc.h" #pragma comment(lib, "..\\MELSECSDK\\lib\\MdFunc32.lib") // æ°æ®åºæ¨¡å #include "..\DatabaseSDK\include\Database.h"