#pragma once #include "CCLinkIEControl.h" #include #include #include #include using OutValuesArray = std::array; using Callback = std::function; using AnalyzeCallback = std::function; using LogCallback = std::function; class CPLCSignalListener { public: CPLCSignalListener(); ~CPLCSignalListener(); bool Initialize(StationIdentifier station, int nIntervalMs = 200); void SetStartCallback(Callback cb); void SetStopCallback(Callback cb); void SetAnalyzeCallback(AnalyzeCallback cb); void SetLogCallback(LogCallback cb); bool Start(); void Stop(); bool WriteOutValues(const OutValuesArray& values); private: void LogInfo(const CString& strText, int nType); bool SendHeartbeat(); bool CheckHeartbeat(); bool MonitorHeartbeat(); void StartHeartbeatMonitor(); void StopHeartbeatMonitor(); void PulseBitDevice(DeviceType eDevType, long nBitNo, int nDelayMs = 50); void HandleAckLife(int i, bool bCurrTriggerBit); void ThreadProc(); private: // === PLC ͨÐźËÐĶÔÏó === std::unique_ptr m_pPlc; // PLC ͨÐÅ¿ØÖÆÆ÷ StationIdentifier m_station; // PLC Õ¾ºÅ std::atomic m_bConnected{ false }; // ÊÇ·ñ³É¹¦Á¬½Ó // === ¿ØÖƲÎÊý === int m_nIntervalMs = 200; // ÂÖѯÖÜÆÚ£¨ms£© // === ÃüÁî´¥·¢×´Ì¬»º´æ === std::vector m_vecPrevBits; // ÉÏÒ»ÖÜÆÚµÄÃüÁîλ״̬£¨ÓÃÓÚ¼ì²âÉÏÉýÑØ£© // === »Øµ÷º¯Êý£¨¿ØÖÆ/¼ÆËã/ÈÕÖ¾£©=== Callback m_cbStart; // Start ÃüÁî»Øµ÷ Callback m_cbStop; // Stop ÃüÁî»Øµ÷ AnalyzeCallback m_cbAnalyze; // Analyze ¼ÆËã»Øµ÷£¨·µ»Ø OUT1~OUT4£© LogCallback m_cbLog; // ÈÕÖ¾Êä³ö»Øµ÷ // === Ö÷Ï߳̿ØÖÆ === std::atomic m_bRunning{ false }; // Ö÷¼àÌýÏß³ÌÊÇ·ñÔËÐÐ std::thread m_thread; // Ö÷¼àÌýÏ̶߳ÔÏó // === ACK ÐźÅ״̬ === std::array m_vecAckSent = { false, false }; // ÊÇ·ñÒÑ·¢ËÍÓ¦´ðÐźţ¨B10/B11£© std::array m_vecAckCounter = { 0, 0 }; // ¶ÔÓ¦Ó¦´ðÐźŵÄÉúÃüÖÜÆÚ¼ÆÊýÆ÷ // === ÐÄÌø¼ì²âÏà¹Ø === std::thread m_heartbeatThread; // ÐÄÌø¼ì²âÏ̶߳ÔÏó std::atomic m_bHeartbeatRunning = false; // ÐÄÌøÏß³ÌÔËÐбêÖ¾ std::atomic m_bHeartbeatLost = false; // ÐÄÌø¶ªÊ§±êÖ¾ int m_nMissedHeartbeatCount = 0; // ÐÄÌøÎ´±ä»¯´ÎÊý£¨ÓÃÓÚ¼ì²â PLC µôÏߣ© };