#pragma once
|
|
#include "CCLinkIEControl.h"
|
|
#include <thread>
|
#include <atomic>
|
#include <functional>
|
#include <vector>
|
|
using OutValuesArray = std::array<double, 4>;
|
using Callback = std::function<void()>;
|
using AnalyzeCallback = std::function<OutValuesArray()>;
|
using LogCallback = std::function<void(const CString& strContent, int type)>;
|
|
class CPLCSignalListener
|
{
|
public:
|
CPLCSignalListener();
|
~CPLCSignalListener();
|
|
/**
|
* @brief ³õʼ»¯ PLC ÐźżàÌýÆ÷¡£
|
*
|
* @param station Ä¿±ê PLC µÄÕ¾ºÅ±êʶ·û¡£
|
* @param nIntervalMs ÂÖѯÖÜÆÚ£¨µ¥Î»£ººÁÃ룩£¬Ä¬ÈÏ 200ms¡£
|
* @return true ³õʼ»¯³É¹¦¡£
|
* @return false ³õʼ»¯Ê§°Ü¡£
|
*/
|
bool Initialize(StationIdentifier station, int nIntervalMs = 200);
|
|
/**
|
* @brief ÉèÖÿªÊ¼ÃüÁîµÄ»Øµ÷º¯Êý£¨¶ÔÓ¦ PLC µÄ Start Ðźţ©¡£
|
*
|
* @param cb Óû§×Ô¶¨ÒåµÄ¿ªÊ¼»Øµ÷º¯Êý¡£
|
*/
|
void SetStartCallback(Callback cb);
|
|
/**
|
* @brief ÉèÖÃÍ£Ö¹ÃüÁîµÄ»Øµ÷º¯Êý£¨¶ÔÓ¦ PLC µÄ Stop Ðźţ©¡£
|
*
|
* @param cb Óû§×Ô¶¨ÒåµÄÍ£Ö¹»Øµ÷º¯Êý¡£
|
*/
|
void SetStopCallback(Callback cb);
|
|
/**
|
* @brief ÉèÖ÷ÖÎö¼ÆËã»Øµ÷º¯Êý£¬ÔÚ½ÓÊÕµ½Í£Ö¹ÃüÁîºóµ÷Óá£
|
*
|
* @param cb ·µ»Ø¼ÆËã½á¹ûÊý×飨OUT1~OUT4£©µÄº¯Êý¡£
|
*/
|
void SetAnalyzeCallback(AnalyzeCallback cb);
|
|
/**
|
* @brief ÉèÖÃÈÕÖ¾Êä³ö»Øµ÷º¯Êý¡£
|
*
|
* @param cb Óû§ÌṩµÄÈÕÖ¾Êä³ö½Ó¿Ú£¨°üº¬ÈÕÖ¾ÄÚÈݺÍÈÕÖ¾ÀàÐÍ£©¡£
|
*/
|
void SetLogCallback(LogCallback cb);
|
|
/**
|
* @brief Æô¶¯ÐźżàÌýÏ̡߳£
|
*
|
* @return true Æô¶¯³É¹¦¡£
|
* @return false Æô¶¯Ê§°Ü£¨¿ÉÄÜÒÑÔËÐлòδ³õʼ»¯£©¡£
|
*/
|
bool Start();
|
|
/**
|
* @brief Í£Ö¹ÐźżàÌýÏ̡߳£
|
*/
|
void Stop();
|
|
/**
|
* @brief Ïò PLC дÈë·ÖÎö½á¹ûÖµ£¨Í¨³£Îª OUT1 ~ OUT4£©¡£
|
*
|
* @param values °üº¬Ëĸö double ÀàÐ͵Ľá¹ûÖµ£¬½«×ª»»ÎªÕûÊýºóдÈë PLC¡£
|
* @return true дÈë³É¹¦¡£
|
* @return false дÈëʧ°Ü¡£
|
*/
|
bool WriteOutValues(const OutValuesArray& values);
|
|
private:
|
/**
|
* @brief Êä³öÈÕÖ¾ÐÅÏ¢£¨·â×°ÈÕÖ¾»Øµ÷£©¡£
|
*
|
* @param strText ÈÕÖ¾ÄÚÈÝÎı¾¡£
|
* @param nType ÈÕÖ¾ÀàÐÍ£¨LOG_TYPE_NORMAL / ERROR / WARNING µÈ£©¡£
|
*/
|
void LogInfo(const CString& strText, int nType);
|
|
/**
|
* @brief Ïò PLC дÈëÐÄÌøÐźţ¨½»ÌæÎ»£©¡£
|
*
|
* @return true дÈë³É¹¦¡£
|
* @return false дÈëʧ°Ü£¨ÈçδÁ¬½Ó£©¡£
|
*/
|
bool SendHeartbeat();
|
|
/**
|
* @brief ¼ì²é´Ó PLC ¶ÁÈ¡µ½µÄÐÄÌøÐźÅÊÇ·ñ·¢Éú±ä»¯¡£
|
*
|
* @return true ÐÄÌøÓб仯£¨PLC Õý³£ÔÚÏߣ©¡£
|
* @return false ÐÄÌøÎޱ仯£¨¿ÉÄÜÀëÏߣ©¡£
|
*/
|
bool CheckHeartbeat();
|
|
/**
|
* @brief ¼à¿Ø PLC ÐÄÌøÊÇ·ñÖжϣ¬²¢×Ô¶¯¼Ç¼״̬¡£
|
*
|
* @return true PLC ÔÚÏß»òÔÚÔÊÐíµÄδÏìÓ¦´ÎÊýÄÚ¡£
|
* @return false PLC ÐÄÌøÖжϣ¬³¬¹ýÔÊÐíãÐÖµ¡£
|
*/
|
bool MonitorHeartbeat();
|
|
/**
|
* @brief Æô¶¯ÐÄÌø¼à¿ØỊ̈߳¨¶ÀÁ¢ÓÚÐźżàÌýỊ̈߳©¡£
|
*/
|
void StartHeartbeatMonitor();
|
|
/**
|
* @brief Í£Ö¹ÐÄÌø¼à¿ØÏ̡߳£
|
*/
|
void StopHeartbeatMonitor();
|
|
/**
|
* @brief ÏòÖ¸¶¨ÈíÔª¼þλдÈëÒ»¸öÂö³å£¨ÏÈд1£¬ÑÓʱºó×Ô¶¯Ð´0£©¡£
|
*
|
* @param eDevType λÈíÔª¼þÀàÐÍ£¨Èç M/B£©¡£
|
* @param nBitNo λµØÖ·±àºÅ¡£
|
* @param nDelayMs Âö³å³ÖÐøÊ±¼ä£¬Ä¬ÈÏ50ºÁÃë¡£
|
*/
|
void PulseBitDevice(DeviceType eDevType, long nBitNo, int nDelayMs = 50);
|
|
/**
|
* @brief ¹ÜÀí ACK ÏìÓ¦µÄÉúÃüÖÜÆÚ£¬³¬Ê±×Ô¶¯Çå³ý¡£
|
*
|
* @param i ¿ØÖÆÎ»Ë÷Òý£¨0=Start£¬1=Stop£©¡£
|
* @param bCurrTriggerBit µ±Ç°´Ó PLC ¶ÁÈ¡µ½µÄ´¥·¢Î»×´Ì¬¡£
|
*/
|
void HandleAckLife(int i, bool bCurrTriggerBit);
|
|
/**
|
* @brief Ö÷¼àÌýÏß³ÌÂß¼£¬Ñ»·¶ÁÈ¡ PLC ¿ØÖÆÐźŲ¢´¦Àí´¥·¢¡£
|
*/
|
void ThreadProc();
|
|
private:
|
// === PLC ͨÐźËÐĶÔÏó ===
|
std::unique_ptr<CCCLinkIEControl> m_pPlc; // PLC ͨÐÅ¿ØÖÆÆ÷
|
StationIdentifier m_station; // PLC Õ¾ºÅ
|
std::atomic<bool> m_bConnected{ false }; // ÊÇ·ñ³É¹¦Á¬½Ó
|
|
// === ¿ØÖƲÎÊý ===
|
int m_nIntervalMs = 200; // ÂÖѯÖÜÆÚ£¨ms£©
|
|
// === ÃüÁî´¥·¢×´Ì¬»º´æ ===
|
std::vector<bool> m_vecPrevBits; // ÉÏÒ»ÖÜÆÚµÄÃüÁîλ״̬£¨ÓÃÓÚ¼ì²âÉÏÉýÑØ£©
|
|
// === »Øµ÷º¯Êý£¨¿ØÖÆ/¼ÆËã/ÈÕÖ¾£©===
|
Callback m_cbStart; // Start ÃüÁî»Øµ÷
|
Callback m_cbStop; // Stop ÃüÁî»Øµ÷
|
AnalyzeCallback m_cbAnalyze; // Analyze ¼ÆËã»Øµ÷£¨·µ»Ø OUT1~OUT4£©
|
LogCallback m_cbLog; // ÈÕÖ¾Êä³ö»Øµ÷
|
|
// === Ö÷Ï߳̿ØÖÆ ===
|
std::atomic<bool> m_bRunning{ false }; // Ö÷¼àÌýÏß³ÌÊÇ·ñÔËÐÐ
|
std::thread m_thread; // Ö÷¼àÌýÏ̶߳ÔÏó
|
|
// === ACK ÐźÅ״̬ ===
|
std::array<bool, 2> m_vecAckSent = { false, false }; // ÊÇ·ñÒÑ·¢ËÍÓ¦´ðÐźţ¨B10/B11£©
|
std::array<int, 2> m_vecAckCounter = { 0, 0 }; // ¶ÔÓ¦Ó¦´ðÐźŵÄÉúÃüÖÜÆÚ¼ÆÊýÆ÷
|
|
// === ÐÄÌø¼ì²âÏà¹Ø ===
|
std::thread m_heartbeatThread; // ÐÄÌø¼ì²âÏ̶߳ÔÏó
|
std::atomic<bool> m_bHeartbeatRunning = false; // ÐÄÌøÏß³ÌÔËÐбêÖ¾
|
std::atomic<bool> m_bHeartbeatLost = false; // ÐÄÌø¶ªÊ§±êÖ¾
|
int m_nMissedHeartbeatCount = 0; // ÐÄÌøÎ´±ä»¯´ÎÊý£¨ÓÃÓÚ¼ì²â PLC µôÏߣ©
|
};
|