4 Commits

Author SHA1 Message Date
Вячеслав Штейбезандт
7dc314d266 Fix & update
> Исправлено окно настроек (Период опроса плат и раздел сетевого адреса)
> Исправлено значение Odd Parity при передаче
> Добавлена возможность остановить опрос платы

Добавлен модуль LineRinger для опроса Modbus устройств.
2025-03-12 11:05:14 +03:00
Вячеслав Штейбезандт
568ec9b5d3 Third checkpoint 2025-01-23 17:17:45 +03:00
Вячеслав Штейбезандт
009ac176f9 Second checkpoint 2025-01-23 17:10:34 +03:00
Вячеслав Штейбезандт
1b7388821e Checkpoint to git test 2025-01-23 17:05:06 +03:00
20 changed files with 13154 additions and 11488 deletions

21
Debug/.qmake.stash Normal file
View File

@@ -0,0 +1,21 @@
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 7
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 3
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 0
QMAKE_CXX.COMPILER_MACROS = \
QT_COMPILER_STDCXX \
QMAKE_GCC_MAJOR_VERSION \
QMAKE_GCC_MINOR_VERSION \
QMAKE_GCC_PATCH_VERSION
QMAKE_CXX.INCDIRS = \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++ \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/i686-w64-mingw32 \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include/c++/backward \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0/include-fixed \
C:/Qt/Qt5.14.2/Tools/mingw730_32/i686-w64-mingw32/include
QMAKE_CXX.LIBDIRS = \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc/i686-w64-mingw32/7.3.0 \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib/gcc \
C:/Qt/Qt5.14.2/Tools/mingw730_32/i686-w64-mingw32/lib \
C:/Qt/Qt5.14.2/Tools/mingw730_32/lib

BIN
Debug/debug/M3KTE_TERM.exe Normal file

Binary file not shown.

View File

@@ -16,6 +16,9 @@ CONFIG += c++11
# deprecated API in order to know how to port your code away from it. # deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DEPRECATED_WARNINGS
TEMPLATE = lib
DEFINES += M3KTE_LIBRARY
# You can also make your code fail to compile if it uses deprecated APIs. # You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line. # In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt. # You can also select to disable deprecated APIs only up to a certain version of Qt.
@@ -23,26 +26,37 @@ DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \ SOURCES += \
devicesettingsdialog.cpp \ devicesettingsdialog.cpp \
lineringer.cpp \
main.cpp \ main.cpp \
m3kte.cpp \ m3kte.cpp \
multiplesettings.cpp \ multiplesettings.cpp \
scanboard.cpp \
settingsdialog.cpp \ settingsdialog.cpp \
writeregistermodel.cpp writeregistermodel.cpp
HEADERS += \ HEADERS += \
devicesettingsdialog.h \ devicesettingsdialog.h \
lineringer.h \
m3kte.h \ m3kte.h \
multiplesettings.h \ multiplesettings.h \
scanboard.h \
settingsdialog.h \ settingsdialog.h \
writeregistermodel.h writeregistermodel.h
FORMS += \ FORMS += \
devicesettingsdialog.ui \ devicesettingsdialog.ui \
lineringer.ui \
m3kte.ui \ m3kte.ui \
multiplesettings.ui \ multiplesettings.ui \
scanboard.ui \
settingsdialog.ui settingsdialog.ui
# Default rules for deployment. # Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin #qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin #else: unix:!android: target.path = /opt/$${TARGET}/bin
#!isEmpty(target.path): INSTALLS += target
unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target

View File

@@ -55,7 +55,7 @@ void DeviceSettingsDialog::on_buttonApplyChangeParity_clicked()
void DeviceSettingsDialog::on_buttonApplyChangeAdr_clicked() void DeviceSettingsDialog::on_buttonApplyChangeAdr_clicked()
{ {
BoardIdHasBeenChanged* _boardIdHasBeenChanged = new BoardIdHasBeenChanged(ui->idComboBox->currentIndex(), ui->adrSpinBox->value()); BoardIdHasBeenChanged* _boardIdHasBeenChanged = new BoardIdHasBeenChanged(ui->idComboBox->currentText().toUInt(), ui->adrSpinBox->value());
QCoreApplication::postEvent(parent(), _boardIdHasBeenChanged); QCoreApplication::postEvent(parent(), _boardIdHasBeenChanged);
close(); close();
} }
@@ -75,22 +75,25 @@ unsigned short DeviceSettingsDialog::currentParity()
return _currentParity; return _currentParity;
} }
void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, int CurrentConnectedDevice) void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, bool *ActiveDevices)
{ {
ui->speedBox->setCurrentText(QString::number(_currentSpeed=tmp_speed, 10)); ui->speedBox->setCurrentText(QString::number(_currentSpeed=tmp_speed, 10));
if(tmp_parity>0) if(tmp_parity>0)
tmp_parity--; tmp_parity--;
ui->parityBox->setCurrentIndex(_currentParity = tmp_parity); ui->parityBox->setCurrentIndex(_currentParity = tmp_parity);
for(int i = 0; i < CurrentConnectedDevice; i++) for(int i = 0; i < 4; i++)
{
if(ActiveDevices[i])
{ {
_m_timer[i]->setEnabled(true); _m_timer[i]->setEnabled(true);
ui->idComboBox->addItem(QString::number(i)); ui->idComboBox->addItem(QString::number(i));
_currentAdrs[i] = tmp_adr[i]; _currentAdrs[i] = tmp_adr[i];
} }
for(int i = CurrentConnectedDevice; i < 4; i++) else
{ {
_m_timer[i]->setEnabled(false); _m_timer[i]->setEnabled(false);
} }
}
on_idComboBox_currentIndexChanged(ui->idComboBox->currentIndex()); on_idComboBox_currentIndexChanged(ui->idComboBox->currentIndex());
} }
@@ -129,3 +132,25 @@ void DeviceSettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
break; break;
} }
} }
void DeviceSettingsDialog::initPollForBoard(unsigned boardID, unsigned boardAdr)
{
ui->idPollComboBox->addItem(QString("Плата №%1 (ID %2)").arg(boardID).arg(boardAdr), QVariant(boardID));
}
void DeviceSettingsDialog::updatePollStatus(unsigned boardID, bool status)
{
_currentPollStatus[boardID] = status;
}
void DeviceSettingsDialog::on_buttonApplyChangePoll_clicked()
{
updatePollStatus(ui->idPollComboBox->currentData().toUInt(), (bool)ui->pollStatusBox->currentIndex());
pollStatusChange* _pollStatusChanged = new pollStatusChange(ui->idPollComboBox->currentData().toUInt(), _currentPollStatus[ui->idPollComboBox->currentData().toUInt()]);
QCoreApplication::postEvent(parent(), _pollStatusChanged);
}
void DeviceSettingsDialog::on_idPollComboBox_currentIndexChanged(int index)
{
ui->pollStatusBox->setCurrentIndex(_currentPollStatus[ui->idPollComboBox->currentData().toUInt()]);
}

View File

@@ -21,6 +21,20 @@ private:
short _BoardNewID; short _BoardNewID;
}; };
class pollStatusChange : public QEvent
{
public:
pollStatusChange(unsigned BoardID, bool Stat) : QEvent((QEvent::Type)1001) {_BoardID = BoardID; _Status = Stat;}
~pollStatusChange() {}
unsigned BoardID() const {return _BoardID;}
bool Status() const {return _Status;}
private:
unsigned _BoardID;
bool _Status;
};
namespace Ui { namespace Ui {
class DeviceSettingsDialog; class DeviceSettingsDialog;
} }
@@ -36,7 +50,9 @@ public:
unsigned currentBoardTimer(unsigned short _ID); unsigned currentBoardTimer(unsigned short _ID);
unsigned currentSpeed(); unsigned currentSpeed();
unsigned short currentParity(); unsigned short currentParity();
void updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, int CurrentConnectedDevice); void updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, bool *ActiveDevices);
void updatePollStatus(unsigned boardID, bool status);
void initPollForBoard(unsigned boardID, unsigned boardAdr);
signals: signals:
void parityChanged(); void parityChanged();
void speedChanged(); void speedChanged();
@@ -59,12 +75,17 @@ private slots:
void on_buttonBox_clicked(QAbstractButton *button); void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonApplyChangePoll_clicked();
void on_idPollComboBox_currentIndexChanged(int index);
private: private:
QSpinBox *_m_timer[4]; QSpinBox *_m_timer[4];
unsigned _currentBoardTimers[4]; unsigned _currentBoardTimers[4];
unsigned _currentSpeed; unsigned _currentSpeed;
unsigned short _currentParity; unsigned short _currentParity;
unsigned _currentAdrs[4]; unsigned _currentAdrs[4];
bool _currentPollStatus[4];
Ui::DeviceSettingsDialog *ui; Ui::DeviceSettingsDialog *ui;
}; };

View File

@@ -6,77 +6,14 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>243</width> <width>278</width>
<height>431</height> <height>500</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Dialog</string> <string>Dialog</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_4"> <layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Скорость обмена</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QPushButton" name="buttonApplyChangeSpeed">
<property name="text">
<string>Применить</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="speedBox">
<property name="currentIndex">
<number>3</number>
</property>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>14400</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>31250</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
<item>
<property name="text">
<string>56000</string>
</property>
</item>
<item>
<property name="text">
<string>57600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
@@ -188,6 +125,41 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>Контроль четности</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="1">
<widget class="QPushButton" name="buttonApplyChangeParity">
<property name="text">
<string>Применить</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="parityBox">
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Even</string>
</property>
</item>
<item>
<property name="text">
<string>Odd</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QGroupBox" name="groupBox_3"> <widget class="QGroupBox" name="groupBox_3">
<property name="title"> <property name="title">
@@ -221,7 +193,70 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Скорость обмена</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="1">
<widget class="QPushButton" name="buttonApplyChangeSpeed">
<property name="text">
<string>Применить</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="speedBox">
<property name="currentIndex">
<number>3</number>
</property>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>14400</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>31250</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
<item>
<property name="text">
<string>56000</string>
</property>
</item>
<item>
<property name="text">
<string>57600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@@ -231,38 +266,36 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="4" column="0">
<widget class="QGroupBox" name="groupBox_4"> <widget class="QGroupBox" name="groupBox_5">
<property name="title"> <property name="title">
<string>Контроль четности</string> <string>Опрос ТЭ</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout_5"> <layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QComboBox" name="idPollComboBox"/>
</item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QPushButton" name="buttonApplyChangeParity"> <widget class="QComboBox" name="pollStatusBox">
<item>
<property name="text">
<string>Вкл</string>
</property>
</item>
<item>
<property name="text">
<string>Выкл</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="buttonApplyChangePoll">
<property name="text"> <property name="text">
<string>Применить</string> <string>Применить</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QComboBox" name="parityBox">
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Even</string>
</property>
</item>
<item>
<property name="text">
<string>Odd</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

315
M3KTE_TERM/lineringer.cpp Normal file
View File

