Modbus dev...
This commit is contained in:
parent
9ef96c5db5
commit
8f046e4223
@ -70,7 +70,7 @@
|
||||
#define USE_NETWORKING
|
||||
#define TCP_SERVER_PORT 1234
|
||||
#define CUSTOM_KERNEL_INSTALLED //Custom kernel with modified serial.c to disable hardware FIFO.
|
||||
#define COMPILE_MODBUS_TEST_MODE //Utilisé seulement pour les tests d'intégration Modbus.
|
||||
//#define COMPILE_MODBUS_TEST_MODE //Utilisé seulement pour les tests d'intégration Modbus.
|
||||
|
||||
|
||||
//Debug defs
|
||||
|
||||
@ -350,8 +350,8 @@ int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
|
||||
QByteArray RegisterValues = Transaction.mPDU.mData.right(ByteCount);
|
||||
|
||||
|
||||
qDebug("Master Rx Read Holding Registers Response.");
|
||||
qDebug("Data: %s",RegisterValues.toHex().data());
|
||||
// qDebug("Master Rx Read Holding Registers Response.");
|
||||
// qDebug("Data: %s",RegisterValues.toHex().data());
|
||||
|
||||
mModbusRepo->WriteHRData(Request->mStartAddress,Request->mNbRegisters,RegisterValues);
|
||||
RegistersDatabaseUpdated(Request->mStartAddress, Request->mNbRegisters);
|
||||
@ -374,8 +374,10 @@ int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
|
||||
delete Request;
|
||||
return RET_ERROR;
|
||||
}
|
||||
qDebug("Master Rx Write Single Register response. Address: %d,",RegAddress);
|
||||
qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
|
||||
// qDebug("Master Rx Write Single Register response. Address: %d,",RegAddress);
|
||||
// qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
|
||||
|
||||
ModbusWriteSingleRegsSuccess();
|
||||
|
||||
//Everything seems good.
|
||||
|
||||
@ -405,6 +407,7 @@ int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
|
||||
|
||||
// qDebug("Master Rx Write Multiple Registers response. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
|
||||
// qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
|
||||
ModbusWriteMultipleRegsSuccess();
|
||||
|
||||
//All is good.
|
||||
|
||||
@ -414,7 +417,8 @@ int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
|
||||
{
|
||||
//Received "Illegal function code" response
|
||||
//TODO: Log this.
|
||||
qDebug("Master received illegal function code 0x%x",Transaction.mPDU.mFunctionCode);
|
||||
CEngLog::instance()->AddLogString(QString().sprintf("Modbus Maître, réception d'un code de fonction illégal: 0x%x",Transaction.mPDU.mFunctionCode));
|
||||
// qDebug("Master received illegal function code 0x%x",Transaction.mPDU.mFunctionCode);
|
||||
emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_FCT,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
|
||||
break;
|
||||
}
|
||||
@ -483,7 +487,7 @@ int CModbusBackend::SendReadHoldingRegistersRequest(quint16 StartAddress, quint1
|
||||
//First, validate that the reading range is within our repo
|
||||
if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false)
|
||||
{
|
||||
CEngLog::instance()->AddLogString("Trying to send a read HR in an invalid range");
|
||||
CEngLog::instance()->AddLogString("ModbusBackend: Tentative de lecture d'un registre hors de portée.");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
@ -647,12 +651,12 @@ void CModbusBackend::RequestTimerExpired()
|
||||
{
|
||||
//The max number of retry has been reached. The device is probably offline.
|
||||
|
||||
CZTLog::instance()->AddLogString("Modbus Maître: Nombre maximal de tentatives sans réponse atteint avec le partenaire",true);
|
||||
// CZTLog::instance()->AddLogString("Modbus Maître: Nombre maximal de tentatives sans réponse atteint avec le partenaire",true);
|
||||
|
||||
|
||||
delete mRequestsList[i];
|
||||
mRequestsList.removeAt(i);
|
||||
|
||||
ModbusRequestMaxRetryReached();
|
||||
|
||||
//TODO: Manage this situation (log?)
|
||||
|
||||
@ -734,3 +738,18 @@ void CModbusBackend::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode
|
||||
Q_UNUSED(FctCode)
|
||||
CEngLog::instance()->AddLogString("ModbusResponseException called from within master object... weird stuff!");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusWriteMultipleRegsSuccess()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusWriteMultipleRegsSuccess() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusWriteSingleRegsSuccess()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusWriteSingleRegsSuccess() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusRequestMaxRetryReached()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusRequestMaxRetryReached() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
|
||||
@ -137,16 +137,21 @@ public:
|
||||
|
||||
|
||||
|
||||
virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; //Fonction virtuelle à être implémentée par le parent
|
||||
virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
//Appelée lorsque de nouvelles données ont été reçues du réseau Modbus et écrites dans le registre
|
||||
|
||||
virtual void ModbusWriteMultipleRegsSuccess(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée suite à la réception d'une réponse à une requête d'écriture multiple.
|
||||
virtual void ModbusWriteSingleRegsSuccess(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée suite à la réception d'une réponse à une requête d'écriture simple.
|
||||
virtual void ModbusRequestMaxRetryReached(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée lors de l'atteinte du nombre maximal d'essai de transmission d'une requête.
|
||||
|
||||
|
||||
//Master Exception
|
||||
virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par le parent
|
||||
//Sert à informer le parent lorsqu'une exception se produit dans la communication Modbus (réponse)
|
||||
virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode) = 0; //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
//Sert à informer la classe dérivée lorsqu'une exception se produit dans la communication Modbus (réponse)
|
||||
|
||||
|
||||
//Slave Exception
|
||||
virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par le parent
|
||||
virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode) = 0; //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
//Sert à informer le parent lorsqu'une exception se produit dans la communication Modbus (requête)
|
||||
|
||||
|
||||
|
||||
@ -10,7 +10,9 @@
|
||||
|
||||
#define SEI_MODBUS_ZT_WATCHDOG_REG 2027
|
||||
#define SEI_MODBUS_SEI_WATCHDOG_REG 2038
|
||||
#define SEI_MODBUS_SEI_WATCHDOG_MASK 0x0001
|
||||
|
||||
#define SEI_MODBUS_SEI_ALARMS_RESET_REG 2037
|
||||
#define SEI_MODBUS_SEI_ZT1_ALARM_RESET_MASK 0X0001
|
||||
#define SEI_MODBUS_SEI_ZT2_ALARM_RESET_MASK 0X0002
|
||||
|
||||
|
||||
@ -25,9 +25,18 @@ CModbusSEIMgr::CModbusSEIMgr(CModbusRepository *SEIRepo, CModbusRepository *CCRe
|
||||
|
||||
mSEIModbusUpdateTimer = new QTimer();
|
||||
mSEIModbusUpdateTimer->setInterval(1000);
|
||||
mSEIModbusUpdateTimer->setSingleShot(false);
|
||||
mSEIModbusUpdateTimer->setSingleShot(true);
|
||||
mSEIModbusUpdateTimer->stop();
|
||||
|
||||
mSEIWatchdogTimer = new QTimer();
|
||||
mSEIWatchdogTimer->setInterval(SEI_MODBUS_WATCHDOG_TIMEOUT);
|
||||
mSEIWatchdogTimer->setSingleShot(true);
|
||||
mSEIWatchdogTimer->stop();
|
||||
|
||||
|
||||
mSEILinkState = false;
|
||||
mSEIWatchdogState = 0;
|
||||
|
||||
|
||||
mModbusTCPSocketHandle = new QTcpSocket();
|
||||
connect(mModbusTCPSocketHandle,SIGNAL(readyRead()),this,SLOT(ModbusDataReady()));
|
||||
@ -35,6 +44,7 @@ CModbusSEIMgr::CModbusSEIMgr(CModbusRepository *SEIRepo, CModbusRepository *CCRe
|
||||
connect(mModbusTCPSocketHandle,SIGNAL(connected()),this,SLOT(SocketConnected()));
|
||||
connect(mConnectionTimer,SIGNAL(timeout()),this,SLOT(ConnectionTimerExpired()));
|
||||
connect(mSEIModbusUpdateTimer,SIGNAL(timeout()),this,SLOT(SEIModbusUpdateTimerExpired()));
|
||||
connect(mSEIWatchdogTimer,SIGNAL(timeout()),this,SLOT(SEIModbusWatchdogtimerExpired()));
|
||||
}
|
||||
|
||||
CModbusSEIMgr::~CModbusSEIMgr()
|
||||
@ -50,6 +60,8 @@ CModbusSEIMgr::~CModbusSEIMgr()
|
||||
delete mConnectionTimer;
|
||||
if(mSEIModbusUpdateTimer)
|
||||
delete mSEIModbusUpdateTimer;
|
||||
if(mSEIWatchdogTimer)
|
||||
delete mSEIWatchdogTimer;
|
||||
}
|
||||
|
||||
int CModbusSEIMgr::StartSEICommunication()
|
||||
@ -85,16 +97,18 @@ void CModbusSEIMgr::SocketConnected()
|
||||
CZTLog::instance()->AddLogString("Connection Modbus (Ethernet) avec NetTrac établi",true);
|
||||
mConnectionTimer->stop();
|
||||
mSEIModbusUpdateTimer->start();
|
||||
mSEIWatchdogTimer->start(SEI_MODBUS_WATCHDOG_TIMEOUT*2); //allow twice the time for the first watchdog to come in
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::SocketDisconnected()
|
||||
{
|
||||
ModbusLinkDisconnected();
|
||||
emit ModbusMasterDisconnected();
|
||||
emit SEIModbusLinkLost();
|
||||
mConnectionTimer->start();
|
||||
mSEIModbusUpdateTimer->stop();
|
||||
// qDebug("Disconnected from NetTrac");
|
||||
// CZTLog::instance()->AddLogString("Connexion avec NetTrac établi",true);
|
||||
mSEILinkState = false;
|
||||
mSEIWatchdogState = 0xBEEF;
|
||||
CZTLog::instance()->AddLogString("Connection Modbus (Ethernet) avec NetTrac rompue",true);
|
||||
}
|
||||
|
||||
@ -133,6 +147,13 @@ int CModbusSEIMgr::SEISettingsChanged(QHostAddress ServerIP, int ModbusPort, int
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::SEIModbusUpdateTimerExpired()
|
||||
{
|
||||
|
||||
//Read the SEI data...
|
||||
SendReadHoldingRegistersRequest(SEI_MODBUS_SEI_DATA_BASE_REG,SEI_MODBUS_SEI_TABLE_DATA_SIZE);
|
||||
}
|
||||
|
||||
int CModbusSEIMgr::SendZTRegistersToSEI()
|
||||
{
|
||||
//The SEI Modbus table is updated on event, triggered by the TKTransport object (see ZTTKUpdated()).
|
||||
//Just update the watchdog and send the current table.
|
||||
@ -149,6 +170,7 @@ void CModbusSEIMgr::SEIModbusUpdateTimerExpired()
|
||||
|
||||
SendWriteHoldingRegistersRequest(SEI_MODBUS_ZT_DATA_BASE_REG,SEI_MODBUS_ZT_TABLE_DATA_SIZE);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -175,11 +197,42 @@ void CModbusSEIMgr::ZTTKUpdated()
|
||||
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::SEIModbusWatchdogtimerExpired()
|
||||
{
|
||||
CZTLog::instance()->AddLogString("Perte du lien de communication avec la NetTrac: Watchdog NetTrac Expiré",true);
|
||||
|
||||
emit SEIModbusLinkLost();
|
||||
mSEILinkState = false;
|
||||
// mSEIWatchdogState = 0;
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length)
|
||||
{
|
||||
Q_UNUSED(StartAddress)
|
||||
Q_UNUSED(Length)
|
||||
|
||||
qint16 WD = mModbusRepo->GetSingleReg(SEI_MODBUS_SEI_WATCHDOG_REG);
|
||||
WD = (WD & SEI_MODBUS_SEI_WATCHDOG_MASK);
|
||||
// qDebug("WD = %d",WD);
|
||||
if(WD != mSEIWatchdogState)
|
||||
{
|
||||
mSEIWatchdogTimer->start(SEI_MODBUS_WATCHDOG_TIMEOUT); //The watchdog has toggled. Kick the timer.
|
||||
mSEIWatchdogState = WD;
|
||||
if(mSEILinkState == false)
|
||||
{
|
||||
mSEILinkState = true;
|
||||
emit SEIModbusLinkRecovered();
|
||||
CZTLog::instance()->AddLogString("Lien de communication (Watchdog) avec NetTrac rétabli",true);
|
||||
}
|
||||
}
|
||||
|
||||
if(mSEILinkState == true) //only consider data when link is healthy
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SendZTRegistersToSEI();
|
||||
|
||||
emit ModbusMasterRepositoryUpdated();
|
||||
}
|
||||
|
||||
@ -187,3 +240,28 @@ void CModbusSEIMgr::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode
|
||||
{
|
||||
qDebug("Modbus MASTER exception: code:%d Fct:%d",ExceptionCode,FctCode);
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::ModbusWriteMultipleRegsSuccess()
|
||||
{
|
||||
if(mModbusTCPSocketHandle->state() == QAbstractSocket::ConnectedState)
|
||||
{
|
||||
mSEIModbusUpdateTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::ModbusWriteSingleRegsSuccess()
|
||||
{
|
||||
if(mModbusTCPSocketHandle->state() == QAbstractSocket::ConnectedState)
|
||||
{
|
||||
mSEIModbusUpdateTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
void CModbusSEIMgr::ModbusRequestMaxRetryReached()
|
||||
{
|
||||
//The server did not respond to last request... Retry...
|
||||
if(mModbusTCPSocketHandle->state() == QAbstractSocket::ConnectedState)
|
||||
{
|
||||
mSEIModbusUpdateTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#include <QElapsedTimer>
|
||||
#include <QHostAddress>
|
||||
|
||||
|
||||
#define SEI_MODBUS_WATCHDOG_TIMEOUT 7000 //ms
|
||||
|
||||
|
||||
class CModbusSEIMgr : public CModbusBackend
|
||||
@ -23,13 +23,17 @@ public:
|
||||
int ReadModbusRegisters();
|
||||
int StartSEICommunication();
|
||||
int SEISettingsChanged(QHostAddress ServerIP, int ModbusPort, int DevID);
|
||||
int SendZTRegistersToSEI();
|
||||
|
||||
|
||||
virtual void RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length);
|
||||
virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode);
|
||||
virtual void ModbusWriteMultipleRegsSuccess();
|
||||
virtual void ModbusWriteSingleRegsSuccess();
|
||||
virtual void ModbusRequestMaxRetryReached();
|
||||
|
||||
QTimer *mConnectionTimer;
|
||||
// QTimer *mSEIWatchdogTimer;
|
||||
QTimer *mSEIWatchdogTimer;
|
||||
QTimer *mSEIModbusUpdateTimer;
|
||||
|
||||
private:
|
||||
@ -37,11 +41,19 @@ private:
|
||||
QHostAddress mSEIIPAddress;
|
||||
CModbusRepository *mCCRepoHandle;
|
||||
bool mZTWatchdog;
|
||||
bool mSEILinkState;
|
||||
|
||||
int mSEIWatchdogState;
|
||||
|
||||
|
||||
|
||||
|
||||
signals:
|
||||
void ModbusMasterConnected(qint32 LocalIP, qint32 RemoteIP);
|
||||
void ModbusMasterDisconnected();
|
||||
void ModbusMasterRepositoryUpdated();
|
||||
void SEIModbusLinkLost();
|
||||
void SEIModbusLinkRecovered();
|
||||
|
||||
public slots:
|
||||
void SocketConnected();
|
||||
@ -49,6 +61,8 @@ public slots:
|
||||
void ConnectionTimerExpired();
|
||||
void SEIModbusUpdateTimerExpired();
|
||||
void ZTTKUpdated();
|
||||
void SEIModbusWatchdogtimerExpired();
|
||||
|
||||
};
|
||||
|
||||
#endif // CMODBUSSEIMGR_H
|
||||
|
||||
@ -606,6 +606,8 @@ unsigned int CZoneTest::InitZT()
|
||||
|
||||
connect(mModbusSEIMgr,SIGNAL(ModbusMasterConnected(qint32,qint32)),panel.mSEISettingsPage,SLOT(ModbusSEIConnected(qint32,qint32)));
|
||||
connect(mModbusSEIMgr,SIGNAL(ModbusMasterDisconnected()),panel.mSEISettingsPage,SLOT(ModbusSEIDisconnected()));
|
||||
connect(mModbusSEIMgr,SIGNAL(SEIModbusLinkLost()),panel.mSEISettingsPage,SLOT(ModbusSEILinkDown()));
|
||||
connect(mModbusSEIMgr,SIGNAL(SEIModbusLinkRecovered()),panel.mSEISettingsPage,SLOT(ModbusSEILinkUP()));
|
||||
|
||||
panel.mZTMainPage->ModbusSEIDisconnected();
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user