OutilModbus/Sources/OutilModbus.cpp

575 lines
16 KiB
C++

#include "OutilModbus.h"
#include "ProtocolDefs.h"
#include <QDateTime>
COutilModbus::COutilModbus(QObject *parent) :
QObject(parent)
{
mModbusSEIEmulator = new CModbusSlave(&mSEIModbusRepo);
mModbusCCEmulator = new CModbusMaster(&mCCModbusRepo);
w = new MainWindow(0,this);
mAutoRequestTimer = new QTimer();
mAutoRequestTimer->setSingleShot(false);
connect(mAutoRequestTimer,SIGNAL(timeout()),this,SLOT(AutoRequestTimeExpired()));
mWatchdogEnabled = true;
mWatchdog = 0;
mWatchdogTimer = new QTimer();
mWatchdogTimer->setSingleShot(false);
connect(mWatchdogTimer,SIGNAL(timeout()),this,SLOT(WatchdogTimerExpired()));
mWatchdogTimer->setInterval(MODBUS_CC_WATCHDOG_TIMEOUT);
mSEIWatchdogTimer = new QTimer();
mSEIWatchdogTimer->setSingleShot(false);
mSEIWatchdogTimer->setInterval(MODBUS_SEI_WATCHDOG_TIMEOUT);
connect(mSEIWatchdogTimer,SIGNAL(timeout()),this,SLOT(SEIWatchdogExpired()));
mZTAlarmGenerator = new CZTAlarmGenerator;
mZTAlarmGenerator->mAlarmGeneratorPageHandle = w->mZTAlarmGeneratorPage;
w->mZTAlarmGeneratorPage->mProgramHandle = mZTAlarmGenerator;
mSEIWatchdogValue = 0;
}
COutilModbus::~COutilModbus()
{
delete mModbusSEIEmulator;
delete mAutoRequestTimer;
delete mWatchdogTimer;
delete w;
delete mSEIWatchdogTimer;
delete mZTAlarmGenerator;
}
int COutilModbus::Start()
{
w->resize(1024,768);
w->show();
mModbusPageHandle = w->mModbusPage;
mSEIModbusPageHandle = w->mSEIModbusPage;
mCCModbusRepo.AddHRDataMap(2000,128);
//mModbusSEIEmulator->StartSlaveServer(502);
mModbusSEIEmulator->SetServerPort(503);
mSEIModbusRepo.AddHRDataMap(2000,128);
mSEIModbusRepo.AddHRDataMap(3000,128);
connect(mModbusCCEmulator,SIGNAL(ModbusMasterConnected(CModbusMaster*)),this,SLOT(ModbusMasterConnected(CModbusMaster*)));
connect(mModbusCCEmulator,SIGNAL(ModbusMasterDisconnected(CModbusMaster*)),this,SLOT(ModbusMasterDisconnected(CModbusMaster*)));
connect(mModbusCCEmulator,SIGNAL(ModbusMasterRepositoryUpdated()),this,SLOT(ModbusMasterRepositoryUpdated()));
connect(mModbusCCEmulator,SIGNAL(ModbusRX()),mModbusPageHandle,SLOT(ModbusActivity()));
connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveConnected(CModbusSlave*)),this,SLOT(SEIModbusConnected(CModbusSlave*)));
connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveDisconnected(CModbusSlave*)),this,SLOT(SEIModbusDisconnected(CModbusSlave*)));
connect(mModbusSEIEmulator,SIGNAL(ModbusSlaveRepoUpdated()),this,SLOT(SEIRepositoryUpdated()));
return 1;
}
void COutilModbus::ModbusMasterConnected(CModbusMaster *Master)
{
mModbusPageHandle->MasterConnected();
mAutoRequestTimer->stop();
if(mWatchdogEnabled)
{
mWatchdogTimer->start();
}
}
void COutilModbus::ModbusMasterDisconnected(CModbusMaster *Master)
{
mModbusPageHandle->MasterDisconnected();
mWatchdogTimer->stop();
mAutoRequestTimer->stop();
}
void COutilModbus::ModbusMasterRepositoryUpdated()
{
if(UpdateZTInfo(&mCurZTInfo,&mCCModbusRepo) == RET_OK)
{
mModbusPageHandle->UpdateZTInfo(&mCurZTInfo);
}
}
void COutilModbus::SEIModbusConnected(CModbusSlave *Slave)
{
mSEIModbusPageHandle->SetConnected(true);
}
void COutilModbus::SEIModbusDisconnected(CModbusSlave *Slave)
{
mSEIModbusPageHandle->SetConnected(false);
}
void COutilModbus::SEIRepositoryUpdated()
{
if(UpdateZTInfo(&mCurZTInfo, &mSEIModbusRepo) == RET_OK)
{
mSEIModbusPageHandle->UpdateZTInfo(&mCurZTInfo);
}
}
int COutilModbus::ConnectCCToZTButtonPressed(QString IP, int Port)
{
mModbusCCEmulator->ConnectToSlave(IP,Port);
return 1;
}
int COutilModbus::DisconnectCCFromZTButtonPressed()
{
return mModbusCCEmulator->DisconnectFromSlave();
}
int COutilModbus::SetCCReqDelay(int delay)
{
return 1;
}
int COutilModbus::SendMasterReadCommand()
{
return mModbusCCEmulator->ReadModbusRegisters();
}
int COutilModbus::UpdateZTInfo(CZTInfo *DataStruct, CModbusRepository *SourceRepo)
{
bool OK = false;
// quint16 data = mCCModbusRepo.GetSingleReg(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,&OK);
quint16 data = SourceRepo->GetSingleReg(MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD,&OK);
if(OK == true)
{
DataStruct->mZT1PPIAlarmFlag1 = (data & ZT1_PP_INT_FLAG_MASK_1) != 0;
DataStruct->mZT1PPIAlarmFlag2 = (data & ZT1_PP_INT_FLAG_MASK_2) != 0;
DataStruct->mZT1PPIAlarmFlag3 = (data & ZT1_PP_INT_FLAG_MASK_3) != 0;
DataStruct->mZT1PPIAlarmFlag4 = (data & ZT1_PP_INT_FLAG_MASK_4) != 0;
DataStruct->mZT1PPEAlarmFlag1 = (data & ZT1_PP_EXT_FLAG_MASK_1) != 0;
DataStruct->mZT1PPEAlarmFlag2 = (data & ZT1_PP_EXT_FLAG_MASK_2) != 0;
DataStruct->mZT1PPEAlarmFlag3 = (data & ZT1_PP_EXT_FLAG_MASK_3) != 0;
DataStruct->mZT1PPEAlarmFlag4 = (data & ZT1_PP_EXT_FLAG_MASK_4) != 0;
DataStruct->mZT1PGAlarmFlag1 = (data & ZT1_PG_FLAG_MASK_1) != 0;
DataStruct->mZT1PGAlarmFlag2 = (data & ZT1_PG_FLAG_MASK_2) != 0;
DataStruct->mZT1PGAlarmFlag3 = (data & ZT1_PG_FLAG_MASK_3) != 0;
DataStruct->mZT1PGAlarmFlag4 = (data & ZT1_PG_FLAG_MASK_4) != 0;
DataStruct->mZT1FNAlarmFlag1 = (data & ZT1_FN_FLAG_MASK_1) != 0;
DataStruct->mZT1FNAlarmFlag2 = (data & ZT1_FN_FLAG_MASK_2) != 0;
DataStruct->mZT1FNAlarmFlag3 = (data & ZT1_FN_FLAG_MASK_3) != 0;
DataStruct->mZT1FNAlarmFlag4 = (data & ZT1_FN_FLAG_MASK_4) != 0;
}
else
{
qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT1_ALARM_DATA_BASE_REG_ADD)");
return RET_ERROR;
}
QList<qint16> RankData;
RankData = SourceRepo->GetRegs(MODBUS_ZT1_ALARM_RANKS_BASE_ADD,16,&OK);
if(OK == true)
{
DataStruct->mZT1Ranks = RankData;
}
else
{
qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT1_ALARM_RANKS_BASE_ADD)");
return RET_ERROR;
}
data = SourceRepo->GetSingleReg(MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD,&OK);
if(OK == true)
{
DataStruct->mZT2PPIAlarmFlag1 = (data & ZT2_PP_INT_FLAG_MASK_1) != 0;
DataStruct->mZT2PPIAlarmFlag2 = (data & ZT2_PP_INT_FLAG_MASK_2) != 0;
DataStruct->mZT2PPIAlarmFlag3 = (data & ZT2_PP_INT_FLAG_MASK_3) != 0;
DataStruct->mZT2PPIAlarmFlag4 = (data & ZT2_PP_INT_FLAG_MASK_4) != 0;
DataStruct->mZT2PPEAlarmFlag1 = (data & ZT2_PP_EXT_FLAG_MASK_1) != 0;
DataStruct->mZT2PPEAlarmFlag2 = (data & ZT2_PP_EXT_FLAG_MASK_2) != 0;
DataStruct->mZT2PPEAlarmFlag3 = (data & ZT2_PP_EXT_FLAG_MASK_3) != 0;
DataStruct->mZT2PPEAlarmFlag4 = (data & ZT2_PP_EXT_FLAG_MASK_4) != 0;
}
else
{
qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT2_ALARM_DATA_BASE_REG_ADD)");
return RET_ERROR;
}
RankData.clear();
RankData = SourceRepo->GetRegs(MODBUS_ZT2_ALARM_RANKS_BASE_ADD,8,&OK);
if(OK == true)
{
DataStruct->mZT2Ranks = RankData;
}
else
{
qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_ZT2_ALARM_RANKS_BASE_ADD)");
return RET_ERROR;
}
data = SourceRepo->GetSingleReg(MODBUS_MISC_DATA_BASE_REG_ADD,&OK);
if(OK == true)
{
DataStruct->mZT1V00AlarmFlag = (data & ZT1_V00_ALARM_FLAG_MASK) != 0;
DataStruct->mZT1PEQ1AlarmFlag = (data & ZT1_PEQ1_ALARM_FLAG_MASK) != 0;
DataStruct->mZT2V02AlarmFlag = (data & ZT2_V02_ALARM_FLAG_MASK) != 0;
DataStruct->mZT2PEQ2AlarmFlag = (data & ZT2_PEQ2_ALARM_FLAG_MASK) != 0;
DataStruct->mITI10_12Flag = (data & ZT1_ALARM_ITI_FLAG_MASK) != 0;
}
else
{
qDebug("GetSingleReg failed in UpdateZTInfo (MODBUS_PANNES_DATA_BASE_REG_ADD)");
return RET_ERROR;
}
DataStruct->mWatchdogZT = SourceRepo->GetSingleReg(MODBUS_ZT_WATCHDOG_REG_ADD,&OK);
return RET_OK;
}
int COutilModbus::SendAN1Request() //FCYCLE
{
bool OK = false;
quint16 AN1;
quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK);
AN1 = CurValue & MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
if(OK == true)
{
if(AN1 == 0)
{
CurValue |= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Setting FCYCLE in repo");
}
else
{
CurValue &= ~MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Clearing FCYCLE in repo");
}
mModbusCCEmulator->SendAN1ToZT();
}
return RET_OK;
}
int COutilModbus::SendAN2Request()
{
bool OK = false;
quint16 AN2;
quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK);
AN2 = CurValue & MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
if(OK == true)
{
if(AN2 == 0)
{
CurValue |= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Setting FCYCLE in repo");
}
else
{
CurValue &= ~MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Clearing FCYCLE in repo");
}
mModbusCCEmulator->SendAN2ToZT();
}
return RET_OK;
}
int COutilModbus::SendZTCZT1Request()
{
bool OK = false;
quint16 ZTC1;
quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK);
ZTC1 = CurValue & MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
if(OK == true)
{
if(ZTC1 == 0)
{
CurValue |= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Setting ZTC1 in repo");
}
else
{
CurValue ^= MODBUS_CC_FCYCLE_ZT1_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Clearing ZTC1 in repo");
}
mModbusCCEmulator->SendAN2ToZT();
}
return RET_OK;
}
int COutilModbus::SendZTCZT2Request()
{
bool OK = false;
quint16 ZTC2;
quint16 CurValue = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK);
ZTC2 = CurValue & MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
if(OK == true)
{
if(ZTC2 == 0)
{
CurValue |= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Setting ZTC2 in repo");
}
else
{
CurValue ^= MODBUS_CC_FCYCLE_ZT2_FLAG_MASK;
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,CurValue);
qDebug("Clearing ZTC2 in repo");
}
mModbusCCEmulator->SendAN2ToZT();
}
return RET_OK;
}
int COutilModbus::SetAutoRequestMode(bool Auto, int Delay)
{
if(Auto == false)
{
mAutoRequestTimer->stop();
}
else
{
mAutoRequestTimer->setInterval(Delay);
mAutoRequestTimer->start();
}
return RET_OK;
}
void COutilModbus::AutoRequestTimeExpired()
{
SendMasterReadCommand();
}
int COutilModbus::EnableWatchdog(bool Enabled)
{
mWatchdogEnabled = Enabled;
if(Enabled)
{
mWatchdogTimer->start();
}
else
{
mWatchdogTimer->stop();
}
return RET_OK;
}
void COutilModbus::WatchdogTimerExpired()
{
if(mWatchdog == 0)
{
mWatchdog = 1;
}
else
{
mWatchdog = 0;
}
mCCModbusRepo.WriteSingleReg(MODBUS_CC_WATCHDOG_BASE_REG_ADD,mWatchdog);
// qDebug("Watchdog: %d",mWatchdog);
mModbusCCEmulator->SendWatchdog();
}
int COutilModbus::SendDateTime()
{
QList<qint16> DateTimeData;
QDateTime CurDateTime = QDateTime::currentDateTime().toUTC();
qint16 tmpWord;
qint8 tmpByte;
DateTimeData.append(MODBUS_CC_CLK_UPDATE_FLAG_MASK);
tmpByte = DecToBCDByte((qint8)CurDateTime.time().second());
tmpWord = (qint16)tmpByte << 8;
DateTimeData.append(tmpWord);
tmpByte = DecToBCDByte((qint8)CurDateTime.time().hour());
tmpWord = (qint16)tmpByte << 8;
tmpByte = DecToBCDByte((qint8)CurDateTime.time().minute());
tmpWord += tmpByte;
DateTimeData.append(tmpWord);
tmpByte = DecToBCDByte((qint8)CurDateTime.date().month());
tmpWord = (qint16)tmpByte << 8;
tmpByte = DecToBCDByte((qint8)CurDateTime.date().day());
tmpWord += tmpByte;
DateTimeData.append(tmpWord);
tmpWord = DecToBCDWord((qint16)CurDateTime.date().year());
DateTimeData.append(tmpWord);
mCCModbusRepo.WriteMultipleRegs(MODBUS_CC_CLK_UPDATE_BASE_REG_ADD,DateTimeData);
mModbusCCEmulator->SendDateTime();
return RET_OK;
}
int COutilModbus::SendTrainInfo(QList<qint16> TrainInfo)
{
mCCModbusRepo.WriteMultipleRegs(MODBUS_CC_ZT1_TRAIN_TYPE_REG_ADD,TrainInfo);
mModbusCCEmulator->SendTrainData();
return RET_OK;
}
int COutilModbus::SendInhibitZT(qint16 InhibZT1, qint16 InhibZT2)
{
bool OK = false;
qint16 Register = mCCModbusRepo.GetSingleReg(MODBUS_CC_AN_BASE_REG_ADD,&OK);
if(OK)
{
if(InhibZT1 == 0)
{
Register &= ~MODBUS_CC_INHIBIT_ZT1_FLAG_MASK;
}
else
{
Register |= MODBUS_CC_INHIBIT_ZT1_FLAG_MASK;
}
if(InhibZT2 == 0)
{
Register &= ~MODBUS_CC_INHIBIT_ZT2_FLAG_MASK;
}
else
{
Register |= MODBUS_CC_INHIBIT_ZT2_FLAG_MASK;
}
mCCModbusRepo.WriteSingleReg(MODBUS_CC_AN_BASE_REG_ADD,Register);
mModbusCCEmulator->SendZTInhibitionData();
return RET_OK;
}
return RET_ERROR;
}
quint8 COutilModbus::DecToBCDByte(const quint8 byte)
{
quint8 out = 0;
out = ((byte/10) << 4) + (byte%10);
return out;
}
quint16 COutilModbus::DecToBCDWord(const quint16 word)
{
quint16 out = 0;
quint16 temp = 0;
out = word % 10;
temp = (((word /10) % 10) << 4);
out += temp;
temp = (((word / 100) % 10) << 8);
out += temp;
temp = (((word / 1000) % 10) << 12);
out += temp;
return out;
}
int COutilModbus::ToggleSEIServerState()
{
return mModbusSEIEmulator->ToggleServerState();
}
bool COutilModbus::IsSEIServerOpened()
{
return mModbusSEIEmulator->IsSlaveServerOpened();
}
int COutilModbus::SEIWatchdogEnable(bool Enabled)
{
if(Enabled)
{
mSEIWatchdogTimer->start();
}
else
{
mSEIWatchdogTimer->stop();
}
return RET_OK;
}
void COutilModbus::SEIWatchdogExpired()
{
if(mSEIWatchdogValue == 0)
{
mSEIWatchdogValue = SEI_MODBUS_SEI_WATCHDOG_MASK;
}
else
{
mSEIWatchdogValue = 0;
}
mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_WATCHDOG_REG,mSEIWatchdogValue);
}
int COutilModbus::SEIAN1Toggle(bool Enabled)
{
qint16 temp;
bool OK;
temp = mSEIModbusRepo.GetSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,&OK);
if(OK == false)
{
qDebug("SEIAN1Toggle(): logic error in modbus table assignment. Can't read address %d",SEI_MODBUS_SEI_ALARMS_RESET_REG);
return RET_ERROR;
}
if(Enabled)
{
temp |= SEI_MODBUS_SEI_ZT1_ALARM_RESET_MASK;
}
else
{
temp &= ~SEI_MODBUS_SEI_ZT1_ALARM_RESET_MASK;
}
mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,temp);
return RET_OK;
}
int COutilModbus::SEIAN2Toggle(bool Enabled)
{
qint16 temp;
bool OK;
temp = mSEIModbusRepo.GetSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,&OK);
if(OK == false)
{
qDebug("SEIAN2Toggle(): logic error in modbus table assignment. Can't read address %d",SEI_MODBUS_SEI_ALARMS_RESET_REG);
return RET_ERROR;
}
if(Enabled)
{
temp |= SEI_MODBUS_SEI_ZT2_ALARM_RESET_MASK;
}
else
{
temp &= ~SEI_MODBUS_SEI_ZT2_ALARM_RESET_MASK;
}
mSEIModbusRepo.WriteSingleReg(SEI_MODBUS_SEI_ALARMS_RESET_REG,temp);
return RET_OK;
}