@@ -0,0 +1,315 @@
#include "lineringer.h"
#include "ui_lineringer.h"
LineRinger::LineRinger(QWidget *parent) :
QWidget(parent),
ui(new Ui::LineRinger)
{
ui->setupUi(this);
const auto listPorts = QSerialPortInfo::availablePorts();
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->deviceOnlineView->horizontalHeader()->setVisible(true);
syncColumnHeaders();
ui->deviceOnlineView->setColumnHidden(1, true);
ui->ringButton->setEnabled(false);
modbusDevice = new QModbusRtuSerialMaster(this);
}
LineRinger::~LineRinger()
{
if (modbusDevice->state() == QModbusDevice::ConnectedState)
on_connectButton_clicked();
delete ui;
}
void LineRinger::syncColumnHeaders()
{
QStringList headers;
headers << "ID" << "BaudRate" << "Vendor Name" << "Product Code" << "Major Minor Revision" << "Vendor Url" << "Product Name" << "Model Name" << "User Application Name" << "Примечание";
ui->deviceOnlineView->setHorizontalHeaderLabels(headers);
ui->deviceOnlineView->resizeColumnsToContents();
}
void LineRinger::on_connectButton_clicked()
{
if (!modbusDevice)
return;
if (modbusDevice->state() != QModbusDevice::ConnectedState) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
ui->comBox->currentData().toString());
#if QT_CONFIG(modbus_serialport)
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
ui->parityControlBox->currentData().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
ui->baudRateBox->currentText().toInt(nullptr, 10));
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
ui->dataBox->currentData().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
ui->stopBox->currentData().toInt());
#endif
modbusDevice->setTimeout(50);
modbusDevice->setNumberOfRetries(0);
if (!modbusDevice->connectDevice()) {
QMessageBox::warning(this, "Ошибка", "Произошла ошибка при попытке подключения.");
} else {
ui->connectButton->setText(tr("Отключить"));
ui->ringButton->setEnabled(true);
currentBaudRate = ui->baudRateBox->currentText().toUInt(nullptr, 10);
}
} else {
modbusDevice->disconnectDevice();
ui->connectButton->setText(tr("Подключить"));
ui->ringButton->setEnabled(false);
}
}
LineRinger::callStatus LineRinger::lineCall()
{
QModbusRequest readDeviceBasicIdentification(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0100"));
QModbusRequest readDeviceRegularIdentification(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0200"));
bool isRun = false;
bool *tmp_isRun = &isRun;
uint tmp_adr = 1;
auto bar = new QProgressDialog(this);
connect(bar, &QProgressDialog::canceled, this, [this, tmp_isRun]()
{
*tmp_isRun = true;
});
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++)
{
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()));
bar->close();
bar->deleteLater();
return callStatus::ERROR;
}
while(!reply->isFinished())
{
if(isRun)
{
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
QCoreApplication::processEvents();
}
if(isRun)
{
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
else if (!isRun)
{
//Нужна проверка типа устройства
if(reply->error()!=QModbusDevice::TimeoutError)
{
deviceOnLine currentDevice;
currentDevice.adr = tmp_adr;
currentDevice.baudRate = currentBaudRate;
bool regularReplyError = false;
QString regularReplyErrorString;
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++)
{
uint8_t objectID = result.at(0);
uint8_t lengthOfObject = result.at(1);
if(lengthOfObject>0)
{
currentDevice.fields[objectID].clear();
}
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)
{
QMessageBox::warning(this, "Ошибка при сканировании.", QString("%1: %2").arg(modbusDevice->error()).arg(modbusDevice->errorString()));
bar->close();
bar->deleteLater();
return callStatus::ERROR;
}
while(!regularReply->isFinished())
{
if(isRun)
{
bar->close();
bar->deleteLater();
return callStatus::INTERRUPT;
}
QCoreApplication::processEvents();
}
if(isRun)
{
bar->close();
bar->deleteLater();
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());
}
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++)
{
uint8_t objectID = regularResult.at(0);
if(objectID > 0x06)
continue;
uint8_t lengthOfObject = regularResult.at(1);
if(lengthOfObject>0)
{
currentDevice.fields[objectID].clear();
}
for (int i = 0; i < lengthOfObject; i++) {
currentDevice.fields[objectID] += QString(regularResult.at(2+i));
}
regularResult.remove(0, lengthOfObject+2);
}
}
}
if(!isRun)
{
devicesList.append(currentDevice);
unsigned newRow = ui->deviceOnlineView->rowCount();
ui->deviceOnlineView->insertRow(newRow);
ui->deviceOnlineView->setItem(newRow, 0, new QTableWidgetItem(QString::number(currentDevice.adr)));
ui->deviceOnlineView->setItem(newRow, 1, new QTableWidgetItem(QString::number(currentDevice.baudRate)));
for (int i = 0; i < 7; i++) {
ui->deviceOnlineView->setItem(newRow, i+2, new QTableWidgetItem(currentDevice.fields[i]));
}
if(reply->error()!=QModbusDevice::NoError)
{
ui->deviceOnlineView->setItem(newRow, 9, new QTableWidgetItem(QString("%1: %2").arg(reply->error()).arg(reply->errorString())));
}
else if(regularReplyError)
{
ui->deviceOnlineView->setItem(newRow, 9, new QTableWidgetItem(regularReplyErrorString));
}
ui->deviceOnlineView->resizeColumnsToContents();
syncColumnHeaders();
}
}
}
}
return callStatus::NOERROR;
}
void LineRinger::on_ringButton_clicked()
{
ui->deviceOnlineView->clear();
devicesList.clear();
syncColumnHeaders();
while(ui->deviceOnlineView->rowCount()!=0)
ui->deviceOnlineView->removeRow(ui->deviceOnlineView->rowCount()-1);
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]()
{
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()) {
QMessageBox::warning(this, "Ошибка", "Произошла ошибка при попытке подключения.");
on_connectButton_clicked();
break;
}
currentBaudRate = ui->baudRateBox->itemText(i).toUInt(nullptr, 10);
if(lineCall() == callStatus::INTERRUPT)
{
QMessageBox::warning(this, "Уведомление", QString("Досрочное завершение опроса. Найдено %1 устройств.").arg(devicesList.count()));
modbusDevice->disconnectDevice();
on_connectButton_clicked();
bar->close();
bar->deleteLater();
ui->timer->setTime(QTime::currentTime());
ui->timer->setDate(QDate::currentDate());
return;
}
modbusDevice->disconnectDevice();
}
on_connectButton_clicked();
}
else
{
ui->deviceOnlineView->setColumnHidden(1, true);
if(lineCall() == callStatus::INTERRUPT)
{
QMessageBox::warning(this, "Уведомление", QString("Досрочное завершение опроса. Найдено %1 устройств.").arg(devicesList.count()));
}
}
ui->timer->setTime(QTime::currentTime());
ui->timer->setDate(QDate::currentDate());
}
void LineRinger::on_checkAutoBaud_stateChanged(int arg1)
{
isAutoBaud = (bool)arg1;
}

59
M3KTE_TERM/lineringer.h Normal file
View File

@@ -0,0 +1,59 @@
#ifndef LINERINGER_H
#define LINERINGER_H
#include <QWidget>
#include <QModbusTcpClient>
#include <QModbusRtuSerialMaster>
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QMessageBox>
#include <QProgressDialog>
namespace Ui {
class LineRinger;
}
class LineRinger : public QWidget
{
Q_OBJECT
public:
enum callStatus{
NOERROR = 0,
ERROR = 1,
INTERRUPT = 2
};
explicit LineRinger(QWidget *parent = nullptr);
~LineRinger();
callStatus lineCall();
signals:
void stopLineCall();
private slots:
void on_connectButton_clicked();
void on_ringButton_clicked();
void on_checkAutoBaud_stateChanged(int arg1);
private:
Ui::LineRinger *ui;
void syncColumnHeaders();
struct deviceOnLine
{
uint8_t adr;
unsigned baudRate;
QString fields[7] = {"Undefined", "Undefined", "Undefined", "Undefined", "Undefined", "Undefined", "Undefined"};
};
QVector<deviceOnLine>devicesList;
bool isAutoBaud = false;
unsigned currentBaudRate;
QModbusClient *modbusDevice = nullptr;
};
#endif // LINERINGER_H

303
M3KTE_TERM/lineringer.ui Normal file
View File

