diff --git a/M3KTE_TERM/devicesettingsdialog.cpp b/M3KTE_TERM/devicesettingsdialog.cpp index f793ea7..a256829 100644 --- a/M3KTE_TERM/devicesettingsdialog.cpp +++ b/M3KTE_TERM/devicesettingsdialog.cpp @@ -1,26 +1,23 @@ #include "devicesettingsdialog.h" #include "ui_devicesettingsdialog.h" +#include +#include +#include DeviceSettingsDialog::DeviceSettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::DeviceSettingsDialog) { ui->setupUi(this); - - _currentBoardTimers[0] = ui->spinTimerBoard_1->value(); - _currentBoardTimers[1] = ui->spinTimerBoard_2->value(); - _currentBoardTimers[2] = ui->spinTimerBoard_3->value(); - _currentBoardTimers[3] = ui->spinTimerBoard_4->value(); - - _m_timer[0] = ui->spinTimerBoard_1; - _m_timer[1] = ui->spinTimerBoard_2; - _m_timer[2] = ui->spinTimerBoard_3; - _m_timer[3] = ui->spinTimerBoard_4; - + on_buttonApplyChangeTimer_clicked(); + { + _m_timer[0] = ui->spinTimerBoard_1; + _m_timer[1] = ui->spinTimerBoard_2; + _m_timer[2] = ui->spinTimerBoard_3; + _m_timer[3] = ui->spinTimerBoard_4; + } _currentSpeed = ui->speedBox->currentText().toUInt(); - _currentParity = ui->parityBox->currentIndex(); - for(int i = 0; i < 4; i++) { _currentAdrs[i] = i+1; } @@ -105,17 +102,11 @@ void DeviceSettingsDialog::on_buttonBox_clicked(QAbstractButton *button) ui->spinTimerBoard_2->setValue(1000); ui->spinTimerBoard_3->setValue(1000); ui->spinTimerBoard_4->setValue(1000); - _currentBoardTimers[0] = ui->spinTimerBoard_1->value(); - _currentBoardTimers[1] = ui->spinTimerBoard_2->value(); - _currentBoardTimers[2] = ui->spinTimerBoard_3->value(); - _currentBoardTimers[3] = ui->spinTimerBoard_4->value(); - + on_buttonApplyChangeTimer_clicked(); ui->speedBox->setCurrentText("31250"); _currentSpeed = ui->speedBox->currentText().toUInt(); - ui->parityBox->setCurrentIndex(0); _currentParity = ui->parityBox->currentIndex(); - for(int i = 0; i < 4; i++) { _currentAdrs[i] = i+1; } @@ -131,7 +122,7 @@ void DeviceSettingsDialog::on_buttonBox_clicked(QAbstractButton *button) void DeviceSettingsDialog::initPollForBoard(unsigned boardID, unsigned boardAdr) { - ui->idPollComboBox->addItem(QString("Плата №%1 (ID %2)").arg(boardID).arg(boardAdr), QVariant(boardID)); + ui->idPollComboBox->addItem(QString("Плата №%1 (ID %2)").arg(boardID+1).arg(boardAdr), QVariant(boardID)); } void DeviceSettingsDialog::updatePollStatus(unsigned boardID, bool status) diff --git a/M3KTE_TERM/lineringer.cpp b/M3KTE_TERM/lineringer.cpp index 285ae5b..1f4e9ea 100644 --- a/M3KTE_TERM/lineringer.cpp +++ b/M3KTE_TERM/lineringer.cpp @@ -11,23 +11,25 @@ LineRinger::LineRinger(QWidget *parent) : for (const auto& port: listPorts) { ui->comBox->addItem(QString(port.portName() + ": " + port.manufacturer()), QVariant(port.portName())); } - - ui->parityControlBox->addItem("No", QVariant(QSerialPort::NoParity)); - ui->parityControlBox->addItem("Even", QVariant(QSerialPort::EvenParity)); - ui->parityControlBox->addItem("Odd", QVariant(QSerialPort::OddParity)); - ui->parityControlBox->addItem("Space", QVariant(QSerialPort::SpaceParity)); - ui->parityControlBox->addItem("Mark", QVariant(QSerialPort::MarkParity)); - - ui->dataBox->addItem("Data5", QVariant(QSerialPort::Data5)); - ui->dataBox->addItem("Data6", QVariant(QSerialPort::Data6)); - ui->dataBox->addItem("Data7", QVariant(QSerialPort::Data7)); - ui->dataBox->addItem("Data8", QVariant(QSerialPort::Data8)); - ui->dataBox->setCurrentIndex(3); - - ui->stopBox->addItem("One", QVariant(QSerialPort::OneStop)); - ui->stopBox->addItem("OneAndHalf", QVariant(QSerialPort::OneAndHalfStop)); - ui->stopBox->addItem("Two", QVariant(QSerialPort::TwoStop)); - + { + ui->parityControlBox->addItem("No", QVariant(QSerialPort::NoParity)); + ui->parityControlBox->addItem("Even", QVariant(QSerialPort::EvenParity)); + ui->parityControlBox->addItem("Odd", QVariant(QSerialPort::OddParity)); + ui->parityControlBox->addItem("Space", QVariant(QSerialPort::SpaceParity)); + ui->parityControlBox->addItem("Mark", QVariant(QSerialPort::MarkParity)); + } + { + ui->dataBox->addItem("Data5", QVariant(QSerialPort::Data5)); + ui->dataBox->addItem("Data6", QVariant(QSerialPort::Data6)); + ui->dataBox->addItem("Data7", QVariant(QSerialPort::Data7)); + ui->dataBox->addItem("Data8", QVariant(QSerialPort::Data8)); + ui->dataBox->setCurrentIndex(3); + } + { + ui->stopBox->addItem("One", QVariant(QSerialPort::OneStop)); + ui->stopBox->addItem("OneAndHalf", QVariant(QSerialPort::OneAndHalfStop)); + ui->stopBox->addItem("Two", QVariant(QSerialPort::TwoStop)); + } ui->deviceOnlineView->horizontalHeader()->setVisible(true); syncColumnHeaders(); ui->deviceOnlineView->setColumnHidden(1, true); @@ -93,10 +95,10 @@ LineRinger::callStatus LineRinger::lineCall() bool *tmp_isRun = &isRun; uint tmp_adr = 1; auto bar = new QProgressDialog(this); - connect(bar, &QProgressDialog::canceled, this, [this, tmp_isRun]() { + connect(bar, &QProgressDialog::canceled, this, [tmp_isRun]() { *tmp_isRun = true; }); - connect(this, &LineRinger::stopLineCall, this, [this, tmp_isRun]() { + connect(this, &LineRinger::stopLineCall, this, [tmp_isRun]() { *tmp_isRun = true; }); bar->setLabelText(tr("Поиск устройств... Текущий адрес: %1").arg(tmp_adr)); @@ -107,7 +109,6 @@ LineRinger::callStatus LineRinger::lineCall() bar->setValue(tmp_adr); bar->setLabelText(tr("Поиск устройств... Текущий адрес: %1/247").arg(tmp_adr)); auto *reply = modbusDevice->sendRawRequest(readDeviceBasicIdentification, tmp_adr); - //auto *reply = modbusDevice->sendReadRequest(*_unit, tmp_adr); //Запрос типа устройства. if(reply == nullptr) { QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1").arg(modbusDevice->errorString())); @@ -171,10 +172,6 @@ LineRinger::callStatus LineRinger::lineCall() return callStatus::INTERRUPT; } else if(!isRun) { if(regularReply->error()!=QModbusDevice::NoError) { -// QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1: %2").arg(regularReply->error()).arg(regularReply->errorString())); -// bar->close(); -// bar->deleteLater(); -// return callStatus::ERROR; regularReplyError = true; regularReplyErrorString = QString("%1: %2").arg(regularReply->error()).arg(regularReply->errorString()); } @@ -237,12 +234,10 @@ void LineRinger::on_ringButton_clicked() emit stopLineCall(); }); bar->setValue(0); - ui->deviceOnlineView->setColumnHidden(1, false); modbusDevice->disconnectDevice(); for (int i = 0; i < ui->baudRateBox->count(); i++) { bar->setValue(i+1); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, ui->baudRateBox->itemText(i).toInt(nullptr, 10)); if (!modbusDevice->connectDevice()) { diff --git a/M3KTE_TERM/m3kte.cpp b/M3KTE_TERM/m3kte.cpp index abc33cf..eaae695 100644 --- a/M3KTE_TERM/m3kte.cpp +++ b/M3KTE_TERM/m3kte.cpp @@ -12,6 +12,10 @@ #include #include +#include +#include +#include +#include QWidget* init(QWidget *parent) { @@ -354,12 +358,12 @@ M3KTE::M3KTE(QWidget *parent) ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters); ui->writeTable->addItem(tr("Accidents"), QModbusDataUnit::HoldingRegisters); for(int i = 0; i < 4; i++) { - Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/3*20), false); + Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/4*20), false); Boards[i].ModbusModelCoil->setStartAddress(0); - Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/3*20))); - Boards[i].ModbusModelHoldingReg = new WriteRegisterModel(this, (85 - (i/3*20))*2, true); + Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/4*20))); + Boards[i].ModbusModelHoldingReg = new WriteRegisterModel(this, (85 - (i/4*20))*2, true); Boards[i].ModbusModelHoldingReg->setStartAddress(0); - Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/3*20))); + Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/4*20))); } m_deviceSettingsDialog = new DeviceSettingsDialog(this); m_regMultipleSettings = new MultipleSettings(this); @@ -385,11 +389,12 @@ M3KTE::M3KTE(QWidget *parent) connect(Boards[3].boardScanners, &QTimer::timeout, this, [this]() { boardScan(3); }); - Boards[0].adr = 1; - Boards[1].adr = 2; - Boards[2].adr = 3; - Boards[3].adr = 4; - //ui->M3kteMenuSettings->setEnabled(false); + { + Boards[0].adr = 1; + Boards[1].adr = 2; + Boards[2].adr = 3; + Boards[3].adr = 4; + } ui->M3kteRegSettings->setEnabled(false); ui->BSM_Warning->setEnabled(false); ui->BSM_Accident->setEnabled(false); @@ -400,21 +405,24 @@ M3KTE::M3KTE(QWidget *parent) ui->boardSelectBox->setCurrentIndex(0); ui->writeTable->setCurrentIndex(0); changeTable(0, 0); - Boards_Fields[0] = ui->FCBoardBox; - Boards_Fields[1] = ui->FCBoardBox_2; - Boards_Fields[2] = ui->FCBoardBox_3; - Boards_Fields[3] = ui->FCBoardBox_4; - - Boards[0].timerStatus = ui->timeStatus_1; - Boards[1].timerStatus = ui->timeStatus_2; - Boards[2].timerStatus = ui->timeStatus_3; - Boards[3].timerStatus = ui->timeStatus_4; - - Boards[0].timerData = ui->timeData_1; - Boards[1].timerData = ui->timeData_2; - Boards[2].timerData = ui->timeData_3; - Boards[3].timerData = ui->timeData_4; - + { + Boards_Fields[0] = ui->FCBoardBox; + Boards_Fields[1] = ui->FCBoardBox_2; + Boards_Fields[2] = ui->FCBoardBox_3; + Boards_Fields[3] = ui->FCBoardBox_4; + } + { + Boards[0].timerStatus = ui->timeStatus_1; + Boards[1].timerStatus = ui->timeStatus_2; + Boards[2].timerStatus = ui->timeStatus_3; + Boards[3].timerStatus = ui->timeStatus_4; + } + { + Boards[0].timerData = ui->timeData_1; + Boards[1].timerData = ui->timeData_2; + Boards[2].timerData = ui->timeData_3; + Boards[3].timerData = ui->timeData_4; + } for(int i = 0; i < 4; i++) { statusM3KTE.Warnings[i] = false; statusM3KTE.Accidents[i] = false; @@ -426,7 +434,7 @@ M3KTE::M3KTE(QWidget *parent) ui->writeValueTable->resizeColumnToContents(i); } QBrush tb(Qt::transparent); // Transparent brush, solid pattern - for(int i = 0; i<320; i++) { + for(int i = 0; i < 320; i++) { m_ProgressBar[i]->setTextVisible(true); m_ProgressBar[i]->setMinimumSize(25, 25); m_ProgressBar[i]->setMaximumSize(25, 25); @@ -445,7 +453,6 @@ M3KTE::M3KTE(QWidget *parent) } connect(m_deviceSettingsDialog, &DeviceSettingsDialog::parityChanged, this, &M3KTE::onParityUpdate); connect(m_deviceSettingsDialog, &DeviceSettingsDialog::speedChanged, this, &M3KTE::onSpeedUpdate); - loggerTable = new QTableWidget(ui->loggerWidget); ui->loggerWidget->layout()->addWidget(loggerTable); loggerTable->setColumnCount(5); @@ -660,8 +667,8 @@ void M3KTE::onReadReady() arg(reply->errorString()). arg(reply->error(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr), - reply->errorString(), ++Boards[Adr].error_RX, - QString::number(reply->error(), 16)); + reply->errorString(), ++Boards[Adr].error_RX, + QString::number(reply->error(), 16)); } reply->deleteLater(); } @@ -676,10 +683,12 @@ void M3KTE::onWriteButtonClicked() for(int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) { if(table == QModbusDataUnit::Coils) { - Boards[ui->boardSelectBox->currentIndex()].coil[i+writeUnit.startAddress()] = Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]; + Boards[ui->boardSelectBox->currentIndex()].coil[i+writeUnit.startAddress()] = + Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]; writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]); } else { - Boards[ui->boardSelectBox->currentIndex()].HR[i+writeUnit.startAddress()] = Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i+writeUnit.startAddress()]; + Boards[ui->boardSelectBox->currentIndex()].HR[i+writeUnit.startAddress()] = + Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i+writeUnit.startAddress()]; writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i + writeUnit.startAddress()]); } } @@ -794,11 +803,11 @@ bool M3KTE::event(QEvent *event) connect(reply, &QModbusReply::finished, this, [reply, this, _event, _unit]() { if(reply->error()==QModbusDevice::TimeoutError) { if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr)) { - if(!subreply->isFinished()) + if(!subreply->isFinished()) { connect(subreply, &QModbusReply::finished, this, [subreply, this, _event]() { checkAdrChange(subreply, _event->BoardNum()); }); - else { + } else { logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr), subreply->errorString(), ++Boards[_event->BoardNum()].error_adr_change, "Не удалось изменить адрес устройства. [1]"); @@ -869,176 +878,49 @@ void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum) //OK Boards[boardNum].adr = Boards[boardNum]._tmp_adr; reply->deleteLater(); - } - else { + } else { logError(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr), - reply->errorString(), - ++Boards[boardNum].error_adr_change, + reply->errorString(), ++Boards[boardNum].error_adr_change, "Ошибка при подтверждении изменения адреса устройства."); reply->deleteLater(); } } -/* -void M3KTE::onSpeedUpdate() -{ - stopScanBoard(); - QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1); - QModbusDataUnit* _unitcheck = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); - _unit->setValue(0, m_deviceSettingsDialog->currentSpeed()); - unsigned tmp_speed = 0; - 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; - } - modbusDevice->setTimeout(500); - for(int i = 0; i < 4; i++) { - if(!Boards[i].isActive) { - continue; - } - if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr)) { - QEventLoop loop; - connect(reply, &QModbusReply::finished, &loop, &QEventLoop::quit); - loop.exec(); - if(reply->error()==QModbusDevice::TimeoutError) { - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - tmp_speed); - modbusDevice->connectDevice(); - if(auto *subreply = modbusDevice->sendReadRequest(*_unitcheck, Boards[i].adr)) { - QEventLoop subloop; - connect(subreply, &QModbusReply::finished, &subloop, &QEventLoop::quit); - subloop.exec(); - if(subreply->error() != QModbusDevice::NoError) { - 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); - loggerTable->setItem(newRow, 2, new QTableWidgetItem(subreply->errorString())); - loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_baud_change, 10))); - loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при подтверждении изменения скорости обмена.")); - loggerTable->resizeColumnsToContents(); - if(!loggerTable->verticalScrollBar()->isSliderDown()) - loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); - subreply->deleteLater(); - } else { - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - m_settingsDialog->UpdateBaud(m_deviceSettingsDialog->currentSpeed())); - modbusDevice->connectDevice(); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - beginScanBoards(); - return; - } - } else { - 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); - loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString())); - loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_baud_change, 10))); - loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при отправке подтверждения изменения скорости обмена.")); - loggerTable->resizeColumnsToContents(); - if(!loggerTable->verticalScrollBar()->isSliderDown()) - loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); - } - } else { - 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); - loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString())); - loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_baud_change, 10))); - loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении скорости обмена.")); - loggerTable->resizeColumnsToContents(); - if(!loggerTable->verticalScrollBar()->isSliderDown()) - loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); - delete reply; // broadcast replies return immediately - } - } - } - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - m_settingsDialog->curBaud()); - modbusDevice->connectDevice(); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - beginScanBoards(); -} -*/ void M3KTE::checkBoards() { QModbusDataUnit unitCheck(QModbusDataUnit::InputRegisters, 85, 1); - int totalActiveBoards = 0; - int confirmedBoards = 0; - - QSet pendingBoards; + // Используем shared pointers вместо ссылок на стековые переменные + auto totalActiveBoards = QSharedPointer::create(0); + auto confirmedBoards = QSharedPointer::create(0); + auto pendingBoards = QSharedPointer>::create(); for(int i = 0; i < 4; ++i) { if(!Boards[i].isActive) continue; - - totalActiveBoards++; + (*totalActiveBoards)++; int slaveAddress = Boards[i].adr; - QModbusReply *reply = modbusDevice->sendReadRequest(unitCheck, slaveAddress); if(!reply) { revertToOldSpeedAndRestart(); return; } + pendingBoards->insert(slaveAddress); - pendingBoards.insert(slaveAddress); - - connect(reply, &QModbusReply::finished, this, [this, i, reply, slaveAddress, &confirmedBoards, &pendingBoards, totalActiveBoards]() mutable { + connect(reply, &QModbusReply::finished, this, + [this, i, reply, slaveAddress, totalActiveBoards, confirmedBoards, pendingBoards]() { if(reply->error() == QModbusDevice::NoError) { - confirmedBoards++; + (*confirmedBoards)++; } else { logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAddress), reply->errorString(), ++Boards[i].error_baud_change, "Ошибка при подтверждении изменения скорости обмена."); } - - pendingBoards.remove(slaveAddress); + pendingBoards->remove(slaveAddress); reply->deleteLater(); - if(pendingBoards.isEmpty()) { - if(confirmedBoards != totalActiveBoards) { + if(pendingBoards->isEmpty()) { + if(*confirmedBoards != *totalActiveBoards) { emit errorAtCheckBoards(); } else { emit successAtCheckBoards(); @@ -1046,8 +928,9 @@ void M3KTE::checkBoards() } }); } + // Если нет ни одной активной платы — сразу запускаем сканирование - if(totalActiveBoards == 0) { + if(*totalActiveBoards == 0) { emit errorAtCheckBoards(); } } @@ -1056,34 +939,18 @@ void M3KTE::onSpeedUpdate() { stopScanBoard(); modbusDevice->setTimeout(500); - unsigned tmp_speed = 0; 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; + 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) { logError(tr("Программная ошибка"), "Неожиданное значение скорости", 0, "Ошибка при изменении скорости обмена."); @@ -1091,27 +958,63 @@ void M3KTE::onSpeedUpdate() return; } - int totalActiveBoards = 0; - int confirmedBoards = 0; - - QSet pendingBoards; + // Используем shared pointers вместо ссылок на стековые переменные + auto totalActiveBoards = QSharedPointer::create(0); + auto confirmedBoards = QSharedPointer::create(0); + auto pendingBoards = QSharedPointer>::create(); + auto newSpeed = tmp_speed; // копируем для захвата QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 173, 1); unit.setValue(0, m_deviceSettingsDialog->currentSpeed()); + // Лямбда для обработки результата + auto processResult = [this, totalActiveBoards, confirmedBoards, newSpeed]() { + if(*confirmedBoards != *totalActiveBoards) { + modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); + revertToOldSpeedAndRestart(); + beginScanBoards(); + } else { + modbusDevice->disconnectDevice(); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, newSpeed); + modbusDevice->connectDevice(); + + // Используем QPointer для безопасного доступа к this + QPointer safeThis(this); + + connect(this, &M3KTE::errorAtCheckBoards, this, [safeThis]() { + if (!safeThis) return; + safeThis->disconnect(safeThis, &M3KTE::errorAtCheckBoards, safeThis, nullptr); + safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime); + safeThis->revertToOldSpeedAndRestart(); + safeThis->beginScanBoards(); + }); + + connect(this, &M3KTE::successAtCheckBoards, this, [safeThis]() { + if (!safeThis) return; + safeThis->disconnect(safeThis, &M3KTE::successAtCheckBoards, safeThis, nullptr); + safeThis->m_settingsDialog->UpdateBaud(safeThis->m_deviceSettingsDialog->currentSpeed()); + safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime); + safeThis->beginScanBoards(); + }); + + checkBoards(); + } + }; + for(int i = 0; i < 4; i++) { if(!Boards[i].isActive) continue; - int slaveAdress = Boards[i].adr; - auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress); if(reply) { - totalActiveBoards++; - pendingBoards.insert(slaveAdress); - connect(reply, &QModbusReply::finished, this, [this, i, reply, slaveAdress, &confirmedBoards, &pendingBoards, totalActiveBoards, tmp_speed]() mutable { + (*totalActiveBoards)++; + pendingBoards->insert(slaveAdress); + + // Захватываем shared pointers по значению - это безопасно + connect(reply, &QModbusReply::finished, this, + [this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() { if(reply->error() == QModbusDevice::TimeoutError) { - confirmedBoards++; + (*confirmedBoards)++; } else if (reply->error() == QModbusDevice::NoError) { logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress), tr("Неожиданный ответ."), ++Boards[i].error_baud_change, @@ -1121,31 +1024,11 @@ void M3KTE::onSpeedUpdate() reply->errorString(), ++Boards[i].error_baud_change, "Ошибка при изменении скорости обмена."); } - pendingBoards.remove(slaveAdress); + pendingBoards->remove(slaveAdress); reply->deleteLater(); - if(pendingBoards.isEmpty()) { - if(confirmedBoards != totalActiveBoards) { - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - revertToOldSpeedAndRestart(); - beginScanBoards(); - } else { - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, tmp_speed); - modbusDevice->connectDevice(); - connect(this, &M3KTE::errorAtCheckBoards, this, [this]() { - disconnect(this, &M3KTE::errorAtCheckBoards, this, nullptr); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - revertToOldSpeedAndRestart(); - beginScanBoards(); - }); - connect(this, &M3KTE::successAtCheckBoards, this, [this]() { - disconnect(this, &M3KTE::successAtCheckBoards, this, nullptr); - m_settingsDialog->UpdateBaud(m_deviceSettingsDialog->currentSpeed()); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - beginScanBoards(); - }); - checkBoards(); - } + + if(pendingBoards->isEmpty()) { + processResult(); } }); } @@ -1162,105 +1045,10 @@ void M3KTE::revertToOldSpeedAndRestart() modbusDevice->connectDevice(); } -//void M3KTE::onParityUpdate() -//{ -// stopScanBoard(); -// QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 174, 1); -// switch(m_deviceSettingsDialog->currentParity()) { -// case 0: //Нет контроля -// _unit->setValue(0, 0x000); -// break; -// case 1: //Четный -// _unit->setValue(0, 0x0400); -// break; -// case 2: //Нечетный -// _unit->setValue(0, 0x0600); -// break; -// } -// for(int i = 0; i < 4; i++) { -// if(!Boards[i].isActive) { -// continue; -// } -// if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr)) { -// QEventLoop loop; -// connect(reply, &QModbusReply::finished, &loop, &QEventLoop::quit); -// loop.exec(); // Ожидает завершения reply без блокировки интерфейса -// if(reply->error()==QModbusDevice::TimeoutError) { -// modbusDevice->disconnectDevice(); -// modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, -// m_deviceSettingsDialog->currentParity()); -// modbusDevice->connectDevice(); -// QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); -// if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) { -// QEventLoop subloop; -// connect(subreply, &QModbusReply::finished, &subloop, &QEventLoop::quit); -// subloop.exec(); // Ожидает завершения subreply без блокировки интерфейса -// if(subreply->error() != QModbusDevice::NoError) { -// 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); -// loggerTable->setItem(newRow, 2, new QTableWidgetItem(subreply->errorString())); -// loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_parity_change))); -// loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении чётности платы.")); -// loggerTable->resizeColumnsToContents(); -// if(!loggerTable->verticalScrollBar()->isSliderDown()) -// loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); -// } -// } else { -// 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); -// loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString())); -// loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_parity_change))); -// loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении чётности платы.")); -// loggerTable->resizeColumnsToContents(); -// if(!loggerTable->verticalScrollBar()->isSliderDown()) -// loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); -// } -// modbusDevice->disconnectDevice(); -// modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, -// m_settingsDialog->curParity()); -// modbusDevice->connectDevice(); -// } else { -// 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); -// loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString())); -// loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_parity_change))); -// loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении чётности платы.")); -// loggerTable->resizeColumnsToContents(); -// if(!loggerTable->verticalScrollBar()->isSliderDown()) -// loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); -// } -// } else { -// 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("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr))); -// loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString())); -// loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[i].error_parity_change))); -// loggerTable->setItem(newRow, 4, new QTableWidgetItem("Ошибка при изменении чётности платы.")); -// loggerTable->resizeColumnsToContents(); -// if(!loggerTable->verticalScrollBar()->isSliderDown()) -// loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum()); -// delete reply; // broadcast replies return immediately -// } -// } -// modbusDevice->disconnectDevice(); -// modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, -// m_settingsDialog->UpdateParity(m_deviceSettingsDialog->currentParity())); -// modbusDevice->connectDevice(); -// beginScanBoards(); -//} - void M3KTE::onParityUpdate() { stopScanBoard(); modbusDevice->setTimeout(500); - QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 174, 1); switch(m_deviceSettingsDialog->currentParity()) { case 0: //Нет контроля @@ -1274,61 +1062,73 @@ void M3KTE::onParityUpdate() break; } - int totalActiveBoards = 0; - int confirmedBoards = 0; + // Используем shared pointers вместо ссылок на стековые переменные + auto totalActiveBoards = QSharedPointer::create(0); + auto confirmedBoards = QSharedPointer::create(0); + auto pendingBoards = QSharedPointer>::create(); + auto oldParity = m_settingsDialog->curParity(); // сохраняем старую четность для отката + auto newParity = m_deviceSettingsDialog->currentParity(); - QSet pendingBoards; + // Лямбда для обработки результата + auto processResult = [this, totalActiveBoards, confirmedBoards, oldParity, newParity]() { + if(*confirmedBoards != *totalActiveBoards) { + modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); + beginScanBoards(); + } else { + modbusDevice->disconnectDevice(); + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, newParity); + modbusDevice->connectDevice(); + + auto errorHandler = [this, oldParity]() { + disconnect(this, &M3KTE::errorAtCheckBoards, this, nullptr); + modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); + modbusDevice->disconnectDevice(); + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, oldParity); + modbusDevice->connectDevice(); + beginScanBoards(); + }; + + auto successHandler = [this, newParity]() { + disconnect(this, &M3KTE::successAtCheckBoards, this, nullptr); + m_settingsDialog->UpdateParity(newParity); + modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); + beginScanBoards(); + }; + + connect(this, &M3KTE::errorAtCheckBoards, this, errorHandler); + connect(this, &M3KTE::successAtCheckBoards, this, successHandler); + + checkBoards(); + } + }; for(int i = 0; i < 4; i++) { if(!Boards[i].isActive) continue; - int slaveAdress = Boards[i].adr; - auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress); if(reply) { - totalActiveBoards++; - pendingBoards.insert(slaveAdress); - connect(reply, &QModbusReply::finished, this, [this, i, reply, slaveAdress, &confirmedBoards, &pendingBoards, totalActiveBoards]() mutable { + (*totalActiveBoards)++; + pendingBoards->insert(slaveAdress); + + connect(reply, &QModbusReply::finished, this, + [this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() { if(reply->error() == QModbusDevice::TimeoutError) { - confirmedBoards++; + (*confirmedBoards)++; } else if (reply->error() == QModbusDevice::NoError) { logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress), tr("Неожиданный ответ."), ++Boards[i].error_baud_change, "Ошибка при изменении чётности."); } else { logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress), - reply->errorString(), ++Boards[i].error_baud_change, - "Ошибка при изменении чётности."); + reply->errorString(), ++Boards[i].error_baud_change, + "Ошибка при изменении чётности."); } - pendingBoards.remove(slaveAdress); + pendingBoards->remove(slaveAdress); reply->deleteLater(); - if(pendingBoards.isEmpty()) { - if(confirmedBoards != totalActiveBoards) { - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - beginScanBoards(); - } else { - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, - m_deviceSettingsDialog->currentParity()); - modbusDevice->connectDevice(); - connect(this, &M3KTE::errorAtCheckBoards, this, [this](){ - disconnect(this, &M3KTE::errorAtCheckBoards, this, nullptr); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - modbusDevice->disconnectDevice(); - modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, - m_settingsDialog->curParity()); - modbusDevice->connectDevice(); - beginScanBoards(); - }); - connect(this, &M3KTE::successAtCheckBoards, this, [this](){ - disconnect(this, &M3KTE::successAtCheckBoards, this, nullptr); - m_settingsDialog->UpdateParity(m_deviceSettingsDialog->currentParity()); - modbusDevice->setTimeout(m_settingsDialog->settings().responseTime); - beginScanBoards(); - }); - checkBoards(); - } + + if(pendingBoards->isEmpty()) { + processResult(); } }); } @@ -1351,14 +1151,11 @@ bool M3KTE::pingNetworkDevices() bar->setMinimumDuration(100); bar->setValue(CurrentConnectedDevice); modbusDevice->setNumberOfRetries(0); - QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404")); QModbusRequest requestOfBoardID(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0401")); - modbusDevice->setTimeout(50); for(CurrentConnectedDevice=0; CurrentConnectedDevice<4;) { auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr); - //auto *reply = modbusDevice->sendReadRequest(*_unit, tmp_adr); //Запрос типа устройства. if(reply == nullptr) { onConnectClicked(); @@ -1389,9 +1186,9 @@ bool M3KTE::pingNetworkDevices() 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")) { auto *subreply = modbusDevice->sendRawRequest(requestOfBoardID, tmp_adr); + while(!subreply->isFinished()) { if(isRun && CurrentConnectedDevice < 1) { onConnectClicked(); @@ -1403,6 +1200,38 @@ bool M3KTE::pingNetworkDevices() } QCoreApplication::processEvents(); } + int plata_ind = 0; + if(subreply->rawResult().data().size() >= MODBUS_REQUEST_PROTOCOL_INFO_LENGTH) // ответ принят + plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH); // парс ответа + if(plata_ind == 0) // если номер = 0 повторяем всё еще раз + { + qDebug() << "Reqest plata_ind again for address " << tmp_adr; + subreply = modbusDevice->sendRawRequest(requestOfBoardID, tmp_adr); + + while(!subreply->isFinished()) { + if(isRun && CurrentConnectedDevice < 1) { + onConnectClicked(); + bar->close(); + bar->deleteLater(); + return false; + } else if(isRun) { + break; + } + QCoreApplication::processEvents(); + } + plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH); + } + if(plata_ind == 0) + { + QMessageBox::warning(this, "Ошибка при сканировании сети.", + QString("Не удалось получить порядковый номер платы по адресу %1").arg(tmp_adr)); + onConnectClicked(); + bar->close(); + bar->deleteLater(); + return false; + } + + int board_ind = plata_ind-1; if(isRun && CurrentConnectedDevice < 1) { onConnectClicked(); bar->close(); @@ -1411,19 +1240,21 @@ bool M3KTE::pingNetworkDevices() } else if(isRun) { break; } else { - //QString boardID(subreply->rawResult().data()); - //boardID.remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH); - if(Boards[(int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1].isActive) { - QMessageBox::warning(this, "Ошибка при сканировании сети.", QString("Платы по адресам %1 и %2 имеют одинаковый ID %3").arg(Boards[(int)subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH)].adr).arg(tmp_adr).arg((int)subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))); + statusBar()->showMessage(tr("Плата %1 найдена по адресу %2.").arg(board_ind).arg(tmp_adr), + m_settingsDialog->settings().responseTime); + if(Boards[board_ind].isActive) { + QMessageBox::warning(this, "Ошибка при сканировании сети.", + QString("Платы по адресам %1 и %2 имеют одинаковый порядковый номер %3").arg(Boards[board_ind].adr).arg(tmp_adr).arg(plata_ind)); onConnectClicked(); bar->close(); bar->deleteLater(); return false; } CurrentConnectedDevice++; - Boards[(int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1].adr = Boards[(int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1]._tmp_adr = tmp_adr; - statusBar()->showMessage(tr("Плата %1 найдена по адресу %2.").arg((int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1).arg(tmp_adr), m_settingsDialog->settings().responseTime); - Boards[(int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1].isActive = true; + Boards[board_ind].adr = Boards[board_ind]._tmp_adr = tmp_adr; + + + Boards[board_ind].isActive = true; bar->setValue(CurrentConnectedDevice); } } @@ -1434,7 +1265,8 @@ bool M3KTE::pingNetworkDevices() if(tmp_adr>=247 && (CurrentConnectedDevice<1)) { //ERROR //OUT OF RANGE - QMessageBox::warning(this, "Ошибка при сканировании сети.", QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(CurrentConnectedDevice)); + QMessageBox::warning(this, "Ошибка при сканировании сети.", + QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(CurrentConnectedDevice)); bar->setValue(4); bar->close(); bar->deleteLater(); @@ -1460,10 +1292,10 @@ bool M3KTE::pingNetworkDevices() _unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85); _unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85); _unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85); - for(int i=0; i<4; i++) { + for(int i = 0; i < 4; i++) { if(Boards[i].isActive) { Boards_Fields[i]->setEnabled(true); - for(int j = 0; j<3; j++) { + for(int j = 0; j < 3; j++) { bar->setValue(i*3+j); if(isRun) { onConnectClicked(); @@ -1480,7 +1312,8 @@ bool M3KTE::pingNetworkDevices() } while(!reply->isFinished()) { if(isRun) { - QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя.")); + QMessageBox::warning(this, "Ошибка при получении текущих настроек.", + QString("Прерывание по запросу пользователя.")); onConnectClicked(); bar->close(); bar->deleteLater(); @@ -1491,7 +1324,8 @@ bool M3KTE::pingNetworkDevices() if(reply->error()==QModbusDevice::NoError) { applySettingsFromScan(reply); } else { - QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Таймаут при опросе устройства %1 по адресу %2").arg(i+1).arg(Boards[i].adr)); + QMessageBox::warning(this, "Ошибка при получении текущих настроек.", + QString("Таймаут при опросе устройства %1 по адресу %2").arg(i+1).arg(Boards[i].adr)); bar->setValue(CurrentConnectedDevice*3); bar->close(); bar->deleteLater(); @@ -1512,7 +1346,7 @@ void M3KTE::beginScanBoards() { for(int i = 0; i < 4; i++) { if(Boards[i].isActive) { - m_deviceSettingsDialog->initPollForBoard(i+1, Boards[i].adr); + m_deviceSettingsDialog->initPollForBoard(i, Boards[i].adr); boardScan(i); } } @@ -1525,7 +1359,6 @@ void M3KTE::boardScan(unsigned boardID) return; QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); statusBar()->clearMessage(); - if(auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[boardID].adr)) { Boards[boardID].timerToStatusResponse.start(); if(!reply->isFinished()) @@ -1598,8 +1431,6 @@ void M3KTE::boardScan(unsigned boardID) delete reply; // broadcast replies return immediately } } else { - // QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID+1), QString(tr("Read error: ") + modbusDevice->errorString())); - // statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr), modbusDevice->errorString(), ++Boards[boardID].error_TX, ""); } @@ -1614,8 +1445,6 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID) bool W_Flag = false; bool A_Flag = false; if(unit.startAddress() != 0 || unit.valueCount() != 85) { - //ERROR - //QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID), QString("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount())); logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr), "Ошибка при приёме.", ++Boards[boardID].error_RX, tr("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount())); @@ -1627,7 +1456,7 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID) for(int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) { if(Boards[boardID].coil[i]==true) { int j = 0; - if(Boards[boardID].HR[i + 85] > unit.value(i)) { + if(Boards[boardID].HR[i+85] > unit.value(i)) { j = 1; if(j != m_ProgressBar[i+boardID*85]->value()) { A_Adr += tr("ТЭ%1 ").arg(i); @@ -1697,15 +1526,13 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID) } } else if(reply->error() == QModbusDevice::ProtocolError) { statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). - arg(reply->errorString()). - arg(reply->rawResult().exceptionCode(), -1, 16), 5000); + arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr), reply->errorString(), ++Boards[boardID].error_RX, QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)); } else { statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). - arg(reply->errorString()). - arg(reply->error(), -1, 16), 5000); + arg(reply->errorString()).arg(reply->error(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr), reply->errorString(), ++Boards[boardID].error_RX, QString::number(reply->error(), 16)); @@ -1739,15 +1566,13 @@ void M3KTE::applySettingsFromScan(QModbusReply *reply) } } else if(reply->error() == QModbusDevice::ProtocolError) { statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). - arg(reply->errorString()). - arg(reply->rawResult().exceptionCode(), -1, 16), 5000); + arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr), reply->errorString(), ++Boards[Adr].error_RX, QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)); } else { statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). - arg(reply->errorString()). - arg(reply->error(), -1, 16), 5000); + arg(reply->errorString()).arg(reply->error(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr), reply->errorString(), ++Boards[Adr].error_RX, QString::number(reply->error(), 16)); @@ -1792,8 +1617,7 @@ void M3KTE::multipleRegSend() connect(reply, &QModbusReply::finished, this, [this, reply, Adr]() { if(reply->error() == QModbusDevice::ProtocolError) { statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)") - .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), - 5000); + .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000); logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr), reply->errorString(), ++Boards[Adr].error_TX, QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)); @@ -1839,7 +1663,6 @@ bool M3KTE::autoBaudRateScan() unsigned countOfDeviceOnLine = 0; QString resultOfScan; QVector KTE[8]; - modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, m_settingsDialog->settings().portName); #if QT_CONFIG(modbus_serialport) @@ -1850,36 +1673,29 @@ bool M3KTE::autoBaudRateScan() modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, m_settingsDialog->settings().stopBits); #endif - modbusDevice->setTimeout(50); modbusDevice->setNumberOfRetries(0); uint m_baud[] = {9600, 14400, 19200, 31250, 38400, 56000, 57600, 115200}; - bool isRun = false; bool *tmp_isRun = &isRun; auto bar = new QProgressDialog(this); connect(bar, &QProgressDialog::canceled, this, [tmp_isRun]() { *tmp_isRun = true; }); - bar->setCancelButton(nullptr); bar->setRange(0, 8); bar->setMinimumDuration(100); bar->setValue(0); - QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404")); - for(int i = 0; i < 8; i++) { bar->setValue(i); bar->setLabelText(tr("Поиск плат... Текущая скорость: %1").arg(m_baud[i])); - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - m_baud[i]); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_baud[i]); if(!modbusDevice->connectDevice()) { statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000); } for(int tmp_adr = 1; tmp_adr < 248; tmp_adr++) { auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr); - //auto *reply = modbusDevice->sendReadRequest(*_unit, tmp_adr); //Запрос типа устройства. if(reply == nullptr) { onConnectClicked(); @@ -1906,7 +1722,6 @@ bool M3KTE::autoBaudRateScan() 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")) { countOfDeviceOnLine++; KTE[i].append(tmp_adr); @@ -1925,21 +1740,20 @@ bool M3KTE::autoBaudRateScan() 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) { - 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; } } } } - QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1); _unit->setValue(0, m_scanBoard->getBaud()); 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++) { - modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, - m_baud[i]); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_baud[i]); if(!modbusDevice->connectDevice()) { statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000); } @@ -1952,7 +1766,6 @@ bool M3KTE::autoBaudRateScan() } while(!reply->isFinished()) { if(isRun) { - //dfQMessageBox::warning(this, "Ошибка при синхронизации скоростей.", QString("Прерывание по запросу пользователя.")); onConnectClicked(); bar->close(); bar->deleteLater(); @@ -1969,7 +1782,6 @@ bool M3KTE::autoBaudRateScan() if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) { while(!subreply->isFinished()) { if(isRun) { - //dfQMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя.")); onConnectClicked(); bar->close(); bar->deleteLater(); @@ -1978,15 +1790,13 @@ bool M3KTE::autoBaudRateScan() QCoreApplication::processEvents(); } if(subreply->error()!=QModbusDevice::NoError) { - //QMessageBox::warning(); onConnectClicked(); bar->close(); bar->deleteLater(); return false; } } - } - else if(reply->error()!=QModbusDevice::NoError) { + } else if(reply->error()!=QModbusDevice::NoError) { return false; } modbusDevice->disconnectDevice(); @@ -2006,4 +1816,3 @@ void M3KTE::stopScanBoard() } return; } - diff --git a/M3KTE_TERM/m3kte.h b/M3KTE_TERM/m3kte.h index 6340046..c54d31e 100644 --- a/M3KTE_TERM/m3kte.h +++ b/M3KTE_TERM/m3kte.h @@ -56,52 +56,36 @@ private: void stopScanBoard(); void displayResultOfScan(QModbusReply *reply, int boardID); void applySettingsFromScan(QModbusReply *reply); - void multipleRegWrite(); void multipleRegSend(); - bool autoBaudRateScan(); - void selectPositionOnTree(unsigned index); - signals: void successAtCheckBoards(); void errorAtCheckBoards(); - private slots: void logError(const QString &errorPlace, const QString &errorString, unsigned errorCount, const QString &description); void slotmultipleRegWrite(); void slotmultipleRegWriteAndSend(); - void onConnectClicked(); - void onReadButtonClicked(); void onReadReady(); - void checkAdrChange(QModbusReply *reply, unsigned boardNum); - void onWriteButtonClicked(); void onSelectedBoardChanged(int index); void onWriteTableChanged(int index); - void checkBoards(); - void onSpeedUpdate(); void revertToOldSpeedAndRestart(); - void onParityUpdate(); - void boardScan(unsigned boardID); - public: M3KTE(QWidget *parent = nullptr); ~M3KTE(); - private: Ui::M3KTE *ui; QTableWidget *loggerTable = nullptr; int CurrentConnectedDevice = 0; - //int DeviceOnNetwork[4]; QProgressBar *m_ProgressBar[320]; QPushButton *ThePhantomMenace[320]; QModbusReply *lastRequest = nullptr; @@ -110,28 +94,20 @@ private: SettingsDialog *m_settingsDialog = nullptr; MultipleSettings *m_regMultipleSettings = nullptr; ScanBoard *m_scanBoard = nullptr; - LineRinger *m_lineRinger = nullptr; QGroupBox *Boards_Fields[4]; - //WriteRegisterModel *writeModel = nullptr; - struct StatusM3KTE{ bool Warnings[4]; bool Accidents[4]; }statusM3KTE; - unsigned error_terminal; - struct BoardModbusRegisters { bool isActive = false; bool pollIsActive = true; - int adr; int _tmp_adr; - bool coil[85]; unsigned HR[170]; - unsigned error_W = 0; unsigned error_A = 0; unsigned error_modbus = 0; @@ -141,19 +117,15 @@ private: unsigned error_TX = 0; unsigned error_adr_change = 0; unsigned error_cmd_change = 0; - QLabel *timerData = nullptr; QLabel *timerStatus = nullptr; - WriteRegisterModel *ModbusModelCoil; WriteRegisterModel *ModbusModelHoldingReg; QTimer *boardScanners; bool isScan = false; - QElapsedTimer timerToStatusResponse; QElapsedTimer timerToDataResponse; }Boards[4]; - union statusreg { struct parsingFields { unsigned accident:1; diff --git a/M3KTE_TERM/main.cpp b/M3KTE_TERM/main.cpp index 02d2da5..63a5649 100644 --- a/M3KTE_TERM/main.cpp +++ b/M3KTE_TERM/main.cpp @@ -4,6 +4,7 @@ int main(int argc, char *argv[]) { + qputenv("QT_FATAL_WARNINGS", "0"); // отключает падение от ASSERT QApplication a(argc, argv); M3KTE w; w.show(); diff --git a/M3KTE_TERM/multiplesettings.cpp b/M3KTE_TERM/multiplesettings.cpp index 8f7d678..ffcfeb0 100644 --- a/M3KTE_TERM/multiplesettings.cpp +++ b/M3KTE_TERM/multiplesettings.cpp @@ -6,7 +6,6 @@ MultipleSettings::MultipleSettings(QWidget *parent) : ui(new Ui::MultipleSettings) { ui->setupUi(this); - ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Записать"); ui->buttonBox->button(QDialogButtonBox::SaveAll)->setText("Записать и установить"); } @@ -58,7 +57,6 @@ void MultipleSettings::on_boardBox_currentIndexChanged(int index) break; default: ui->countBox->setRange(1, 85-ui->adrBox->value()+85*ui->regTypeBox->currentIndex()/2); - } } diff --git a/M3KTE_TERM/settingsdialog.cpp b/M3KTE_TERM/settingsdialog.cpp index c817d68..427d469 100644 --- a/M3KTE_TERM/settingsdialog.cpp +++ b/M3KTE_TERM/settingsdialog.cpp @@ -6,7 +6,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : ui(new Ui::SettingsDialog) { ui->setupUi(this); - ui->parityCombo->setCurrentIndex(0); #if QT_CONFIG(modbus_serialport) ui->baudCombo->setCurrentText(QString::number(m_settings.baud)); @@ -16,8 +15,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : #endif ui->timeoutSpinner->setValue(m_settings.responseTime); ui->retriesSpinner->setValue(m_settings.numberOfRetries); - - connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() { #if QT_CONFIG(modbus_serialport) m_settings.portName = ui->comBox->currentData().toString(); @@ -30,7 +27,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : #endif m_settings.responseTime = ui->timeoutSpinner->value(); m_settings.numberOfRetries = ui->retriesSpinner->value(); - hide(); }); } diff --git a/M3KTE_TERM/settingsdialog.h b/M3KTE_TERM/settingsdialog.h index de0de91..3716f38 100644 --- a/M3KTE_TERM/settingsdialog.h +++ b/M3KTE_TERM/settingsdialog.h @@ -24,7 +24,7 @@ public: int baud = 115200; int dataBits = QSerialPort::Data8; int stopBits = QSerialPort::OneStop; - int responseTime = 50; + int responseTime = 1000; int numberOfRetries = 0; }; diff --git a/M3KTE_TERM/writeregistermodel.cpp b/M3KTE_TERM/writeregistermodel.cpp index fbe9abc..98103f5 100644 --- a/M3KTE_TERM/writeregistermodel.cpp +++ b/M3KTE_TERM/writeregistermodel.cpp @@ -29,16 +29,12 @@ QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const Q_ASSERT(m_holdingRegisters.count() == RowCount); if (index.column() == NumColumn && role == Qt::DisplayRole) return QString::number(index.row()); - if (index.column() == NameColumn && role == Qt::DisplayRole) return QString("ТЭ%1").arg(index.row()%(RowCount/(1+isHR))+1); - if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked; - if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16)); - if(index.column() == CurrentUColumn && role == Qt::DisplayRole) return QString("%1 В").arg(QString::number((double)((double)m_currentU.at(index.row())/(double)1000), 'f', 3)); return QVariant(); @@ -73,7 +69,6 @@ bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value return false; Q_ASSERT(m_coils.count() == RowCount); Q_ASSERT(m_holdingRegisters.count() == RowCount); - if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils auto s = static_cast(value.toUInt()); s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row()); @@ -85,7 +80,6 @@ bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value quint16 newValue = value.toString().toUShort(&result, 16); if (result) m_holdingRegisters[index.row()] = newValue; - emit dataChanged(index, index); return result; } @@ -96,16 +90,13 @@ Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const { if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) return QAbstractTableModel::flags(index); - Qt::ItemFlags flags = QAbstractTableModel::flags(index); if ((index.row() < m_address) || (index.row() >= (m_address + m_number))) flags &= ~Qt::ItemIsEnabled; - if (index.column() == CoilsColumn) // coils return flags | Qt::ItemIsUserCheckable; if (index.column() == HoldingColumn) // holding registers return flags | Qt::ItemIsEditable; - return flags; } diff --git a/MZKT_Test_Terminal.exe b/MZKT_Test_Terminal.exe new file mode 100644 index 0000000..b7a30c7 Binary files /dev/null and b/MZKT_Test_Terminal.exe differ diff --git a/Release/release/M3KTE_TERM.exe b/Release/release/M3KTE_TERM.exe index 56e076e..f35b8d8 100644 Binary files a/Release/release/M3KTE_TERM.exe and b/Release/release/M3KTE_TERM.exe differ