Обновление алгоритма смены скорости обмена - промежуточный коммит
This commit is contained in:
parent
a4cdcb7091
commit
d9f58e72e4
2
.gitignore
vendored
2
.gitignore
vendored
@ -54,3 +54,5 @@ compile_commands.json
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
|
||||
/Debug/debug/M3KTE_TERM.exe
|
||||
|
@ -981,7 +981,7 @@ void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum)
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void M3KTE::onSpeedUpdate()
|
||||
{
|
||||
stopScanBoard();
|
||||
@ -1102,6 +1102,204 @@ void M3KTE::onSpeedUpdate()
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
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()
|
||||
{
|
||||
@ -1861,23 +2059,18 @@ bool M3KTE::autoBaudRateScan()
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if(isRun)
|
||||
{
|
||||
if(isRun) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
else if(!isRun)
|
||||
{
|
||||
} else if(!isRun) {
|
||||
//Нужна проверка типа устройства
|
||||
if(reply->error()==QModbusDevice::NoError)
|
||||
{
|
||||
if(reply->error()==QModbusDevice::NoError) {
|
||||
QModbusResponse resp = reply->rawResult();
|
||||
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
||||
//result.remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH);
|
||||
if(result == QString("KTE"))
|
||||
{
|
||||
if(result == QString("KTE")) {
|
||||
countOfDeviceOnLine++;
|
||||
KTE[i].append(tmp_adr);
|
||||
}
|
||||
@ -1889,17 +2082,12 @@ bool M3KTE::autoBaudRateScan()
|
||||
countOfDeviceOnLine = 0;
|
||||
modbusDevice->disconnectDevice();
|
||||
}
|
||||
if(m_scanBoard->exec()==QDialog::Accepted)
|
||||
{
|
||||
if(m_scanBoard->getCheckState()==Qt::Checked)
|
||||
{
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
for(int j = 0; j < KTE[i].size(); j++)
|
||||
{
|
||||
if(m_scanBoard->exec()==QDialog::Accepted) {
|
||||
if(m_scanBoard->getCheckState()==Qt::Checked) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
for(int j = 0; j < KTE[i].size(); j++) {
|
||||
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]));
|
||||
return false;
|
||||
}
|
||||
@ -1912,25 +2100,21 @@ bool M3KTE::autoBaudRateScan()
|
||||
for(int i = 0; i < 8; i++) {
|
||||
bar->setValue(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,
|
||||
m_baud[i]);
|
||||
if(!modbusDevice->connectDevice()) {
|
||||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||||
}
|
||||
auto *reply = modbusDevice->sendWriteRequest(*_unit, KTE[i].at(j));
|
||||
if(!reply)
|
||||
{
|
||||
if(!reply) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
while(!reply->isFinished())
|
||||
{
|
||||
if(isRun)
|
||||
{
|
||||
while(!reply->isFinished()) {
|
||||
if(isRun) {
|
||||
//dfQMessageBox::warning(this, "Ошибка при синхронизации скоростей.", QString("Прерывание по запросу пользователя."));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
@ -1939,19 +2123,15 @@ bool M3KTE::autoBaudRateScan()
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if(reply->error()==QModbusDevice::TimeoutError)
|
||||
{
|
||||
if(reply->error()==QModbusDevice::TimeoutError) {
|
||||
modbusDevice->disconnectDevice();
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||
m_settingsDialog->UpdateBaud(m_scanBoard->getBaud()));
|
||||
modbusDevice->connectDevice();
|
||||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
||||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr))
|
||||
{
|
||||
while(!subreply->isFinished())
|
||||
{
|
||||
if(isRun)
|
||||
{
|
||||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) {
|
||||
while(!subreply->isFinished()) {
|
||||
if(isRun) {
|
||||
//dfQMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
@ -1960,8 +2140,7 @@ bool M3KTE::autoBaudRateScan()
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if(subreply->error()!=QModbusDevice::NoError)
|
||||
{
|
||||
if(subreply->error()!=QModbusDevice::NoError) {
|
||||
//QMessageBox::warning();
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
@ -1970,8 +2149,7 @@ bool M3KTE::autoBaudRateScan()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(reply->error()!=QModbusDevice::NoError)
|
||||
{
|
||||
else if(reply->error()!=QModbusDevice::NoError) {
|
||||
return false;
|
||||
}
|
||||
modbusDevice->disconnectDevice();
|
||||
|
@ -84,6 +84,10 @@ private slots:
|
||||
|
||||
void boardScan(unsigned boardID);
|
||||
|
||||
void handleSpeedChangeReply(QModbusReply *reply, int boardIndex);
|
||||
void onAllSpeedChangeRepliesReceived();
|
||||
void revertToOldSpeedAndRestart();
|
||||
|
||||
public:
|
||||
M3KTE(QWidget *parent = nullptr);
|
||||
~M3KTE();
|
||||
@ -159,5 +163,17 @@ private:
|
||||
}ParsingReg;
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user