#include "CoreCommunication.h" #include "../Communication/S7Command.h" #include "../config/ConfigManager.h" #include "../SystemInfo.h" #include "../ScannerCtrl/BaseCtrl.h" #include "../include/log/Logger.h" #include CoreCommunication::CoreCommunication() : m_Config(NULL) , m_ReadThread(INVALID_HANDLE_VALUE) , m_WriteThread(INVALID_HANDLE_VALUE) , m_sendTdExitFlag(false) { m_IsSmart = true; m_Invoker = new PLCInvoker(); } CoreCommunication::~CoreCommunication() { Shutdown(); if (m_S7Client) { if (m_S7Client->Connected)m_S7Client->Disconnect(); delete m_S7Client; } m_sendTdExitFlag = true; if (m_sendTd.joinable()) m_sendTd.join(); } void CoreCommunication::Startup() { Shutdown(); m_RunFlag = true; m_AssistRunFlag = true; m_ReadThread = AtlCreateThread(ReadProc, this); m_AssistThread = AtlCreateThread(AssistProc, this); m_sendTdExitFlag = false; m_sendTd = std::thread([this] {SendProc(); }); } void CoreCommunication::Shutdown() { m_RunFlag = false; m_AssistRunFlag = false; if (m_ReadThread != INVALID_HANDLE_VALUE) { if (WaitForSingleObject(m_ReadThread, 2000) == WAIT_TIMEOUT) { TerminateThread(m_ReadThread, 0); } CloseHandle(m_ReadThread); m_ReadThread = INVALID_HANDLE_VALUE; } if (m_WriteThread != INVALID_HANDLE_VALUE) { if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) { TerminateThread(m_WriteThread, 0); } CloseHandle(m_WriteThread); m_WriteThread = INVALID_HANDLE_VALUE; } if (m_AssistThread != INVALID_HANDLE_VALUE) { if (WaitForSingleObject(m_AssistThread, 1000) == WAIT_TIMEOUT) { TerminateThread(m_AssistThread, 0); } CloseHandle(m_AssistThread); m_AssistThread = INVALID_HANDLE_VALUE; } m_sendTdExitFlag = true; if (m_sendTd.joinable()) m_sendTd.join(); m_BaseStat.isConnected = false; m_S7Client->Disconnect(); std::unique_lock lck(m_WirteMutex); while (!m_RTCommands.empty()) { Command* command = m_RTCommands.front(); if (command->isNeedDel) { delete command; command = NULL; } m_RTCommands.pop(); } } void CoreCommunication::Init() { map* tcpCfgs = ConfigManager::GetInstance()->GetCommunicationCfg(); if (tcpCfgs->find("PLC") != tcpCfgs->end()) { m_Config = (*tcpCfgs)["PLC"]; ConfigManager::GetInstance()->AddComRefCfg(m_Config, this); } m_CoverCfg = ConfigManager::GetInstance()->GetCoverCfg(); m_S7Client = new TSnap7Client(); int sendtimeout = 100; int readtimeout = 500; int pdusize = 1200; if (m_IsSmart) { m_S7Client->SetConnectionParams(m_Config->m_IP.c_str(), 0x0200, 0x0200); //ip wxxtest } m_S7Client->SetParam(p_i32_PDURequest, &pdusize); m_S7Client->SetParam(p_i32_SendTimeout, &sendtimeout); m_S7Client->SetParam(p_i32_RecvTimeout, &readtimeout); #ifdef _DEBUG int pingTimeout = 0; m_S7Client->SetParam(p_i32_PingTimeout, &pingTimeout); #endif InitCommand(); //if (m_IOCfgWrapper) // m_IOCfgWrapper->SetCC(this); } void CoreCommunication::InitCommand() { vector vec; ConfigManager::GetInstance()->GetMachine()->InitPLCCommand(vec); for (size_t i = 0; i < vec.size();i++) { m_CycleCommands.push_back(vec[i]); } } Command* CoreCommunication::GetSendCycleCommand() { Command* command = NULL; for (size_t i = 0; i < m_CycleCommands.size(); ++i) { if (!m_CycleCommands[i]->isFinished) { command = m_CycleCommands[i]; break; } } return command; } void CoreCommunication::UpdateCycleCommands() { bool isAllFinished = true; for (size_t i = 0; i < m_CycleCommands.size(); ++i) { if (!m_CycleCommands[i]->isFinished) { isAllFinished = false; break; } } if (isAllFinished) { for (size_t i = 0; i < m_CycleCommands.size(); ++i) { m_CycleCommands[i]->isFinished = false; } } } DWORD WINAPI CoreCommunication::ReadProc(CoreCommunication* _this) { if (_this) { _this->ReadRun(); } return 0; } void CoreCommunication::ReadRun() { while (m_RunFlag) { if (!m_S7Client->Connected) { int rel = 0; m_BaseStat.isConnected = false; m_BaseStat.readTimeoutFlag = 0; if (m_IsSmart) { m_S7Client->SetConnectionParams(m_Config->m_IP.c_str(), (word)0x0200, (word)0x0200); rel = m_S7Client->Connect(); } else { rel = m_S7Client->ConnectTo(m_Config->m_IP.c_str(), 0, 2); } if (rel != 0) { int counttick = 0; while (m_RunFlag) { counttick++; if (counttick > 20) { break; } Sleep(100); } continue; } if (m_WriteThread != INVALID_HANDLE_VALUE) { m_RunFlag = false; if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) { } CloseHandle(m_WriteThread); m_WriteThread = INVALID_HANDLE_VALUE; m_RunFlag = true; } m_WriteThread = AtlCreateThread(WriteProc, this); } Command* pCommand = GetSendCycleCommand(); if (pCommand != NULL) { S7Command* ps7 = (S7Command*)pCommand; TS7DataItem* items = ps7->getDataItems(); std::unique_lock lck(m_ReadWriteMutex); int readlrel = m_S7Client->ReadMultiVars(items, ps7->getItemCount()); lck.unlock(); if (readlrel == 0) { m_BaseStat.readTimeoutFlag = 0; m_BaseStat.isConnected = true; if (ps7->m_Fun)ps7->m_Fun(ps7->m_Ref, ps7); } else { m_BaseStat.readTimeoutFlag++; if (m_BaseStat.readTimeoutFlag >= m_Config->m_AlarmTimeoutTimes) { m_BaseStat.isConnected = false; m_BaseStat.readTimeoutFlag = 0; m_S7Client->Disconnect(); if (m_WriteThread != INVALID_HANDLE_VALUE) { m_RunFlag = false; if (WaitForSingleObject(m_WriteThread, 2000) == WAIT_TIMEOUT) { } CloseHandle(m_WriteThread); m_WriteThread = INVALID_HANDLE_VALUE; m_RunFlag = true; } } } pCommand->isFinished = true; } UpdateCycleCommands(); Sleep(10); } } DWORD WINAPI CoreCommunication::WriteProc(CoreCommunication* _this) { if (_this) { _this->WriteRun(); } return 0; } void CoreCommunication::WriteRun() { while (m_RunFlag) { Command* command = NULL; unique_lock lck(m_WirteMutex); if (!m_RTCommands.empty()) { command = m_RTCommands.front(); m_RTCommands.pop(); } lck.unlock(); if (!command) { Sleep(10); continue; } S7Command* ps7 = (S7Command*)command; TS7DataItem* items = ps7->getDataItems(); //TS7DataItem item = items[0]; std::unique_lock wrlck(m_ReadWriteMutex); int rel=m_S7Client->WriteMultiVars(items, ps7->getItemCount()); wrlck.unlock(); //int rel = m_S7Client->WriteArea(item.Ar0ea, item.DBNumber, item.Start, item.Amount, item.WordLen, item.pdata); if (rel == 0) { if (ps7->m_Fun)ps7->m_Fun(ps7->m_Ref, ps7); } if (command->isNeedDel)delete command; //Sleep(10); } } DWORD WINAPI CoreCommunication::AssistProc(CoreCommunication* _this) { if (_this) { _this->AssistRun(); } return 0; } void CoreCommunication::AssistRun() { while (m_AssistRunFlag) { if (!m_S7Client->Connected) { Sleep(200); continue; } uint64_t nowtick = GetTickCount64(); if (nowtick - m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveTimetick >= 500) { m_AlarmStateWrapper->m_KeepAliveCommand->SetKeepAliveValue(); if (BaseCtrl::IsStandBy()) { //m_AlarmStateWrapper->m_KeepAliveCommand->SetDeviceStanbyValue(true); m_AlarmStateWrapper->m_KeepAliveCommand->SetDevicePrintingValue(false); } else if (BaseCtrl::IsStart()) { //m_AlarmStateWrapper->m_KeepAliveCommand->SetDeviceStanbyValue(false); m_AlarmStateWrapper->m_KeepAliveCommand->SetDevicePrintingValue(true); } m_Invoker->SetCommand(m_AlarmStateWrapper->m_KeepAliveCommand); m_Invoker->Call(); m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveFlag = !m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveFlag; m_AlarmStateWrapper->m_KeepAliveCommand->m_PrintKeepAliveTimetick = nowtick; } if (m_IOCfgWrapper->m_SystemStop->IsActive()) { vector* laserCfgs = ConfigManager::GetInstance()->GetMatchScannerControlCfg(); for (size_t i = 0; i < laserCfgs->size(); i++) { ScannerControlCfg* laserCfg = (*laserCfgs)[i]; laserCfg->m_LaserEnable->SetActive(false); } if (m_IOCfgWrapper->m_ServoMotor)m_IOCfgWrapper->m_ServoMotor->SetActive(false); } bool sysPreClose = false; if (m_SysParamWrapper->m_PrintPressure->GetValue() > m_SysParamWrapper->m_PrintPressureThrehold->GetValue() || m_AlarmStateWrapper->m_PrintPressureOverLimitAlarm->GetValue()) { m_IOCfgWrapper->m_PressureRelease->SetActive(true); } else { sysPreClose = true; } if (m_IOCfgWrapper->IsSystemCtrlPressure()) { if (sysPreClose && m_IOCfgWrapper->m_PressureRelease->IsActive()) { m_IOCfgWrapper->m_PressureRelease->SetActive(false); } } m_SysParamWrapper->m_OutsideOxygen->SetValue(g_SystemInfo->GetComOutsideOxygen()); Sleep(100); } } void CoreCommunication::GetAlarmState(SignalState& signalState) { std::shared_lock lock(m_ValueMtx); //ConfigManager::GetInstance()->GetMachine()->GetAlarmState(signalState); } void CoreCommunication::GetEnvState(EnvState& envState) { std::shared_lock lock(m_ValueMtx); //ConfigManager::GetInstance()->GetMachine()->GetAlarmState(envState); envState.m_PrintOxygen1Analog=m_SysParamWrapper->m_PrintOxygen1->GetValue(); envState.m_PrintOxygen2Analog =m_SysParamWrapper->m_PrintOxygen2->GetValue(); envState.m_OutsideOxygenAnalog =m_SysParamWrapper->m_OutsideOxygen->GetValue(); envState.m_HighPressureAnalog =m_SysParamWrapper->m_HighPressure->GetValue(); envState.m_ProtectGasPressureAnalog =m_SysParamWrapper->m_ProtectGasPressure->GetValue(); envState.m_PrintPressureAnalog =m_SysParamWrapper->m_PrintPressure->GetValue(); envState.m_MoldMainCurrentPos=m_SysParamWrapper->m_MoldMainCurrentPos->GetValue(); //打印主轴当前位置_R envState.m_MoldMainCurrentLoad=m_SysParamWrapper->m_MoldMainCurrentLoad->GetValue(); //打印主轴当前扭矩_R envState.m_MoldSlaveCurrentPos=m_SysParamWrapper->m_MoldSlaveCurrentPos->GetValue(); //打印从轴当前位置_R envState.m_MoldSlaveCurrentLoad=m_SysParamWrapper->m_MoldSlaveCurrentLoad->GetValue(); //打印从轴当前扭矩_R envState.m_CleanMainCurrentPos=m_SysParamWrapper->m_CleanMainCurrentPos->GetValue(); //清粉主轴当前位置_R envState.m_CleanMainCurrentLoad=m_SysParamWrapper->m_CleanMainCurrentLoad->GetValue(); //清粉主轴当前扭矩_R envState.m_CleanSlaveCurrentPos=m_SysParamWrapper->m_CleanSlaveCurrentPos->GetValue(); //清粉从轴当前位置_R envState.m_CleanSlaveCurrentLoad=m_SysParamWrapper->m_CleanSlaveCurrentLoad->GetValue(); //清粉从轴当前扭矩_R envState.m_LoadAxisCurrentPos=m_SysParamWrapper->m_LoadAxisCurrentPos->GetValue(); //移载轴当前位置_R envState.m_LoadAxisCurrentLoad=m_SysParamWrapper->m_LoadAxisCurrentLoad->GetValue(); //移载轴当前扭矩_R envState.m_ArmCurrentPos=m_SysParamWrapper->m_ArmCurrentPos->GetValue(); //铺粉轴当前位置_R envState.m_ArmCurrentLoad=m_SysParamWrapper->m_ArmCurrentLoad->GetValue(); //铺粉轴当前扭矩_R envState.m_SupplyCurrentPos=m_SysParamWrapper->m_SupplyCurrentPos->GetValue(); //供粉转轴当前位置_R envState.m_SupplyCurrentLoad=m_SysParamWrapper->m_SupplyCurrentLoad->GetValue(); //供粉转轴当前扭矩_R envState.m_IsPrintCabinDoorClose = m_IOCfgWrapper->IsSafeDoorClose(); envState.m_PowderJarCabinPressureVoltage=m_SysParamWrapper->m_PowderJarCabinPressureVoltage->GetValue(); envState.m_PowderJarCabinPressure=m_SysParamWrapper->m_PowderJarCabinPressureValue->GetValue(); envState.m_PowderLevelLength = m_SysParamWrapper->m_PowderLevelLength->GetValue(); envState.m_PowderLevelValue = m_SysParamWrapper->m_PowderLevelValue->GetValue(); envState.m_LinearLayerPos = m_SysParamWrapper->m_LinearEncoderPerLayerRealValue->GetValue(); envState.m_MoldTheoryDistance = m_SysParamWrapper->m_MoldTheoryDistance->GetValue(); envState.m_LinearActDistance = m_SysParamWrapper->m_LinearActDistance->GetValue(); envState.m_LinearActPulse = m_SysParamWrapper->m_LinearActPulse->GetValue(); envState.m_LineEncPulseEqu = m_SysParamWrapper->m_LineEncPulseEqu->GetValue(); envState.m_PrintCar1RealWeight = m_SysParamWrapper->m_PrintCar1RealWeight->GetValue(); envState.m_PrintCar2RealWeight = m_SysParamWrapper->m_PrintCar2RealWeight->GetValue(); envState.m_CleanCar1RealWeight = m_SysParamWrapper->m_CleanCar1RealWeight->GetValue(); envState.m_CleanCar2RealWeight = m_SysParamWrapper->m_CleanCar2RealWeight->GetValue(); } /*void CoreCommunication::AddCmd(Command* cmd) { unique_lock lck(m_WirteMutex); m_RTCommands.push(cmd); m_WriteCV.notify_one(); }*/ void CoreCommunication::SendProc() { string valStr; DATATYPE dataType; list its; while (!m_sendTdExitFlag) { std::unique_lock lock(m_ValueMtx); valStr = ""; its.clear(); auto param = SysParam::m_sysParamMp.begin(); while (param != SysParam::m_sysParamMp.end()) { valStr = param->second.GetValue(dataType); its.emplace_back(Item{ param->first,valStr,dataType}); ++param; } ClientWrapper::Instance()->PushAllClient(WriteData(SYSPARAMDATA, its)); valStr = ""; its.clear(); auto ioItem = m_IOCfgWrapper->m_IOCfgMap.begin(); while (ioItem != m_IOCfgWrapper->m_IOCfgMap.end()) { if (ioItem->second) { valStr = to_string(ioItem->second->IsActive()); its.emplace_back(Item{ ioItem->first,valStr,iBOOL }); } ++ioItem; } ClientWrapper::Instance()->PushAllClient(WriteData(SYSPARAMDATA, its)); int count = 10; while(!m_sendTdExitFlag && count--) { std::this_thread::sleep_for(std::chrono::milliseconds(20)); } } }