Обновление алгоритма смены скорости обмена - промежуточный коммит
This commit is contained in:
parent
a4cdcb7091
commit
d9f58e72e4
2
.gitignore
vendored
2
.gitignore
vendored
@ -54,3 +54,5 @@ compile_commands.json
|
|||||||
|
|
||||||
*_qmlcache.qrc
|
*_qmlcache.qrc
|
||||||
|
|
||||||
|
|
||||||
|
/Debug/debug/M3KTE_TERM.exe
|
||||||
|
@ -981,7 +981,7 @@ void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum)
|
|||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void M3KTE::onSpeedUpdate()
|
void M3KTE::onSpeedUpdate()
|
||||||
{
|
{
|
||||||
stopScanBoard();
|
stopScanBoard();
|
||||||
@ -1102,6 +1102,204 @@ void M3KTE::onSpeedUpdate()
|
|||||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||||
beginScanBoards();
|
beginScanBoards();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void M3KTE::onSpeedUpdate()
|
||||||
|
{
|
||||||
|
stopScanBoard();
|
||||||
|
modbusDevice->setTimeout(500);
|
||||||
|
|
||||||
|
switch(m_deviceSettingsDialog->currentSpeed()) {
|
||||||
|
case 0:
|
||||||
|
tmp_speed = 9600;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
tmp_speed = 14400;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
tmp_speed = 19200;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
tmp_speed = 31250;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
tmp_speed = 38400;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
tmp_speed = 56000;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
tmp_speed = 57600;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
tmp_speed = 115200;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(tmp_speed == 0) {
|
||||||
|
unsigned newRow = loggerTable->rowCount();
|
||||||
|
loggerTable->insertRow(newRow);
|
||||||
|
loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
|
||||||
|
loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Программная ошибка")));
|
||||||
|
loggerTable->setItem(newRow, 2, new QTableWidgetItem("Неожиданное значение скорости"));
|
||||||
|
loggerTable->setItem(newRow, 3, new QTableWidgetItem(0));
|
||||||
|
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении скорости обмена."));
|
||||||
|
loggerTable->resizeColumnsToContents();
|
||||||
|
if(!loggerTable->verticalScrollBar()->isSliderDown())
|
||||||
|
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
|
||||||
|
beginScanBoards();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
speedChangeRequests.clear();
|
||||||
|
pendingSpeedChangeRequestsCount = 0;
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
speedChangeRequests[i].errorOccurred = false;
|
||||||
|
speedChangeRequests[i].finished = false;
|
||||||
|
speedChangeRequests[i].confirmationReceived = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
if(!Boards[i].isActive)
|
||||||
|
continue;
|
||||||
|
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 173, 1);
|
||||||
|
unit.setValue(0, m_deviceSettingsDialog->currentSpeed());
|
||||||
|
|
||||||
|
auto *reply = modbusDevice->sendWriteRequest(unit, Boards[i].adr);
|
||||||
|
if (reply) {
|
||||||
|
SpeedChangeRequest req;
|
||||||
|
req.boardIndex = i;
|
||||||
|
speedChangeRequests.append(req);
|
||||||
|
pendingSpeedChangeRequestsCount++;
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::finished, this, [this, reply, i]() {
|
||||||
|
this->handleSpeedChangeReply(reply, i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void M3KTE::handleSpeedChangeReply(QModbusReply *reply, int boardIndex)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(speedChangeRequests.begin(), speedChangeRequests.end(),
|
||||||
|
[boardIndex](const SpeedChangeRequest &r) { return r.boardIndex == boardIndex; });
|
||||||
|
|
||||||
|
if (it == speedChangeRequests.end()) {
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление состояния
|
||||||
|
it->finished = true;
|
||||||
|
|
||||||
|
if (reply->error() != QModbusDevice::TimeoutError) {
|
||||||
|
// Произошла ошибка
|
||||||
|
it->errorOccurred = true; // флаг ошибки
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
// Отслеживание завершения всех запросов
|
||||||
|
pendingSpeedChangeRequestsCount--;
|
||||||
|
|
||||||
|
// Проверяем, все ли запросы завершены
|
||||||
|
if (pendingSpeedChangeRequestsCount == 0) {
|
||||||
|
// Проверяем, был ли хоть один сбой (кроме тайм-аутов)
|
||||||
|
bool hasError = false;
|
||||||
|
for (const auto &req : speedChangeRequests) {
|
||||||
|
if (req.errorOccurred) {
|
||||||
|
hasError = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasError) {
|
||||||
|
// Был сбой — отменяем переход и восстанавливаем старую скорость
|
||||||
|
// Восстановим старую скорость порта
|
||||||
|
revertToOldSpeedAndRestart();
|
||||||
|
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||||
|
beginScanBoards();
|
||||||
|
} else {
|
||||||
|
onAllSpeedChangeRepliesReceived();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void M3KTE::onAllSpeedChangeRepliesReceived()
|
||||||
|
{
|
||||||
|
// Переключаемся на tmp_speed
|
||||||
|
modbusDevice->disconnectDevice();
|
||||||
|
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, tmp_speed);
|
||||||
|
if (!modbusDevice->connectDevice()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QModbusDataUnit unitCheck(QModbusDataUnit::InputRegisters, 85, 1);
|
||||||
|
|
||||||
|
int totalActiveBoards = 0;
|
||||||
|
int confirmedBoards = 0;
|
||||||
|
|
||||||
|
QSet<int> pendingBoards;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (!Boards[i].isActive)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
totalActiveBoards++;
|
||||||
|
int slaveAddress = Boards[i].adr;
|
||||||
|
|
||||||
|
QModbusReply *reply = modbusDevice->sendReadRequest(unitCheck, slaveAddress);
|
||||||
|
if (!reply) {
|
||||||
|
revertToOldSpeedAndRestart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingBoards.insert(slaveAddress);
|
||||||
|
|
||||||
|
connect(reply, &QModbusReply::finished, this, [this, reply, slaveAddress, &confirmedBoards, &pendingBoards, totalActiveBoards]() mutable {
|
||||||
|
if (reply->error() == QModbusDevice::NoError) {
|
||||||
|
// Проверяем что пришел валидный ответ
|
||||||
|
QModbusDataUnit unit = reply->result();
|
||||||
|
if (unit.valueCount() > 0) {
|
||||||
|
confirmedBoards++;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pendingBoards.remove(slaveAddress);
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
|
if (pendingBoards.isEmpty()) {
|
||||||
|
if (confirmedBoards != totalActiveBoards) {
|
||||||
|
revertToOldSpeedAndRestart();
|
||||||
|
beginScanBoards();
|
||||||
|
} else {
|
||||||
|
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||||
|
beginScanBoards();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Если нет ни одной активной платы — сразу запускаем сканирование
|
||||||
|
if (totalActiveBoards == 0) {
|
||||||
|
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||||
|
beginScanBoards();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вспомогательная функция восстановления старой скорости
|
||||||
|
void M3KTE::revertToOldSpeedAndRestart()
|
||||||
|
{
|
||||||
|
modbusDevice->disconnectDevice();
|
||||||
|
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||||
|
m_settingsDialog->curBaud());
|
||||||
|
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||||
|
modbusDevice->connectDevice();
|
||||||
|
}
|
||||||
|
|
||||||
void M3KTE::onParityUpdate()
|
void M3KTE::onParityUpdate()
|
||||||
{
|
{
|
||||||
@ -1861,23 +2059,18 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
}
|
}
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
}
|
}
|
||||||
if(isRun)
|
if(isRun) {
|
||||||
{
|
|
||||||
onConnectClicked();
|
onConnectClicked();
|
||||||
bar->close();
|
bar->close();
|
||||||
bar->deleteLater();
|
bar->deleteLater();
|
||||||
return false;
|
return false;
|
||||||
}
|
} else if(!isRun) {
|
||||||
else if(!isRun)
|
|
||||||
{
|
|
||||||
//Нужна проверка типа устройства
|
//Нужна проверка типа устройства
|
||||||
if(reply->error()==QModbusDevice::NoError)
|
if(reply->error()==QModbusDevice::NoError) {
|
||||||
{
|
|
||||||
QModbusResponse resp = reply->rawResult();
|
QModbusResponse resp = reply->rawResult();
|
||||||
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
||||||
//result.remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH);
|
//result.remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH);
|
||||||
if(result == QString("KTE"))
|
if(result == QString("KTE")) {
|
||||||
{
|
|
||||||
countOfDeviceOnLine++;
|
countOfDeviceOnLine++;
|
||||||
KTE[i].append(tmp_adr);
|
KTE[i].append(tmp_adr);
|
||||||
}
|
}
|
||||||
@ -1889,17 +2082,12 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
countOfDeviceOnLine = 0;
|
countOfDeviceOnLine = 0;
|
||||||
modbusDevice->disconnectDevice();
|
modbusDevice->disconnectDevice();
|
||||||
}
|
}
|
||||||
if(m_scanBoard->exec()==QDialog::Accepted)
|
if(m_scanBoard->exec()==QDialog::Accepted) {
|
||||||
{
|
if(m_scanBoard->getCheckState()==Qt::Checked) {
|
||||||
if(m_scanBoard->getCheckState()==Qt::Checked)
|
for(int i = 0; i < 8; i++) {
|
||||||
{
|
for(int j = 0; j < KTE[i].size(); j++) {
|
||||||
for(int i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
for(int j = 0; j < KTE[i].size(); j++)
|
|
||||||
{
|
|
||||||
for(int l = i; l < 8; l++) {
|
for(int l = i; l < 8; l++) {
|
||||||
if(KTE[l].indexOf(KTE[i].at(j))==-1)
|
if(KTE[l].indexOf(KTE[i].at(j))==-1) {
|
||||||
{
|
|
||||||
QMessageBox::warning(this, "Error", QString("Несколько устройств по адресу %1, работающих на скоростях %2 и %3.").arg(KTE[i].at(j)).arg(m_baud[i]).arg(m_baud[l]));
|
QMessageBox::warning(this, "Error", QString("Несколько устройств по адресу %1, работающих на скоростях %2 и %3.").arg(KTE[i].at(j)).arg(m_baud[i]).arg(m_baud[l]));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1912,25 +2100,21 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
bar->setValue(i);
|
bar->setValue(i);
|
||||||
bar->setLabelText(tr("Синхронизация плат на скорости %1").arg(m_baud[i]));
|
bar->setLabelText(tr("Синхронизация плат на скорости %1").arg(m_baud[i]));
|
||||||
for(int j = 0; j < KTE[i].size(); j++)
|
for(int j = 0; j < KTE[i].size(); j++) {
|
||||||
{
|
|
||||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||||
m_baud[i]);
|
m_baud[i]);
|
||||||
if(!modbusDevice->connectDevice()) {
|
if(!modbusDevice->connectDevice()) {
|
||||||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||||||
}
|
}
|
||||||
auto *reply = modbusDevice->sendWriteRequest(*_unit, KTE[i].at(j));
|
auto *reply = modbusDevice->sendWriteRequest(*_unit, KTE[i].at(j));
|
||||||
if(!reply)
|
if(!reply) {
|
||||||
{
|
|
||||||
onConnectClicked();
|
onConnectClicked();
|
||||||
bar->close();
|
bar->close();
|
||||||
bar->deleteLater();
|
bar->deleteLater();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while(!reply->isFinished())
|
while(!reply->isFinished()) {
|
||||||
{
|
if(isRun) {
|
||||||
if(isRun)
|
|
||||||
{
|
|
||||||
//dfQMessageBox::warning(this, "Ошибка при синхронизации скоростей.", QString("Прерывание по запросу пользователя."));
|
//dfQMessageBox::warning(this, "Ошибка при синхронизации скоростей.", QString("Прерывание по запросу пользователя."));
|
||||||
onConnectClicked();
|
onConnectClicked();
|
||||||
bar->close();
|
bar->close();
|
||||||
@ -1939,19 +2123,15 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
}
|
}
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
}
|
}
|
||||||
if(reply->error()==QModbusDevice::TimeoutError)
|
if(reply->error()==QModbusDevice::TimeoutError) {
|
||||||
{
|
|
||||||
modbusDevice->disconnectDevice();
|
modbusDevice->disconnectDevice();
|
||||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||||
m_settingsDialog->UpdateBaud(m_scanBoard->getBaud()));
|
m_settingsDialog->UpdateBaud(m_scanBoard->getBaud()));
|
||||||
modbusDevice->connectDevice();
|
modbusDevice->connectDevice();
|
||||||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
||||||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr))
|
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) {
|
||||||
{
|
while(!subreply->isFinished()) {
|
||||||
while(!subreply->isFinished())
|
if(isRun) {
|
||||||
{
|
|
||||||
if(isRun)
|
|
||||||
{
|
|
||||||
//dfQMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
|
//dfQMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
|
||||||
onConnectClicked();
|
onConnectClicked();
|
||||||
bar->close();
|
bar->close();
|
||||||
@ -1960,8 +2140,7 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
}
|
}
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
}
|
}
|
||||||
if(subreply->error()!=QModbusDevice::NoError)
|
if(subreply->error()!=QModbusDevice::NoError) {
|
||||||
{
|
|
||||||
//QMessageBox::warning();
|
//QMessageBox::warning();
|
||||||
onConnectClicked();
|
onConnectClicked();
|
||||||
bar->close();
|
bar->close();
|
||||||
@ -1970,8 +2149,7 @@ bool M3KTE::autoBaudRateScan()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(reply->error()!=QModbusDevice::NoError)
|
else if(reply->error()!=QModbusDevice::NoError) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
modbusDevice->disconnectDevice();
|
modbusDevice->disconnectDevice();
|
||||||
|
@ -84,6 +84,10 @@ private slots:
|
|||||||
|
|
||||||
void boardScan(unsigned boardID);
|
void boardScan(unsigned boardID);
|
||||||
|
|
||||||
|
void handleSpeedChangeReply(QModbusReply *reply, int boardIndex);
|
||||||
|
void onAllSpeedChangeRepliesReceived();
|
||||||
|
void revertToOldSpeedAndRestart();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
M3KTE(QWidget *parent = nullptr);
|
M3KTE(QWidget *parent = nullptr);
|
||||||
~M3KTE();
|
~M3KTE();
|
||||||
@ -159,5 +163,17 @@ private:
|
|||||||
}ParsingReg;
|
}ParsingReg;
|
||||||
unsigned AllReg:16;
|
unsigned AllReg:16;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Структура для отслеживания состояния запроса смены скорости
|
||||||
|
struct SpeedChangeRequest {
|
||||||
|
int boardIndex;
|
||||||
|
bool errorOccurred = false;
|
||||||
|
bool finished = false;
|
||||||
|
bool confirmationReceived = false;
|
||||||
|
};
|
||||||
|
QVector<SpeedChangeRequest> speedChangeRequests;
|
||||||
|
int pendingSpeedChangeRequestsCount = 0;
|
||||||
|
int pendingConfirmationsCount = 0;
|
||||||
|
unsigned tmp_speed = 0;
|
||||||
};
|
};
|
||||||
#endif // M3KTE_H
|
#endif // M3KTE_H
|
||||||
|
Loading…
Reference in New Issue
Block a user