@@ -0,0 +1,303 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LineRinger</class>
<widget class="QWidget" name="LineRinger">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>939</width>
<height>522</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QGroupBox" name="gridGroupBox_2">
<layout class="QGridLayout" name="cmdLayout">
<item row="4" column="1">
<widget class="QLabel" name="labelTimer">
<property name="text">
<string>Последний опрос:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="ringButton">
<property name="text">
<string>Опросить</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkAutoBaud">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Любая скорость</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QDateTimeEdit" name="timer">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="keyboardTracking">
<bool>true</bool>
</property>
<property name="currentSection">
<enum>QDateTimeEdit::DaySection</enum>
</property>
<property name="displayFormat">
<string>dd.MM.yyyy HH:mm:ss</string>
</property>
<property name="calendarPopup">
<bool>false</bool>
</property>
<property name="currentSectionIndex">
<number>0</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="controlGroup">
<layout class="QGridLayout" name="controlLaylout">
<item row="0" column="5">
<widget class="QLabel" name="labelStopBit">
<property name="text">
<string>Стоп-биты</string>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QPushButton" name="connectButton">
<property name="text">
<string>Подключить</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLabel" name="labelEvenControl">
<property name="text">
<string>Чётность</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QComboBox" name="stopBox"/>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="comBox">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="pushButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="text">
<string>Поиск</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="parityControlBox"/>
</item>
<item row="1" column="3">
<widget class="QComboBox" name="baudRateBox">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>14400</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>31250</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
<item>
<property name="text">
<string>56000</string>
</property>
</item>
<item>
<property name="text">
<string>57600</string>
</property>
</item>
<item>
<property name="text">
<string>115200</string>
</property>
</item>
</widget>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="dataBox"/>
</item>
<item row="0" column="3">
<widget class="QLabel" name="labelBaud">
<property name="text">
<string>Скорость</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="labelCom">
<property name="text">
<string>Порт</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="labelDataBit">
<property name="text">
<string>Биты данных</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="3">
<widget class="QTableWidget" name="deviceOnlineView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="textElideMode">
<enum>Qt::ElideMiddle</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="columnCount">
<number>10</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderCascadingSectionResizes">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderShowSortIndicator" stdset="0">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<column>
<property name="text">
<string>BaudRate</string>
</property>
</column>
<column>
<property name="text">
<string>Vendor Name</string>
</property>
</column>
<column>
<property name="text">
<string>Product Code</string>
</property>
</column>
<column>
<property name="text">
<string>Major Minor Revision</string>
</property>
</column>
<column>
<property name="text">
<string>Vendor Url</string>
</property>
</column>
<column>
<property name="text">
<string>Product Name</string>
</property>
</column>
<column>
<property name="text">
<string>Model Name</string>
</property>
</column>
<column>
<property name="text">
<string>User Application Name</string>
</property>
</column>
<column>
<property name="text">
<string>Примечание</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -9,6 +9,14 @@
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QStatusBar> #include <QStatusBar>
#include <QUrl> #include <QUrl>
#include <QScrollBar>
#include <QTableWidget>
QWidget* init(QWidget *parent)
{
return new M3KTE(parent);
}
//1024 768 //1024 768
//Ширина колбы - уже //Ширина колбы - уже
@@ -17,7 +25,6 @@ M3KTE::M3KTE(QWidget *parent)
, ui(new Ui::M3KTE) , ui(new Ui::M3KTE)
{ {
ui->setupUi(this); ui->setupUi(this);
//Массив указателей на индикаторы напряжения топливных элементов //Массив указателей на индикаторы напряжения топливных элементов
{ {
int i = 0; int i = 0;
@@ -342,14 +349,10 @@ M3KTE::M3KTE(QWidget *parent)
m_ProgressBar[i++] = ui->FuelCellVoltageBar_319; m_ProgressBar[i++] = ui->FuelCellVoltageBar_319;
m_ProgressBar[i++] = ui->FuelCellVoltageBar_320; m_ProgressBar[i++] = ui->FuelCellVoltageBar_320;
} }
m_settingsDialog = new SettingsDialog(this); m_settingsDialog = new SettingsDialog(this);
ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils); ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils);
ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters); ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters);
ui->writeTable->addItem(tr("Accidents"), 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 = new WriteRegisterModel(this, 85 - (i/3*20), false);
@@ -359,57 +362,86 @@ M3KTE::M3KTE(QWidget *parent)
Boards[i].ModbusModelHoldingReg->setStartAddress(0); Boards[i].ModbusModelHoldingReg->setStartAddress(0);
Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/3*20))); Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/3*20)));
} }
m_deviceSettingsDialog = new DeviceSettingsDialog(this); m_deviceSettingsDialog = new DeviceSettingsDialog(this);
m_regMultipleSettings = new MultipleSettings(this); m_regMultipleSettings = new MultipleSettings(this);
modbusDevice = new QModbusRtuSerialMaster(this); modbusDevice = new QModbusRtuSerialMaster(this);
//ui->M3kteRegSettings->setEnabled(false); m_lineRinger = new LineRinger();
Boards[0].boardScanners = new QTimer(); Boards[0].boardScanners = new QTimer();
Boards[1].boardScanners = new QTimer(); Boards[1].boardScanners = new QTimer();
Boards[2].boardScanners = new QTimer(); Boards[2].boardScanners = new QTimer();
Boards[3].boardScanners = new QTimer(); Boards[3].boardScanners = new QTimer();
Boards[0].boardScanners->setSingleShot(true); Boards[0].boardScanners->setSingleShot(true);
Boards[1].boardScanners->setSingleShot(true); Boards[1].boardScanners->setSingleShot(true);
Boards[2].boardScanners->setSingleShot(true); Boards[2].boardScanners->setSingleShot(true);
Boards[3].boardScanners->setSingleShot(true); Boards[3].boardScanners->setSingleShot(true);
connect(Boards[0].boardScanners, &QTimer::timeout, this, [this]()
connect(Boards[0].boardScanners, &QTimer::timeout, this, &M3KTE::firstBoardScan); {
connect(Boards[1].boardScanners, &QTimer::timeout, this, &M3KTE::secondBoardScan); boardScan(0);
connect(Boards[2].boardScanners, &QTimer::timeout, this, &M3KTE::thirdBoardScan); });
connect(Boards[3].boardScanners, &QTimer::timeout, this, &M3KTE::fourthBoardScan); connect(Boards[1].boardScanners, &QTimer::timeout, this, [this]()
{
boardScan(1);
});
connect(Boards[2].boardScanners, &QTimer::timeout, this, [this]()
{
boardScan(2);
});
connect(Boards[3].boardScanners, &QTimer::timeout, this, [this]()
{
boardScan(3);
});
Boards[0].adr = 1; Boards[0].adr = 1;
Boards[1].adr = 2; Boards[1].adr = 2;
Boards[2].adr = 3; Boards[2].adr = 3;
Boards[3].adr = 4; Boards[3].adr = 4;
//ui->M3kteMenuSettings->setEnabled(false);
ui->M3kteRegSettings->setEnabled(false);
ui->BSM_Warning->setEnabled(false); ui->BSM_Warning->setEnabled(false);
ui->BSM_Accident->setEnabled(false); ui->BSM_Accident->setEnabled(false);
ui->BSM_WorkInProgress->setEnabled(false); ui->BSM_WorkInProgress->setEnabled(false);
initActions(); initActions();
ui->BST_Off->setChecked(true); ui->BST_Off->setChecked(true);
ui->boardSelectBox->setCurrentIndex(0); ui->boardSelectBox->setCurrentIndex(0);
ui->writeTable->setCurrentIndex(0); ui->writeTable->setCurrentIndex(0);
changeTable(0, 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;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
statusM3KTE.Warnings[i] = false; statusM3KTE.Warnings[i] = false;
statusM3KTE.Accidents[i] = false; statusM3KTE.Accidents[i] = false;
Boards_Fields[i]->setEnabled(false);
Boards[i].timerData->setText(" ");
Boards[i].timerStatus->setText(" ");;
}
for (int i = 0; i < 5; i++)
{
ui->writeValueTable->resizeColumnToContents(i);
} }
QBrush tb(Qt::transparent); // Transparent brush, solid pattern 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);
m_ProgressBar[i]->resize(25, 25);
m_ProgressBar[i]->setAlignment(Qt::AlignCenter);
m_ProgressBar[i]->setFormat(QString("%1").arg((i%85+1)));
m_ProgressBar[i]->setValue(3); m_ProgressBar[i]->setValue(3);
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} "; QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
m_ProgressBar[i]->setStyleSheet(style_fc_off); m_ProgressBar[i]->setStyleSheet(style_fc_off);
ThePhantomMenace[i] = new QPushButton(m_ProgressBar[i]); ThePhantomMenace[i] = new QPushButton(m_ProgressBar[i]);
ThePhantomMenace[i]->setFlat(true); ThePhantomMenace[i]->setFlat(true);
ThePhantomMenace[i]->setPalette(QPalette(tb, tb, tb, tb, tb, tb, tb, tb, tb)); ThePhantomMenace[i]->setPalette(QPalette(tb, tb, tb, tb, tb, tb, tb, tb, tb));
@@ -417,16 +449,17 @@ M3KTE::M3KTE(QWidget *parent)
selectPositionOnTree(i); selectPositionOnTree(i);
}); });
} }
debug();
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::parityChanged, this, &M3KTE::onParityUpdate); connect(m_deviceSettingsDialog, &DeviceSettingsDialog::parityChanged, this, &M3KTE::onParityUpdate);
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::speedChanged, this, &M3KTE::onSpeedUpdate); connect(m_deviceSettingsDialog, &DeviceSettingsDialog::speedChanged, this, &M3KTE::onSpeedUpdate);
loggerTable = new QTableWidget(ui->loggerWidget);
//Вызов окна настройки подключения ui->loggerWidget->layout()->addWidget(loggerTable);
loggerTable->setColumnCount(5);
//Вызов окна настройки устройства QStringList headers;
headers << "Время" << "Плата" << "Тип ошибки" << "Счётчик" << "Примечание";
loggerTable->setHorizontalHeaderLabels(headers);
loggerTable->setSortingEnabled(true);
loggerTable->setAutoScroll(true);
} }
M3KTE::~M3KTE() M3KTE::~M3KTE()
@@ -438,56 +471,11 @@ M3KTE::~M3KTE()
delete ui; delete ui;
} }
void M3KTE::debug()
{
srand(time(0));
for(int i = 0; i < 320; i++)
{
m_ProgressBar[i]->setTextVisible(true);
m_ProgressBar[i]->setMinimumSize(25, 25);
m_ProgressBar[i]->setMaximumSize(25, 25);
m_ProgressBar[i]->resize(25, 25);
m_ProgressBar[i]->setAlignment(Qt::AlignCenter);
m_ProgressBar[i]->setFormat(QString("%1").arg((i%85+1)));
// int j = rand()%4;
// if(j!=3) j=rand()%4;
// m_ProgressBar[i]->setValue(j);
// QString style_fc = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(j*50-50) + ", 255, 255, 100%);} ";
// QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
// m_ProgressBar[i]->setStyleSheet(style_fc);
// switch (j) {
// case 1:
// {
// m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(i/85+1), QString::number(i%85)));
// break;
// }
// case 2:
// {
// m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(i/85+1), QString::number(i%85)));
// break;
// }
// case 3:
// {
// m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Уровень напряжения в норме.").arg(QString::number(i/85+1), QString::number(i%85)));
// break;
// }
// case 0:
// m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
// m_ProgressBar[i]->setStyleSheet(style_fc_off);
// m_ProgressBar[i]->setValue(3);
// break;
// }
}
}
void M3KTE::initActions() void M3KTE::initActions()
{ {
ui->ConnectionMenuConnect->setEnabled(true); ui->ConnectionMenuConnect->setEnabled(true);
ui->ConnectionMenuDisconnect->setEnabled(false); ui->ConnectionMenuDisconnect->setEnabled(false);
ui->ConnectionMenuSettings->setEnabled(true); ui->ConnectionMenuSettings->setEnabled(true);
connect(ui->ConnectionMenuConnect, &QAction::triggered, connect(ui->ConnectionMenuConnect, &QAction::triggered,
this, &M3KTE::onConnectClicked); this, &M3KTE::onConnectClicked);
connect(ui->ConnectionMenuDisconnect, &QAction::triggered, connect(ui->ConnectionMenuDisconnect, &QAction::triggered,
@@ -500,11 +488,10 @@ void M3KTE::initActions()
this, &M3KTE::onSelectedBoardChanged); this, &M3KTE::onSelectedBoardChanged);
connect(ui->writeTable, QOverload<int>::of(&QComboBox::currentIndexChanged), connect(ui->writeTable, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &M3KTE::onWriteTableChanged); this, &M3KTE::onWriteTableChanged);
connect(ui->LineCall, &QAction::triggered, m_lineRinger, &QWidget::show);
connect(ui->M3kteRegSettings, &QAction::triggered, m_regMultipleSettings, &QDialog::show); connect(ui->M3kteRegSettings, &QAction::triggered, m_regMultipleSettings, &QDialog::show);
connect(m_regMultipleSettings, &MultipleSettings::write, this, &M3KTE::slotmultipleRegWrite); connect(m_regMultipleSettings, &MultipleSettings::write, this, &M3KTE::slotmultipleRegWrite);
connect(m_regMultipleSettings, &MultipleSettings::writeAndSend, this, &M3KTE::slotmultipleRegWriteAndSend); connect(m_regMultipleSettings, &MultipleSettings::writeAndSend, this, &M3KTE::slotmultipleRegWriteAndSend);
connect(ui->ConnectionMenuSettings, &QAction::triggered, m_settingsDialog, &QDialog::show); connect(ui->ConnectionMenuSettings, &QAction::triggered, m_settingsDialog, &QDialog::show);
connect(ui->M3kteMenuSettings, &QAction::triggered, m_deviceSettingsDialog, &QDialog::show); connect(ui->M3kteMenuSettings, &QAction::triggered, m_deviceSettingsDialog, &QDialog::show);
} }
@@ -513,7 +500,6 @@ void M3KTE::onConnectClicked()
{ {
if (!modbusDevice) if (!modbusDevice)
return; return;
statusBar()->clearMessage(); statusBar()->clearMessage();
if (modbusDevice->state() != QModbusDevice::ConnectedState) { if (modbusDevice->state() != QModbusDevice::ConnectedState) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
@@ -535,37 +521,47 @@ void M3KTE::onConnectClicked()
} else { } else {
ui->ConnectionMenuConnect->setEnabled(false); ui->ConnectionMenuConnect->setEnabled(false);
ui->ConnectionMenuDisconnect->setEnabled(true); ui->ConnectionMenuDisconnect->setEnabled(true);
if(pingNetworkDevices()) //Опрос устройств
if(pingNetworkDevices())
{ {
unsigned tmp_adr[4]; unsigned tmp_adr[4];
bool ActiveDevices[4];
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
tmp_adr[i] = Boards[i].adr; tmp_adr[i] = Boards[i].adr;
ActiveDevices[i] = Boards[i].isActive;
} }
ui->M3kteRegSettings->setEnabled(true); ui->M3kteRegSettings->setEnabled(true);
m_deviceSettingsDialog->updateSettingsAfterConnection(m_settingsDialog->settings().baud, m_settingsDialog->settings().parity, tmp_adr, ActiveDevices);
m_deviceSettingsDialog->updateSettingsAfterConnection(m_settingsDialog->settings().baud, m_settingsDialog->settings().parity, tmp_adr, CurrentConnectedDevice);
ui->boardSelectBox->setCurrentIndex(0); ui->boardSelectBox->setCurrentIndex(0);
ui->writeTable->setCurrentIndex(0); ui->writeTable->setCurrentIndex(0);
changeTable(0, 0); changeTable(0, 0);
ui->M3kteMenuSettings->setEnabled(true);
ui->M3kteRegSettings->setEnabled(true);
ui->BST_Off->setChecked(false); ui->BST_Off->setChecked(false);
ui->BST_On->setChecked(true); ui->BST_On->setChecked(true);
ui->BSM_Warning->setEnabled(true); ui->BSM_Warning->setEnabled(true);
ui->BSM_Accident->setEnabled(true); ui->BSM_Accident->setEnabled(true);
ui->BSM_WorkInProgress->setEnabled(true); ui->BSM_WorkInProgress->setEnabled(true);
ui->BSM_WorkInProgress->setChecked(true); ui->BSM_WorkInProgress->setChecked(true);
} }
//Опрос устройств
} }
} else { } else {
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} "; 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[i].boardScanners->stop();
Boards_Fields[i]->setEnabled(false);
Boards[i].isActive=false;
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;
Boards[i].ModbusModelHoldingReg->m_holdingRegisters[j] = 0;
Boards[i].ModbusModelHoldingReg->m_holdingRegisters[j + (85 - (i/3*20))] = 0;
}
Boards_Fields[i]->setTitle(QString("Плата №%1").arg(i));
Boards[i].timerData->setText(" ");;
Boards[i].timerStatus->setText(" ");;
} }
for(int i = 0; i < 320; i++) for(int i = 0; i < 320; i++)
{ {
@@ -574,21 +570,19 @@ void M3KTE::onConnectClicked()
m_ProgressBar[i]->setValue(3); m_ProgressBar[i]->setValue(3);
m_ProgressBar[i]->setStyleSheet(style_fc_off); m_ProgressBar[i]->setStyleSheet(style_fc_off);
} }
modbusDevice->disconnectDevice(); modbusDevice->disconnectDevice();
ui->M3kteMenuSettings->setEnabled(false);
ui->M3kteRegSettings->setEnabled(false);
ui->ConnectionMenuConnect->setEnabled(true); ui->ConnectionMenuConnect->setEnabled(true);
ui->ConnectionMenuDisconnect->setEnabled(false); ui->ConnectionMenuDisconnect->setEnabled(false);
ui->BST_Off->setChecked(true); ui->BST_Off->setChecked(true);
ui->BST_On->setChecked(false); ui->BST_On->setChecked(false);
ui->BSM_Warning->setChecked(false); ui->BSM_Warning->setChecked(false);
ui->BSM_Accident->setChecked(false); ui->BSM_Accident->setChecked(false);
ui->BSM_WorkInProgress->setChecked(false); ui->BSM_WorkInProgress->setChecked(false);
ui->BSM_Warning->setEnabled(false); ui->BSM_Warning->setEnabled(false);
ui->BSM_Accident->setEnabled(false); ui->BSM_Accident->setEnabled(false);
ui->BSM_WorkInProgress->setEnabled(false); ui->BSM_WorkInProgress->setEnabled(false);
ui->M3kteRegSettings->setEnabled(false); ui->M3kteRegSettings->setEnabled(false);
} }
} }
@@ -597,10 +591,7 @@ void M3KTE::onReadButtonClicked()
{ {
if (!modbusDevice) if (!modbusDevice)
return; return;
//ui->readValue->clear();
statusBar()->clearMessage(); statusBar()->clearMessage();
if (auto *reply = modbusDevice->sendReadRequest(readRequest(), Boards[ui->boardSelectBox->currentIndex()].adr)) { if (auto *reply = modbusDevice->sendReadRequest(readRequest(), Boards[ui->boardSelectBox->currentIndex()].adr)) {
if (!reply->isFinished()) if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady); connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady);
@@ -609,22 +600,6 @@ void M3KTE::onReadButtonClicked()
} else { } else {
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
} }
// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {
// if (!reply->isFinished())
// connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady);
// else
// delete reply; // broadcast replies return immediately
// } else {
// statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
// }
// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {
// if (!reply->isFinished())
// connect(reply, &QModbusReply::finished, this, &M3KTE::onReadReady);
// else
// delete reply; // broadcast replies return immediately
// } else {
// statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
// }
} }
void M3KTE::onReadReady() void M3KTE::onReadReady()
@@ -632,23 +607,20 @@ void M3KTE::onReadReady()
auto reply = qobject_cast<QModbusReply *>(sender()); auto reply = qobject_cast<QModbusReply *>(sender());
if (!reply) if (!reply)
return; return;
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
int Adr = 255; int Adr = 255;
for(int i = 0; i < CurrentConnectedDevice; i++) for(int i = 0; i < 4; i++)
{ {
if(Boards[i].adr==reply->serverAddress()) if(Boards[i].isActive && Boards[i].adr==reply->serverAddress())
{ {
Adr = i; Adr = i;
break; break;
} }
} }
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
for (int i = 0, total = int(unit.valueCount()); i < total; ++i) { for (int i = 0, total = int(unit.valueCount()); i < total; ++i) {
//ui->readValue->addItem(entry);
if(unit.registerType() == QModbusDataUnit::Coils) if(unit.registerType() == QModbusDataUnit::Coils)
{ {
//QStandardItem *item = ui->writeValueTable->model()->item
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i); Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
if(unit.value(i)==1) if(unit.value(i)==1)
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole); Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
@@ -665,12 +637,31 @@ void M3KTE::onReadReady()
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16), 5000); arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_RX, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->rawResult().exceptionCode(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else { } else {
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->error(), -1, 16), 5000); arg(reply->error(), -1, 16), 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_RX, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->error(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
reply->deleteLater(); reply->deleteLater();
} }
@@ -679,7 +670,6 @@ void M3KTE::onWriteButtonClicked()
if (!modbusDevice) if (!modbusDevice)
return; return;
statusBar()->clearMessage(); statusBar()->clearMessage();
QModbusDataUnit writeUnit = writeRequest(); QModbusDataUnit writeUnit = writeRequest();
QModbusDataUnit::RegisterType table = writeUnit.registerType(); QModbusDataUnit::RegisterType table = writeUnit.registerType();
for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) { for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) {
@@ -694,17 +684,37 @@ void M3KTE::onWriteButtonClicked()
writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i + writeUnit.startAddress()]); writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i + writeUnit.startAddress()]);
} }
} }
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, Boards[ui->boardSelectBox->currentIndex()].adr)) { if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, Boards[ui->boardSelectBox->currentIndex()].adr)) {
if (!reply->isFinished()) { if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, this, [this, reply]() { unsigned tmp_id = ui->boardSelectBox->currentIndex();
connect(reply, &QModbusReply::finished, this, [this, reply, tmp_id]() {
if (reply->error() == QModbusDevice::ProtocolError) { if (reply->error() == QModbusDevice::ProtocolError) {
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)") statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
5000); 5000);
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(tmp_id+1).arg(Boards[tmp_id].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[tmp_id].error_TX, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->rawResult().exceptionCode(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else if (reply->error() != QModbusDevice::NoError) { } else if (reply->error() != QModbusDevice::NoError) {
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)"). statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000); arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
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(tmp_id+1).arg(Boards[tmp_id].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[tmp_id].error_TX, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->error(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
reply->deleteLater(); reply->deleteLater();
}); });
@@ -714,6 +724,14 @@ void M3KTE::onWriteButtonClicked()
} }
} else { } else {
statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000); statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
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(modbusDevice->errorString()));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
} }
@@ -729,7 +747,6 @@ void M3KTE::onWriteTableChanged(int index)
void M3KTE::changeTable(int board, int tabletype) void M3KTE::changeTable(int board, int tabletype)
{ {
if(tabletype==0) if(tabletype==0)
{ {
ui->writeValueTable->setModel(Boards[board].ModbusModelCoil); ui->writeValueTable->setModel(Boards[board].ModbusModelCoil);
@@ -771,17 +788,18 @@ void M3KTE::changeTable(int board, int tabletype)
ui->writeValueTable->hideColumn(2); ui->writeValueTable->hideColumn(2);
ui->writeValueTable->showColumn(3); ui->writeValueTable->showColumn(3);
} }
for (int i = 0; i < 5; i++)
{
ui->writeValueTable->resizeColumnToContents(i);
}
} }
QModbusDataUnit M3KTE::readRequest() const QModbusDataUnit M3KTE::readRequest() const
{ {
const auto table = const auto table =
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt()); static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
int startAddress = 85 * (ui->writeTable->currentIndex()/2); int startAddress = 85 * (ui->writeTable->currentIndex()/2);
Q_ASSERT(startAddress >= 0 && startAddress < 340); Q_ASSERT(startAddress >= 0 && startAddress < 340);
// do not go beyond 10 entries
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress)); quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
return QModbusDataUnit(table, startAddress, numberOfEntries); return QModbusDataUnit(table, startAddress, numberOfEntries);
} }
@@ -790,11 +808,8 @@ QModbusDataUnit M3KTE::writeRequest() const
{ {
const auto table = const auto table =
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt()); static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
int startAddress = 85 * (ui->writeTable->currentIndex()/2); int startAddress = 85 * (ui->writeTable->currentIndex()/2);
Q_ASSERT(startAddress >= 0 && startAddress < 340); Q_ASSERT(startAddress >= 0 && startAddress < 340);
// do not go beyond 10 entries
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress)); quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
return QModbusDataUnit(table, startAddress, numberOfEntries); return QModbusDataUnit(table, startAddress, numberOfEntries);
} }
@@ -806,6 +821,7 @@ bool M3KTE::event(QEvent *event)
BoardIdHasBeenChanged* _event = static_cast<BoardIdHasBeenChanged*>(event); BoardIdHasBeenChanged* _event = static_cast<BoardIdHasBeenChanged*>(event);
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 172, 1); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 172, 1);
_unit->setValue(0, _event->BoardNewID()); _unit->setValue(0, _event->BoardNewID());
Boards[_event->BoardNum()]._tmp_adr = _event->BoardNewID();
if (auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardNum()].adr)) if (auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardNum()].adr))
{ {
if(!reply->isFinished()) if(!reply->isFinished())
@@ -816,143 +832,272 @@ bool M3KTE::event(QEvent *event)
if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr)) if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr))
{ {
if (!subreply->isFinished()) if (!subreply->isFinished())
connect(subreply, &QModbusReply::finished, this, &M3KTE::checkAdrChange); connect(subreply, &QModbusReply::finished, this, [subreply, this, _event]()
{
checkAdrChange(subreply, _event->BoardNum());
});
else else
{ {
errorAdrChange(); 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(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(subreply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardNum()].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
delete subreply; // broadcast replies return immediately delete subreply; // broadcast replies return immediately
} }
} else { } else {
errorAdrChange(); 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(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardNum()].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
} }
} }
else else
{ {
errorAdrChange(); 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(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardNum()].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
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"))));
loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardNum()].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
delete reply; delete reply;
} }
} }
else else
{ {
errorAdrChange(); 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(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardNum()].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
} }
// if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr))
// {
// if (!reply->isFinished())
// connect(reply, &QModbusReply::finished, this, &M3KTE::checkAdrChange);
// else
// delete reply; // broadcast replies return immediately
// } else {
// errorAdrChange();
// }
m_deviceSettingsDialog->show(); m_deviceSettingsDialog->show();
return true; return true;
} }
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());
if (auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardID()].adr))
{
if(!reply->isFinished())
connect(reply, &QModbusReply::finished, this, [reply, this, _event]()
{
if(reply->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(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardID()].error_cmd_change, 10)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
}
});
}
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(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[_event->BoardID()].error_cmd_change, 10)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
}
return true;
}
return QWidget::event(event); return QWidget::event(event);
} }
void M3KTE::checkAdrChange() void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum)
{ {
auto reply = qobject_cast<QModbusReply *>(sender());
if (!reply) if (!reply)
{ {
errorAdrChange(); 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(boardNum+1).arg(Boards[boardNum].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardNum].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
return; return;
} }
if (reply->error() == QModbusDevice::NoError) { if (reply->error() == QModbusDevice::NoError) {
for (int i = 0; i < CurrentConnectedDevice; i++) { if(Boards[boardNum]._tmp_adr == reply->serverAddress())
if(Boards[i]._tmp_adr == reply->serverAddress())
{ {
//OK //OK
Boards[i].adr = Boards[i]._tmp_adr; Boards[boardNum].adr = Boards[boardNum]._tmp_adr;
reply->deleteLater(); reply->deleteLater();
return; return;
} }
}
//ERROR //ERROR
errorAdrChange(); else{
Boards[boardNum]._tmp_adr = Boards[boardNum].adr;
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(boardNum+1).arg(Boards[boardNum].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardNum].error_adr_change, 10)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater(); reply->deleteLater();
return; return;
} }
errorAdrChange();
reply->deleteLater();
} }
unsigned newRow = loggerTable->rowCount();
void M3KTE::errorAdrChange() loggerTable->insertRow(newRow);
{ loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
QMessageBox msgBox; loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr)));
msgBox.setText("Не удалось изменить адрес устройства."); loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
msgBox.setStandardButtons(QMessageBox::Ok); loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardNum].error_adr_change, 10)));
msgBox.setDefaultButton(QMessageBox::Ok); loggerTable->setItem(newRow, 4, new QTableWidgetItem("Не удалось изменить адрес устройства."));
int ret = msgBox.exec(); loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater();
} }
void M3KTE::onSpeedUpdate() void M3KTE::onSpeedUpdate()
{ {
//Отсутствие контроля записи регистра на плате. stopScanBoard();
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 173, 1);
QModbusDataUnit* _unitcheck = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
_unit->setValue(0, m_deviceSettingsDialog->currentSpeed()); _unit->setValue(0, m_deviceSettingsDialog->currentSpeed());
for (int i = 0; i < CurrentConnectedDevice; i++) { unsigned tmp_speed = m_deviceSettingsDialog->currentSpeed();
auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr); for (int i = 0; i < 4; i++) {
if (!Boards[i].isActive)
{ {
if (!reply->isFinished()) continue;
connect(reply, &QModbusReply::finished, this, [this, reply, i](){ }
if (auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr))
{
while(!reply->isFinished())
{
QCoreApplication::processEvents();
}
if(reply->error()==QModbusDevice::TimeoutError) if(reply->error()==QModbusDevice::TimeoutError)
{ {
modbusDevice->disconnectDevice(); modbusDevice->disconnectDevice();
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
m_settingsDialog->UpdateBaud(m_deviceSettingsDialog->currentSpeed())); tmp_speed);
modbusDevice->connectDevice(); modbusDevice->connectDevice();
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); if(auto *subreply = modbusDevice->sendReadRequest(*_unitcheck, Boards[i].adr))
if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr))
{ {
if (!subreply->isFinished()) while (!subreply->isFinished())
connect(subreply, &QModbusReply::finished, this, [subreply, this, i](){ {
QCoreApplication::processEvents();
}
if(subreply->error() != QModbusDevice::NoError) if(subreply->error() != QModbusDevice::NoError)
{ {
QMessageBox msgBox; unsigned newRow = loggerTable->rowCount();
msgBox.setText(tr("Не удалось изменить скорость платы %1.").arg(i)); loggerTable->insertRow(newRow);
msgBox.setStandardButtons(QMessageBox::Ok); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
msgBox.setDefaultButton(QMessageBox::Ok); loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr)));
int ret = msgBox.exec(); 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("Ошибка при изменении скорости обмена."));
else loggerTable->resizeColumnsToContents();
{ if(!loggerTable->verticalScrollBar()->isSliderDown())
QMessageBox msgBox; loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
msgBox.setText(tr("Не удалось изменить скорость платы %1.").arg(i)); subreply->deleteLater();
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
delete subreply; // broadcast replies return immediately
} }
} else { } else {
QMessageBox msgBox; unsigned newRow = loggerTable->rowCount();
msgBox.setText(tr("Не удалось изменить скорость платы %1.").arg(i)); loggerTable->insertRow(newRow);
msgBox.setStandardButtons(QMessageBox::Ok); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
msgBox.setDefaultButton(QMessageBox::Ok); loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr)));
int ret = msgBox.exec(); 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());
} }
modbusDevice->disconnectDevice();
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
m_settingsDialog->curBaud());
modbusDevice->connectDevice();
} }
});
else 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 delete reply; // broadcast replies return immediately
} }
} }
}
modbusDevice->disconnectDevice();
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
m_settingsDialog->UpdateBaud(tmp_speed));
modbusDevice->connectDevice();
beginScanBoards();
} }
void M3KTE::onParityUpdate() void M3KTE::onParityUpdate()
{ {
//Отсутствие контроля записи регистра на плате. stopScanBoard();
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 174, 1); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 174, 1);
switch (m_deviceSettingsDialog->currentParity()) switch (m_deviceSettingsDialog->currentParity())
{ {
@@ -968,68 +1113,105 @@ void M3KTE::onParityUpdate()
} }
case 2: //Нечетный case 2: //Нечетный
{ {
_unit->setValue(0, 0x0800); _unit->setValue(0, 0x0600);
break; break;
} }
} }
for (int i = 0; i < CurrentConnectedDevice; i++) { for (int i = 0; i < 4; i++) {
auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr); if (!Boards[i].isActive)
{ {
if (!reply->isFinished()) continue;
connect(reply, &QModbusReply::finished, this, [this, reply, i](){ }
if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[i].adr))
{
while (!reply->isFinished())
{
QCoreApplication::processEvents();
}
if(reply->error()==QModbusDevice::TimeoutError) if(reply->error()==QModbusDevice::TimeoutError)
{ {
modbusDevice->disconnectDevice(); modbusDevice->disconnectDevice();
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
m_settingsDialog->UpdateParity(m_deviceSettingsDialog->currentParity())); m_deviceSettingsDialog->currentParity());
modbusDevice->connectDevice(); modbusDevice->connectDevice();
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr)) if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[i].adr))
{ {
if (!subreply->isFinished()) while (!subreply->isFinished())
connect(subreply, &QModbusReply::finished, this, [subreply, this, i](){ {
QCoreApplication::processEvents();
}
if(subreply->error() != QModbusDevice::NoError) if(subreply->error() != QModbusDevice::NoError)
{ {
QMessageBox msgBox; unsigned newRow = loggerTable->rowCount();
msgBox.setText(tr("Не удалось изменить чётность платы %1.").arg(i)); loggerTable->insertRow(newRow);
msgBox.setStandardButtons(QMessageBox::Ok); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
msgBox.setDefaultButton(QMessageBox::Ok); loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr)));
int ret = msgBox.exec(); 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("Ошибка при изменении чётности платы."));
else loggerTable->resizeColumnsToContents();
{ if(!loggerTable->verticalScrollBar()->isSliderDown())
QMessageBox msgBox; loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
msgBox.setText(tr("Не удалось изменить чётность платы %1.").arg(i));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
delete subreply; // broadcast replies return immediately
} }
} else { } else {
QMessageBox msgBox; unsigned newRow = loggerTable->rowCount();
msgBox.setText(tr("Не удалось изменить чётность платы %1.").arg(i)); loggerTable->insertRow(newRow);
msgBox.setStandardButtons(QMessageBox::Ok); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
msgBox.setDefaultButton(QMessageBox::Ok); loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(i+1).arg(Boards[i].adr)));
int ret = msgBox.exec(); 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 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 delete reply; // broadcast replies return immediately
} }
} }
modbusDevice->disconnectDevice();
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
m_settingsDialog->UpdateParity(m_deviceSettingsDialog->currentParity()));
modbusDevice->connectDevice();
beginScanBoards();
} }
bool M3KTE::pingNetworkDevices() bool M3KTE::pingNetworkDevices()
{ {
int i=0; CurrentConnectedDevice = 0;
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, &M3KTE::timeForPingIsGone);
timer->setSingleShot(true);
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
int tmp_adr = 1; int tmp_adr = 1;
bool isRun = false; bool isRun = false;
bool *tmp_isRun = &isRun; bool *tmp_isRun = &isRun;
auto bar = new QProgressDialog(this); auto bar = new QProgressDialog(this);
@@ -1037,34 +1219,36 @@ bool M3KTE::pingNetworkDevices()
{ {
*tmp_isRun = true; *tmp_isRun = true;
}); });
bar->setLabelText(tr("Поиск плат...")); bar->setLabelText(tr("Поиск плат... Текущий адрес: %1").arg(tmp_adr));
bar->setCancelButton(nullptr); bar->setCancelButton(nullptr);
bar->setRange(0, 4); bar->setRange(0, 4);
bar->setMinimumDuration(100); bar->setMinimumDuration(100);
bar->setValue(i); bar->setValue(CurrentConnectedDevice);
modbusDevice->setNumberOfRetries(0);
CurrentConnectedDevice = 0; QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404"));
QModbusRequest requestOfBoardID(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0401"));
for(i=0; i<4;) modbusDevice->setTimeout(50);
for(CurrentConnectedDevice=0; CurrentConnectedDevice<4;)
{ {
auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr);
if(isRun && CurrentConnectedDevice < 1) //auto *reply = modbusDevice->sendReadRequest(*_unit, tmp_adr);
//Запрос типа устройства.
if(reply == nullptr)
{ {
onConnectClicked(); onConnectClicked();
bar->close();
bar->deleteLater();
return false; return false;
} }
else if(isRun) while(!reply->isFinished())
{
break;
}
timerForPingSignal = false;
timer->start(m_settingsDialog->settings().responseTime);
auto *reply = modbusDevice->sendReadRequest(*_unit, tmp_adr);
while(!reply->isFinished() && !timerForPingSignal)
{ {
if(isRun && CurrentConnectedDevice < 1) if(isRun && CurrentConnectedDevice < 1)
{ {
onConnectClicked(); onConnectClicked();
bar->close();
bar->deleteLater();
return false; return false;
} }
else if(isRun) else if(isRun)
@@ -1073,20 +1257,73 @@ bool M3KTE::pingNetworkDevices()
} }
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
if(timerForPingSignal) if(isRun && CurrentConnectedDevice < 1)
{ {
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
else if(isRun)
{
break;
}
else if (!isRun)
{
//Нужна проверка типа устройства
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();
bar->close();
bar->deleteLater();
return false;
}
else if(isRun)
{
break;
}
QCoreApplication::processEvents();
}
if(isRun && CurrentConnectedDevice < 1)
{
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
else if(isRun)
{
break;
} }
else else
{ {
if(reply->error()==QModbusDevice::NoError) //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)
{ {
timer->stop(); 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)));
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
CurrentConnectedDevice++; CurrentConnectedDevice++;
Boards[i].adr = Boards[i]._tmp_adr = tmp_adr; 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(i).arg(tmp_adr), m_settingsDialog->settings().responseTime); statusBar()->showMessage(tr("Плата %1 найдена по адресу %2.").arg((int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1).arg(tmp_adr), m_settingsDialog->settings().responseTime);
i++; Boards[(int)(subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH))-1].isActive = true;
bar->setValue(i); bar->setValue(CurrentConnectedDevice);
}
}
} }
} }
tmp_adr++; tmp_adr++;
@@ -1095,8 +1332,9 @@ bool M3KTE::pingNetworkDevices()
{ {
//ERROR //ERROR
//OUT OF RANGE //OUT OF RANGE
QMessageBox::warning(this, "Ошибка при сканировании сети.", QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(i)); QMessageBox::warning(this, "Ошибка при сканировании сети.", QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(CurrentConnectedDevice));
bar->setValue(4); bar->setValue(4);
bar->close();
bar->deleteLater(); bar->deleteLater();
onConnectClicked(); onConnectClicked();
return false; return false;
@@ -1107,238 +1345,273 @@ bool M3KTE::pingNetworkDevices()
} }
} }
isRun=false; isRun=false;
QMessageBox::warning(this, "Сканирование сети завершено.", tr("Найдено плат: %1 из 4.").arg(i)); QMessageBox::warning(this, "Сканирование сети завершено.", tr("Найдено плат: %1 из 4.").arg(CurrentConnectedDevice));
if(isRun) if(isRun)
{ {
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
onConnectClicked(); onConnectClicked();
bar->close();
bar->deleteLater();
return false; return false;
} }
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
bar->setLabelText(tr("Считывание текущих настроек...")); bar->setLabelText(tr("Считывание текущих настроек..."));
bar->setRange(0, CurrentConnectedDevice*3); bar->setRange(0, CurrentConnectedDevice*3);
QModbusDataUnit* _unit_settings[3]; QModbusDataUnit* _unit_settings[3];
_unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85); _unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85);
_unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85); _unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85);
_unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85); _unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85);
for(int i=0; i<4; i++)
for(i=0; i<CurrentConnectedDevice; 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); bar->setValue(i*3+j);
if(isRun) if(isRun)
{ {
onConnectClicked(); onConnectClicked();
bar->close();
bar->deleteLater();
return false; return false;
} }
timerForPingSignal = false;
timer->start(m_settingsDialog->settings().responseTime);
auto *reply = modbusDevice->sendReadRequest(*_unit_settings[j], Boards[i].adr); auto *reply = modbusDevice->sendReadRequest(*_unit_settings[j], Boards[i].adr);
while(!reply->isFinished() && !timerForPingSignal) if(!reply)
{
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
while(!reply->isFinished())
{ {
if(isRun) if(isRun)
{ {
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
onConnectClicked(); onConnectClicked();
bar->close();
bar->deleteLater();
return false; return false;
} }
QCoreApplication::processEvents(); QCoreApplication::processEvents();
} }
if(timerForPingSignal)
{
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Таймаут при опросе устройства %1 по адресу %2").arg(i).arg(Boards[i].adr));
onConnectClicked();
return false;
}
else
{
if(reply->error()==QModbusDevice::NoError) if(reply->error()==QModbusDevice::NoError)
{ {
timer->stop(); applySettingsFromScan(reply);
stepForScanCurrentSettings(reply);
} }
else else
{ {
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Таймаут при опросе устройства %1 по адресу %2").arg(i).arg(Boards[i].adr)); QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Таймаут при опросе устройства %1 по адресу %2").arg(i+1).arg(Boards[i].adr));
bar->setValue(CurrentConnectedDevice*3); bar->setValue(CurrentConnectedDevice*3);
bar->close();
bar->deleteLater();
onConnectClicked(); onConnectClicked();
return false; return false;
} }
} }
Boards_Fields[i]->setTitle(QString("Плата №%1 (ID %2)").arg(i).arg(Boards[i].adr));
} }
} }
modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);
beginScanBoards(); beginScanBoards();
bar->deleteLater(); bar->deleteLater();
return true; return true;
}
void M3KTE::timeForPingIsGone()
{
timerForPingSignal=true;
} }
void M3KTE::beginScanBoards() void M3KTE::beginScanBoards()
{ {
if(CurrentConnectedDevice>=1) for (int i = 0; i < 4; i++) {
firstBoardScan(); if(Boards[i].isActive)
if(CurrentConnectedDevice>=2) {
secondBoardScan(); m_deviceSettingsDialog->initPollForBoard(i, Boards[i].adr);
if(CurrentConnectedDevice>=3) boardScan(i);
thirdBoardScan(); }
if(CurrentConnectedDevice>=4) }
fourthBoardScan();
return; return;
} }
void M3KTE::firstBoardScan() void M3KTE::boardScan(unsigned boardID)
{ {
if (!modbusDevice) if (!modbusDevice)
return; return;
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 85, 1);
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85);
statusBar()->clearMessage(); statusBar()->clearMessage();
if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[0].adr)) { if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[boardID].adr)) {
Boards[boardID].timerToStatusResponse.start();
if (!reply->isFinished()) if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &M3KTE::firstBoardReady); connect(reply, &QModbusReply::finished, this, [this, boardID, reply]()
else
delete reply; // broadcast replies return immediately
} else {
QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(1), QString(tr("Read error: ") + modbusDevice->errorString()));
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
}
}
void M3KTE::secondBoardScan()
{ {
if (!modbusDevice) Boards[boardID].timerStatus->setText(QString("Status: %1 ms").arg(Boards[boardID].timerToStatusResponse.elapsed()));
if(reply->error()==QModbusDevice::NoError) {
statusreg StatusReg;
StatusReg.AllReg = reply->result().value(0);
if(StatusReg.ParsingReg.poll_allowed)
{
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
return; return;
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85);
statusBar()->clearMessage();
if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[1].adr)) {
if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &M3KTE::secondBoardReady);
else
delete reply; // broadcast replies return immediately
} else {
QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(2), QString(tr("Read error: ") + modbusDevice->errorString()));
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
} }
} if(StatusReg.ParsingReg.mzkte_status)
void M3KTE::thirdBoardScan()
{ {
if (!modbusDevice) switch (StatusReg.ParsingReg.mzkte_error) {
case 1:
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
return; return;
case 2:
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
statusBar()->clearMessage();
if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[2].adr)) {
if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &M3KTE::thirdBoardReady);
else
delete reply; // broadcast replies return immediately
} else {
QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(3), QString(tr("Read error: ") + modbusDevice->errorString()));
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
}
}
void M3KTE::fourthBoardScan()
{
if (!modbusDevice)
return; return;
case 3:
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
return;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
default:
break;
}
}
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85); QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::InputRegisters, 0, 85);
statusBar()->clearMessage();
if (auto *reply = modbusDevice->sendReadRequest(*_unit, Boards[3].adr)) { if (auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[boardID].adr)) {
if (!reply->isFinished()) Boards[boardID].timerToDataResponse.start();
connect(reply, &QModbusReply::finished, this, &M3KTE::fourthBoardReady); if (!subreply->isFinished())
else {
delete reply; // broadcast replies return immediately connect(subreply, &QModbusReply::finished, this, [this, boardID]()
{
Boards[boardID].timerData->setText(QString("Data: %1 ms").arg(Boards[boardID].timerToStatusResponse.elapsed()));
auto subreply = qobject_cast<QModbusReply *>(sender());
displayResultOfScan(subreply, boardID);
subreply->deleteLater();
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
});
} else { } else {
QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(4), QString(tr("Read error: ") + modbusDevice->errorString())); Boards[boardID].timerToDataResponse.elapsed();
statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000); 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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_TX)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
delete subreply;
} }
} 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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_TX)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
delete subreply;
} }
} else {
void M3KTE::firstBoardReady() 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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_TX)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
}
});
else
{ {
auto reply = qobject_cast<QModbusReply *>(sender()); Boards[boardID].timerToStatusResponse.elapsed();
displayResultOfScan(reply, 0); unsigned newRow = loggerTable->rowCount();
reply->deleteLater(); loggerTable->insertRow(newRow);
Boards[0].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(0)); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_TX)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
Boards[boardID].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(boardID));
delete reply; // broadcast replies return immediately
} }
} else {
void M3KTE::secondBoardReady() // QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID+1), QString(tr("Read error: ") + modbusDevice->errorString()));
{ // statusBar()->showMessage(tr("Read error: ") + modbusDevice->errorString(), 5000);
auto reply = qobject_cast<QModbusReply *>(sender()); unsigned newRow = loggerTable->rowCount();
displayResultOfScan(reply, 1); loggerTable->insertRow(newRow);
reply->deleteLater(); loggerTable->setItem(newRow, 0, new QTableWidgetItem((QTime::currentTime().toString("HH:mm:ss"))));
Boards[1].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(1)); loggerTable->setItem(newRow, 1, new QTableWidgetItem(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(modbusDevice->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_TX)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
void M3KTE::thirdBoardReady()
{
auto reply = qobject_cast<QModbusReply *>(sender());
displayResultOfScan(reply, 2);
reply->deleteLater();
Boards[2].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(2));
}
void M3KTE::fourthBoardReady()
{
auto reply = qobject_cast<QModbusReply *>(sender());
displayResultOfScan(reply, 3);
reply->deleteLater();
Boards[3].boardScanners->start(m_deviceSettingsDialog->currentBoardTimer(3));
} }
void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID) void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID)
{ {
if (!reply) if (!reply)
return; return;
if (reply->error() == QModbusDevice::NoError) { if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result(); const QModbusDataUnit unit = reply->result();
bool W_Flag = false; bool W_Flag = false;
bool A_Flag = false; bool A_Flag = false;
if(unit.startAddress() != 0 || unit.valueCount() != 85) if(unit.startAddress() != 0 || unit.valueCount() != 85)
{ {
//ERROR //ERROR
//QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID), QString("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount()));
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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem("Ошибка при приёме."));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_RX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount())));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
reply->deleteLater(); reply->deleteLater();
QMessageBox::warning(this, QString("Ошибка при опросе платы #%1").arg(boardID), QString("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount()));
return; return;
} }
QString W_Adr;
QString A_Adr;
for(int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i) for(int i = unit.startAddress(), total = int(unit.valueCount()); i < total; ++i)
{ {
//QErrorMessage::showMessage()
//if(Boards[boardID].ModbusModelCoil->data(Boards[boardID].ModbusModelCoil->index(i, 2), Qt::CheckStateRole).Bool != 0)
//if(Boards[boardID].ModbusModelCoil->get_coil(Boards[boardID].ModbusModelCoil->index(i, 2))==true)
if(Boards[boardID].coil[i]==true) if(Boards[boardID].coil[i]==true)
{ {
int j = 0; int j = 0;
//if(Boards[boardID].ModbusModelHoldingReg->get_holreg(Boards[boardID].ModbusModelHoldingReg->index(85+i, 3)) > unit.value(i))
if(Boards[boardID].HR[i + 85] > unit.value(i)) if(Boards[boardID].HR[i + 85] > unit.value(i))
{ {
j = 1; j = 1;
if(j != m_ProgressBar[i+boardID*85]->value())
{
A_Adr += tr("ТЭ%1 ").arg(i);
Boards[boardID].error_A++;
}
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
A_Flag = true; A_Flag = true;
} }
//else if(Boards[boardID].ModbusModelHoldingReg->get_holreg(Boards[boardID].ModbusModelHoldingReg->index(i, 3)) > unit.value(i))
else if(Boards[boardID].HR[i] > unit.value(i)) else if(Boards[boardID].HR[i] > unit.value(i))
{ {
j = 2; j = 2;
if(j != m_ProgressBar[i+boardID*85]->value())
{
W_Adr += tr("ТЭ%1 ").arg(i);
Boards[boardID].error_W++;
}
m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); m_ProgressBar[i+boardID*85]->setStatusTip(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85))); m_ProgressBar[i+boardID*85]->setWhatsThis(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
W_Flag = true; W_Flag = true;
@@ -1365,14 +1638,37 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID)
Boards[boardID].ModbusModelHoldingReg->set_currentU(unit.value(i), i); Boards[boardID].ModbusModelHoldingReg->set_currentU(unit.value(i), i);
} }
if(A_Flag) if(A_Flag)
{
statusM3KTE.Accidents[boardID] = true; statusM3KTE.Accidents[boardID] = true;
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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem("Авария"));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(Boards[boardID].error_A)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(A_Adr));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
}
else else
statusM3KTE.Accidents[boardID] = false; statusM3KTE.Accidents[boardID] = false;
if(W_Flag) if(W_Flag)
{
statusM3KTE.Warnings[boardID] = true; statusM3KTE.Warnings[boardID] = true;
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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem("Предупреждение"));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(Boards[boardID].error_W)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(W_Adr));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
}
else else
statusM3KTE.Warnings[boardID] = false; statusM3KTE.Warnings[boardID] = false;
ui->BSM_Warning->setChecked(false); ui->BSM_Warning->setChecked(false);
ui->BSM_Accident->setChecked(false); ui->BSM_Accident->setChecked(false);
ui->BSM_WorkInProgress->setChecked(true); ui->BSM_WorkInProgress->setChecked(true);
@@ -1396,33 +1692,54 @@ void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID)
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16), 5000); arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_RX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else { } else {
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->error(), -1, 16), 5000); arg(reply->error(), -1, 16), 5000);
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(boardID+1).arg(Boards[boardID].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[boardID].error_RX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->error(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
reply->deleteLater(); reply->deleteLater();
} }
void M3KTE::stepForScanCurrentSettings(QModbusReply *reply) void M3KTE::applySettingsFromScan(QModbusReply *reply)
{ {
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
int Adr = 255; int Adr = 255;
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
if(Boards[i].adr==reply->serverAddress()) if(Boards[i].adr==reply->serverAddress() &&Boards[i].isActive)
{ {
Adr = i; Adr = i;
break; break;
} }
} }
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
for (int i = 0, total = int(unit.valueCount()); i < (total); ++i) { for (int i = 0, total = int(unit.valueCount()); i < (total); ++i) {
//ui->readValue->addItem(entry);
if(unit.registerType() == QModbusDataUnit::Coils) if(unit.registerType() == QModbusDataUnit::Coils)
{ {
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i); Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
//QStandardItem *item = ui->writeValueTable->model()->item
if(unit.value(i)==1) if(unit.value(i)==1)
{ {
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole); Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
@@ -1431,7 +1748,6 @@ void M3KTE::stepForScanCurrentSettings(QModbusReply *reply)
{ {
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole); 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)
{ {
@@ -1440,15 +1756,35 @@ void M3KTE::stepForScanCurrentSettings(QModbusReply *reply)
} }
} }
} else if (reply->error() == QModbusDevice::ProtocolError) { } else if (reply->error() == QModbusDevice::ProtocolError) {
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16), 5000); arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_RX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else { } else {
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)"). statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()). arg(reply->errorString()).
arg(reply->error(), -1, 16), 5000); arg(reply->error(), -1, 16), 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_RX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->error(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
reply->deleteLater(); reply->deleteLater();
} }
@@ -1489,17 +1825,37 @@ void M3KTE::multipleRegSend()
Boards[m_regMultipleSettings->getBoardId()].coil[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue(); Boards[m_regMultipleSettings->getBoardId()].coil[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
} }
} }
if (auto *reply = modbusDevice->sendWriteRequest(*unit_tx, Boards[m_regMultipleSettings->getBoardId()].adr)) { if (auto *reply = modbusDevice->sendWriteRequest(*unit_tx, Boards[m_regMultipleSettings->getBoardId()].adr)) {
unsigned Adr = m_regMultipleSettings->getBoardId();
if (!reply->isFinished()) { if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, this, [this, reply]() { connect(reply, &QModbusReply::finished, this, [this, reply, Adr]() {
if (reply->error() == QModbusDevice::ProtocolError) { if (reply->error() == QModbusDevice::ProtocolError) {
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)") statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
5000); 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_TX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} else if (reply->error() != QModbusDevice::NoError) { } else if (reply->error() != QModbusDevice::NoError) {
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)"). statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000); arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
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(Adr+1).arg(Boards[Adr].adr)));
loggerTable->setItem(newRow, 2, new QTableWidgetItem(reply->errorString()));
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(++Boards[Adr].error_TX)));
loggerTable->setItem(newRow, 4, new QTableWidgetItem(QString::number(reply->error(), 16)));
loggerTable->resizeColumnsToContents();
if(!loggerTable->verticalScrollBar()->isSliderDown())
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
} }
reply->deleteLater(); reply->deleteLater();
}); });
@@ -1517,12 +1873,10 @@ void M3KTE::multipleRegWrite()
for (unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) { for (unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) {
if(m_regMultipleSettings->getTypeReg()) if(m_regMultipleSettings->getTypeReg())
{ {
//Boards[m_regMultipleSettings->getBoardId()].HR[i] = m_regMultipleSettings->getNewValue();
Boards[m_regMultipleSettings->getBoardId()].ModbusModelHoldingReg->m_holdingRegisters[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue(); Boards[m_regMultipleSettings->getBoardId()].ModbusModelHoldingReg->m_holdingRegisters[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
} }
else else
{ {
//Boards[m_regMultipleSettings->getBoardId()].coil[i] = m_regMultipleSettings->getNewValue();
Boards[m_regMultipleSettings->getBoardId()].ModbusModelCoil->m_coils[i+m_regMultipleSettings->getStartAdr()] = (bool)m_regMultipleSettings->getNewValue(); Boards[m_regMultipleSettings->getBoardId()].ModbusModelCoil->m_coils[i+m_regMultipleSettings->getStartAdr()] = (bool)m_regMultipleSettings->getNewValue();
} }
} }
@@ -1534,5 +1888,206 @@ void M3KTE::selectPositionOnTree(unsigned int index)
QModelIndex selected = ui->writeValueTable->model()->index(index%85, 0); QModelIndex selected = ui->writeValueTable->model()->index(index%85, 0);
ui->writeValueTable->selectionModel()->select(selected, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows); ui->writeValueTable->selectionModel()->select(selected, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows);
ui->writeValueTable->scrollTo(selected); ui->writeValueTable->scrollTo(selected);
//selection
} }
bool M3KTE::autoBaudRateScan()
{
unsigned countOfDeviceOnLine = 0;
QString resultOfScan;
QVector<unsigned> KTE[8];
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
m_settingsDialog->settings().portName);
#if QT_CONFIG(modbus_serialport)
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
m_settingsDialog->settings().parity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
m_settingsDialog->settings().dataBits);
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, [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]);
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();
bar->close();
bar->deleteLater();
return false;
}
while(!reply->isFinished())
{
if(isRun)
{
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
QCoreApplication::processEvents();
}
if(isRun)
{
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
else if (!isRun)
{
//Нужна проверка типа устройства
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);
}
}
}
}
if(countOfDeviceOnLine>0)
resultOfScan += QString("%1 плат M3KTE работают на скорости %2.\n").arg(countOfDeviceOnLine).arg(m_baud[i]);
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++)
{
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]));
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]);
if (!modbusDevice->connectDevice()) {
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
}
auto *reply = modbusDevice->sendWriteRequest(*_unit, KTE[i].at(j));
if(!reply)
{
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
while(!reply->isFinished())
{
if(isRun)
{
//dfQMessageBox::warning(this, "Ошибка при синхронизации скоростей.", QString("Прерывание по запросу пользователя."));
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
QCoreApplication::processEvents();
}
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)
{
//dfQMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
QCoreApplication::processEvents();
}
if(subreply->error()!=QModbusDevice::NoError)
{
//QMessageBox::warning();
onConnectClicked();
bar->close();
bar->deleteLater();
return false;
}
}
}
else if(reply->error()!=QModbusDevice::NoError)
{
return false;
}
modbusDevice->disconnectDevice();
}
}
}
return true;
}
else
return false;
}
void M3KTE::stopScanBoard()
{
for (int i = 0; i < 4; i++) {
Boards[i].boardScanners->stop();
}
return;
}

