Алгоритм изменения скорости обмена данными с платами. Пока без вывода ошибок в лог.

This commit is contained in:
Вячеслав Штейбезандт 2025-09-15 13:07:14 +03:00
parent d9f58e72e4
commit b4803e19e2
7 changed files with 176 additions and 295 deletions

Binary file not shown.

View File

@ -21,8 +21,7 @@ DeviceSettingsDialog::DeviceSettingsDialog(QWidget *parent) :
_currentParity = ui->parityBox->currentIndex();
for(int i = 0; i < 4; i++)
{
for(int i = 0; i < 4; i++) {
_currentAdrs[i] = i+1;
}
}
@ -81,16 +80,12 @@ void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, uns
if(tmp_parity>0)
tmp_parity--;
ui->parityBox->setCurrentIndex(_currentParity = tmp_parity);
for(int i = 0; i < 4; i++)
{
if(ActiveDevices[i])
{
for(int i = 0; i < 4; i++) {
if(ActiveDevices[i]) {
_m_timer[i]->setEnabled(true);
ui->idComboBox->addItem(QString::number(i));
_currentAdrs[i] = tmp_adr[i];
}
else
{
} else {
_m_timer[i]->setEnabled(false);
}
}
@ -121,8 +116,7 @@ void DeviceSettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
ui->parityBox->setCurrentIndex(0);
_currentParity = ui->parityBox->currentIndex();
for(int i = 0; i < 4; i++)
{
for(int i = 0; i < 4; i++) {
_currentAdrs[i] = i+1;
}
ui->adrSpinBox->setValue(_currentAdrs[ui->idComboBox->currentIndex()]);

View File

@ -8,8 +8,7 @@ LineRinger::LineRinger(QWidget *parent) :
ui->setupUi(this);
const auto listPorts = QSerialPortInfo::availablePorts();
for (const auto& port: listPorts)
{
for (const auto& port: listPorts) {
ui->comBox->addItem(QString(port.portName() + ": " + port.manufacturer()), QVariant(port.portName()));
}
@ -55,9 +54,9 @@ void LineRinger::syncColumnHeaders()
void LineRinger::on_connectButton_clicked()
{
if (!modbusDevice)
if(!modbusDevice)
return;
if (modbusDevice->state() != QModbusDevice::ConnectedState) {
if(modbusDevice->state() != QModbusDevice::ConnectedState) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
ui->comBox->currentData().toString());
#if QT_CONFIG(modbus_serialport)
@ -72,7 +71,7 @@ void LineRinger::on_connectButton_clicked()
#endif
modbusDevice->setTimeout(50);
modbusDevice->setNumberOfRetries(0);
if (!modbusDevice->connectDevice()) {
if(!modbusDevice->connectDevice()) {
QMessageBox::warning(this, "Ошибка", "Произошла ошибка при попытке подключения.");
} else {
ui->connectButton->setText(tr("Отключить"));
@ -94,105 +93,84 @@ 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, [this, tmp_isRun]() {
*tmp_isRun = true;
});
connect(this, &LineRinger::stopLineCall, this, [this, tmp_isRun]()
{
connect(this, &LineRinger::stopLineCall, this, [this, tmp_isRun]() {
*tmp_isRun = true;
});
bar->setLabelText(tr("Поиск устройств... Текущий адрес: %1").arg(tmp_adr));
bar->setCancelButton(nullptr);
bar->setRange(1, 247);
bar->setMinimumDuration(100);
for(tmp_adr = 1; tmp_adr<248; tmp_adr++)
{
for(tmp_adr = 1; tmp_adr<248; tmp_adr++) {
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)
{
if(reply == nullptr) {
QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1").arg(modbusDevice->errorString()));
bar->close();
bar->deleteLater();
return callStatus::ERROR;
}
while(!reply->isFinished())
{
if(isRun)
{
while(!reply->isFinished()) {
if(isRun) {
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
QCoreApplication::processEvents();
}
if(isRun)
{
if(isRun) {
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
else if (!isRun)
{
} else if(!isRun) {
//Нужна проверка типа устройства
if(reply->error()!=QModbusDevice::TimeoutError)
{
if(reply->error()!=QModbusDevice::TimeoutError) {
deviceOnLine currentDevice;
currentDevice.adr = tmp_adr;
currentDevice.baudRate = currentBaudRate;
bool regularReplyError = false;
QString regularReplyErrorString;
if(reply->error()==QModbusDevice::NoError)
{
if(reply->error()==QModbusDevice::NoError) {
QModbusResponse resp = reply->rawResult();
uint8_t numOfObject = resp.data().at(5);
QByteArray result = resp.data().remove(0, 6);
for(int tmp_obj = 0; tmp_obj < numOfObject; tmp_obj++)
{
for(int tmp_obj = 0; tmp_obj < numOfObject; tmp_obj++) {
uint8_t objectID = result.at(0);
uint8_t lengthOfObject = result.at(1);
if(lengthOfObject>0)
{
if(lengthOfObject>0) {
currentDevice.fields[objectID].clear();
}
for(int i = 0; i < lengthOfObject; i++)
{
for(int i = 0; i < lengthOfObject; i++) {
currentDevice.fields[objectID] += QString(result.at(2+i));
}
result.remove(0, lengthOfObject+2);
}
auto *regularReply = modbusDevice->sendRawRequest(readDeviceRegularIdentification, tmp_adr);
if(regularReply == nullptr)
{
if(regularReply == nullptr) {
QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1: %2").arg(modbusDevice->error()).arg(modbusDevice->errorString()));
bar->close();
bar->deleteLater();
return callStatus::ERROR;
}
while(!regularReply->isFinished())
{
if(isRun)
{
while(!regularReply->isFinished()) {
if(isRun) {
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
QCoreApplication::processEvents();
}
if(isRun)
{
if(isRun) {
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
else if(!isRun)
{
if(regularReply->error()!=QModbusDevice::NoError)
{
} else if(!isRun) {
if(regularReply->error()!=QModbusDevice::NoError) {
// QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1: %2").arg(regularReply->error()).arg(regularReply->errorString()));
// bar->close();
// bar->deleteLater();
@ -203,14 +181,12 @@ LineRinger::callStatus LineRinger::lineCall()
QModbusResponse regularResp = regularReply->rawResult();
uint8_t numOfRegularObject = regularResp.data().at(5);
QByteArray regularResult = regularResp.data().remove(0, 6);
for(int tmp_obj = 0; tmp_obj < numOfRegularObject; tmp_obj++)
{
for(int tmp_obj = 0; tmp_obj < numOfRegularObject; tmp_obj++) {
uint8_t objectID = regularResult.at(0);
if(objectID > 0x06)
continue;
uint8_t lengthOfObject = regularResult.at(1);
if(lengthOfObject>0)
{
if(lengthOfObject>0) {
currentDevice.fields[objectID].clear();
}
for (int i = 0; i < lengthOfObject; i++) {
@ -220,8 +196,7 @@ LineRinger::callStatus LineRinger::lineCall()
}
}
}
if(!isRun)
{
if(!isRun) {
devicesList.append(currentDevice);
unsigned newRow = ui->deviceOnlineView->rowCount();
ui->deviceOnlineView->insertRow(newRow);
@ -230,12 +205,9 @@ LineRinger::callStatus LineRinger::lineCall()
for (int i = 0; i < 7; i++) {
ui->deviceOnlineView->setItem(newRow, i+2, new QTableWidgetItem(currentDevice.fields[i]));
}
if(reply->error()!=QModbusDevice::NoError)
{
if(reply->error()!=QModbusDevice::NoError) {
ui->deviceOnlineView->setItem(newRow, 9, new QTableWidgetItem(QString("%1: %2").arg(reply->error()).arg(reply->errorString())));
}
else if(regularReplyError)
{
} else if(regularReplyError) {
ui->deviceOnlineView->setItem(newRow, 9, new QTableWidgetItem(regularReplyErrorString));
}
ui->deviceOnlineView->resizeColumnsToContents();
@ -254,16 +226,14 @@ void LineRinger::on_ringButton_clicked()
syncColumnHeaders();
while(ui->deviceOnlineView->rowCount()!=0)
ui->deviceOnlineView->removeRow(ui->deviceOnlineView->rowCount()-1);
if(isAutoBaud)
{
if(isAutoBaud) {
auto bar = new QProgressDialog(this);
bar->setLabelText(tr("Поиск устройств... Текущая скорость: %1").arg(currentBaudRate));
bar->setRange(0, ui->baudRateBox->count());
bar->setAutoClose(true);
bar->setMinimumDuration(0);
bar->setCancelButton(nullptr);
connect(bar, &QProgressDialog::canceled, this, [this]()
{
connect(bar, &QProgressDialog::canceled, this, [this]() {
emit stopLineCall();
});
bar->setValue(0);
@ -271,7 +241,6 @@ void LineRinger::on_ringButton_clicked()
ui->deviceOnlineView->setColumnHidden(1, false);
modbusDevice->disconnectDevice();
for (int i = 0; i < ui->baudRateBox->count(); i++) {
bar->setValue(i+1);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
@ -283,8 +252,7 @@ void LineRinger::on_ringButton_clicked()
}
currentBaudRate = ui->baudRateBox->itemText(i).toUInt(nullptr, 10);
bar->setLabelText(tr("Поиск устройств... Текущая скорость: %1").arg(currentBaudRate));
if(lineCall() == callStatus::INTERRUPT)
{
if(lineCall() == callStatus::INTERRUPT) {
QMessageBox::warning(this, "Уведомление", QString("Досрочное завершение опроса. Найдено %1 устройств.").arg(devicesList.count()));
modbusDevice->disconnectDevice();
on_connectButton_clicked();
@ -297,12 +265,9 @@ void LineRinger::on_ringButton_clicked()
modbusDevice->disconnectDevice();
}
on_connectButton_clicked();
}
else
{
} else {
ui->deviceOnlineView->setColumnHidden(1, true);
if(lineCall() == callStatus::INTERRUPT)
{
if(lineCall() == callStatus::INTERRUPT) {
QMessageBox::warning(this, "Уведомление", QString("Досрочное завершение опроса. Найдено %1 устройств.").arg(devicesList.count()));
}
}

View File

@ -353,8 +353,7 @@ M3KTE::M3KTE(QWidget *parent)
ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils);
ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters);
ui->writeTable->addItem(tr("Accidents"), QModbusDataUnit::HoldingRegisters);
for(int i = 0; i < 4; i++)
{
for(int i = 0; i < 4; i++) {
Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/3*20), false);
Boards[i].ModbusModelCoil->setStartAddress(0);
Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/3*20)));
@ -374,20 +373,16 @@ M3KTE::M3KTE(QWidget *parent)
Boards[1].boardScanners->setSingleShot(true);
Boards[2].boardScanners->setSingleShot(true);
Boards[3].boardScanners->setSingleShot(true);
connect(Boards[0].boardScanners, &QTimer::timeout, this, [this]()
{
connect(Boards[0].boardScanners, &QTimer::timeout, this, [this]() {
boardScan(0);
});
connect(Boards[1].boardScanners, &QTimer::timeout, this, [this]()
{
connect(Boards[1].boardScanners, &QTimer::timeout, this, [this]() {
boardScan(1);
});
connect(Boards[2].boardScanners, &QTimer::timeout, this, [this]()
{
connect(Boards[2].boardScanners, &QTimer::timeout, this, [this]() {
boardScan(2);
});
connect(Boards[3].boardScanners, &QTimer::timeout, this, [this]()
{
connect(Boards[3].boardScanners, &QTimer::timeout, this, [this]() {
boardScan(3);
});
Boards[0].adr = 1;
@ -426,13 +421,11 @@ M3KTE::M3KTE(QWidget *parent)
Boards[i].timerData->setText(" ");
Boards[i].timerStatus->setText(" ");;
}
for(int i = 0; i < 5; i++)
{
for(int i = 0; i < 5; i++) {
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);
@ -464,8 +457,7 @@ M3KTE::M3KTE(QWidget *parent)
M3KTE::~M3KTE()
{
if(modbusDevice->state() == QModbusDevice::ConnectedState)
{
if(modbusDevice->state() == QModbusDevice::ConnectedState) {
onConnectClicked();
}
delete ui;
@ -521,8 +513,7 @@ void M3KTE::onConnectClicked()
} else {
ui->ConnectionMenuConnect->setEnabled(false);
ui->ConnectionMenuDisconnect->setEnabled(true);
if(pingNetworkDevices()) //Опрос устройств
{
if(pingNetworkDevices()) { //Опрос устройств
unsigned tmp_adr[4];
bool ActiveDevices[4];
for(int i = 0; i < 4; i++) {
@ -546,13 +537,11 @@ void M3KTE::onConnectClicked()
}
} else {
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
for(int i = 0; i < 4; i++)
{
for(int i = 0; i < 4; i++) {
Boards[i].boardScanners->stop();
Boards_Fields[i]->setEnabled(false);
Boards[i].isActive=false;
for(int j = 0; j < (85 - (i/3*20)); j++)
{
for(int j = 0; j < (85 - (i/3*20)); j++) {
Boards[i].coil[j] = false;
Boards[i].ModbusModelCoil->m_coils[j]=0;
Boards[i].ModbusModelHoldingReg->m_currentU[j]=0;
@ -563,8 +552,7 @@ void M3KTE::onConnectClicked()
Boards[i].timerData->setText(" ");;
Boards[i].timerStatus->setText(" ");;
}
for(int i = 0; i < 320; i++)
{
for(int i = 0; i < 320; i++) {
m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
m_ProgressBar[i]->setWhatsThis(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
m_ProgressBar[i]->setValue(3);
@ -609,10 +597,8 @@ void M3KTE::onReadReady()
if(!reply)
return;
int Adr = 255;
for(int i = 0; i < 4; i++)
{
if(Boards[i].isActive && Boards[i].adr==reply->serverAddress())
{
for(int i = 0; i < 4; i++) {
if(Boards[i].isActive && Boards[i].adr==reply->serverAddress()) {
Adr = i;
break;
}
@ -620,16 +606,13 @@ void M3KTE::onReadReady()
if(reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
for(int i = 0, total = int(unit.valueCount()); i < total; ++i) {
if(unit.registerType() == QModbusDataUnit::Coils)
{
if(unit.registerType() == QModbusDataUnit::Coils) {
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
if(unit.value(i)==1)
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
else
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole);
}
else if(unit.registerType() == QModbusDataUnit::HoldingRegisters)
{
} else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) {
Boards[Adr].HR[i + unit.startAddress()] = unit.value(i);
Boards[Adr].ModbusModelHoldingReg->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 3), QString::number(unit.value(i), 16), Qt::EditRole);
}
@ -690,9 +673,7 @@ void M3KTE::onWriteButtonClicked()
{
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
{
} else {
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()]);
}
@ -768,8 +749,7 @@ void M3KTE::changeTable(int board, int tabletype)
}
ui->writeValueTable->hideColumn(3);
ui->writeValueTable->showColumn(2);
}
else {
} else {
ui->writeValueTable->setModel(Boards[board].ModbusModelHoldingReg);
if(tabletype==1) {
Boards[board].ModbusModelHoldingReg->setStartAddress(0);
@ -780,8 +760,7 @@ void M3KTE::changeTable(int board, int tabletype)
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true);
}
}
else {
} else {
Boards[board].ModbusModelHoldingReg->setStartAddress(Boards[board].ModbusModelHoldingReg->rowCount()/2);
int i = 0;
for(;i<Boards[board].ModbusModelHoldingReg->rowCount()/2;i++) {
@ -862,8 +841,7 @@ bool M3KTE::event(QEvent *event)
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
}
}
else {
} else {
unsigned newRow = loggerTable->rowCount();
loggerTable->insertRow(newRow);
loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
@ -891,8 +869,7 @@ bool M3KTE::event(QEvent *event)
reply->deleteLater();
delete reply;
}
}
else {
} else {
unsigned newRow = loggerTable->rowCount();
loggerTable->insertRow(newRow);
loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
@ -907,8 +884,7 @@ bool M3KTE::event(QEvent *event)
}
m_deviceSettingsDialog->show();
return true;
}
else if(event->type() == (QEvent::Type)1001) {
} else if(event->type() == (QEvent::Type)1001) {
pollStatusChange* _event = static_cast<pollStatusChange*>(event);
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 170, 1);
_unit->setValue(0, _event->Status());
@ -928,8 +904,7 @@ bool M3KTE::event(QEvent *event)
reply->deleteLater();
}
});
}
else {
} else {
unsigned newRow = loggerTable->rowCount();
loggerTable->insertRow(newRow);
loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
@ -1104,11 +1079,67 @@ void M3KTE::onSpeedUpdate()
}
*/
void M3KTE::checkBoards()
{
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) {
emit errorAtCheckBoards();
} else {
emit successAtCheckBoards();
}
}
});
}
// Если нет ни одной активной платы — сразу запускаем сканирование
if(totalActiveBoards == 0) {
emit errorAtCheckBoards();
}
}
void M3KTE::onSpeedUpdate()
{
stopScanBoard();
modbusDevice->setTimeout(500);
unsigned tmp_speed = 0;
switch(m_deviceSettingsDialog->currentSpeed()) {
case 0:
tmp_speed = 9600;
@ -1149,145 +1180,57 @@ void M3KTE::onSpeedUpdate()
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)
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 173, 1);
unit.setValue(0, m_deviceSettingsDialog->currentSpeed());
for(int i = 0; i < 4; i++) {
if(!Boards[i].isActive)
continue;
totalActiveBoards++;
int slaveAddress = Boards[i].adr;
int slaveAdress = 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) {
auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress);
if(reply) {
totalActiveBoards++;
pendingBoards.insert(slaveAdress);
connect(reply, &QModbusReply::finished, this, [this, reply, slaveAdress, &confirmedBoards, &pendingBoards, totalActiveBoards, tmp_speed]() mutable {
if(reply->error() == QModbusDevice::TimeoutError) {
confirmedBoards++;
} else {
}
} else {
}
pendingBoards.remove(slaveAddress);
reply->deleteLater();
if (pendingBoards.isEmpty()) {
if (confirmedBoards != totalActiveBoards) {
revertToOldSpeedAndRestart();
beginScanBoards();
} else {
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
beginScanBoards();
pendingBoards.remove(slaveAdress);
reply->deleteLater();
if(pendingBoards.isEmpty()) {
if(confirmedBoards != totalActiveBoards) {
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
revertToOldSpeedAndRestart();
beginScanBoards();
} else {
// Переключаемся на tmp_speed
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);
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
beginScanBoards();
});
checkBoards();
}
}
}
});
}
// Если нет ни одной активной платы — сразу запускаем сканирование
if (totalActiveBoards == 0) {
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
beginScanBoards();
});
}
}
}
@ -1362,8 +1305,7 @@ void M3KTE::onParityUpdate()
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
m_settingsDialog->curParity());
modbusDevice->connectDevice();
}
else {
} else {
unsigned newRow = loggerTable->rowCount();
loggerTable->insertRow(newRow);
loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
@ -1829,7 +1771,6 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID)
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else {
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()).

View File

@ -63,6 +63,12 @@ private:
bool autoBaudRateScan();
void selectPositionOnTree(unsigned index);
signals:
void successAtCheckBoards();
void errorAtCheckBoards();
private slots:
void slotmultipleRegWrite();
@ -79,15 +85,15 @@ private slots:
void onSelectedBoardChanged(int index);
void onWriteTableChanged(int index);
void checkBoards();
void onSpeedUpdate();
void revertToOldSpeedAndRestart();
void onParityUpdate();
void boardScan(unsigned boardID);
void handleSpeedChangeReply(QModbusReply *reply, int boardIndex);
void onAllSpeedChangeRepliesReceived();
void revertToOldSpeedAndRestart();
public:
M3KTE(QWidget *parent = nullptr);
~M3KTE();
@ -117,8 +123,7 @@ private:
unsigned error_terminal;
struct BoardModbusRegisters
{
struct BoardModbusRegisters {
bool isActive = false;
bool pollIsActive = true;
@ -150,10 +155,8 @@ private:
QElapsedTimer timerToDataResponse;
}Boards[4];
union statusreg
{
struct parsingFields
{
union statusreg {
struct parsingFields {
unsigned accident:1;
unsigned warning:1;
unsigned poll_allowed:1;
@ -163,17 +166,5 @@ 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

View File

@ -18,28 +18,21 @@ MultipleSettings::~MultipleSettings()
void MultipleSettings::on_buttonBox_clicked(QAbstractButton *button)
{
if(button == ui->buttonBox->button(QDialogButtonBox::Ok))
{
if(button == ui->buttonBox->button(QDialogButtonBox::Ok)) {
newValue = ui->regValueLine->text().toInt(nullptr, 16);
typeReg = ui->regTypeBox->currentIndex();
startAdr = ui->adrBox->value();
countReg = ui->countBox->value();
boardId = ui->boardBox->currentIndex();
emit write();
}
else if (button == ui->buttonBox->button(QDialogButtonBox::SaveAll))
{
} else if (button == ui->buttonBox->button(QDialogButtonBox::SaveAll)) {
newValue = ui->regValueLine->text().toInt(nullptr, 16);
typeReg = ui->regTypeBox->currentIndex();
startAdr = ui->adrBox->value();
countReg = ui->countBox->value();
boardId = ui->boardBox->currentIndex();
emit writeAndSend();
}
else
{
}
} else {}
}
void MultipleSettings::on_regTypeBox_currentIndexChanged(int index)

View File

@ -54,11 +54,9 @@ int SettingsDialog::UpdateBaud(int baud)
int SettingsDialog::UpdateParity(int parity)
{
ui->parityCombo->setCurrentIndex(parity);
if(parity>0)
{
if(parity>0) {
return (m_settings.parity = ++parity);
}
else {
} else {
return (m_settings.parity = parity);
}
}
@ -77,8 +75,7 @@ void SettingsDialog::on_updateComBox_clicked()
{
ui->comBox->clear();
const auto listPorts = QSerialPortInfo::availablePorts();
for (const auto& port: listPorts)
{
for (const auto& port: listPorts) {
ui->comBox->addItem(QString(port.portName() + ": " + port.manufacturer()), QVariant(port.portName()));
}
}