View File

@@ -9,6 +9,8 @@
#include "writeregistermodel.h" #include "writeregistermodel.h"
#include "devicesettingsdialog.h" #include "devicesettingsdialog.h"
#include "multiplesettings.h" #include "multiplesettings.h"
#include "scanboard.h"
#include "lineringer.h"
#include <QModbusTcpClient> #include <QModbusTcpClient>
#include <QModbusRtuSerialMaster> #include <QModbusRtuSerialMaster>
@@ -18,6 +20,10 @@
#include <QProgressDialog> #include <QProgressDialog>
#include <QErrorMessage> #include <QErrorMessage>
#include <QPushButton> #include <QPushButton>
#include <QGroupBox>
#include <QTableWidget>
#include <QTime>
#include <QElapsedTimer>
#include <QtSerialBus/qtserialbusglobal.h> #include <QtSerialBus/qtserialbusglobal.h>
@@ -25,6 +31,10 @@
#include <QSerialPort> #include <QSerialPort>
#endif #endif
#define MODBUS_REQUEST_PROTOCOL_INFO_LENGTH 8
extern "C" __declspec(dllexport) QWidget* init(QWidget *parent);
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class M3KTE; class SettingsDialog;} namespace Ui { class M3KTE; class SettingsDialog;}
QT_END_NAMESPACE QT_END_NAMESPACE
@@ -40,17 +50,18 @@ private:
QModbusDataUnit readRequest() const; QModbusDataUnit readRequest() const;
QModbusDataUnit writeRequest() const; QModbusDataUnit writeRequest() const;
void changeTable(int board, int tabletype); void changeTable(int board, int tabletype);
void debug();
void errorAdrChange();
bool event(QEvent* event); bool event(QEvent* event);
bool pingNetworkDevices(); bool pingNetworkDevices();
void beginScanBoards(); void beginScanBoards();
void stopScanBoard();
void displayResultOfScan(QModbusReply *reply, int boardID); void displayResultOfScan(QModbusReply *reply, int boardID);
void stepForScanCurrentSettings(QModbusReply *reply); void applySettingsFromScan(QModbusReply *reply);
void multipleRegWrite(); void multipleRegWrite();
void multipleRegSend(); void multipleRegSend();
bool autoBaudRateScan();
void selectPositionOnTree(unsigned index); void selectPositionOnTree(unsigned index);
private slots: private slots:
@@ -62,9 +73,7 @@ private slots:
void onReadButtonClicked(); void onReadButtonClicked();
void onReadReady(); void onReadReady();
void timeForPingIsGone(); void checkAdrChange(QModbusReply *reply, unsigned boardNum);
void checkAdrChange();
void onWriteButtonClicked(); void onWriteButtonClicked();
void onSelectedBoardChanged(int index); void onSelectedBoardChanged(int index);
@@ -73,22 +82,15 @@ private slots:
void onSpeedUpdate(); void onSpeedUpdate();
void onParityUpdate(); void onParityUpdate();
void firstBoardScan(); void boardScan(unsigned boardID);
void secondBoardScan();
void thirdBoardScan();
void fourthBoardScan();
void firstBoardReady();
void secondBoardReady();
void thirdBoardReady();
void fourthBoardReady();
public: public:
M3KTE(QWidget *parent = nullptr); M3KTE(QWidget *parent = nullptr);
~M3KTE(); ~M3KTE();
private: private:
Ui::M3KTE *ui; Ui::M3KTE *ui;
bool timerForPingSignal = false; QTableWidget *loggerTable = nullptr;
int CurrentConnectedDevice = 0; int CurrentConnectedDevice = 0;
//int DeviceOnNetwork[4]; //int DeviceOnNetwork[4];
QProgressBar *m_ProgressBar[320]; QProgressBar *m_ProgressBar[320];
@@ -98,6 +100,10 @@ private:
DeviceSettingsDialog *m_deviceSettingsDialog = nullptr; DeviceSettingsDialog *m_deviceSettingsDialog = nullptr;
SettingsDialog *m_settingsDialog = nullptr; SettingsDialog *m_settingsDialog = nullptr;
MultipleSettings *m_regMultipleSettings = nullptr; MultipleSettings *m_regMultipleSettings = nullptr;
ScanBoard *m_scanBoard = nullptr;
LineRinger *m_lineRinger = nullptr;
QGroupBox *Boards_Fields[4];
//WriteRegisterModel *writeModel = nullptr; //WriteRegisterModel *writeModel = nullptr;
struct StatusM3KTE{ struct StatusM3KTE{
@@ -105,17 +111,52 @@ private:
bool Accidents[4]; bool Accidents[4];
}statusM3KTE; }statusM3KTE;
unsigned error_terminal;
struct BoardModbusRegisters struct BoardModbusRegisters
{ {
bool isActive = false;
bool pollIsActive = true;
int adr; int adr;
int _tmp_adr; int _tmp_adr;
bool coil[85]; bool coil[85];
unsigned HR[170]; unsigned HR[170];
unsigned error_W = 0;
unsigned error_A = 0;
unsigned error_modbus = 0;
unsigned error_baud_change = 0;
unsigned error_parity_change = 0;
unsigned error_RX = 0;
unsigned error_TX = 0;
unsigned error_adr_change = 0;
unsigned error_cmd_change = 0;
QLabel *timerData = nullptr;
QLabel *timerStatus = nullptr;
WriteRegisterModel *ModbusModelCoil; WriteRegisterModel *ModbusModelCoil;
WriteRegisterModel *ModbusModelHoldingReg; WriteRegisterModel *ModbusModelHoldingReg;
QTimer *boardScanners; QTimer *boardScanners;
QElapsedTimer timerToStatusResponse;
QElapsedTimer timerToDataResponse;
}Boards[4]; }Boards[4];
union statusreg
{
struct parsingFields
{
unsigned accident:1;
unsigned warning:1;
unsigned poll_allowed:1;
unsigned mzkte_status:2;
unsigned reserv:3;
unsigned mzkte_error:8;
}ParsingReg;
unsigned AllReg:16;
};
}; };
#endif // M3KTE_H #endif // M3KTE_H

File diff suppressed because it is too large Load Diff

39
M3KTE_TERM/scanboard.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "scanboard.h"
#include "ui_scanboard.h"
ScanBoard::ScanBoard(QWidget *parent) :
QDialog(parent),
ui(new Ui::ScanBoard)
{
ui->setupUi(this);
}
ScanBoard::~ScanBoard()
{
delete ui;
}
Qt::CheckState ScanBoard::getCheckState()
{
return checkState;
}
void ScanBoard::on_applyToAllBox_stateChanged(int arg1)
{
checkState = (Qt::CheckState)arg1;
}
void ScanBoard::showMeTheTruth(QString resultOfScan)
{
ui->logger->append(resultOfScan);
}
quint16 ScanBoard::getBaud()
{
return baud;
}
void ScanBoard::on_baudRateBox_currentTextChanged(const QString &arg1)
{
baud = arg1.toInt(nullptr, 10);
}

33
M3KTE_TERM/scanboard.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef SCANBOARD_H
#define SCANBOARD_H
#include <QDialog>
namespace Ui {
class ScanBoard;
}
class ScanBoard : public QDialog
{
Q_OBJECT
public:
explicit ScanBoard(QWidget *parent = nullptr);
~ScanBoard();
Qt::CheckState getCheckState();
void showMeTheTruth(QString resultOfScan);
quint16 getBaud();
private slots:
void on_applyToAllBox_stateChanged(int arg1);
void on_baudRateBox_currentTextChanged(const QString &arg1);
private:
Qt::CheckState checkState;
quint16 baud;
Ui::ScanBoard *ui;
};
#endif // SCANBOARD_H

81
M3KTE_TERM/scanboard.ui Normal file
View File

@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ScanBoard</class>
<widget class="QDialog" name="ScanBoard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>337</width>
<height>145</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QTextEdit" name="logger"/>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="baudRateBox"/>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="applyToAllBox">
<property name="text">
<string>Применить ко всем обнаруженным платам</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ScanBoard</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ScanBoard</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -12,13 +12,15 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
ui->baudCombo->setCurrentText(QString::number(m_settings.baud)); ui->baudCombo->setCurrentText(QString::number(m_settings.baud));
ui->dataBitsCombo->setCurrentText(QString::number(m_settings.dataBits)); ui->dataBitsCombo->setCurrentText(QString::number(m_settings.dataBits));
ui->stopBitsCombo->setCurrentText(QString::number(m_settings.stopBits)); ui->stopBitsCombo->setCurrentText(QString::number(m_settings.stopBits));
on_updateComBox_clicked();
#endif #endif
ui->timeoutSpinner->setValue(m_settings.responseTime); ui->timeoutSpinner->setValue(m_settings.responseTime);
ui->retriesSpinner->setValue(m_settings.numberOfRetries); ui->retriesSpinner->setValue(m_settings.numberOfRetries);
connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() { connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() {
#if QT_CONFIG(modbus_serialport) #if QT_CONFIG(modbus_serialport)
m_settings.portName = ui->portEdit->text(); m_settings.portName = ui->comBox->currentData().toString();
m_settings.parity = ui->parityCombo->currentIndex(); m_settings.parity = ui->parityCombo->currentIndex();
if (m_settings.parity > 0) if (m_settings.parity > 0)
m_settings.parity++; m_settings.parity++;
@@ -70,3 +72,13 @@ int SettingsDialog::curParity()
{ {
return ui->parityCombo->currentIndex(); return ui->parityCombo->currentIndex();
} }
void SettingsDialog::on_updateComBox_clicked()
{
ui->comBox->clear();
const auto listPorts = QSerialPortInfo::availablePorts();
for (const auto& port: listPorts)
{
ui->comBox->addItem(QString(port.portName() + ": " + port.manufacturer()), QVariant(port.portName()));
}
}

View File

@@ -6,6 +6,7 @@
#include <QtSerialBus/qtserialbusglobal.h> #include <QtSerialBus/qtserialbusglobal.h>
#if QT_CONFIG(modbus_serialport) #if QT_CONFIG(modbus_serialport)
#include <QSerialPort> #include <QSerialPort>
#include <QSerialPortInfo>
#endif #endif
namespace Ui { namespace Ui {
@@ -23,7 +24,7 @@ public:
int baud = 115200; int baud = 115200;
int dataBits = QSerialPort::Data8; int dataBits = QSerialPort::Data8;
int stopBits = QSerialPort::OneStop; int stopBits = QSerialPort::OneStop;
int responseTime = 500; int responseTime = 50;
int numberOfRetries = 0; int numberOfRetries = 0;
}; };
@@ -37,6 +38,9 @@ public:
int curBaud(); int curBaud();
int curParity(); int curParity();
private slots:
void on_updateComBox_clicked();
private: private:
Settings m_settings; Settings m_settings;
Ui::SettingsDialog *ui; Ui::SettingsDialog *ui;

View File

@@ -20,13 +20,13 @@
<string> мс</string> <string> мс</string>
</property> </property>
<property name="minimum"> <property name="minimum">
<number>-1</number> <number>10</number>
</property> </property>
<property name="maximum"> <property name="maximum">
<number>5000</number> <number>5000</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<number>20</number> <number>1</number>
</property> </property>
<property name="value"> <property name="value">
<number>200</number> <number>200</number>
@@ -36,7 +36,7 @@
<item row="2" column="1" rowspan="2" colspan="2"> <item row="2" column="1" rowspan="2" colspan="2">
<widget class="QSpinBox" name="retriesSpinner"> <widget class="QSpinBox" name="retriesSpinner">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>true</bool>
</property> </property>
<property name="value"> <property name="value">
<number>0</number> <number>0</number>
@@ -69,16 +69,6 @@
<string>Serial Parameters</string> <string>Serial Parameters</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>Порт</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="portEdit"/>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="parityLabel"> <widget class="QLabel" name="parityLabel">
<property name="text"> <property name="text">
@@ -86,32 +76,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QComboBox" name="parityCombo">
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Even</string>
</property>
</item>
<item>
<property name="text">
<string>Odd</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="baudLabel">
<property name="text">
<string>Скорость</string>
</property>
</widget>
</item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="baudCombo"> <widget class="QComboBox" name="baudCombo">
<property name="currentIndex"> <property name="currentIndex">
@@ -166,6 +130,51 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1">
<widget class="QComboBox" name="stopBitsCombo">
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="baudLabel">
<property name="text">
<string>Скорость</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="parityCombo">
<item>
<property name="text">
<string>No</string>
</property>
</item>
<item>
<property name="text">
<string>Even</string>
</property>
</item>
<item>
<property name="text">
<string>Odd</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="dataBitsCombo"> <widget class="QComboBox" name="dataBitsCombo">
<property name="currentIndex"> <property name="currentIndex">
@@ -193,6 +202,13 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="portLabel">
<property name="text">
<string>Порт</string>
</property>
</widget>
</item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QLabel" name="stopBitsLabel"> <widget class="QLabel" name="stopBitsLabel">
<property name="text"> <property name="text">
@@ -200,25 +216,39 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="stopBitsCombo"> <layout class="QGridLayout" name="gridLayout_3">
<item> <item row="0" column="1">
<property name="text"> <widget class="QComboBox" name="comBox">
<string>1</string> <property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property> </property>
</item>
<item>
<property name="text">
<string>3</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="0" column="2">
<widget class="QPushButton" name="updateComBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>45</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Поиск</string>
</property>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
</item> </item>

View File

@@ -25,10 +25,8 @@ QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const
{ {
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
return QVariant(); return QVariant();
Q_ASSERT(m_coils.count() == RowCount); Q_ASSERT(m_coils.count() == RowCount);
Q_ASSERT(m_holdingRegisters.count() == RowCount); Q_ASSERT(m_holdingRegisters.count() == RowCount);
if (index.column() == NumColumn && role == Qt::DisplayRole) if (index.column() == NumColumn && role == Qt::DisplayRole)
return QString::number(index.row()); return QString::number(index.row());
@@ -42,17 +40,14 @@ QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const
return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16)); return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16));
if(index.column() == CurrentUColumn && role == Qt::DisplayRole) if(index.column() == CurrentUColumn && role == Qt::DisplayRole)
return QString("%1 В").arg(QString::number((double)((double)m_currentU.at(index.row())/(double)1000))); return QString("%1 В").arg(QString::number((double)((double)m_currentU.at(index.row())/(double)1000), 'f', 3));
return QVariant(); return QVariant();
} }
QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const
{ {
if (role != Qt::DisplayRole) if (role != Qt::DisplayRole)
return QVariant(); return QVariant();
if (orientation == Qt::Horizontal) { if (orientation == Qt::Horizontal) {
switch (section) { switch (section) {
case NumColumn: case NumColumn:
@@ -76,7 +71,6 @@ bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value
{ {
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
return false; return false;
Q_ASSERT(m_coils.count() == RowCount); Q_ASSERT(m_coils.count() == RowCount);
Q_ASSERT(m_holdingRegisters.count() == RowCount); Q_ASSERT(m_holdingRegisters.count() == RowCount);
@@ -86,7 +80,6 @@ bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value
emit dataChanged(index, index); emit dataChanged(index, index);
return true; return true;
} }
if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers
bool result = false; bool result = false;
quint16 newValue = value.toString().toUShort(&result, 16); quint16 newValue = value.toString().toUShort(&result, 16);
@@ -96,7 +89,6 @@ bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value
emit dataChanged(index, index); emit dataChanged(index, index);
return result; return result;
} }
return false; return false;
} }

0
test.bmp Normal file
View File