Compare commits
25 Commits
59e9fb65a3
...
Pre-releas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9071eb4322 | ||
|
|
227deaf686 | ||
|
|
4ec595d92e | ||
|
|
a9f3d13b5f | ||
|
|
5ae694d254 | ||
|
|
c2a32e3ff5 | ||
|
|
1e3ecd0834 | ||
|
|
5b3faa798b | ||
|
|
93b4a24b8b | ||
|
|
4ae15d8c01 | ||
|
|
190f3337ed | ||
|
|
726d8d24ef | ||
|
|
c9b44e5dab | ||
|
|
14d7907d92 | ||
|
|
b4803e19e2 | ||
|
|
d9f58e72e4 | ||
|
|
a4cdcb7091 | ||
|
|
7dc314d266 | ||
|
|
568ec9b5d3 | ||
|
|
009ac176f9 | ||
|
|
1b7388821e | ||
|
|
fc01a6c06d | ||
|
|
49083ca06d | ||
|
|
d7063703b6 | ||
|
|
5b2a64a39b |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -54,3 +54,6 @@ compile_commands.json
|
||||
|
||||
*_qmlcache.qrc
|
||||
|
||||
|
||||
/Debug
|
||||
/Release
|
||||
|
||||
21
Debug/.qmake.stash
Normal file
21
Debug/.qmake.stash
Normal 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
|
||||
@@ -1,5 +1,11 @@
|
||||
QT += core gui
|
||||
QT += widgets serialport
|
||||
QT += serialbus widgets
|
||||
|
||||
requires(qtConfig(combobox))
|
||||
QT += serialport
|
||||
qtConfig(modbus-serialport): QT += serialport
|
||||
QT += charts
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
@@ -10,22 +16,53 @@ CONFIG += c++11
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
#TEMPLATE = lib
|
||||
#DEFINES += M3KTE_LIBRARY
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# 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.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
adcgraphdialog.cpp \
|
||||
debugterminaldialog.cpp \
|
||||
devicesettingsdialog.cpp \
|
||||
lineringer.cpp \
|
||||
main.cpp \
|
||||
m3kte.cpp
|
||||
m3kte.cpp \
|
||||
multiplesettings.cpp \
|
||||
scanboard.cpp \
|
||||
settingsdialog.cpp \
|
||||
writeregistermodel.cpp
|
||||
|
||||
HEADERS += \
|
||||
m3kte.h
|
||||
adcgraphdialog.h \
|
||||
debugterminaldialog.h \
|
||||
devicesettingsdialog.h \
|
||||
lineringer.h \
|
||||
m3kte.h \
|
||||
multiplesettings.h \
|
||||
scanboard.h \
|
||||
settingsdialog.h \
|
||||
writeregistermodel.h
|
||||
|
||||
FORMS += \
|
||||
m3kte.ui
|
||||
adcgraphdialog.ui \
|
||||
debugTerminalDialog.ui \
|
||||
devicesettingsdialog.ui \
|
||||
lineringer.ui \
|
||||
m3kte.ui \
|
||||
multiplesettings.ui \
|
||||
scanboard.ui \
|
||||
settingsdialog.ui
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${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
|
||||
581
M3KTE_TERM/adcgraphdialog.cpp
Normal file
581
M3KTE_TERM/adcgraphdialog.cpp
Normal file
@@ -0,0 +1,581 @@
|
||||
#include "adcgraphdialog.h"
|
||||
#include "ui_adcgraphdialog.h"
|
||||
#include <QModbusReply>
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QValueAxis>
|
||||
#include <QVBoxLayout> // Добавить этот include
|
||||
#include <QChartView> // Добавить этот include
|
||||
|
||||
// Адреса регистров для АЦП
|
||||
#define REG_ADC_ZERO 555
|
||||
#define REG_ADC_ONE_VOLT 556
|
||||
#define REG_STABLE_START 557
|
||||
#define REG_STABLE_END 558
|
||||
#define REG_TE_NUMBER 564
|
||||
#define REG_ADC_BUFFER_START 571
|
||||
#define REG_ADC_BUFFER_END 1070
|
||||
|
||||
AdcGraphDialog::AdcGraphDialog(QModbusClient *modbusDevice, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AdcGraphDialog),
|
||||
m_modbusDevice(modbusDevice),
|
||||
m_updateTimer(new QTimer(this)),
|
||||
m_boardId(-1),
|
||||
m_boardAddress(-1),
|
||||
m_teNumber(-1),
|
||||
m_adcZero(0),
|
||||
m_adcOneVolt(4096),
|
||||
m_series(new QLineSeries()),
|
||||
m_chart(new QChart()),
|
||||
m_stableStartLine(new QLineSeries()),
|
||||
m_stableEndLine(new QLineSeries()),
|
||||
m_stableStartIndex(-1),
|
||||
m_stableEndIndex(-1),
|
||||
m_startAddress(0),
|
||||
m_registerCount(100)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// Настройка основного графика
|
||||
m_series->setName("АЦП данные");
|
||||
m_chart->addSeries(m_series);
|
||||
|
||||
// Настройка линий стабильного участка
|
||||
m_stableStartLine->setName("Начало стаб. участка");
|
||||
m_stableStartLine->setColor(Qt::red);
|
||||
m_stableStartLine->setPen(QPen(Qt::red, 2, Qt::DashLine));
|
||||
m_chart->addSeries(m_stableStartLine);
|
||||
|
||||
m_stableEndLine->setName("Конец стаб. участка");
|
||||
m_stableEndLine->setColor(Qt::green);
|
||||
m_stableEndLine->setPen(QPen(Qt::green, 2, Qt::DashLine));
|
||||
m_chart->addSeries(m_stableEndLine);
|
||||
|
||||
m_chart->setTitle("График АЦП");
|
||||
m_chart->legend()->setVisible(true);
|
||||
m_chart->legend()->setAlignment(Qt::AlignTop);
|
||||
|
||||
m_axisX = new QValueAxis();
|
||||
m_axisX->setTitleText("Отсчеты АЦП");
|
||||
m_axisX->setRange(0, m_registerCount);
|
||||
m_chart->addAxis(m_axisX, Qt::AlignBottom);
|
||||
m_series->attachAxis(m_axisX);
|
||||
m_stableStartLine->attachAxis(m_axisX);
|
||||
m_stableEndLine->attachAxis(m_axisX);
|
||||
|
||||
m_axisY = new QValueAxis();
|
||||
m_axisY->setTitleText("Напряжение, В");
|
||||
m_axisY->setRange(-1.3, 1.3);
|
||||
m_chart->addAxis(m_axisY, Qt::AlignLeft);
|
||||
m_series->attachAxis(m_axisY);
|
||||
m_stableStartLine->attachAxis(m_axisY);
|
||||
m_stableEndLine->attachAxis(m_axisY);
|
||||
|
||||
QChartView *chartView = new QChartView(m_chart);
|
||||
chartView->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(ui->plotWidget);
|
||||
layout->addWidget(chartView);
|
||||
|
||||
// Подключаем сигналы элементов управления диапазоном
|
||||
connect(ui->registerCountSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, &AdcGraphDialog::on_registerCountChanged);
|
||||
connect(ui->rangeApplyButton, &QPushButton::clicked,
|
||||
this, &AdcGraphDialog::on_rangeApplyClicked);
|
||||
connect(ui->teNumberSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
|
||||
this, &AdcGraphDialog::on_teNumberChanged);
|
||||
|
||||
connect(m_updateTimer, &QTimer::timeout, this, &AdcGraphDialog::onUpdateTimer);
|
||||
connect(ui->closeBtn, &QPushButton::clicked, this, &AdcGraphDialog::on_closeBtn_clicked);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AdcGraphDialog::~AdcGraphDialog()
|
||||
{
|
||||
stopGraph();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AdcGraphDialog::setModbusDevice(QModbusClient *device)
|
||||
{
|
||||
m_modbusDevice = device;
|
||||
}
|
||||
|
||||
void AdcGraphDialog::on_teNumberChanged(int value)
|
||||
{
|
||||
if(m_teNumber != value)
|
||||
setTENumber(m_boardId, value);
|
||||
}
|
||||
|
||||
void AdcGraphDialog::setTENumber(int boardID, int teNumber)
|
||||
{
|
||||
if (m_boardAddress == -1) return;
|
||||
|
||||
m_teNumber = teNumber;
|
||||
m_boardId = boardID;
|
||||
m_boardAddress = m_boardId + 1;
|
||||
|
||||
// Обновляем заголовок окна
|
||||
setWindowTitle(QString("График АЦП - Плата %1, ТЭ %2 (адр %3-%4)")
|
||||
.arg(m_boardId + 1)
|
||||
.arg(m_teNumber)
|
||||
.arg(m_startAddress)
|
||||
.arg(m_startAddress + m_registerCount - 1));
|
||||
|
||||
// Записываем новый номер ТЭ в устройство
|
||||
if (m_modbusDevice) {
|
||||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, REG_TE_NUMBER, 1);
|
||||
unit.setValue(0, teNumber);
|
||||
|
||||
if (auto *reply = m_modbusDevice->sendWriteRequest(unit, m_boardAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply, teNumber]() {
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
qDebug() << "TE number changed to:" << teNumber;
|
||||
// Можно обновить данные сразу после смены ТЭ
|
||||
readAdcDataAndIndices();
|
||||
} else {
|
||||
qDebug() << "Error writing TE number:" << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
ui->teNumberSpinBox->setValue(teNumber);
|
||||
}
|
||||
|
||||
void AdcGraphDialog::readCalibrationValues()
|
||||
{
|
||||
if (!m_modbusDevice || m_boardAddress == -1) return;
|
||||
|
||||
// Читаем калибровочные значения (регистры 555 и 556)
|
||||
QModbusDataUnit unit(QModbusDataUnit::InputRegisters, REG_ADC_ZERO, 2);
|
||||
|
||||
if (auto *reply = m_modbusDevice->sendReadRequest(unit, m_boardAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply]() {
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit result = reply->result();
|
||||
if (result.valueCount() >= 2) {
|
||||
m_adcZero = result.value(0);
|
||||
m_adcOneVolt = result.value(1);
|
||||
//qDebug() << "Calibration values - Zero:" << m_adcZero << "1V:" << m_adcOneVolt;
|
||||
}
|
||||
} else {
|
||||
//qDebug() << "Error reading calibration:" << reply->errorString();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdcGraphDialog::readStableIndices()
|
||||
{
|
||||
if (!m_modbusDevice || m_boardAddress == -1) return;
|
||||
|
||||
// Читаем индексы стабильного участка (регистры 557 и 558)
|
||||
QModbusDataUnit unit(QModbusDataUnit::InputRegisters, REG_STABLE_START, 2);
|
||||
|
||||
if (auto *reply = m_modbusDevice->sendReadRequest(unit, m_boardAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &AdcGraphDialog::onStableIndicesReady);
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AdcGraphDialog::onStableIndicesReady()
|
||||
{
|
||||
auto *reply = qobject_cast<QModbusReply*>(sender());
|
||||
if (!reply) return;
|
||||
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit result = reply->result();
|
||||
if (result.valueCount() >= 2) {
|
||||
m_stableStartIndex = result.value(0);
|
||||
m_stableEndIndex = result.value(1);
|
||||
//qDebug() << "Stable indices updated - Start:" << m_stableStartIndex << "End:" << m_stableEndIndex;
|
||||
updateStableLines();
|
||||
|
||||
// Обновляем статистику с новыми индексами
|
||||
updateStatisticsWithStableInfo();
|
||||
}
|
||||
} else {
|
||||
//qDebug() << "Error reading stable indices:" << reply->errorString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void AdcGraphDialog::updateStatistics()
|
||||
{
|
||||
if (m_series->count() > 0) {
|
||||
double min = 1000, max = -1000, sum = 0;
|
||||
for (const QPointF &point : m_series->points()) {
|
||||
double y = point.y();
|
||||
if (y < min) min = y;
|
||||
if (y > max) max = y;
|
||||
sum += y;
|
||||
}
|
||||
double avg = sum / m_series->count();
|
||||
|
||||
ui->minLabel->setText(QString::number(min, 'f', 3) + " В");
|
||||
ui->maxLabel->setText(QString::number(max, 'f', 3) + " В");
|
||||
ui->avgLabel->setText(QString::number(avg, 'f', 3) + " В");
|
||||
|
||||
// Обновляем информацию о стабильном участке
|
||||
updateStatisticsWithStableInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AdcGraphDialog::updateStatisticsWithStableInfo()
|
||||
{
|
||||
if (m_series->count() > 0) {
|
||||
// Используем абсолютные индексы в формате "начальный-конечный"
|
||||
ui->samplesLabel->setText(
|
||||
QString("%1 отсч. (адр %2-%3) [стаб: %4-%5]")
|
||||
.arg(m_series->count())
|
||||
.arg(m_startAddress)
|
||||
.arg(m_startAddress + m_registerCount - 1)
|
||||
.arg(m_stableStartIndex) // Абсолютный начальный индекс
|
||||
.arg(m_stableEndIndex) // Абсолютный конечный индекс
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AdcGraphDialog::updateStableLines()
|
||||
{
|
||||
// Очищаем предыдущие линии
|
||||
m_stableStartLine->clear();
|
||||
m_stableEndLine->clear();
|
||||
|
||||
// Получаем текущий диапазон оси Y
|
||||
double yMin = m_axisY->min();
|
||||
double yMax = m_axisY->max();
|
||||
|
||||
// Добавляем вертикальную линию для начала стабильного участка
|
||||
// Учитываем текущий диапазон отображения
|
||||
if (m_stableStartIndex >= m_startAddress && m_stableStartIndex < m_startAddress + m_registerCount) {
|
||||
int relativeStartIndex = m_stableStartIndex - m_startAddress;
|
||||
m_stableStartLine->append(relativeStartIndex, yMin);
|
||||
m_stableStartLine->append(relativeStartIndex, yMax);
|
||||
}
|
||||
|
||||
// Добавляем вертикальную линию для конца стабильного участка
|
||||
if (m_stableEndIndex >= m_startAddress && m_stableEndIndex < m_startAddress + m_registerCount) {
|
||||
int relativeEndIndex = m_stableEndIndex - m_startAddress;
|
||||
m_stableEndLine->append(relativeEndIndex, yMin);
|
||||
m_stableEndLine->append(relativeEndIndex, yMax);
|
||||
}
|
||||
}
|
||||
|
||||
void AdcGraphDialog::updateGraphRange()
|
||||
{
|
||||
// Обновляем диапазон оси X
|
||||
m_axisX->setRange(0, m_registerCount);
|
||||
m_axisX->setTitleText(QString("Отсчеты АЦП (%1-%2)").arg(m_startAddress).arg(m_startAddress + m_registerCount - 1));
|
||||
|
||||
// Сбрасываем ось Y к разумному диапазону по умолчанию
|
||||
m_axisY->setRange(-1.2, 1.2);
|
||||
|
||||
// Обновляем линии стабильного участка с учетом нового диапазона
|
||||
updateStableLines();
|
||||
}
|
||||
|
||||
void AdcGraphDialog::readAdcDataAndIndices()
|
||||
{
|
||||
if (!m_modbusDevice || m_boardAddress == -1) return;
|
||||
|
||||
// Создаем один запрос для данных АЦП + индексов стабильности
|
||||
// Адреса: данные АЦП (571+), индексы (557-558)
|
||||
int start = m_startAddress + REG_ADC_BUFFER_START;
|
||||
int count = m_registerCount;
|
||||
|
||||
// Читаем индексы стабильности (557-558) и данные АЦП одним запросом
|
||||
QModbusDataUnit unit(QModbusDataUnit::InputRegisters, REG_STABLE_START,
|
||||
count + (start - REG_STABLE_START));
|
||||
|
||||
//qDebug() << "Reading combined data from address" << REG_STABLE_START << "count:" << unit.valueCount();
|
||||
|
||||
if (auto *reply = m_modbusDevice->sendReadRequest(unit, m_boardAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &AdcGraphDialog::onCombinedDataReady);
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
} else {
|
||||
//qDebug() << "Failed to send combined data read request";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AdcGraphDialog::onCombinedDataReady()
|
||||
{
|
||||
auto *reply = qobject_cast<QModbusReply*>(sender());
|
||||
if (!reply) return;
|
||||
|
||||
if((m_adcZero == 0) || (m_adcOneVolt == 0))
|
||||
{
|
||||
readCalibrationValues();
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit result = reply->result();
|
||||
|
||||
// Обрабатываем индексы стабильности (первые 2 регистра)
|
||||
if (result.valueCount() >= 2) {
|
||||
m_stableStartIndex = result.value(0);
|
||||
m_stableEndIndex = result.value(1);
|
||||
//qDebug() << "Stable indices - Start:" << m_stableStartIndex << "End:" << m_stableEndIndex;
|
||||
}
|
||||
|
||||
// Обрабатываем данные АЦП (остальные регистры)
|
||||
int adcDataStartIndex = (m_startAddress + REG_ADC_BUFFER_START) - REG_STABLE_START;
|
||||
|
||||
// Очищаем предыдущие данные
|
||||
m_series->clear();
|
||||
|
||||
// Добавляем новые точки и определяем диапазон
|
||||
double minVoltage = 1000, maxVoltage = -1000;
|
||||
for (int i = 0; i < m_registerCount; ++i) {
|
||||
if (adcDataStartIndex + i < result.valueCount()) {
|
||||
double voltage = convertAdcToVoltage(result.value(adcDataStartIndex + i));
|
||||
m_series->append(i, voltage);
|
||||
|
||||
// Обновляем мин/макс для автоматического масштабирования
|
||||
if (voltage < minVoltage) minVoltage = voltage;
|
||||
if (voltage > maxVoltage) maxVoltage = voltage;
|
||||
}
|
||||
}
|
||||
|
||||
// Обновляем график и статистику
|
||||
updateYAxisRange(minVoltage, maxVoltage);
|
||||
updateStableLines();
|
||||
updateStatistics();
|
||||
|
||||
} else {
|
||||
// qDebug() << "Error reading combined data:" << reply->errorString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void AdcGraphDialog::readAdcBuffer()
|
||||
{
|
||||
if (!m_modbusDevice || m_boardAddress == -1) return;
|
||||
|
||||
// Читаем выбранный диапазон буфера АЦП
|
||||
QModbusDataUnit unit(QModbusDataUnit::InputRegisters, m_startAddress+REG_ADC_BUFFER_START, m_registerCount);
|
||||
|
||||
// qDebug() << "Reading ADC buffer from address" << m_startAddress << "count:" << m_registerCount;
|
||||
|
||||
if (auto *reply = m_modbusDevice->sendReadRequest(unit, m_boardAddress)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, &AdcGraphDialog::onReadReady);
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
} else {
|
||||
// qDebug() << "Failed to send ADC buffer read request";
|
||||
}
|
||||
}
|
||||
|
||||
void AdcGraphDialog::startGraph(int boardId, int teNumber)
|
||||
{
|
||||
m_boardId = boardId;
|
||||
m_teNumber = teNumber;
|
||||
m_boardAddress = boardId + 1;
|
||||
|
||||
// Устанавливаем начальное значение в спинбокс
|
||||
ui->teNumberSpinBox->setValue(teNumber);
|
||||
|
||||
setWindowTitle(QString("График АЦП - Плата %1, ТЭ %2 (адр %3-%4)")
|
||||
.arg(boardId + 1)
|
||||
.arg(teNumber)
|
||||
.arg(m_startAddress)
|
||||
.arg(m_startAddress + m_registerCount - 1));
|
||||
|
||||
// Очищаем предыдущие данные
|
||||
m_series->clear();
|
||||
m_stableStartLine->clear();
|
||||
m_stableEndLine->clear();
|
||||
|
||||
// Обновляем диапазон графика
|
||||
updateGraphRange();
|
||||
|
||||
readCalibrationValues();
|
||||
|
||||
// Записываем начальный номер ТЭ
|
||||
setTENumber(m_boardAddress, teNumber);
|
||||
|
||||
m_updateTimer->start(m_timeout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AdcGraphDialog::setTimeout(int timeout)
|
||||
{
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
void AdcGraphDialog::stopGraph()
|
||||
{
|
||||
m_updateTimer->stop();
|
||||
m_boardId = -1;
|
||||
m_boardAddress = -1;
|
||||
|
||||
// Отменяем все pending запросы Modbus
|
||||
if (m_modbusDevice) {
|
||||
m_modbusDevice->disconnect(this); // Отключаем все сигналы
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AdcGraphDialog::onUpdateTimer()
|
||||
{
|
||||
if (m_boardAddress == -1) return;
|
||||
// Читаем и буфер АЦП, и индексы стабильности каждый период
|
||||
readAdcDataAndIndices();
|
||||
}
|
||||
|
||||
void AdcGraphDialog::onReadReady()
|
||||
{
|
||||
auto *reply = qobject_cast<QModbusReply*>(sender());
|
||||
if (!reply) return;
|
||||
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit result = reply->result();
|
||||
|
||||
// Очищаем предыдущие данные
|
||||
m_series->clear();
|
||||
|
||||
// Добавляем новые точки и определяем диапазон
|
||||
double minVoltage = 1000, maxVoltage = -1000;
|
||||
for (int i = 0; i < result.valueCount(); ++i) {
|
||||
double voltage = convertAdcToVoltage(result.value(i));
|
||||
m_series->append(i, voltage);
|
||||
|
||||
// Обновляем мин/макс для автоматического масштабирования
|
||||
if (voltage < minVoltage) minVoltage = voltage;
|
||||
if (voltage > maxVoltage) maxVoltage = voltage;
|
||||
}
|
||||
|
||||
// Автоматически настраиваем диапазон оси Y
|
||||
updateYAxisRange(minVoltage, maxVoltage);
|
||||
|
||||
// Обновляем линии стабильного участка
|
||||
updateStableLines();
|
||||
|
||||
// Обновляем статистику
|
||||
if (m_series->count() > 0) {
|
||||
double min = 1000, max = -1000, sum = 0;
|
||||
for (const QPointF &point : m_series->points()) {
|
||||
double y = point.y();
|
||||
if (y < min) min = y;
|
||||
if (y > max) max = y;
|
||||
sum += y;
|
||||
}
|
||||
double avg = sum / m_series->count();
|
||||
|
||||
ui->minLabel->setText(QString::number(min, 'f', 3) + " В");
|
||||
ui->maxLabel->setText(QString::number(max, 'f', 3) + " В");
|
||||
ui->avgLabel->setText(QString::number(avg, 'f', 3) + " В");
|
||||
|
||||
// Обновляем информацию о стабильном участке
|
||||
updateStatisticsWithStableInfo();
|
||||
}
|
||||
|
||||
} else {
|
||||
// qDebug() << "Error reading ADC buffer:" << reply->errorString();
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void AdcGraphDialog::updateYAxisRange(double minVoltage, double maxVoltage)
|
||||
{
|
||||
// Добавляем запас 10% к диапазону
|
||||
double range = maxVoltage - minVoltage;
|
||||
double margin = range * 0.1;
|
||||
|
||||
double yMin = minVoltage - margin;
|
||||
double yMax = maxVoltage + margin;
|
||||
|
||||
// Если диапазон слишком маленький или слишком большой, устанавливаем разумные пределы
|
||||
// if ((range < 0.1) || ((maxVoltage > 0.5) && (minVoltage < -0.5)))
|
||||
// {
|
||||
// yMin = -1.5;
|
||||
// yMax = 1.5;
|
||||
// }
|
||||
// else if(maxVoltage > 0.5) {
|
||||
// yMin = -0.1;
|
||||
// yMax = 1.5;
|
||||
// }
|
||||
// else if(minVoltage < -0.5)
|
||||
// {
|
||||
// yMin = -1.5;
|
||||
// yMax =0.1;
|
||||
// }
|
||||
// else
|
||||
{
|
||||
yMin = -1.5;
|
||||
yMax = 1.5;
|
||||
}
|
||||
|
||||
// Ограничиваем разумными пределами
|
||||
yMin = qMax(yMin, -5.0); // Не ниже -5В
|
||||
yMax = qMin(yMax, 5.0); // Не выше 5В
|
||||
|
||||
// Устанавливаем новый диапазон
|
||||
m_axisY->setRange(yMin, yMax);
|
||||
|
||||
// Обновляем линии стабильного участка с новым диапазоном
|
||||
updateStableLines();
|
||||
}
|
||||
|
||||
|
||||
double AdcGraphDialog::convertAdcToVoltage(quint16 adcValue)
|
||||
{
|
||||
if (m_adcOneVolt == m_adcZero) return 0;
|
||||
return (adcValue - m_adcZero) * 1.1 / (m_adcOneVolt - m_adcZero);
|
||||
}
|
||||
|
||||
|
||||
void AdcGraphDialog::on_registerCountChanged(int value)
|
||||
{
|
||||
m_registerCount = value;
|
||||
// qDebug() << "Register count changed to:" << value;
|
||||
}
|
||||
|
||||
void AdcGraphDialog::on_rangeApplyClicked()
|
||||
{
|
||||
// qDebug() << "Applying new range - Start:" << m_startAddress << "Count:" << m_registerCount;
|
||||
updateGraphRange();
|
||||
|
||||
// Немедленно обновляем данные
|
||||
if (m_boardAddress != -1) {
|
||||
readAdcBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
void AdcGraphDialog::on_closeBtn_clicked()
|
||||
{
|
||||
stopGraph();
|
||||
reject(); // Или accept() в зависимости от логики
|
||||
}
|
||||
97
M3KTE_TERM/adcgraphdialog.h
Normal file
97
M3KTE_TERM/adcgraphdialog.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef ADCGRAPHDIALOG_H
|
||||
#define ADCGRAPHDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
#include <QtCharts>
|
||||
#include <QModbusClient>
|
||||
|
||||
QT_CHARTS_USE_NAMESPACE
|
||||
|
||||
// Forward declaration
|
||||
class QModbusClient;
|
||||
|
||||
namespace Ui {
|
||||
class AdcGraphDialog;
|
||||
}
|
||||
|
||||
class AdcGraphDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AdcGraphDialog(QModbusClient *modbusDevice, QWidget *parent = nullptr);
|
||||
~AdcGraphDialog();
|
||||
|
||||
void setTENumber(int boardID, int teNumber);
|
||||
void setModbusDevice(QModbusClient *device);
|
||||
void startGraph(int boardId, int teNumber);
|
||||
void stopGraph();
|
||||
void setTimeout(int timeout);
|
||||
void readyClose();
|
||||
|
||||
signals:
|
||||
void dialogClosed();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override {
|
||||
stopGraph();
|
||||
event->accept();
|
||||
emit dialogClosed();
|
||||
QDialog::closeEvent(event);
|
||||
}
|
||||
|
||||
private slots:
|
||||
void on_teNumberChanged(int value);
|
||||
void onUpdateTimer();
|
||||
void onReadReady();
|
||||
void onStableIndicesReady();
|
||||
void on_closeBtn_clicked();
|
||||
void on_registerCountChanged(int value);
|
||||
void on_rangeApplyClicked();
|
||||
|
||||
private:
|
||||
Ui::AdcGraphDialog *ui;
|
||||
QModbusClient *m_modbusDevice;
|
||||
QTimer *m_updateTimer;
|
||||
int m_boardId;
|
||||
int m_boardAddress;
|
||||
int m_teNumber;
|
||||
int m_timeout;
|
||||
|
||||
// Калибровочные значения
|
||||
double m_adcZero;
|
||||
double m_adcOneVolt;
|
||||
|
||||
// Для отображения стабильного участка
|
||||
QLineSeries *m_stableStartLine;
|
||||
QLineSeries *m_stableEndLine;
|
||||
int m_stableStartIndex;
|
||||
int m_stableEndIndex;
|
||||
|
||||
// Данные графика
|
||||
QLineSeries *m_series;
|
||||
QValueAxis *m_axisX;
|
||||
QValueAxis *m_axisY;
|
||||
QChart *m_chart; // Добавить указатель на chart
|
||||
|
||||
// Управление диапазоном регистров
|
||||
int m_startAddress;
|
||||
int m_registerCount;
|
||||
|
||||
void updateStatistics();
|
||||
void readAdcDataAndIndices();
|
||||
void onCombinedDataReady();
|
||||
void updateStatisticsWithStableInfo();
|
||||
void updateYAxisRange(double minVoltage, double maxVoltage);
|
||||
void setupRangeControls();
|
||||
void updateGraphRange();
|
||||
void readStableIndices();
|
||||
void updateStableLines();
|
||||
void readCalibrationValues();
|
||||
void readAdcBuffer();
|
||||
double convertAdcToVoltage(quint16 adcValue);
|
||||
};
|
||||
|
||||
#endif // ADCGRAPHDIALOG_H
|
||||
162
M3KTE_TERM/adcgraphdialog.ui
Normal file
162
M3KTE_TERM/adcgraphdialog.ui
Normal file
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AdcGraphDialog</class>
|
||||
<widget class="QDialog" name="AdcGraphDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>График АЦП</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="rangeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="registerCountLabel">
|
||||
<property name="text">
|
||||
<string>Количество:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="registerCountSpinBox">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="rangeApplyButton">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Номер ТЭ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="teNumberSpinBox">
|
||||
<property name="maximum">
|
||||
<number>85</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="plotWidget" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Мин:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="minLabel">
|
||||
<property name="text">
|
||||
<string>0.000 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Макс:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="maxLabel">
|
||||
<property name="text">
|
||||
<string>0.000 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Средн:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="avgLabel">
|
||||
<property name="text">
|
||||
<string>0.000 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Сэмплов:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="samplesLabel">
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QPushButton" name="closeBtn">
|
||||
<property name="text">
|
||||
<string>Закрыть</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
796
M3KTE_TERM/debugTerminalDialog.ui
Normal file
796
M3KTE_TERM/debugTerminalDialog.ui
Normal file
@@ -0,0 +1,796 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DebugTerminalDialog</class>
|
||||
<widget class="QDialog" name="DebugTerminalDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1188</width>
|
||||
<height>578</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QGroupBox" name="DbgPlate_4">
|
||||
<property name="title">
|
||||
<string>Плата 3</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_25">
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="leds_3">
|
||||
<property name="title">
|
||||
<string>Тест светодиодов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_13">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ledWorkTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ledWarnTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="ledErrTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="ledConnectTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Связь</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ledVH1TestChkBox_3">
|
||||
<property name="text">
|
||||
<string>LED VH1 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ledVH2TestChkBox_3">
|
||||
<property name="text">
|
||||
<string>LED VH2 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="ledVH3TestChkBox_3">
|
||||
<property name="text">
|
||||
<string>LED VH3 (Красный)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enableLedTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Тест ламп и дискретных сигналов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_11">
|
||||
<property name="title">
|
||||
<string>Вызов функций</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="pollTECallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Опрос ТЭ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="continiusCallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Непрерывный вызов калибр. и опроса</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="calibrateCallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Калибровка</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="getHardfaultCallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Генерация HardFault</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="resetDefaultCallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Настройки по умолчанию</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="resetKeyCallChkBox_3">
|
||||
<property name="text">
|
||||
<string>Сбросить все ключи</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="discs_3">
|
||||
<property name="title">
|
||||
<string>Тест дискретных сигналов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="discErrTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VsciTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 Vsci</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="discWarnTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="discWorkTestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="discErr5TestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="discErr24TestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Ошибка 24 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VATestChkBox_3">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 VA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="DbgPlate_3">
|
||||
<property name="title">
|
||||
<string>Плата 2</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_24">
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="leds_2">
|
||||
<property name="title">
|
||||
<string>Тест светодиодов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_21">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ledWorkTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ledWarnTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="ledErrTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="ledConnectTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Связь</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ledVH1TestChkBox_2">
|
||||
<property name="text">
|
||||
<string>LED VH1 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ledVH2TestChkBox_2">
|
||||
<property name="text">
|
||||
<string>LED VH2 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="ledVH3TestChkBox_2">
|
||||
<property name="text">
|
||||
<string>LED VH3 (Красный)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enableLedTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Тест ламп и дискретных сигналов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_21">
|
||||
<property name="title">
|
||||
<string>Вызов функций</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_19">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="calibrateCallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Калибровка</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="resetDefaultCallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Настройки по умолчанию</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="resetKeyCallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Сбросить все ключи</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="pollTECallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Опрос ТЭ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="getHardfaultCallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Генерация HardFault</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="continiusCallChkBox_2">
|
||||
<property name="text">
|
||||
<string>Непрерывный вызов калибр. и опроса</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="discs_2">
|
||||
<property name="title">
|
||||
<string>Тест дискретных сигналов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_20">
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VsciTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 Vsci</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="discErr24TestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Ошибка 24 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="discWarnTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="discWorkTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="discErr5TestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="discErrTestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VATestChkBox_2">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 VA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="DbgPlate_1">
|
||||
<property name="title">
|
||||
<string>Плата 1</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Вызов функций</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="pollTECallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Опрос ТЭ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="continiusCallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Непрерывный вызов калибр. и опроса</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="calibrateCallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Калибровка</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QCheckBox" name="getHardfaultCallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Генерация HardFault</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="resetDefaultCallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Настройки по умолчанию</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="resetKeyCallChkBox_1">
|
||||
<property name="text">
|
||||
<string>Сбросить все ключи</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="leds_1">
|
||||
<property name="title">
|
||||
<string>Тест светодиодов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ledWorkTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ledWarnTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="ledErrTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="ledConnectTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Связь</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ledVH1TestChkBox_1">
|
||||
<property name="text">
|
||||
<string>LED VH1 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ledVH2TestChkBox_1">
|
||||
<property name="text">
|
||||
<string>LED VH2 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="ledVH3TestChkBox_1">
|
||||
<property name="text">
|
||||
<string>LED VH3 (Красный)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="discs_1">
|
||||
<property name="title">
|
||||
<string>Тест дискретных сигналов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VsciTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 Vsci</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="discErr24TestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Ошибка 24 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="discWarnTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="discErr5TestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="discWorkTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="discErrTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VATestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 VA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enableLedTestChkBox_1">
|
||||
<property name="text">
|
||||
<string>Тест ламп и дискретных сигналов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QGroupBox" name="DbgPlate_2">
|
||||
<property name="title">
|
||||
<string>Плата 4</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_23">
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="discs_4">
|
||||
<property name="title">
|
||||
<string>Тест дискретных сигналов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_16">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="discWarnTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="discErrTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VsciTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 Vsci</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="discWorkTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="discErr5TestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="discErr24TestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Ошибка 24 В</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="discErr5VATestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Ошибка 5 VA</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QGroupBox" name="leds_4">
|
||||
<property name="title">
|
||||
<string>Тест светодиодов</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_17">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="ledWorkTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Работа</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="ledWarnTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Предупреждение</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="ledErrTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Авария</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="ledConnectTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Связь</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="ledVH1TestChkBox_4">
|
||||
<property name="text">
|
||||
<string>LED VH1 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="ledVH2TestChkBox_4">
|
||||
<property name="text">
|
||||
<string>LED VH2 (Зеленый)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="ledVH3TestChkBox_4">
|
||||
<property name="text">
|
||||
<string>LED VH3 (Красный)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="enableLedTestChkBox_4">
|
||||
<property name="text">
|
||||
<string>Тест ламп и дискретных сигналов</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_16">
|
||||
<property name="title">
|
||||
<string>Вызов функций</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_15">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="pollTECallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Опрос ТЭ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="continiusCallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Непрерывный вызов калибр. и опроса</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="calibrateCallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Калибровка</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="getHardfaultCallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Генерация HardFault</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="resetDefaultCallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Настройки по умолчанию</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="resetKeyCallChkBox_4">
|
||||
<property name="text">
|
||||
<string>Сбросить все ключи</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DebugTerminalDialog</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>DebugTerminalDialog</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>
|
||||
811
M3KTE_TERM/debugterminaldialog.cpp
Normal file
811
M3KTE_TERM/debugterminaldialog.cpp
Normal file
@@ -0,0 +1,811 @@
|
||||
#include "debugterminaldialog.h"
|
||||
#include "ui_debugTerminalDialog.h"
|
||||
#include "adcgraphdialog.h"
|
||||
#include <QDebug>
|
||||
#include <QShowEvent>
|
||||
#include <QCloseEvent>
|
||||
#include <QAbstractButton>
|
||||
|
||||
DebugTerminalDialog::DebugTerminalDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DebugTerminalDialog),
|
||||
m_adcGraphDialog(nullptr),
|
||||
m_modbusDevice(nullptr)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
boards[0].error24V = ui->discErr24TestChkBox_1;
|
||||
boards[0].error5V = ui->discErr5TestChkBox_1;
|
||||
boards[0].error5VSCI = ui->discErr5VsciTestChkBox_1;
|
||||
boards[0].error5VA = ui->discErr5VATestChkBox_1;
|
||||
|
||||
boards[1].error24V = ui->discErr24TestChkBox_2;
|
||||
boards[1].error5V = ui->discErr5TestChkBox_2;
|
||||
boards[1].error5VSCI = ui->discErr5VsciTestChkBox_2;
|
||||
boards[1].error5VA = ui->discErr5VATestChkBox_2;
|
||||
|
||||
boards[2].error24V = ui->discErr24TestChkBox_3;
|
||||
boards[2].error5V = ui->discErr5TestChkBox_3;
|
||||
boards[2].error5VSCI = ui->discErr5VsciTestChkBox_3;
|
||||
boards[2].error5VA = ui->discErr5VATestChkBox_3;
|
||||
|
||||
boards[3].error24V = ui->discErr24TestChkBox_4;
|
||||
boards[3].error5V = ui->discErr5TestChkBox_4;
|
||||
boards[3].error5VSCI = ui->discErr5VsciTestChkBox_4;
|
||||
boards[3].error5VA = ui->discErr5VATestChkBox_4;
|
||||
initializeConnections();
|
||||
|
||||
// Создаем AdcGraphDialog с nullptr
|
||||
m_adcGraphDialog = new AdcGraphDialog(nullptr, this);
|
||||
}
|
||||
|
||||
DebugTerminalDialog::~DebugTerminalDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
void DebugTerminalDialog::setMainTerm(M3KTE* term)
|
||||
{
|
||||
mainTerm = term;
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::setModbusDevice(QModbusClient *device)
|
||||
{
|
||||
m_modbusDevice = device;
|
||||
if (m_adcGraphDialog && device) {
|
||||
m_adcGraphDialog->setModbusDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::setDebugTerminalCoil(int enable)
|
||||
{
|
||||
writeCoil(0, COIL_DEBUG_MODE, enable);
|
||||
writeCoil(1, COIL_DEBUG_MODE, enable);
|
||||
writeCoil(2, COIL_DEBUG_MODE, enable);
|
||||
writeCoil(3, COIL_DEBUG_MODE, enable);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::showEvent(QShowEvent *event)
|
||||
{
|
||||
QDialog::showEvent(event);
|
||||
// При открытии окна записываем в коил 555 значение "1"
|
||||
|
||||
resetAll();
|
||||
|
||||
setDebugTerminalCoil(1);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::closeEvent(QCloseEvent *event)
|
||||
{
|
||||
// При закрытии окна записываем в коил 555 значение "0"
|
||||
setDebugTerminalCoil(0);
|
||||
QDialog::closeEvent(event);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::initializeConnections()
|
||||
{
|
||||
// // Подключаем кнопки OK и RestoreDefaults
|
||||
// connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &DebugTerminalDialog::on_buttonBox_clicked);
|
||||
|
||||
// // Подключаем все чекбоксы для платы 1
|
||||
// connect(ui->continiusCallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_continiusCallChkBox_1_stateChanged);
|
||||
// connect(ui->calibrateCallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_calibrateCallChkBox_1_stateChanged);
|
||||
// connect(ui->pollTECallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_pollTECallChkBox_1_stateChanged);
|
||||
// connect(ui->resetKeyCallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_resetKeyCallChkBox_1_stateChanged);
|
||||
// connect(ui->resetDefaultCallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_resetDefaultCallChkBox_1_stateChanged);
|
||||
// connect(ui->getHardfaultCallChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_getHardfaultCallChkBox_1_stateChanged);
|
||||
|
||||
|
||||
// connect(ui->enableLedTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::enableLedTestChkBox_1_stateChanged);
|
||||
|
||||
// connect(ui->discWorkTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discWorkTestChkBox_1_stateChanged);
|
||||
// connect(ui->discWarnTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discWarnTestChkBox_1_stateChanged);
|
||||
// connect(ui->discErrTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErrTestChkBox_1_stateChanged);
|
||||
|
||||
|
||||
// connect(ui->discErr24TestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr24TestChkBox_1_stateChanged);
|
||||
// ui->discErr24TestChkBox_1->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5TestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5TestChkBox_1_stateChanged);
|
||||
// ui->discErr5TestChkBox_1->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5VsciTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5VsciTestChkBox_1_stateChanged);
|
||||
// ui->discErr5VsciTestChkBox_1->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5VATestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5VATestChkBox_1_stateChanged);
|
||||
// ui->discErr5VATestChkBox_1->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
|
||||
// connect(ui->ledWorkTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledWorkTestChkBox_1_stateChanged);
|
||||
// connect(ui->ledWarnTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledWarnTestChkBox_1_stateChanged);
|
||||
// connect(ui->ledErrTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledErrTestChkBox_1_stateChanged);
|
||||
// connect(ui->ledConnectTestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledConnectTestChkBox_1_stateChanged);
|
||||
// connect(ui->ledVH1TestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH1TestChkBox_1_stateChanged);
|
||||
// connect(ui->ledVH2TestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH2TestChkBox_1_stateChanged);
|
||||
// connect(ui->ledVH3TestChkBox_1, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH3TestChkBox_1_stateChanged);
|
||||
|
||||
// // Подключаем все чекбоксы для платы 2
|
||||
// connect(ui->continiusCallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_continiusCallChkBox_2_stateChanged);
|
||||
// connect(ui->calibrateCallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_calibrateCallChkBox_2_stateChanged);
|
||||
// connect(ui->pollTECallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_pollTECallChkBox_2_stateChanged);
|
||||
// connect(ui->resetKeyCallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_resetKeyCallChkBox_2_stateChanged);
|
||||
// connect(ui->resetDefaultCallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_resetDefaultCallChkBox_2_stateChanged);
|
||||
// connect(ui->getHardfaultCallChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_getHardfaultCallChkBox_2_stateChanged);
|
||||
|
||||
// connect(ui->enableLedTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::enableLedTestChkBox_2_stateChanged);
|
||||
|
||||
// connect(ui->discWorkTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discWorkTestChkBox_2_stateChanged);
|
||||
// connect(ui->discWarnTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discWarnTestChkBox_2_stateChanged);
|
||||
// connect(ui->discErrTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErrTestChkBox_2_stateChanged);
|
||||
|
||||
// connect(ui->discErr24TestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr24TestChkBox_2_stateChanged);
|
||||
// ui->discErr24TestChkBox_2->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5TestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5TestChkBox_2_stateChanged);
|
||||
// ui->discErr5TestChkBox_2->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5VsciTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5VsciTestChkBox_2_stateChanged);
|
||||
// ui->discErr5VsciTestChkBox_2->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
// connect(ui->discErr5VATestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_discErr5VATestChkBox_2_stateChanged);
|
||||
// ui->discErr5VATestChkBox_2->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
|
||||
// connect(ui->ledWorkTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledWorkTestChkBox_2_stateChanged);
|
||||
// connect(ui->ledWarnTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledWarnTestChkBox_2_stateChanged);
|
||||
// connect(ui->ledErrTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledErrTestChkBox_2_stateChanged);
|
||||
// connect(ui->ledConnectTestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledConnectTestChkBox_2_stateChanged);
|
||||
// connect(ui->ledVH1TestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH1TestChkBox_2_stateChanged);
|
||||
// connect(ui->ledVH2TestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH2TestChkBox_2_stateChanged);
|
||||
// connect(ui->ledVH3TestChkBox_2, &QCheckBox::stateChanged, this, &DebugTerminalDialog::on_ledVH3TestChkBox_2_stateChanged);
|
||||
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::updateConnectionStatus(int boardID, bool connected)
|
||||
{
|
||||
// Обновляем визуальное отображение статуса соединения
|
||||
// Можно изменить цвет рамки или добавить индикатор
|
||||
Q_UNUSED(boardID);
|
||||
Q_UNUSED(connected);
|
||||
// Реализация по необходимости
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
switch (ui->buttonBox->buttonRole(button)) {
|
||||
case QDialogButtonBox::ResetRole:
|
||||
resetAll();
|
||||
break;
|
||||
case QDialogButtonBox::AcceptRole:
|
||||
accept();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Реализация слотов для вызова функций платы 1
|
||||
void DebugTerminalDialog::on_continiusCallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_CONTINUOUS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_calibrateCallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_CALIBRATE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_pollTECallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_POLL_TE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetKeyCallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_RESET_KEYS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetDefaultCallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_RESET_DEFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_getHardfaultCallChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_HARDFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для теста дискретных сигналов платы 1
|
||||
void DebugTerminalDialog::on_enableLedTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_TEST_ENABLE, state == Qt::Checked ? 1 : 0);
|
||||
ui->leds_1->setEnabled(state);
|
||||
ui->discs_1->setEnabled(state);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWorkTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_DISC_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWarnTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_DISC_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErrTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_DISC_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErr24TestChkBox_1_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5TestChkBox_1_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VsciTestChkBox_1_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VATestChkBox_1_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
// Реализация слотов для теста светодиодов платы 1
|
||||
void DebugTerminalDialog::on_ledWorkTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledWarnTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledErrTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledConnectTestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_CONNECT_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH1TestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_VH1_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH2TestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_VH2_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH3TestChkBox_1_stateChanged(int state)
|
||||
{
|
||||
writeCoil(0, COIL_LED_VH3_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для вызова функций платы 2
|
||||
void DebugTerminalDialog::on_continiusCallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_CONTINUOUS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_calibrateCallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_CALIBRATE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_pollTECallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_POLL_TE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetKeyCallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_RESET_KEYS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetDefaultCallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_RESET_DEFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_getHardfaultCallChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_HARDFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для теста дискретных сигналов платы 2
|
||||
void DebugTerminalDialog::on_enableLedTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_TEST_ENABLE, state == Qt::Checked ? 1 : 0);
|
||||
ui->leds_2->setEnabled(state);
|
||||
ui->discs_2->setEnabled(state);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWorkTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_DISC_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWarnTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_DISC_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErrTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_DISC_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErr24TestChkBox_2_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5TestChkBox_2_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VsciTestChkBox_2_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VATestChkBox_2_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
// Реализация слотов для теста светодиодов платы 2
|
||||
void DebugTerminalDialog::on_ledWorkTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledWarnTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledErrTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledConnectTestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_CONNECT_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH1TestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_VH1_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH2TestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_VH2_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH3TestChkBox_2_stateChanged(int state)
|
||||
{
|
||||
writeCoil(1, COIL_LED_VH3_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для вызова функций платы 3
|
||||
void DebugTerminalDialog::on_continiusCallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_CONTINUOUS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_calibrateCallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_CALIBRATE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_pollTECallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_POLL_TE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetKeyCallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_RESET_KEYS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetDefaultCallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_RESET_DEFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_getHardfaultCallChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_HARDFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для теста дискретных сигналов платы 3
|
||||
void DebugTerminalDialog::on_enableLedTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_TEST_ENABLE, state == Qt::Checked ? 1 : 0);
|
||||
ui->leds_3->setEnabled(state);
|
||||
ui->discs_3->setEnabled(state);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWorkTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_DISC_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWarnTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_DISC_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErrTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_DISC_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErr24TestChkBox_3_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5TestChkBox_3_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VsciTestChkBox_3_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VATestChkBox_3_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
// Реализация слотов для теста светодиодов платы 3
|
||||
void DebugTerminalDialog::on_ledWorkTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledWarnTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledErrTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledConnectTestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_CONNECT_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH1TestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_VH1_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH2TestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_VH2_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH3TestChkBox_3_stateChanged(int state)
|
||||
{
|
||||
writeCoil(2, COIL_LED_VH3_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для вызова функций платы 4
|
||||
void DebugTerminalDialog::on_continiusCallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_CONTINUOUS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_calibrateCallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_CALIBRATE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_pollTECallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_POLL_TE_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetKeyCallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_RESET_KEYS_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_resetDefaultCallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_RESET_DEFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_getHardfaultCallChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_HARDFAULT_CALL, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
// Реализация слотов для теста дискретных сигналов платы 4
|
||||
void DebugTerminalDialog::on_enableLedTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_TEST_ENABLE, state == Qt::Checked ? 1 : 0);
|
||||
ui->leds_4->setEnabled(state);
|
||||
ui->discs_4->setEnabled(state);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWorkTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_DISC_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discWarnTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_DISC_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErrTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_DISC_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_discErr24TestChkBox_4_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5TestChkBox_4_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VsciTestChkBox_4_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
void DebugTerminalDialog::on_discErr5VATestChkBox_4_stateChanged(int state){Q_UNUSED(state)}
|
||||
|
||||
// Реализация слотов для теста светодиодов платы 4
|
||||
void DebugTerminalDialog::on_ledWorkTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_WORK_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledWarnTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_WARN_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledErrTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_ERR_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledConnectTestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_CONNECT_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH1TestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_VH1_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH2TestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_VH2_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::on_ledVH3TestChkBox_4_stateChanged(int state)
|
||||
{
|
||||
writeCoil(3, COIL_LED_VH3_TEST, state == Qt::Checked ? 1 : 0);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::openAdc(int boardID, int teNumber)
|
||||
{
|
||||
// Удаляем старый диалог и создаем новый
|
||||
if (m_adcGraphDialog) {
|
||||
m_adcGraphDialog->deleteLater();
|
||||
m_adcGraphDialog = nullptr;
|
||||
}
|
||||
|
||||
m_adcGraphDialog = new AdcGraphDialog(m_modbusDevice, this);
|
||||
connect(m_adcGraphDialog, &AdcGraphDialog::dialogClosed, this, [this]() {
|
||||
setDebugTerminalCoil(0);
|
||||
});
|
||||
|
||||
setGraphUpdateInterval(1000);
|
||||
m_adcGraphDialog->startGraph(boardID, teNumber);
|
||||
m_adcGraphDialog->show();
|
||||
m_adcGraphDialog->raise();
|
||||
m_adcGraphDialog->activateWindow();
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::setGraphUpdateInterval(int milliseconds)
|
||||
{
|
||||
if (m_adcGraphDialog) {
|
||||
m_adcGraphDialog->setTimeout(milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::writeCoil(int boardID, int coil, int value)
|
||||
{
|
||||
QGroupBox* boardGroup = nullptr;
|
||||
switch(boardID) {
|
||||
case 0: boardGroup = ui->DbgPlate_1; break; // Плата 1
|
||||
case 1: boardGroup = ui->DbgPlate_2; break; // Плата 2
|
||||
case 2: boardGroup = ui->DbgPlate_3; break; // Плата 3
|
||||
case 3: boardGroup = ui->DbgPlate_4; break; // Плата 4
|
||||
default: return;
|
||||
}
|
||||
if(!boardGroup->isEnabled())
|
||||
return;
|
||||
qDebug() << "Writing board" << boardID << "coil:" << coil << "value:" << value;
|
||||
emit coilValueChanged(boardID, coil, value);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::writeTENumber(int boardId, int teNumber)
|
||||
{
|
||||
m_adcGraphDialog->setTENumber(boardId, teNumber);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::setBoardActive(int boardID, bool active)
|
||||
{
|
||||
// Получаем групбокс для указанной платы
|
||||
QGroupBox* boardGroup = nullptr;
|
||||
switch(boardID) {
|
||||
case 0: boardGroup = ui->DbgPlate_1; break; // Плата 1
|
||||
case 1: boardGroup = ui->DbgPlate_2; break; // Плата 2
|
||||
case 2: boardGroup = ui->DbgPlate_3; break; // Плата 3
|
||||
case 3: boardGroup = ui->DbgPlate_4; break; // Плата 4
|
||||
default: return;
|
||||
}
|
||||
if (boardGroup) {
|
||||
boardGroup->setEnabled(active);
|
||||
// Можно добавить визуальное отличие неактивных плат
|
||||
if (!active) {
|
||||
boardGroup->setStyleSheet("QGroupBox { color: gray; }");
|
||||
} else {
|
||||
boardGroup->setStyleSheet(""); // Сброс стиля
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::updateBoardStates(bool activeBoards[4])
|
||||
{
|
||||
for (int i = 0; i < 4; i++) {
|
||||
setBoardActive(i, activeBoards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::resetAll()
|
||||
{
|
||||
// Сброс всех чекбоксов вызова функций
|
||||
ui->continiusCallChkBox_1->setChecked(false);
|
||||
ui->calibrateCallChkBox_1->setChecked(false);
|
||||
ui->pollTECallChkBox_1->setChecked(false);
|
||||
ui->resetKeyCallChkBox_1->setChecked(false);
|
||||
ui->resetDefaultCallChkBox_1->setChecked(false);
|
||||
ui->getHardfaultCallChkBox_1->setChecked(false);
|
||||
|
||||
ui->enableLedTestChkBox_1->setChecked(false);
|
||||
ui->leds_1->setEnabled(false);
|
||||
ui->discs_1->setEnabled(false);
|
||||
|
||||
ui->discWorkTestChkBox_1->setChecked(false);
|
||||
// Сброс всех чекбоксов теста дискретных сигналов
|
||||
ui->discWorkTestChkBox_1->setChecked(false);
|
||||
ui->discWarnTestChkBox_1->setChecked(false);
|
||||
ui->discErrTestChkBox_1->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов теста светодиодов
|
||||
ui->ledWorkTestChkBox_1->setChecked(false);
|
||||
ui->ledWarnTestChkBox_1->setChecked(false);
|
||||
ui->ledErrTestChkBox_1->setChecked(false);
|
||||
ui->ledConnectTestChkBox_1->setChecked(false);
|
||||
ui->ledVH1TestChkBox_1->setChecked(false);
|
||||
ui->ledVH2TestChkBox_1->setChecked(false);
|
||||
ui->ledVH3TestChkBox_1->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов вызова функций
|
||||
ui->continiusCallChkBox_2->setChecked(false);
|
||||
ui->calibrateCallChkBox_2->setChecked(false);
|
||||
ui->pollTECallChkBox_2->setChecked(false);
|
||||
ui->resetKeyCallChkBox_2->setChecked(false);
|
||||
ui->resetDefaultCallChkBox_2->setChecked(false);
|
||||
ui->getHardfaultCallChkBox_2->setChecked(false);
|
||||
|
||||
ui->enableLedTestChkBox_2->setChecked(false);
|
||||
ui->leds_2->setEnabled(false);
|
||||
ui->discs_2->setEnabled(false);
|
||||
|
||||
ui->discWorkTestChkBox_2->setChecked(false);
|
||||
// Сброс всех чекбоксов теста дискретных сигналов
|
||||
ui->discWorkTestChkBox_2->setChecked(false);
|
||||
ui->discWarnTestChkBox_2->setChecked(false);
|
||||
ui->discErrTestChkBox_2->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов теста светодиодов
|
||||
ui->ledWorkTestChkBox_2->setChecked(false);
|
||||
ui->ledWarnTestChkBox_2->setChecked(false);
|
||||
ui->ledErrTestChkBox_2->setChecked(false);
|
||||
ui->ledConnectTestChkBox_2->setChecked(false);
|
||||
ui->ledVH1TestChkBox_2->setChecked(false);
|
||||
ui->ledVH2TestChkBox_2->setChecked(false);
|
||||
ui->ledVH3TestChkBox_2->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов вызова функций
|
||||
ui->continiusCallChkBox_3->setChecked(false);
|
||||
ui->calibrateCallChkBox_3->setChecked(false);
|
||||
ui->pollTECallChkBox_3->setChecked(false);
|
||||
ui->resetKeyCallChkBox_3->setChecked(false);
|
||||
ui->resetDefaultCallChkBox_3->setChecked(false);
|
||||
ui->getHardfaultCallChkBox_3->setChecked(false);
|
||||
|
||||
ui->enableLedTestChkBox_3->setChecked(false);
|
||||
ui->leds_3->setEnabled(false);
|
||||
ui->discs_3->setEnabled(false);
|
||||
|
||||
ui->discWorkTestChkBox_3->setChecked(false);
|
||||
// Сброс всех чекбоксов теста дискретных сигналов
|
||||
ui->discWorkTestChkBox_3->setChecked(false);
|
||||
ui->discWarnTestChkBox_3->setChecked(false);
|
||||
ui->discErrTestChkBox_3->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов теста светодиодов
|
||||
ui->ledWorkTestChkBox_3->setChecked(false);
|
||||
ui->ledWarnTestChkBox_3->setChecked(false);
|
||||
ui->ledErrTestChkBox_3->setChecked(false);
|
||||
ui->ledConnectTestChkBox_3->setChecked(false);
|
||||
ui->ledVH1TestChkBox_3->setChecked(false);
|
||||
ui->ledVH2TestChkBox_3->setChecked(false);
|
||||
ui->ledVH3TestChkBox_3->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов вызова функций
|
||||
ui->continiusCallChkBox_4->setChecked(false);
|
||||
ui->calibrateCallChkBox_4->setChecked(false);
|
||||
ui->pollTECallChkBox_4->setChecked(false);
|
||||
ui->resetKeyCallChkBox_4->setChecked(false);
|
||||
ui->resetDefaultCallChkBox_4->setChecked(false);
|
||||
ui->getHardfaultCallChkBox_4->setChecked(false);
|
||||
|
||||
ui->enableLedTestChkBox_4->setChecked(false);
|
||||
ui->leds_4->setEnabled(false);
|
||||
ui->discs_4->setEnabled(false);
|
||||
|
||||
ui->discWorkTestChkBox_4->setChecked(false);
|
||||
// Сброс всех чекбоксов теста дискретных сигналов
|
||||
ui->discWorkTestChkBox_4->setChecked(false);
|
||||
ui->discWarnTestChkBox_4->setChecked(false);
|
||||
ui->discErrTestChkBox_4->setChecked(false);
|
||||
|
||||
// Сброс всех чекбоксов теста светодиодов
|
||||
ui->ledWorkTestChkBox_4->setChecked(false);
|
||||
ui->ledWarnTestChkBox_4->setChecked(false);
|
||||
ui->ledErrTestChkBox_4->setChecked(false);
|
||||
ui->ledConnectTestChkBox_4->setChecked(false);
|
||||
ui->ledVH1TestChkBox_4->setChecked(false);
|
||||
ui->ledVH2TestChkBox_4->setChecked(false);
|
||||
ui->ledVH3TestChkBox_4->setChecked(false);
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::boardDebugReading(int boardID)
|
||||
{
|
||||
if(mainTerm == nullptr)
|
||||
return;
|
||||
|
||||
if(!boards[boardID].isActive)
|
||||
return;
|
||||
|
||||
if(!this->isVisible())
|
||||
return;
|
||||
|
||||
QModbusReply *_24V = mainTerm->readSingleCoil(boardID, 603);
|
||||
if(_24V != nullptr)
|
||||
connect(_24V, &QModbusReply::finished, this, [this, boardID, _24V]() {
|
||||
if(_24V->error() == QModbusDevice::NoError)
|
||||
boards[boardID].error24V->setChecked(_24V->result().value(0));
|
||||
_24V->deleteLater();
|
||||
});
|
||||
|
||||
QModbusReply *_5V = mainTerm->readSingleCoil(boardID, 604);
|
||||
if(_5V != nullptr)
|
||||
connect(_5V, &QModbusReply::finished, this, [this, boardID, _5V]() {
|
||||
if(_5V->error() == QModbusDevice::NoError)
|
||||
boards[boardID].error5V->setChecked(_5V->result().value(0));
|
||||
_5V->deleteLater();
|
||||
});
|
||||
|
||||
QModbusReply *_5VSCI = mainTerm->readSingleCoil(boardID, 605);
|
||||
if(_5VSCI != nullptr)
|
||||
connect(_5VSCI, &QModbusReply::finished, this, [this, boardID, _5VSCI]() {
|
||||
if(_5VSCI->error() == QModbusDevice::NoError)
|
||||
boards[boardID].error5VSCI->setChecked(_5VSCI->result().value(0));
|
||||
_5VSCI->deleteLater();
|
||||
});
|
||||
|
||||
QModbusReply *_5VA = mainTerm->readSingleCoil(boardID, 606);
|
||||
if(_5VA != nullptr)
|
||||
connect(_5VA, &QModbusReply::finished, this, [this, boardID, _5VA]() {
|
||||
if(_5VA->error() == QModbusDevice::NoError)
|
||||
boards[boardID].error5VA->setChecked(_5VA->result().value(0));
|
||||
_5VA->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::setScanBoardActive(bool flag, int boardID)
|
||||
{
|
||||
boards[boardID].isActive = flag;
|
||||
}
|
||||
|
||||
void DebugTerminalDialog::offAllBoard()
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
boards[i].isActive = false;
|
||||
}
|
||||
}
|
||||
225
M3KTE_TERM/debugterminaldialog.h
Normal file
225
M3KTE_TERM/debugterminaldialog.h
Normal file
@@ -0,0 +1,225 @@
|
||||
#ifndef DEBUGTERMINALDIALOG_H
|
||||
#define DEBUGTERMINALDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QModbusClient>
|
||||
#include <QAbstractButton>
|
||||
#include <QCheckBox>
|
||||
#include <m3kte.h>
|
||||
|
||||
// Forward declarations вместо include
|
||||
class M3KTE;
|
||||
class AdcGraphDialog;
|
||||
|
||||
// Дефайны для адресов коилов
|
||||
#define COIL_DEBUG_MODE 555
|
||||
|
||||
#define COIL_CONTINUOUS_CALL 571
|
||||
#define COIL_CALIBRATE_CALL 572
|
||||
#define COIL_POLL_TE_CALL 573
|
||||
#define COIL_RESET_KEYS_CALL 574
|
||||
#define COIL_RESET_DEFAULT_CALL 576
|
||||
#define COIL_HARDFAULT_CALL 586
|
||||
|
||||
#define COIL_LED_TEST_ENABLE 587
|
||||
|
||||
// Тест дискретных сигналов
|
||||
#define COIL_DISC_WORK_TEST 588
|
||||
#define COIL_DISC_WARN_TEST 589
|
||||
#define COIL_DISC_ERR_TEST 590
|
||||
|
||||
// Тест светодиодов
|
||||
#define COIL_LED_CONNECT_TEST 591
|
||||
#define COIL_LED_WORK_TEST 592
|
||||
#define COIL_LED_WARN_TEST 593
|
||||
#define COIL_LED_ERR_TEST 594
|
||||
#define COIL_LED_VH1_TEST 595
|
||||
#define COIL_LED_VH2_TEST 596
|
||||
#define COIL_LED_VH3_TEST 597
|
||||
|
||||
// Адреса для чтения состояний ошибок питания
|
||||
#define COIL_READ_ERR_24V 600 // Чтение ошибки 24В
|
||||
#define COIL_READ_ERR_5V 601 // Чтение ошибки 5В
|
||||
#define COIL_READ_ERR_5VSCI 602 // Чтение ошибки 5Vsci
|
||||
#define COIL_READ_ERR_5VA 603 // Чтение ошибки 5VA
|
||||
|
||||
#define REGISTER_TE_NUMB 564
|
||||
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DebugTerminalDialog;
|
||||
}
|
||||
|
||||
class DebugTerminalDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DebugTerminalDialog(QWidget *parent = nullptr);
|
||||
~DebugTerminalDialog();
|
||||
AdcGraphDialog *m_adcGraphDialog;
|
||||
void setDebugTerminalCoil(int enable);
|
||||
void updateConnectionStatus(int boardId, bool connected);
|
||||
void setBoardActive(int boardId, bool active);
|
||||
void updateBoardStates(bool activeBoards[4]);
|
||||
void setModbusDevice(QModbusClient *device);
|
||||
void setGraphUpdateInterval(int milliseconds);
|
||||
void writeTENumber(int boardId, int teNumber);
|
||||
void openAdc(int boardID, int teNumber);
|
||||
void setMainTerm(M3KTE* term);
|
||||
|
||||
public slots:
|
||||
void boardDebugReading(int boardID);
|
||||
void setScanBoardActive(bool flag, int boardID);
|
||||
void offAllBoard();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
||||
// Плата 1
|
||||
void on_continiusCallChkBox_1_stateChanged(int state);
|
||||
void on_calibrateCallChkBox_1_stateChanged(int state);
|
||||
void on_pollTECallChkBox_1_stateChanged(int state);
|
||||
void on_resetKeyCallChkBox_1_stateChanged(int state);
|
||||
void on_resetDefaultCallChkBox_1_stateChanged(int state);
|
||||
void on_getHardfaultCallChkBox_1_stateChanged(int state);
|
||||
|
||||
void on_enableLedTestChkBox_1_stateChanged(int state);
|
||||
|
||||
void on_discWorkTestChkBox_1_stateChanged(int state);
|
||||
void on_discWarnTestChkBox_1_stateChanged(int state);
|
||||
void on_discErrTestChkBox_1_stateChanged(int state);
|
||||
void on_discErr24TestChkBox_1_stateChanged(int state);
|
||||
void on_discErr5TestChkBox_1_stateChanged(int state);
|
||||
void on_discErr5VsciTestChkBox_1_stateChanged(int state);
|
||||
void on_discErr5VATestChkBox_1_stateChanged(int state);
|
||||
|
||||
void on_ledWorkTestChkBox_1_stateChanged(int state);
|
||||
void on_ledWarnTestChkBox_1_stateChanged(int state);
|
||||
void on_ledErrTestChkBox_1_stateChanged(int state);
|
||||
void on_ledConnectTestChkBox_1_stateChanged(int state);
|
||||
void on_ledVH1TestChkBox_1_stateChanged(int state);
|
||||
void on_ledVH2TestChkBox_1_stateChanged(int state);
|
||||
void on_ledVH3TestChkBox_1_stateChanged(int state);
|
||||
|
||||
// Плата 2
|
||||
void on_continiusCallChkBox_2_stateChanged(int state);
|
||||
void on_calibrateCallChkBox_2_stateChanged(int state);
|
||||
void on_pollTECallChkBox_2_stateChanged(int state);
|
||||
void on_resetKeyCallChkBox_2_stateChanged(int state);
|
||||
void on_resetDefaultCallChkBox_2_stateChanged(int state);
|
||||
void on_getHardfaultCallChkBox_2_stateChanged(int state);
|
||||
|
||||
void on_enableLedTestChkBox_2_stateChanged(int state);
|
||||
|
||||
void on_discWorkTestChkBox_2_stateChanged(int state);
|
||||
void on_discWarnTestChkBox_2_stateChanged(int state);
|
||||
void on_discErrTestChkBox_2_stateChanged(int state);
|
||||
void on_discErr24TestChkBox_2_stateChanged(int state);
|
||||
void on_discErr5TestChkBox_2_stateChanged(int state);
|
||||
void on_discErr5VsciTestChkBox_2_stateChanged(int state);
|
||||
void on_discErr5VATestChkBox_2_stateChanged(int state);
|
||||
|
||||
void on_ledWorkTestChkBox_2_stateChanged(int state);
|
||||
void on_ledWarnTestChkBox_2_stateChanged(int state);
|
||||
void on_ledErrTestChkBox_2_stateChanged(int state);
|
||||
void on_ledConnectTestChkBox_2_stateChanged(int state);
|
||||
void on_ledVH1TestChkBox_2_stateChanged(int state);
|
||||
void on_ledVH2TestChkBox_2_stateChanged(int state);
|
||||
void on_ledVH3TestChkBox_2_stateChanged(int state);
|
||||
|
||||
|
||||
// Плата 3
|
||||
void on_continiusCallChkBox_3_stateChanged(int state);
|
||||
void on_calibrateCallChkBox_3_stateChanged(int state);
|
||||
void on_pollTECallChkBox_3_stateChanged(int state);
|
||||
void on_resetKeyCallChkBox_3_stateChanged(int state);
|
||||
void on_resetDefaultCallChkBox_3_stateChanged(int state);
|
||||
void on_getHardfaultCallChkBox_3_stateChanged(int state);
|
||||
|
||||
void on_enableLedTestChkBox_3_stateChanged(int state);
|
||||
|
||||
void on_discWorkTestChkBox_3_stateChanged(int state);
|
||||
void on_discWarnTestChkBox_3_stateChanged(int state);
|
||||
void on_discErrTestChkBox_3_stateChanged(int state);
|
||||
void on_discErr24TestChkBox_3_stateChanged(int state);
|
||||
void on_discErr5TestChkBox_3_stateChanged(int state);
|
||||
void on_discErr5VsciTestChkBox_3_stateChanged(int state);
|
||||
void on_discErr5VATestChkBox_3_stateChanged(int state);
|
||||
|
||||
void on_ledWorkTestChkBox_3_stateChanged(int state);
|
||||
void on_ledWarnTestChkBox_3_stateChanged(int state);
|
||||
void on_ledErrTestChkBox_3_stateChanged(int state);
|
||||
void on_ledConnectTestChkBox_3_stateChanged(int state);
|
||||
void on_ledVH1TestChkBox_3_stateChanged(int state);
|
||||
void on_ledVH2TestChkBox_3_stateChanged(int state);
|
||||
void on_ledVH3TestChkBox_3_stateChanged(int state);
|
||||
|
||||
// Плата 4
|
||||
void on_continiusCallChkBox_4_stateChanged(int state);
|
||||
void on_calibrateCallChkBox_4_stateChanged(int state);
|
||||
void on_pollTECallChkBox_4_stateChanged(int state);
|
||||
void on_resetKeyCallChkBox_4_stateChanged(int state);
|
||||
void on_resetDefaultCallChkBox_4_stateChanged(int state);
|
||||
void on_getHardfaultCallChkBox_4_stateChanged(int state);
|
||||
|
||||
void on_enableLedTestChkBox_4_stateChanged(int state);
|
||||
|
||||
void on_discWorkTestChkBox_4_stateChanged(int state);
|
||||
void on_discWarnTestChkBox_4_stateChanged(int state);
|
||||
void on_discErrTestChkBox_4_stateChanged(int state);
|
||||
void on_discErr24TestChkBox_4_stateChanged(int state);
|
||||
void on_discErr5TestChkBox_4_stateChanged(int state);
|
||||
void on_discErr5VsciTestChkBox_4_stateChanged(int state);
|
||||
void on_discErr5VATestChkBox_4_stateChanged(int state);
|
||||
|
||||
void on_ledWorkTestChkBox_4_stateChanged(int state);
|
||||
void on_ledWarnTestChkBox_4_stateChanged(int state);
|
||||
void on_ledErrTestChkBox_4_stateChanged(int state);
|
||||
void on_ledConnectTestChkBox_4_stateChanged(int state);
|
||||
void on_ledVH1TestChkBox_4_stateChanged(int state);
|
||||
void on_ledVH2TestChkBox_4_stateChanged(int state);
|
||||
void on_ledVH3TestChkBox_4_stateChanged(int state);
|
||||
|
||||
signals:
|
||||
void coilValueChanged(int boardID, int coil, int value);
|
||||
void writeRegister(int boardID, int reg, int value);
|
||||
void readCoil(int boardID, int coil, QModbusReply *reply);
|
||||
|
||||
private:
|
||||
Ui::DebugTerminalDialog *ui;
|
||||
QModbusClient *m_modbusDevice; // Храним указатель здесь
|
||||
M3KTE* mainTerm = nullptr;
|
||||
|
||||
// Карты для хранения состояний
|
||||
QMap<int, bool> m_functionCalls; // boardId -> coil -> state
|
||||
QMap<int, bool> m_discreteTests; // boardId -> coil -> state
|
||||
QMap<int, bool> m_ledTests; // boardId -> coil -> state
|
||||
|
||||
// Номера ТЭ для каждой платы
|
||||
int m_teNumbers[4] = {0, 0, 0, 0};
|
||||
|
||||
struct boardErrorLinks{
|
||||
bool isActive = false;
|
||||
QCheckBox* error24V = nullptr;
|
||||
QCheckBox* error5V = nullptr;
|
||||
QCheckBox* error5VSCI = nullptr;
|
||||
QCheckBox* error5VA = nullptr;
|
||||
};
|
||||
boardErrorLinks boards[4];
|
||||
|
||||
void initializeConnections();
|
||||
|
||||
void writeCoil(int boardID, int coil, int value);
|
||||
//void readCoil(int coil);
|
||||
void resetAll();
|
||||
};
|
||||
|
||||
#endif // DEBUGTERMINALDIALOG_H
|
||||
155
M3KTE_TERM/devicesettingsdialog.cpp
Normal file
155
M3KTE_TERM/devicesettingsdialog.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "devicesettingsdialog.h"
|
||||
#include "ui_devicesettingsdialog.h"
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication>
|
||||
|
||||
DeviceSettingsDialog::DeviceSettingsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DeviceSettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
on_buttonApplyChangeTimer_clicked();
|
||||
{
|
||||
_m_timer[0] = ui->spinTimerBoard_1;
|
||||
_m_timer[1] = ui->spinTimerBoard_2;
|
||||
_m_timer[2] = ui->spinTimerBoard_3;
|
||||
_m_timer[3] = ui->spinTimerBoard_4;
|
||||
}
|
||||
_currentSpeed = ui->speedBox->currentText().toUInt();
|
||||
_currentParity = ui->parityBox->currentIndex();
|
||||
for(int i = 0; i < 4; i++) {
|
||||
_currentAdrs[i] = i+1;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceSettingsDialog::~DeviceSettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeTimer_clicked()
|
||||
{
|
||||
_currentBoardTimers[0] = ui->spinTimerBoard_1->value();
|
||||
_currentBoardTimers[1] = ui->spinTimerBoard_2->value();
|
||||
_currentBoardTimers[2] = ui->spinTimerBoard_3->value();
|
||||
_currentBoardTimers[3] = ui->spinTimerBoard_4->value();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeSpeed_clicked()
|
||||
{
|
||||
|
||||
_currentSpeed = ui->speedBox->currentIndex();
|
||||
emit speedChanged();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeParity_clicked()
|
||||
{
|
||||
_currentParity = ui->parityBox->currentIndex();
|
||||
emit parityChanged();
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangeAdr_clicked()
|
||||
{
|
||||
BoardIdHasBeenChanged* _boardIdHasBeenChanged = new BoardIdHasBeenChanged(ui->idComboBox->currentText().toUInt(), ui->adrSpinBox->value());
|
||||
QCoreApplication::postEvent(parent(), _boardIdHasBeenChanged);
|
||||
close();
|
||||
}
|
||||
|
||||
unsigned DeviceSettingsDialog::currentBoardTimer(unsigned short _ID)
|
||||
{
|
||||
return _currentBoardTimers[_ID];
|
||||
}
|
||||
|
||||
unsigned DeviceSettingsDialog::currentSpeed()
|
||||
{
|
||||
return _currentSpeed;
|
||||
}
|
||||
|
||||
unsigned short DeviceSettingsDialog::currentParity()
|
||||
{
|
||||
return _currentParity;
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, bool *ActiveDevices)
|
||||
{
|
||||
ui->speedBox->setCurrentText(QString::number(_currentSpeed=tmp_speed, 10));
|
||||
if(tmp_parity>0)
|
||||
tmp_parity--;
|
||||
ui->parityBox->setCurrentIndex(_currentParity = tmp_parity);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(ActiveDevices[i]) {
|
||||
_m_timer[i]->setEnabled(true);
|
||||
ui->idComboBox->addItem(QString::number(i));
|
||||
_currentAdrs[i] = tmp_adr[i];
|
||||
} else {
|
||||
_m_timer[i]->setEnabled(false);
|
||||
}
|
||||
}
|
||||
on_idComboBox_currentIndexChanged(ui->idComboBox->currentIndex());
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_idComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
ui->adrSpinBox->setValue(_currentAdrs[index]);
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
switch (ui->buttonBox->buttonRole(button)) {
|
||||
case QDialogButtonBox::ResetRole:
|
||||
ui->spinTimerBoard_1->setValue(1000);
|
||||
ui->spinTimerBoard_2->setValue(1000);
|
||||
ui->spinTimerBoard_3->setValue(1000);
|
||||
ui->spinTimerBoard_4->setValue(1000);
|
||||
on_buttonApplyChangeTimer_clicked();
|
||||
ui->speedBox->setCurrentText("31250");
|
||||
_currentSpeed = ui->speedBox->currentText().toUInt();
|
||||
ui->parityBox->setCurrentIndex(0);
|
||||
_currentParity = ui->parityBox->currentIndex();
|
||||
for(int i = 0; i < 4; i++) {
|
||||
_currentAdrs[i] = i+1;
|
||||
}
|
||||
ui->adrSpinBox->setValue(_currentAdrs[ui->idComboBox->currentIndex()]);
|
||||
break;
|
||||
case QDialogButtonBox::AcceptRole:
|
||||
close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::initPollForBoard(unsigned boardID, unsigned boardAdr)
|
||||
{
|
||||
ui->idPollComboBox->addItem(QString("Плата №%1 (ID %2)").arg(boardID+1).arg(boardAdr), QVariant(boardID));
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::updatePollStatus(unsigned boardID, bool status)
|
||||
{
|
||||
_currentPollStatus[boardID] = status;
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_buttonApplyChangePoll_clicked()
|
||||
{
|
||||
sendPollCommand(ui->idPollComboBox->currentData().toUInt(), (bool)ui->pollStatusBox->currentIndex());
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::sendPollCommand(unsigned boardID, bool status)
|
||||
{
|
||||
updatePollStatus(boardID, status);
|
||||
pollStatusChange* _pollStatusChanged = new pollStatusChange(boardID, status);
|
||||
QCoreApplication::postEvent(parent(), _pollStatusChanged);
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::on_idPollComboBox_currentIndexChanged(int index)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
ui->pollStatusBox->setCurrentIndex(_currentPollStatus[ui->idPollComboBox->currentData().toUInt()]);
|
||||
}
|
||||
|
||||
void DeviceSettingsDialog::onDisconnect()
|
||||
{
|
||||
ui->idComboBox->clear();
|
||||
ui->idPollComboBox->clear();
|
||||
}
|
||||
96
M3KTE_TERM/devicesettingsdialog.h
Normal file
96
M3KTE_TERM/devicesettingsdialog.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef DEVICESETTINGSDIALOG_H
|
||||
#define DEVICESETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QEvent>
|
||||
#include <QAbstractButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QSpinBox>
|
||||
|
||||
class BoardIdHasBeenChanged : public QEvent
|
||||
{
|
||||
public:
|
||||
BoardIdHasBeenChanged(const short num, const short newId) : QEvent(QEvent::User) {_BoardNum = num; _BoardNewID = newId;}
|
||||
~BoardIdHasBeenChanged() {}
|
||||
|
||||
short BoardNum() const {return _BoardNum;}
|
||||
short BoardNewID() const {return _BoardNewID;}
|
||||
|
||||
private:
|
||||
short _BoardNum;
|
||||
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 {
|
||||
class DeviceSettingsDialog;
|
||||
}
|
||||
|
||||
class DeviceSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DeviceSettingsDialog(QWidget *parent = nullptr);
|
||||
~DeviceSettingsDialog();
|
||||
|
||||
unsigned currentBoardTimer(unsigned short _ID);
|
||||
unsigned currentSpeed();
|
||||
unsigned short currentParity();
|
||||
void updateSettingsAfterConnection(unsigned tmp_speed, unsigned tmp_parity, unsigned *tmp_adr, bool *ActiveDevices);
|
||||
void sendPollCommand(unsigned boardID, bool status);
|
||||
void updatePollStatus(unsigned boardID, bool status);
|
||||
void initPollForBoard(unsigned boardID, unsigned boardAdr);
|
||||
void onDisconnect();
|
||||
signals:
|
||||
void parityChanged();
|
||||
void speedChanged();
|
||||
|
||||
void firstBoardAdrHasBeenChanged();
|
||||
void secondBoardAdrHasBeenChanged();
|
||||
void thirdBoardAdrHasBeenChanged();
|
||||
void fourthBoardAdrHasBeenChanged();
|
||||
|
||||
private slots:
|
||||
|
||||
void on_buttonApplyChangeTimer_clicked();
|
||||
|
||||
void on_buttonApplyChangeSpeed_clicked();
|
||||
|
||||
void on_buttonApplyChangeParity_clicked();
|
||||
|
||||
void on_buttonApplyChangeAdr_clicked();
|
||||
|
||||
void on_idComboBox_currentIndexChanged(int index);
|
||||
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
||||
void on_buttonApplyChangePoll_clicked();
|
||||
|
||||
void on_idPollComboBox_currentIndexChanged(int index);
|
||||
|
||||
private:
|
||||
QSpinBox *_m_timer[4];
|
||||
unsigned _currentBoardTimers[4];
|
||||
unsigned _currentSpeed;
|
||||
unsigned short _currentParity;
|
||||
unsigned _currentAdrs[4];
|
||||
bool _currentPollStatus[4];
|
||||
|
||||
Ui::DeviceSettingsDialog *ui;
|
||||
};
|
||||
|
||||
#endif // DEVICESETTINGSDIALOG_H
|
||||
339
M3KTE_TERM/devicesettingsdialog.ui
Normal file
339
M3KTE_TERM/devicesettingsdialog.ui
Normal file
@@ -0,0 +1,339 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DeviceSettingsDialog</class>
|
||||
<widget class="QDialog" name="DeviceSettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>278</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Период опроса плат</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="boardLabel_5">
|
||||
<property name="text">
|
||||
<string>Плата №3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_3">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="boardLabel_1">
|
||||
<property name="text">
|
||||
<string>Плата №1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="buttonApplyChangeTimer">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_2">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="boardLabel_2">
|
||||
<property name="text">
|
||||
<string>Плата №2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_1">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="boardLabel_4">
|
||||
<property name="text">
|
||||
<string>Плата №4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="spinTimerBoard_4">
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</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">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Сетевой адрес МЗКТЭ</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="idComboBox">
|
||||
<property name="whatsThis">
|
||||
<string>Номер платы</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="adrSpinBox">
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>247</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="buttonApplyChangeAdr">
|
||||
<property name="text">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<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">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Опрос ТЭ</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QComboBox" name="idPollComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<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">
|
||||
<string>Применить</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>DeviceSettingsDialog</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>DeviceSettingsDialog</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>
|
||||
276
M3KTE_TERM/lineringer.cpp
Normal file
276
M3KTE_TERM/lineringer.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#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, [tmp_isRun]() {
|
||||
*tmp_isRun = true;
|
||||
});
|
||||
connect(this, &LineRinger::stopLineCall, 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);
|
||||
//Запрос типа устройства.
|
||||
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) {
|
||||
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);
|
||||
bar->setLabelText(tr("Поиск устройств... Текущая скорость: %1").arg(currentBaudRate));
|
||||
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
59
M3KTE_TERM/lineringer.h
Normal 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
303
M3KTE_TERM/lineringer.ui
Normal 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>
|
||||
2062
M3KTE_TERM/m3kte.cpp
Normal file
2062
M3KTE_TERM/m3kte.cpp
Normal file
@@ -0,0 +1,2062 @@
|
||||
#include "m3kte.h"
|
||||
#include "ui_m3kte.h"
|
||||
|
||||
#include "settingsdialog.h"
|
||||
#include "writeregistermodel.h"
|
||||
|
||||
#include <QModbusTcpClient>
|
||||
#include <QModbusRtuSerialMaster>
|
||||
#include <QStandardItemModel>
|
||||
#include <QStatusBar>
|
||||
#include <QUrl>
|
||||
#include <QScrollBar>
|
||||
|
||||
#include <QTableWidget>
|
||||
#include <QPointer>
|
||||
#include <QDebug>
|
||||
#include <QProcess>
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
QWidget* init(QWidget *parent)
|
||||
{
|
||||
return new M3KTE(parent);
|
||||
}
|
||||
|
||||
//1024 768
|
||||
//Ширина колбы - уже
|
||||
M3KTE::M3KTE(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::M3KTE)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
//Массив указателей на индикаторы напряжения топливных элементов
|
||||
{
|
||||
int i = 0;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_1;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_2;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_3;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_4;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_5;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_6;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_7;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_8;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_9;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_10;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_11;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_12;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_13;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_14;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_15;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_16;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_17;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_18;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_19;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_20;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_21;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_22;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_23;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_24;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_25;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_26;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_27;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_28;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_29;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_30;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_31;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_32;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_33;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_34;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_35;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_36;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_37;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_38;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_39;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_40;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_41;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_42;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_43;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_44;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_45;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_46;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_47;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_48;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_49;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_50;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_51;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_52;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_53;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_54;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_55;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_56;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_57;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_58;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_59;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_60;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_61;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_62;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_63;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_64;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_65;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_66;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_67;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_68;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_69;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_70;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_71;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_72;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_73;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_74;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_75;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_76;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_77;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_78;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_79;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_80;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_81;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_82;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_83;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_84;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_85;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_86;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_87;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_88;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_89;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_90;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_91;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_92;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_93;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_94;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_95;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_96;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_97;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_98;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_99;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_100;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_101;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_102;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_103;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_104;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_105;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_106;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_107;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_108;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_109;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_110;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_111;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_112;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_113;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_114;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_115;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_116;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_117;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_118;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_119;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_120;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_121;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_122;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_123;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_124;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_125;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_126;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_127;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_128;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_129;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_130;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_131;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_132;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_133;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_134;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_135;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_136;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_137;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_138;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_139;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_140;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_141;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_142;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_143;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_144;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_145;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_146;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_147;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_148;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_149;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_150;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_151;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_152;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_153;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_154;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_155;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_156;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_157;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_158;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_159;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_160;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_161;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_162;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_163;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_164;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_165;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_166;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_167;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_168;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_169;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_170;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_171;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_172;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_173;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_174;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_175;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_176;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_177;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_178;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_179;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_180;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_181;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_182;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_183;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_184;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_185;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_186;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_187;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_188;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_189;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_190;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_191;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_192;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_193;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_194;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_195;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_196;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_197;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_198;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_199;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_200;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_201;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_202;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_203;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_204;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_205;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_206;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_207;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_208;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_209;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_210;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_211;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_212;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_213;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_214;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_215;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_216;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_217;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_218;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_219;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_220;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_221;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_222;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_223;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_224;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_225;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_226;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_227;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_228;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_229;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_230;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_231;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_232;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_233;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_234;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_235;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_236;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_237;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_238;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_239;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_240;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_241;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_242;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_243;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_244;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_245;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_246;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_247;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_248;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_249;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_250;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_251;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_252;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_253;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_254;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_255;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_256;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_257;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_258;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_259;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_260;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_261;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_262;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_263;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_264;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_265;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_266;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_267;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_268;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_269;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_270;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_271;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_272;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_273;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_274;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_275;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_276;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_277;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_278;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_279;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_280;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_281;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_282;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_283;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_284;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_285;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_286;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_287;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_288;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_289;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_290;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_291;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_292;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_293;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_294;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_295;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_296;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_297;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_298;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_299;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_300;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_301;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_302;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_303;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_304;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_305;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_306;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_307;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_308;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_309;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_310;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_311;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_312;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_313;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_314;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_315;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_316;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_317;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_318;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_319;
|
||||
m_ProgressBar[i++] = ui->FuelCellVoltageBar_320;
|
||||
}
|
||||
m_settingsDialog = new SettingsDialog(this);
|
||||
ui->writeTable->addItem(tr("Exceptions"), QModbusDataUnit::Coils);
|
||||
ui->writeTable->addItem(tr("Warnings"), QModbusDataUnit::HoldingRegisters);
|
||||
ui->writeTable->addItem(tr("Accidents"), QModbusDataUnit::HoldingRegisters);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
Boards[i].ModbusModelCoil = new WriteRegisterModel(this, 85 - (i/3*20), false);
|
||||
Boards[i].ModbusModelCoil->setStartAddress(0);
|
||||
Boards[i].ModbusModelCoil->setNumberOfValues(QString::number(85-(i/3*20)));
|
||||
Boards[i].ModbusModelHoldingReg = new WriteRegisterModel(this, (85 - (i/3*20))*2, true);
|
||||
Boards[i].ModbusModelHoldingReg->setStartAddress(0);
|
||||
Boards[i].ModbusModelHoldingReg->setNumberOfValues(QString::number(85-(i/3*20)));
|
||||
}
|
||||
m_deviceSettingsDialog = new DeviceSettingsDialog(this);
|
||||
m_debugTerminalDialog = new DebugTerminalDialog(this);
|
||||
m_debugTerminalDialog->setMainTerm(this);
|
||||
m_regMultipleSettings = new MultipleSettings(this);
|
||||
modbusDevice = new QModbusRtuSerialMaster(this);
|
||||
m_debugTerminalDialog->setModbusDevice(modbusDevice);
|
||||
connect(this, &M3KTE::boardReading, m_debugTerminalDialog, &DebugTerminalDialog::boardDebugReading);
|
||||
m_lineRinger = new LineRinger();
|
||||
Boards[0].boardScanners = new QTimer();
|
||||
Boards[1].boardScanners = new QTimer();
|
||||
Boards[2].boardScanners = new QTimer();
|
||||
Boards[3].boardScanners = new QTimer();
|
||||
Boards[0].boardScanners->setSingleShot(true);
|
||||
Boards[1].boardScanners->setSingleShot(true);
|
||||
Boards[2].boardScanners->setSingleShot(true);
|
||||
Boards[3].boardScanners->setSingleShot(true);
|
||||
connect(Boards[0].boardScanners, &QTimer::timeout, this, [this]() {
|
||||
boardScan(0);
|
||||
});
|
||||
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[1].adr = 2;
|
||||
Boards[2].adr = 3;
|
||||
Boards[3].adr = 4;
|
||||
}
|
||||
bool activeBoards[4] = {false, false, false, false};
|
||||
m_debugTerminalDialog->updateBoardStates(activeBoards);
|
||||
|
||||
ui->M3kteRegSettings->setEnabled(false);
|
||||
ui->BSM_Warning->setEnabled(false);
|
||||
ui->BSM_Accident->setEnabled(false);
|
||||
ui->BSM_WorkInProgress->setEnabled(false);
|
||||
initActions();
|
||||
ui->BST_On->setCheckable(false);
|
||||
ui->BST_Off->setChecked(true);
|
||||
ui->boardSelectBox->setCurrentIndex(0);
|
||||
ui->writeTable->setCurrentIndex(0);
|
||||
changeTable(0, 0);
|
||||
{
|
||||
Boards_Fields[0] = ui->FCBoardBox;
|
||||
Boards_Fields[1] = ui->FCBoardBox_2;
|
||||
Boards_Fields[2] = ui->FCBoardBox_3;
|
||||
Boards_Fields[3] = ui->FCBoardBox_4;
|
||||
}
|
||||
{
|
||||
Boards[0].timerStatus = ui->timeStatus_1;
|
||||
Boards[1].timerStatus = ui->timeStatus_2;
|
||||
Boards[2].timerStatus = ui->timeStatus_3;
|
||||
Boards[3].timerStatus = ui->timeStatus_4;
|
||||
}
|
||||
{
|
||||
Boards[0].timerData = ui->timeData_1;
|
||||
Boards[1].timerData = ui->timeData_2;
|
||||
Boards[2].timerData = ui->timeData_3;
|
||||
Boards[3].timerData = ui->timeData_4;
|
||||
}
|
||||
{
|
||||
Boards[0].localError = ui->localErrorEdit_1;
|
||||
Boards[1].localError = ui->localErrorEdit_2;
|
||||
Boards[2].localError = ui->localErrorEdit_3;
|
||||
Boards[3].localError = ui->localErrorEdit_4;
|
||||
}
|
||||
{
|
||||
Boards[0].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_1;
|
||||
Boards[1].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_2;
|
||||
Boards[2].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_3;
|
||||
Boards[3].localState[LOCAL_STATE_POLL] = ui->localPollChkBox_4;
|
||||
|
||||
|
||||
Boards[0].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_1;
|
||||
Boards[1].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_2;
|
||||
Boards[2].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_3;
|
||||
Boards[3].localState[LOCAL_STATE_WARN] = ui->localWarnChkBox_4;
|
||||
|
||||
Boards[0].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_1;
|
||||
Boards[1].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_2;
|
||||
Boards[2].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_3;
|
||||
Boards[3].localState[LOCAL_STATE_ERR] = ui->localErrChkBox_4;
|
||||
|
||||
}
|
||||
{ // не кликабельные чекбоксы и радиобоксы
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
connect(Boards[i].localState[LOCAL_STATE_POLL], &QCheckBox::clicked,
|
||||
this, [i, this](bool checked) {
|
||||
m_deviceSettingsDialog->sendPollCommand(i, checked);
|
||||
});
|
||||
Boards[i].localState[LOCAL_STATE_WARN]->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
Boards[i].localState[LOCAL_STATE_ERR]->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
}
|
||||
|
||||
ui->BSM_Warning->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
ui->BSM_Accident->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
ui->BSM_WorkInProgress->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
ui->BST_On->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
ui->BST_Off->setAttribute(Qt::WA_TransparentForMouseEvents, true);
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
statusM3KTE.Warnings[i] = false;
|
||||
statusM3KTE.Accidents[i] = false;
|
||||
Boards_Fields[i]->setEnabled(false);
|
||||
Boards[i].timerData->setText(" ");
|
||||
Boards[i].timerStatus->setText(" ");;
|
||||
Boards[i].localError->setText(" ");;
|
||||
}
|
||||
for(int i = 0; i < 5; i++) {
|
||||
ui->writeValueTable->resizeColumnToContents(i);
|
||||
}
|
||||
QBrush tb(Qt::transparent); // Transparent brush, solid pattern
|
||||
for(int i = 0; i < 320; i++) {
|
||||
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);
|
||||
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);
|
||||
ThePhantomMenace[i] = new QPushButton(m_ProgressBar[i]);
|
||||
ThePhantomMenace[i]->setFlat(true);
|
||||
ThePhantomMenace[i]->setPalette(QPalette(tb, tb, tb, tb, tb, tb, tb, tb, tb));
|
||||
connect(ThePhantomMenace[i], &QPushButton::clicked, this, [this, i]() {
|
||||
selectPositionOnTree(i);
|
||||
m_debugTerminalDialog->writeTENumber(i/85, i - (i/85)*85 + 1);
|
||||
});
|
||||
}
|
||||
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::parityChanged, this, &M3KTE::onParityUpdate);
|
||||
connect(m_deviceSettingsDialog, &DeviceSettingsDialog::speedChanged, this, &M3KTE::onSpeedUpdate);
|
||||
loggerTable = new QTableWidget(ui->loggerWidget);
|
||||
ui->loggerWidget->layout()->addWidget(loggerTable);
|
||||
loggerTable->setColumnCount(5);
|
||||
QStringList headers;
|
||||
headers << "Время" << "Плата" << "Тип ошибки" << "Счётчик" << "Примечание";
|
||||
loggerTable->setHorizontalHeaderLabels(headers);
|
||||
loggerTable->setSortingEnabled(true);
|
||||
loggerTable->setAutoScroll(true);
|
||||
}
|
||||
|
||||
M3KTE::~M3KTE()
|
||||
{
|
||||
if(modbusDevice->state() == QModbusDevice::ConnectedState) {
|
||||
onConnectClicked();
|
||||
}
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void M3KTE::initActions()
|
||||
{
|
||||
ui->ConnectionMenuConnect->setEnabled(true);
|
||||
ui->ConnectionMenuDisconnect->setEnabled(false);
|
||||
ui->ConnectionMenuSettings->setEnabled(true);
|
||||
connect(ui->ConnectionMenuConnect, &QAction::triggered,
|
||||
this, &M3KTE::onConnectClicked);
|
||||
connect(ui->ConnectionMenuDisconnect, &QAction::triggered,
|
||||
this, &M3KTE::onConnectClicked);
|
||||
connect(ui->readButton, &QPushButton::clicked,
|
||||
this, &M3KTE::onReadButtonClicked);
|
||||
connect(ui->writeButton, &QPushButton::clicked,
|
||||
this, &M3KTE::onWriteButtonClicked);
|
||||
connect(ui->clearLoggerBtn, &QPushButton::clicked,
|
||||
this, &M3KTE::clearLogger);
|
||||
connect(ui->boardSelectBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &M3KTE::onSelectedBoardChanged);
|
||||
connect(ui->writeTable, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &M3KTE::onWriteTableChanged);
|
||||
connect(ui->DebugTerm, &QAction::triggered, m_debugTerminalDialog, &QWidget::show);
|
||||
connect(ui->OpenADCBuff, &QAction::triggered, this, [this]() {
|
||||
m_debugTerminalDialog->setDebugTerminalCoil(1);
|
||||
m_debugTerminalDialog->openAdc(0, 1);
|
||||
});
|
||||
|
||||
connect(m_debugTerminalDialog, &DebugTerminalDialog::coilValueChanged,
|
||||
this, &M3KTE::writeSingleCoil);
|
||||
connect(m_debugTerminalDialog, &DebugTerminalDialog::writeRegister,
|
||||
this, &M3KTE::writeSingleRegister);
|
||||
|
||||
connect(ui->LineCall, &QAction::triggered, m_lineRinger, &QWidget::show);
|
||||
connect(ui->M3kteRegSettings, &QAction::triggered, m_regMultipleSettings, &QDialog::show);
|
||||
connect(m_regMultipleSettings, &MultipleSettings::write, this, &M3KTE::slotmultipleRegWrite);
|
||||
connect(m_regMultipleSettings, &MultipleSettings::writeAndSend, this, &M3KTE::slotmultipleRegWriteAndSend);
|
||||
connect(ui->ConnectionMenuSettings, &QAction::triggered, m_settingsDialog, &QDialog::show);
|
||||
connect(ui->M3kteMenuSettings, &QAction::triggered, m_deviceSettingsDialog, &QDialog::show);
|
||||
}
|
||||
|
||||
void M3KTE::logError(const QString &errorPlace, const QString &errorString, unsigned errorCount, const QString &description)
|
||||
{
|
||||
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(errorPlace));
|
||||
loggerTable->setItem(newRow, 2, new QTableWidgetItem(errorString));
|
||||
loggerTable->setItem(newRow, 3, new QTableWidgetItem(QString::number(errorCount)));
|
||||
loggerTable->setItem(newRow, 4, new QTableWidgetItem(description));
|
||||
loggerTable->resizeColumnsToContents();
|
||||
if(!loggerTable->verticalScrollBar()->isSliderDown())
|
||||
loggerTable->verticalScrollBar()->setSliderPosition(loggerTable->verticalScrollBar()->maximum());
|
||||
}
|
||||
void M3KTE::clearLogger()
|
||||
{
|
||||
// Проверяем, что таблица инициализирована
|
||||
if (!loggerTable) {
|
||||
return;
|
||||
}
|
||||
// Отключаем обновление UI для повышения производительности
|
||||
loggerTable->setUpdatesEnabled(false);
|
||||
// Очищаем все строки таблицы
|
||||
loggerTable->setRowCount(0);
|
||||
// Включаем обновление UI
|
||||
loggerTable->setUpdatesEnabled(true);
|
||||
}
|
||||
|
||||
void M3KTE::onConnectClicked()
|
||||
{
|
||||
if(!modbusDevice)
|
||||
return;
|
||||
statusBar()->clearMessage();
|
||||
if(modbusDevice->state() != QModbusDevice::ConnectedState) {
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
|
||||
m_settingsDialog->settings().portName);
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
|
||||
m_settingsDialog->settings().parity);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||
m_settingsDialog->settings().baud);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
|
||||
m_settingsDialog->settings().dataBits);
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
|
||||
m_settingsDialog->settings().stopBits);
|
||||
#endif
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);
|
||||
if(!modbusDevice->connectDevice()) {
|
||||
statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
|
||||
} else {
|
||||
ui->ConnectionMenuConnect->setEnabled(false);
|
||||
ui->ConnectionMenuDisconnect->setEnabled(true);
|
||||
if(pingNetworkDevices()) { //Опрос устройств
|
||||
unsigned tmp_adr[4];
|
||||
bool ActiveDevices[4];
|
||||
for(int i = 0; i < 4; i++) {
|
||||
tmp_adr[i] = Boards[i].adr;
|
||||
ActiveDevices[i] = Boards[i].isActive;
|
||||
}
|
||||
ui->M3kteRegSettings->setEnabled(true);
|
||||
m_deviceSettingsDialog->updateSettingsAfterConnection(m_settingsDialog->settings().baud, m_settingsDialog->settings().parity, tmp_adr, ActiveDevices);
|
||||
m_debugTerminalDialog->updateBoardStates(ActiveDevices);
|
||||
ui->boardSelectBox->setCurrentIndex(0);
|
||||
ui->writeTable->setCurrentIndex(0);
|
||||
changeTable(0, 0);
|
||||
ui->M3kteMenuSettings->setEnabled(true);
|
||||
ui->M3kteRegSettings->setEnabled(true);
|
||||
ui->BST_Off->setCheckable(false);
|
||||
ui->BST_Off->setChecked(false);
|
||||
ui->BST_On->setCheckable(true);
|
||||
ui->BST_On->setChecked(true);
|
||||
ui->BSM_Warning->setEnabled(true);
|
||||
ui->BSM_Accident->setEnabled(true);
|
||||
ui->BSM_WorkInProgress->setEnabled(true);
|
||||
ui->BSM_WorkInProgress->setChecked(true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QString style_fc_off = "QProgressBar {border: 2px solid black; font: bold 10px} QProgressBar::chunk {background: hsva(" + QString::number(30) + ", 30, 30, 30%);} ";
|
||||
for(int i = 0; i < 4; i++) {
|
||||
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+1));
|
||||
Boards[i].timerData->setText(" ");;
|
||||
Boards[i].timerStatus->setText(" ");;
|
||||
Boards[i].localError->setText(" ");;
|
||||
}
|
||||
for(int i = 0; i < 320; i++) {
|
||||
m_ProgressBar[i]->setStatusTip(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
|
||||
m_ProgressBar[i]->setWhatsThis(QString("П%1 ТЭ%2: Топливный Элемент не учитывается.").arg(QString::number(i/85+1), QString::number(i%85)));
|
||||
m_ProgressBar[i]->setValue(3);
|
||||
m_ProgressBar[i]->setStyleSheet(style_fc_off);
|
||||
}
|
||||
modbusDevice->disconnectDevice();
|
||||
ui->M3kteMenuSettings->setEnabled(false);
|
||||
ui->M3kteRegSettings->setEnabled(false);
|
||||
ui->ConnectionMenuConnect->setEnabled(true);
|
||||
ui->ConnectionMenuDisconnect->setEnabled(false);
|
||||
ui->BST_Off->setCheckable(true);
|
||||
ui->BST_Off->setChecked(true);
|
||||
ui->BST_On->setCheckable(false);
|
||||
ui->BST_On->setChecked(false);
|
||||
ui->BSM_Warning->setChecked(false);
|
||||
ui->BSM_Accident->setChecked(false);
|
||||
ui->BSM_WorkInProgress->setChecked(false);
|
||||
ui->BSM_Warning->setEnabled(false);
|
||||
ui->BSM_Accident->setEnabled(false);
|
||||
ui->BSM_WorkInProgress->setEnabled(false);
|
||||
ui->M3kteRegSettings->setEnabled(false);
|
||||
m_deviceSettingsDialog->onDisconnect();
|
||||
m_debugTerminalDialog->offAllBoard();
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::onReadButtonClicked()
|
||||
{
|
||||
if(!modbusDevice)
|
||||
return;
|
||||
statusBar()->clearMessage();
|
||||
if(auto *reply = modbusDevice->sendReadRequest(readRequest(), Boards[ui->boardSelectBox->currentIndex()].adr)) {
|
||||
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()
|
||||
{
|
||||
auto reply = qobject_cast<QModbusReply *>(sender());
|
||||
if(!reply)
|
||||
return;
|
||||
int Adr = 255;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(Boards[i].isActive && Boards[i].adr==reply->serverAddress()) {
|
||||
Adr = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
for(int i = 0, total = int(unit.valueCount()); i < total; ++i) {
|
||||
if(unit.registerType() == QModbusDataUnit::Coils) {
|
||||
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
|
||||
if(unit.value(i)==1)
|
||||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
|
||||
else
|
||||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole);
|
||||
} else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) {
|
||||
Boards[Adr].HR[i + unit.startAddress()] = unit.value(i);
|
||||
Boards[Adr].ModbusModelHoldingReg->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 3), QString::number(unit.value(i), 10), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
switch(unit.registerType()) {
|
||||
case QModbusDataUnit::Coils:
|
||||
Boards[Adr].ModbusModelCoil->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 2),
|
||||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 2));
|
||||
break;
|
||||
case QModbusDataUnit::HoldingRegisters:
|
||||
Boards[Adr].ModbusModelHoldingReg->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 3),
|
||||
ui->writeValueTable->model()->index(unit.startAddress() + unit.valueCount() -1, 3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||||
arg(reply->errorString()).
|
||||
arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_RX,
|
||||
QString::number(reply->rawResult().exceptionCode()));
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||||
arg(reply->errorString()).
|
||||
arg(reply->error(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_RX,
|
||||
QString::number(reply->error(), 16));
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void M3KTE::onWriteButtonClicked()
|
||||
{
|
||||
if(!modbusDevice)
|
||||
return;
|
||||
statusBar()->clearMessage();
|
||||
QModbusDataUnit writeUnit = writeRequest();
|
||||
QModbusDataUnit::RegisterType table = writeUnit.registerType();
|
||||
for(int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) {
|
||||
if(table == QModbusDataUnit::Coils)
|
||||
{
|
||||
Boards[ui->boardSelectBox->currentIndex()].coil[i+writeUnit.startAddress()] =
|
||||
Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()];
|
||||
writeUnit.setValue(i, Boards[ui->boardSelectBox->currentIndex()].ModbusModelCoil->m_coils[i + writeUnit.startAddress()]);
|
||||
} else {
|
||||
Boards[ui->boardSelectBox->currentIndex()].HR[i+writeUnit.startAddress()] =
|
||||
Boards[ui->boardSelectBox->currentIndex()].ModbusModelHoldingReg->m_holdingRegisters[i+writeUnit.startAddress()];
|
||||
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(!reply->isFinished()) {
|
||||
unsigned tmp_id = ui->boardSelectBox->currentIndex();
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply, tmp_id]() {
|
||||
if(reply->error() == QModbusDevice::ProtocolError) {
|
||||
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
|
||||
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16),
|
||||
5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(tmp_id+1).arg(Boards[tmp_id].adr),
|
||||
reply->errorString(), ++Boards[tmp_id].error_TX,
|
||||
QString::number(reply->rawResult().exceptionCode(), 16));
|
||||
} else if(reply->error() != QModbusDevice::NoError) {
|
||||
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(tmp_id+1).arg(Boards[tmp_id].adr),
|
||||
reply->errorString(), ++Boards[tmp_id].error_TX,
|
||||
QString::number(reply->error()));
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
// broadcast replies return immediately
|
||||
reply->deleteLater();
|
||||
}
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
|
||||
logError(tr("Терминал"), modbusDevice->errorString(), 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::onSelectedBoardChanged(int index)
|
||||
{
|
||||
changeTable(index, ui->writeTable->currentIndex());
|
||||
}
|
||||
|
||||
void M3KTE::onWriteTableChanged(int index)
|
||||
{
|
||||
changeTable(ui->boardSelectBox->currentIndex(), index);
|
||||
}
|
||||
|
||||
void M3KTE::changeTable(int board, int tabletype)
|
||||
{
|
||||
if(tabletype==0) {
|
||||
ui->writeValueTable->setModel(Boards[board].ModbusModelCoil);
|
||||
int i = 0;
|
||||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||||
}
|
||||
ui->writeValueTable->hideColumn(3);
|
||||
ui->writeValueTable->showColumn(2);
|
||||
} else {
|
||||
ui->writeValueTable->setModel(Boards[board].ModbusModelHoldingReg);
|
||||
if(tabletype==1) {
|
||||
Boards[board].ModbusModelHoldingReg->setStartAddress(0);
|
||||
int i = 0;
|
||||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount()/2;i++) {
|
||||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||||
}
|
||||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true);
|
||||
}
|
||||
} else {
|
||||
Boards[board].ModbusModelHoldingReg->setStartAddress(Boards[board].ModbusModelHoldingReg->rowCount()/2);
|
||||
int i = 0;
|
||||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount()/2;i++) {
|
||||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), true);
|
||||
}
|
||||
for(;i<Boards[board].ModbusModelHoldingReg->rowCount();i++) {
|
||||
ui->writeValueTable->setRowHidden(i, ui->writeValueTable->model()->index(i, 0).parent(), false);
|
||||
}
|
||||
}
|
||||
ui->writeValueTable->hideColumn(2);
|
||||
ui->writeValueTable->showColumn(3);
|
||||
}
|
||||
for(int i = 0; i < 5; i++) {
|
||||
ui->writeValueTable->resizeColumnToContents(i);
|
||||
}
|
||||
}
|
||||
|
||||
QModbusDataUnit M3KTE::readRequest() const
|
||||
{
|
||||
const auto table =
|
||||
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
|
||||
int startAddress = 85 * (ui->writeTable->currentIndex()/2);
|
||||
Q_ASSERT(startAddress >= 0 && startAddress < 340);
|
||||
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
|
||||
return QModbusDataUnit(table, startAddress, numberOfEntries);
|
||||
}
|
||||
|
||||
QModbusDataUnit M3KTE::writeRequest() const
|
||||
{
|
||||
const auto table =
|
||||
static_cast<QModbusDataUnit::RegisterType>(ui->writeTable->currentData().toInt());
|
||||
int startAddress = 85 * (ui->writeTable->currentIndex()/2);
|
||||
Q_ASSERT(startAddress >= 0 && startAddress < 340);
|
||||
quint16 numberOfEntries = qMin((ushort)(85 - (ui->boardSelectBox->currentIndex()/3*20)), quint16(340 - startAddress));
|
||||
return QModbusDataUnit(table, startAddress, numberOfEntries);
|
||||
}
|
||||
|
||||
bool M3KTE::event(QEvent *event)
|
||||
{
|
||||
if(event->type() == QEvent::User) {
|
||||
BoardIdHasBeenChanged* _event = static_cast<BoardIdHasBeenChanged*>(event);
|
||||
QModbusDataUnit* _unit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 172, 1);
|
||||
_unit->setValue(0, _event->BoardNewID());
|
||||
Boards[_event->BoardNum()]._tmp_adr = _event->BoardNewID();
|
||||
if(auto *reply = modbusDevice->sendWriteRequest(*_unit, Boards[_event->BoardNum()].adr)) {
|
||||
if(!reply->isFinished())
|
||||
connect(reply, &QModbusReply::finished, this, [reply, this, _event, _unit]() {
|
||||
if(reply->error()==QModbusDevice::TimeoutError) {
|
||||
if(auto *subreply = modbusDevice->sendReadRequest(*_unit, Boards[_event->BoardNum()]._tmp_adr)) {
|
||||
if(!subreply->isFinished()) {
|
||||
connect(subreply, &QModbusReply::finished, this, [subreply, this, _event]() {
|
||||
checkAdrChange(subreply, _event->BoardNum());
|
||||
});
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||||
subreply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||||
"Не удалось изменить адрес устройства. [1]");
|
||||
reply->deleteLater();
|
||||
delete subreply; // broadcast replies return immediately
|
||||
}
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||||
modbusDevice->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||||
"Не удалось изменить адрес устройства. [2]");
|
||||
reply->deleteLater();
|
||||
}
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||||
reply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||||
"Не удалось изменить адрес устройства. [3]");
|
||||
reply->deleteLater();
|
||||
}
|
||||
});
|
||||
else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||||
reply->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||||
"Не удалось изменить адрес устройства. [4]");
|
||||
reply->deleteLater();
|
||||
delete reply;
|
||||
}
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardNum()+1).arg(Boards[_event->BoardNum()].adr),
|
||||
modbusDevice->errorString(), ++Boards[_event->BoardNum()].error_adr_change,
|
||||
"Не удалось изменить адрес устройства. [5]");
|
||||
reply->deleteLater();
|
||||
}
|
||||
m_deviceSettingsDialog->show();
|
||||
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) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr),
|
||||
reply->errorString(), ++Boards[_event->BoardID()].error_cmd_change, "");
|
||||
reply->deleteLater();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(_event->BoardID()+1).arg(Boards[_event->BoardID()].adr),
|
||||
modbusDevice->errorString(), ++Boards[_event->BoardID()].error_cmd_change, "");
|
||||
reply->deleteLater();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void M3KTE::checkAdrChange(QModbusReply *reply, unsigned boardNum)
|
||||
{
|
||||
if(!reply) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr),
|
||||
modbusDevice->errorString(), ++Boards[boardNum].error_adr_change,
|
||||
"Не удалось проверить изменение адреса устройства.");
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
if(reply->error() == QModbusDevice::NoError) {
|
||||
//OK
|
||||
Boards[boardNum].adr = Boards[boardNum]._tmp_adr;
|
||||
reply->deleteLater();
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardNum+1).arg(Boards[boardNum].adr),
|
||||
reply->errorString(), ++Boards[boardNum].error_adr_change,
|
||||
"Ошибка при подтверждении изменения адреса устройства.");
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::checkBoards()
|
||||
{
|
||||
QModbusDataUnit unitCheck(QModbusDataUnit::InputRegisters, 85, 1);
|
||||
// Используем shared pointers вместо ссылок на стековые переменные
|
||||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||||
for(int i = 0; i < 4; ++i) {
|
||||
if(!Boards[i].isActive)
|
||||
continue;
|
||||
(*totalActiveBoards)++;
|
||||
int slaveAddress = Boards[i].adr;
|
||||
QModbusReply *reply = modbusDevice->sendReadRequest(unitCheck, slaveAddress);
|
||||
if(!reply) {
|
||||
revertToOldSpeedAndRestart();
|
||||
return;
|
||||
}
|
||||
pendingBoards->insert(slaveAddress);
|
||||
connect(reply, &QModbusReply::finished, this,
|
||||
[this, i, reply, slaveAddress, totalActiveBoards, confirmedBoards, pendingBoards]() {
|
||||
if(reply->error() == QModbusDevice::NoError) {
|
||||
(*confirmedBoards)++;
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAddress),
|
||||
reply->errorString(), ++Boards[i].error_baud_change,
|
||||
"Ошибка при подтверждении изменения скорости обмена.");
|
||||
}
|
||||
pendingBoards->remove(slaveAddress);
|
||||
reply->deleteLater();
|
||||
if(pendingBoards->isEmpty()) {
|
||||
if(*confirmedBoards != *totalActiveBoards) {
|
||||
emit errorAtCheckBoards();
|
||||
} else {
|
||||
emit successAtCheckBoards();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// Если нет ни одной активной платы
|
||||
if(*totalActiveBoards == 0) {
|
||||
emit errorAtCheckBoards();
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::onSpeedUpdate()
|
||||
{
|
||||
stopScanBoard();
|
||||
modbusDevice->setTimeout(500);
|
||||
unsigned tmp_speed = 0;
|
||||
switch(m_deviceSettingsDialog->currentSpeed()) {
|
||||
case 0: tmp_speed = 9600; break;
|
||||
case 1: tmp_speed = 14400; break;
|
||||
case 2: tmp_speed = 19200; break;
|
||||
case 3: tmp_speed = 31250; break;
|
||||
case 4: tmp_speed = 38400; break;
|
||||
case 5: tmp_speed = 56000; break;
|
||||
case 6: tmp_speed = 57600; break;
|
||||
case 7: tmp_speed = 115200; break;
|
||||
}
|
||||
|
||||
if(tmp_speed == 0) {
|
||||
logError(tr("Программная ошибка"), "Неожиданное значение скорости", 0,
|
||||
"Ошибка при изменении скорости обмена.");
|
||||
beginScanBoards();
|
||||
return;
|
||||
}
|
||||
|
||||
// Используем shared pointers вместо ссылок на стековые переменные
|
||||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||||
auto newSpeed = tmp_speed; // копируем для захвата
|
||||
|
||||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 173, 1);
|
||||
unit.setValue(0, m_deviceSettingsDialog->currentSpeed());
|
||||
|
||||
// Лямбда для обработки результата
|
||||
auto processResult = [this, totalActiveBoards, confirmedBoards, newSpeed]() {
|
||||
if(*confirmedBoards != *totalActiveBoards) {
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
revertToOldSpeedAndRestart();
|
||||
beginScanBoards();
|
||||
} else {
|
||||
modbusDevice->disconnectDevice();
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, newSpeed);
|
||||
modbusDevice->connectDevice();
|
||||
|
||||
// Используем QPointer для безопасного доступа к this
|
||||
QPointer<M3KTE> safeThis(this);
|
||||
|
||||
connect(this, &M3KTE::errorAtCheckBoards, this, [safeThis]() {
|
||||
if (!safeThis) return;
|
||||
safeThis->disconnect(safeThis, &M3KTE::errorAtCheckBoards, safeThis, nullptr);
|
||||
safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime);
|
||||
safeThis->revertToOldSpeedAndRestart();
|
||||
safeThis->beginScanBoards();
|
||||
});
|
||||
|
||||
connect(this, &M3KTE::successAtCheckBoards, this, [safeThis]() {
|
||||
if (!safeThis) return;
|
||||
safeThis->disconnect(safeThis, &M3KTE::successAtCheckBoards, safeThis, nullptr);
|
||||
safeThis->m_settingsDialog->UpdateBaud(safeThis->m_deviceSettingsDialog->currentSpeed());
|
||||
safeThis->modbusDevice->setTimeout(safeThis->m_settingsDialog->settings().responseTime);
|
||||
safeThis->beginScanBoards();
|
||||
});
|
||||
|
||||
checkBoards();
|
||||
}
|
||||
};
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(!Boards[i].isActive)
|
||||
continue;
|
||||
int slaveAdress = Boards[i].adr;
|
||||
auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress);
|
||||
if(reply) {
|
||||
(*totalActiveBoards)++;
|
||||
pendingBoards->insert(slaveAdress);
|
||||
|
||||
// Захватываем shared pointers по значению - это безопасно
|
||||
connect(reply, &QModbusReply::finished, this,
|
||||
[this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() {
|
||||
if(reply->error() == QModbusDevice::TimeoutError) {
|
||||
(*confirmedBoards)++;
|
||||
} else if (reply->error() == QModbusDevice::NoError) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||||
tr("Неожиданный ответ."), ++Boards[i].error_baud_change,
|
||||
"Ошибка при изменении скорости обмена.");
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||||
reply->errorString(), ++Boards[i].error_baud_change,
|
||||
"Ошибка при изменении скорости обмена.");
|
||||
}
|
||||
pendingBoards->remove(slaveAdress);
|
||||
reply->deleteLater();
|
||||
|
||||
if(pendingBoards->isEmpty()) {
|
||||
processResult();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Вспомогательная функция восстановления старой скорости
|
||||
void M3KTE::revertToOldSpeedAndRestart()
|
||||
{
|
||||
modbusDevice->disconnectDevice();
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
|
||||
m_settingsDialog->curBaud());
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
modbusDevice->connectDevice();
|
||||
}
|
||||
|
||||
void M3KTE::onParityUpdate()
|
||||
{
|
||||
stopScanBoard();
|
||||
modbusDevice->setTimeout(500);
|
||||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, 174, 1);
|
||||
switch(m_deviceSettingsDialog->currentParity()) {
|
||||
case 0: //Нет контроля
|
||||
unit.setValue(0, 0x000);
|
||||
break;
|
||||
case 1: //Четный
|
||||
unit.setValue(0, 0x0400);
|
||||
break;
|
||||
case 2: //Нечетный
|
||||
unit.setValue(0, 0x0600);
|
||||
break;
|
||||
}
|
||||
|
||||
// Используем shared pointers вместо ссылок на стековые переменные
|
||||
auto totalActiveBoards = QSharedPointer<int>::create(0);
|
||||
auto confirmedBoards = QSharedPointer<int>::create(0);
|
||||
auto pendingBoards = QSharedPointer<QSet<int>>::create();
|
||||
auto oldParity = m_settingsDialog->curParity(); // сохраняем старую четность для отката
|
||||
auto newParity = m_deviceSettingsDialog->currentParity();
|
||||
|
||||
// Лямбда для обработки результата
|
||||
auto processResult = [this, totalActiveBoards, confirmedBoards, oldParity, newParity]() {
|
||||
if(*confirmedBoards != *totalActiveBoards) {
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
beginScanBoards();
|
||||
} else {
|
||||
modbusDevice->disconnectDevice();
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, newParity);
|
||||
modbusDevice->connectDevice();
|
||||
|
||||
auto errorHandler = [this, oldParity]() {
|
||||
disconnect(this, &M3KTE::errorAtCheckBoards, this, nullptr);
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
modbusDevice->disconnectDevice();
|
||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, oldParity);
|
||||
modbusDevice->connectDevice();
|
||||
beginScanBoards();
|
||||
};
|
||||
|
||||
auto successHandler = [this, newParity]() {
|
||||
disconnect(this, &M3KTE::successAtCheckBoards, this, nullptr);
|
||||
m_settingsDialog->UpdateParity(newParity);
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
beginScanBoards();
|
||||
};
|
||||
|
||||
connect(this, &M3KTE::errorAtCheckBoards, this, errorHandler);
|
||||
connect(this, &M3KTE::successAtCheckBoards, this, successHandler);
|
||||
|
||||
checkBoards();
|
||||
}
|
||||
};
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(!Boards[i].isActive)
|
||||
continue;
|
||||
int slaveAdress = Boards[i].adr;
|
||||
auto *reply = modbusDevice->sendWriteRequest(unit, slaveAdress);
|
||||
if(reply) {
|
||||
(*totalActiveBoards)++;
|
||||
pendingBoards->insert(slaveAdress);
|
||||
|
||||
connect(reply, &QModbusReply::finished, this,
|
||||
[this, i, reply, slaveAdress, totalActiveBoards, confirmedBoards, pendingBoards, processResult]() {
|
||||
if(reply->error() == QModbusDevice::TimeoutError) {
|
||||
(*confirmedBoards)++;
|
||||
} else if (reply->error() == QModbusDevice::NoError) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||||
tr("Неожиданный ответ."), ++Boards[i].error_baud_change,
|
||||
"Ошибка при изменении чётности.");
|
||||
} else {
|
||||
logError(tr("Плата %1 (ID %2)").arg(i+1).arg(slaveAdress),
|
||||
reply->errorString(), ++Boards[i].error_baud_change,
|
||||
"Ошибка при изменении чётности.");
|
||||
}
|
||||
pendingBoards->remove(slaveAdress);
|
||||
reply->deleteLater();
|
||||
|
||||
if(pendingBoards->isEmpty()) {
|
||||
processResult();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool M3KTE::pingNetworkDevices()
|
||||
{
|
||||
CurrentConnectedDevice = 0;
|
||||
int tmp_adr = 1;
|
||||
bool isRun = false;
|
||||
bool *tmp_isRun = &isRun;
|
||||
auto bar = new QProgressDialog(this);
|
||||
connect(bar, &QProgressDialog::canceled, this, [tmp_isRun]() {
|
||||
*tmp_isRun = true;
|
||||
});
|
||||
bar->setLabelText(tr("Поиск плат... Текущий адрес: %1").arg(tmp_adr));
|
||||
bar->setCancelButton(nullptr);
|
||||
bar->setRange(0, 4);
|
||||
bar->setMinimumDuration(100);
|
||||
bar->setValue(CurrentConnectedDevice);
|
||||
modbusDevice->setNumberOfRetries(0);
|
||||
QModbusRequest requestOfDeviceType(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0404"));
|
||||
QModbusRequest requestOfBoardID(QModbusRequest::EncapsulatedInterfaceTransport, QByteArray::fromHex("0E0401"));
|
||||
modbusDevice->setTimeout(50);
|
||||
for(CurrentConnectedDevice=0; CurrentConnectedDevice<4;) {
|
||||
|
||||
auto *reply = modbusDevice->sendRawRequest(requestOfDeviceType, tmp_adr);
|
||||
//Запрос типа устройства.
|
||||
if(reply == nullptr) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
while(!reply->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 if(!isRun) {
|
||||
//Нужна проверка типа устройства
|
||||
if(reply->error()==QModbusDevice::NoError) {
|
||||
QModbusResponse resp = reply->rawResult();
|
||||
QString result = QString(resp.data().remove(0, MODBUS_REQUEST_PROTOCOL_INFO_LENGTH));
|
||||
if(result == QString("KTE")) {
|
||||
//modbusDevice->setTimeout(1000);
|
||||
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();
|
||||
}
|
||||
int plata_ind = 0;
|
||||
if(subreply->rawResult().data().size() >= MODBUS_REQUEST_PROTOCOL_INFO_LENGTH) // ответ принят
|
||||
plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH); // парс ответа
|
||||
if(plata_ind == 0) // если номер = 0 повторяем всё еще раз
|
||||
{
|
||||
qDebug() << "Reqest plata_ind again for address " << tmp_adr;
|
||||
subreply = modbusDevice->sendRawRequest(requestOfBoardID, tmp_adr);
|
||||
|
||||
while(!subreply->isFinished()) {
|
||||
if(isRun && CurrentConnectedDevice < 1) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
} else if(isRun) {
|
||||
break;
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
plata_ind = subreply->rawResult().data().at(MODBUS_REQUEST_PROTOCOL_INFO_LENGTH);
|
||||
}
|
||||
if(plata_ind == 0)
|
||||
{
|
||||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||||
QString("Не удалось получить порядковый номер платы по адресу %1").arg(tmp_adr));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
|
||||
int board_ind = plata_ind-1;
|
||||
if(isRun && CurrentConnectedDevice < 1) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
} else if(isRun) {
|
||||
break;
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Плата %1 найдена по адресу %2.").arg(board_ind).arg(tmp_adr),
|
||||
m_settingsDialog->settings().responseTime);
|
||||
if(Boards[board_ind].isActive) {
|
||||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||||
QString("Платы по адресам %1 и %2 имеют одинаковый порядковый номер %3").arg(Boards[board_ind].adr).arg(tmp_adr).arg(plata_ind));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
CurrentConnectedDevice++;
|
||||
Boards[board_ind].adr = Boards[board_ind]._tmp_adr = tmp_adr;
|
||||
|
||||
|
||||
Boards[board_ind].isActive = true;
|
||||
bar->setValue(CurrentConnectedDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tmp_adr++;
|
||||
bar->setLabelText(tr("Поиск плат... Текущий адрес: %1").arg(tmp_adr));
|
||||
if(tmp_adr>=247 && (CurrentConnectedDevice<1)) {
|
||||
//ERROR
|
||||
//OUT OF RANGE
|
||||
QMessageBox::warning(this, "Ошибка при сканировании сети.",
|
||||
QString("Выход за пределы допустимых адресов. Найдено %1 плат.").arg(CurrentConnectedDevice));
|
||||
bar->setValue(4);
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
onConnectClicked();
|
||||
return false;
|
||||
} else if(tmp_adr>=247) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
isRun=false;
|
||||
QMessageBox::warning(this, "Сканирование сети завершено.", tr("Найдено плат: %1 из 4.").arg(CurrentConnectedDevice));
|
||||
if(isRun) {
|
||||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.", QString("Прерывание по запросу пользователя."));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
modbusDevice->setTimeout(m_settingsDialog->settings().responseTime);
|
||||
bar->setLabelText(tr("Считывание текущих настроек..."));
|
||||
bar->setRange(0, CurrentConnectedDevice*3);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(Boards[i].isActive) {
|
||||
QModbusDataUnit* _unit_settings[3];
|
||||
_unit_settings[0] = new QModbusDataUnit(QModbusDataUnit::Coils, 0, 85-(i/3*20));
|
||||
_unit_settings[1] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 85-(i/3*20));
|
||||
_unit_settings[2] = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 85, 85-(i/3*20));
|
||||
Boards_Fields[i]->setEnabled(true);
|
||||
for(int j = 0; j < 3; j++) {
|
||||
bar->setValue(i*3+j);
|
||||
if(isRun) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
delete _unit_settings[0];
|
||||
delete _unit_settings[1];
|
||||
delete _unit_settings[2];
|
||||
return false;
|
||||
}
|
||||
auto *reply = modbusDevice->sendReadRequest(*_unit_settings[j], Boards[i].adr);
|
||||
if(!reply) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
delete _unit_settings[0];
|
||||
delete _unit_settings[1];
|
||||
delete _unit_settings[2];
|
||||
return false;
|
||||
}
|
||||
while(!reply->isFinished()) {
|
||||
if(isRun) {
|
||||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.",
|
||||
QString("Прерывание по запросу пользователя."));
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
delete _unit_settings[0];
|
||||
delete _unit_settings[1];
|
||||
delete _unit_settings[2];
|
||||
return false;
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if(reply->error()==QModbusDevice::NoError) {
|
||||
applySettingsFromScan(reply);
|
||||
} else {
|
||||
QMessageBox::warning(this, "Ошибка при получении текущих настроек.",
|
||||
QString("Таймаут при опросе устройства %1 по адресу %2").arg(i+1).arg(Boards[i].adr));
|
||||
bar->setValue(CurrentConnectedDevice*3);
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
onConnectClicked();
|
||||
delete _unit_settings[0];
|
||||
delete _unit_settings[1];
|
||||
delete _unit_settings[2];
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Boards_Fields[i]->setTitle(QString("Плата №%1 (ID %2)").arg(i+1).arg(Boards[i].adr));
|
||||
delete _unit_settings[0];
|
||||
delete _unit_settings[1];
|
||||
delete _unit_settings[2];
|
||||
}
|
||||
}
|
||||
modbusDevice->setNumberOfRetries(m_settingsDialog->settings().numberOfRetries);
|
||||
beginScanBoards();
|
||||
bar->deleteLater();
|
||||
return true;
|
||||
}
|
||||
|
||||
void M3KTE::beginScanBoards()
|
||||
{
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(Boards[i].isActive) {
|
||||
m_debugTerminalDialog->setScanBoardActive(true, i);
|
||||
m_deviceSettingsDialog->initPollForBoard(i, Boards[i].adr);
|
||||
boardScan(i);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void M3KTE::boardScan(unsigned boardID)
|
||||
{
|
||||
if (!modbusDevice) {
|
||||
return;
|
||||
}
|
||||
emit boardReading(boardID);
|
||||
|
||||
statusBar()->clearMessage();
|
||||
|
||||
QModbusDataUnit statusUnit(QModbusDataUnit::InputRegisters, 85, 1);
|
||||
|
||||
if (auto *reply = modbusDevice->sendReadRequest(statusUnit, Boards[boardID].adr)) {
|
||||
Boards[boardID].timerToStatusResponse.start();
|
||||
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, boardID, reply]() {
|
||||
if(!Boards[boardID].isActive)
|
||||
return;
|
||||
|
||||
// Обработка ответа статуса
|
||||
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);
|
||||
|
||||
// Запрос полных данных
|
||||
QModbusDataUnit dataUnit(QModbusDataUnit::InputRegisters, 0, 85-(boardID/3*20));
|
||||
if (auto *dataReply = modbusDevice->sendReadRequest(dataUnit, Boards[boardID].adr)) {
|
||||
Boards[boardID].timerToDataResponse.start();
|
||||
|
||||
if (!dataReply->isFinished()) {
|
||||
connect(dataReply, &QModbusReply::finished, this, [this, boardID, dataReply, StatusReg]() {
|
||||
if(!Boards[boardID].isActive)
|
||||
return;
|
||||
Boards[boardID].timerData->setText(QString("Data: %1 ms").arg(Boards[boardID].timerToDataResponse.elapsed()));
|
||||
displayResultOfScan(dataReply, boardID, StatusReg.AllReg);
|
||||
dataReply->deleteLater();
|
||||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||||
Boards[boardID].boardScanners->start(timerInterval);
|
||||
});
|
||||
} else {
|
||||
// Мгновенно завершенный запрос данных
|
||||
Boards[boardID].timerToDataResponse.elapsed();
|
||||
// shouldLog для dataReply должен определяться здесь, но используем тот же принцип
|
||||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||||
}
|
||||
dataReply->deleteLater();
|
||||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||||
Boards[boardID].boardScanners->start(timerInterval);
|
||||
}
|
||||
} else {
|
||||
// Ошибка отправки запроса данных
|
||||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||||
}
|
||||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||||
Boards[boardID].boardScanners->start(timerInterval);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Ошибка в ответе статуса
|
||||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||||
reply->errorString(), ++Boards[boardID].error_TX, "");
|
||||
}
|
||||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||||
Boards[boardID].boardScanners->start(timerInterval);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
// Мгновенно завершенный запрос статуса
|
||||
Boards[boardID].timerToStatusResponse.elapsed();
|
||||
// Для мгновенно завершенных запросов определяем shouldLog здесь
|
||||
if (Boards[boardID].isActive && !(reply->error() == QModbusDevice::ReplyAbortedError)) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||||
}
|
||||
reply->deleteLater();
|
||||
unsigned timerInterval = m_deviceSettingsDialog->currentBoardTimer(boardID);
|
||||
Boards[boardID].boardScanners->start(timerInterval);
|
||||
}
|
||||
} else {
|
||||
// Ошибка отправки запроса статуса
|
||||
if (Boards[boardID].isActive) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID + 1).arg(Boards[boardID].adr),
|
||||
modbusDevice->errorString(), ++Boards[boardID].error_TX, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void M3KTE::displayResultOfScan(QModbusReply *reply, int boardID, int status)
|
||||
{
|
||||
if(!reply)
|
||||
return;
|
||||
if(reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
bool W_Flag = false;
|
||||
bool A_Flag = false;
|
||||
|
||||
if(unit.startAddress() != 0 || unit.valueCount() != (unsigned)(85-(boardID/3*20))) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
"Ошибка при приёме.", ++Boards[boardID].error_RX,
|
||||
tr("Принятый ответ: Стартовый адрес %1, Количество элементов %2").arg(unit.startAddress()).arg(unit.valueCount()));
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
statusreg StatusReg;
|
||||
StatusReg.AllReg = status;
|
||||
|
||||
// Обрабатываем статус MZKT
|
||||
QString statusText;
|
||||
int state = StatusReg.ParsingReg.mzkte_status;
|
||||
int numb_err = StatusReg.ParsingReg.mzkte_error;
|
||||
if (state == 0) {
|
||||
statusText = "Ok";
|
||||
} else if (state == 1) {
|
||||
statusText = "Non-Critical";
|
||||
} else if (state == 2) {
|
||||
statusText = "Critical";
|
||||
}
|
||||
if (state) {
|
||||
switch (numb_err) {
|
||||
case 1:
|
||||
statusText += QString(" (Err 5 VD)");
|
||||
break;
|
||||
case 2:
|
||||
statusText += QString(" (Err 5 VA)");
|
||||
break;
|
||||
case 3:
|
||||
statusText += QString(" (Err 5 Vsci)");
|
||||
break;
|
||||
case 4:
|
||||
statusText += QString(" (Err 24 V)");
|
||||
break;
|
||||
case 5:
|
||||
statusText += QString(" (Hardfault)");
|
||||
break;
|
||||
case 6:
|
||||
statusText += QString(" (Empty Settings)");
|
||||
break;
|
||||
case 7:
|
||||
statusText += QString(" (ADC Error)");
|
||||
break;
|
||||
case 8:
|
||||
statusText += QString(" (Program Err 4)");
|
||||
break;
|
||||
case 9:
|
||||
statusText += QString(" (Program Err 5)");
|
||||
break;
|
||||
case 10:
|
||||
statusText += QString(" (EEPROM Error)");
|
||||
break;
|
||||
case 11:
|
||||
statusText += QString(" (Unstable discharge level)");
|
||||
break;
|
||||
case 12:
|
||||
statusText += QString(" (RS/UART Errors)");
|
||||
break;
|
||||
default:
|
||||
statusText += QString(" (Program Err %1)").arg(numb_err - 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Boards[boardID].localError->setText(statusText);
|
||||
|
||||
|
||||
Boards[boardID].localState[LOCAL_STATE_POLL]->setChecked(StatusReg.ParsingReg.poll_allowed);
|
||||
Boards[boardID].localState[LOCAL_STATE_WARN]->setChecked(StatusReg.ParsingReg.warning);
|
||||
Boards[boardID].localState[LOCAL_STATE_ERR]->setChecked(StatusReg.ParsingReg.accident);
|
||||
|
||||
|
||||
QString W_Adr;
|
||||
QString A_Adr;
|
||||
int total_qnt;
|
||||
if(boardID == 3)
|
||||
{
|
||||
total_qnt = 65;
|
||||
}
|
||||
else
|
||||
{
|
||||
total_qnt = 85;
|
||||
}
|
||||
for(int i = unit.startAddress(), total = total_qnt; i < total; ++i) {
|
||||
if(Boards[boardID].coil[i]==true) {
|
||||
int j = 0;
|
||||
if(Boards[boardID].HR[i+85] > unit.value(i)) {
|
||||
j = 1;
|
||||
if(j != m_ProgressBar[i+boardID*85]->value()) {
|
||||
A_Adr += tr("ТЭ%1 ").arg(i);
|
||||
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]->setWhatsThis(QString("П%1 ТЭ%2: Аварийный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||||
A_Flag = true;
|
||||
} else if(Boards[boardID].HR[i] > unit.value(i)) {
|
||||
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]->setWhatsThis(QString("П%1 ТЭ%2: Предупредительный уровень напряжения.").arg(QString::number(boardID+1), QString::number(i%85)));
|
||||
W_Flag = true;
|
||||
} else {
|
||||
j = 3;
|
||||
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]->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%);} ";
|
||||
m_ProgressBar[i+boardID*85]->setStyleSheet(style_fc);
|
||||
} else {
|
||||
m_ProgressBar[i+boardID*85]->setValue(3);
|
||||
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)));
|
||||
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+boardID*85]->setStyleSheet(style_fc_off);
|
||||
}
|
||||
Boards[boardID].ModbusModelCoil->set_currentU(unit.value(i), i);
|
||||
Boards[boardID].ModbusModelHoldingReg->set_currentU(unit.value(i), i);
|
||||
}
|
||||
Boards[boardID].ModbusModelCoil->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 2),
|
||||
ui->writeValueTable->model()->index(unit.startAddress() + total_qnt -1, 2));
|
||||
Boards[boardID].ModbusModelHoldingReg->dataChanged(ui->writeValueTable->model()->index(unit.startAddress(), 3),
|
||||
ui->writeValueTable->model()->index(unit.startAddress() + total_qnt -1, 3));
|
||||
if(A_Flag && !A_Adr.isEmpty()) {
|
||||
statusM3KTE.Accidents[boardID] = true;
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
"Авария", Boards[boardID].error_A, A_Adr);
|
||||
} else
|
||||
statusM3KTE.Accidents[boardID] = false;
|
||||
if(W_Flag && !W_Adr.isEmpty()) {
|
||||
statusM3KTE.Warnings[boardID] = true;
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
"Предупреждение", Boards[boardID].error_W, W_Adr);
|
||||
} else
|
||||
statusM3KTE.Warnings[boardID] = false;
|
||||
ui->BSM_Warning->setChecked(false);
|
||||
ui->BSM_Accident->setChecked(false);
|
||||
ui->BSM_WorkInProgress->setChecked(true);
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(statusM3KTE.Accidents[i]) {
|
||||
ui->BSM_WorkInProgress->setChecked(false);
|
||||
ui->BSM_Warning->setChecked(false);
|
||||
ui->BSM_Accident->setChecked(true);
|
||||
break;
|
||||
}
|
||||
if(statusM3KTE.Warnings[i]) {
|
||||
ui->BSM_WorkInProgress->setChecked(false);
|
||||
ui->BSM_Accident->setChecked(false);
|
||||
ui->BSM_Warning->setChecked(true);
|
||||
}
|
||||
}
|
||||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
reply->errorString(), ++Boards[boardID].error_RX,
|
||||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
reply->errorString(), ++Boards[boardID].error_RX,
|
||||
QString::number(reply->error(), 16));
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void M3KTE::applySettingsFromScan(QModbusReply *reply)
|
||||
{
|
||||
int Adr = 255;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(Boards[i].adr==reply->serverAddress() &&Boards[i].isActive) {
|
||||
Adr = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
for(int i = 0, total = int(unit.valueCount()); i < (total); ++i) {
|
||||
if(unit.registerType() == QModbusDataUnit::Coils) {
|
||||
Boards[Adr].coil[i + unit.startAddress()] = unit.value(i);
|
||||
if(unit.value(i)==1) {
|
||||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Checked, Qt::CheckStateRole);
|
||||
} else {
|
||||
Boards[Adr].ModbusModelCoil->setData(ui->writeValueTable->model()->index(i + unit.startAddress(), 2), Qt::Unchecked, Qt::CheckStateRole);
|
||||
}
|
||||
} else if(unit.registerType() == QModbusDataUnit::HoldingRegisters) {
|
||||
Boards[Adr].HR[i + unit.startAddress()] = unit.value(i);
|
||||
Boards[Adr].ModbusModelHoldingReg->setData(Boards[Adr].ModbusModelHoldingReg->index(i + unit.startAddress(), 3), QString::number(unit.value(i), 10), Qt::EditRole);
|
||||
}
|
||||
}
|
||||
} else if(reply->error() == QModbusDevice::ProtocolError) {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (Mobus exception: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_RX,
|
||||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Read response error: %1 (code: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_RX,
|
||||
QString::number(reply->error(), 16));
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void M3KTE::slotmultipleRegWrite()
|
||||
{
|
||||
if(!modbusDevice)
|
||||
return;
|
||||
multipleRegWrite();
|
||||
}
|
||||
|
||||
void M3KTE::slotmultipleRegWriteAndSend()
|
||||
{
|
||||
if(!modbusDevice)
|
||||
return;
|
||||
multipleRegWrite();
|
||||
multipleRegSend();
|
||||
}
|
||||
|
||||
void M3KTE::multipleRegSend()
|
||||
{
|
||||
QModbusDataUnit *unit_tx = nullptr;
|
||||
if(m_regMultipleSettings->getTypeReg()) {
|
||||
unit_tx = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, m_regMultipleSettings->getStartAdr(), m_regMultipleSettings->getCountReg());
|
||||
} else {
|
||||
unit_tx = new QModbusDataUnit(QModbusDataUnit::Coils, m_regMultipleSettings->getStartAdr(), m_regMultipleSettings->getCountReg());
|
||||
}
|
||||
for(unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) {
|
||||
unit_tx->setValue(i, m_regMultipleSettings->getNewValue());
|
||||
if(m_regMultipleSettings->getTypeReg()) {
|
||||
Boards[m_regMultipleSettings->getBoardId()].HR[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||||
} else {
|
||||
Boards[m_regMultipleSettings->getBoardId()].coil[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||||
}
|
||||
}
|
||||
if(auto *reply = modbusDevice->sendWriteRequest(*unit_tx, Boards[m_regMultipleSettings->getBoardId()].adr)) {
|
||||
unsigned Adr = m_regMultipleSettings->getBoardId();
|
||||
if(!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply, Adr]() {
|
||||
if(reply->error() == QModbusDevice::ProtocolError) {
|
||||
statusBar()->showMessage(tr("Write response error: %1 (Mobus exception: 0x%2)")
|
||||
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_TX,
|
||||
QString("Mobus exception: 0x%1").arg(reply->rawResult().exceptionCode(), -1, 16));
|
||||
} else if(reply->error() != QModbusDevice::NoError) {
|
||||
statusBar()->showMessage(tr("Write response error: %1 (code: 0x%2)").
|
||||
arg(reply->errorString()).arg(reply->error(), -1, 16), 5000);
|
||||
logError(tr("Плата %1 (ID %2)").arg(Adr+1).arg(Boards[Adr].adr),
|
||||
reply->errorString(), ++Boards[Adr].error_TX,
|
||||
QString::number(reply->error(), 16));
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
// broadcast replies return immediately
|
||||
reply->deleteLater();
|
||||
}
|
||||
} else {
|
||||
statusBar()->showMessage(tr("Write error: ") + modbusDevice->errorString(), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::multipleRegWrite()
|
||||
{
|
||||
for(unsigned i = 0; i < m_regMultipleSettings->getCountReg(); i++) {
|
||||
if(m_regMultipleSettings->getTypeReg()) {
|
||||
Boards[m_regMultipleSettings->getBoardId()].ModbusModelHoldingReg->m_holdingRegisters[i+m_regMultipleSettings->getStartAdr()] = m_regMultipleSettings->getNewValue();
|
||||
} else {
|
||||
Boards[m_regMultipleSettings->getBoardId()].ModbusModelCoil->m_coils[i+m_regMultipleSettings->getStartAdr()] = (bool)m_regMultipleSettings->getNewValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::writeSingleCoil(int boardId, int coilAddress, bool value)
|
||||
{
|
||||
if (!modbusDevice || !Boards[boardId].isActive)
|
||||
return;
|
||||
|
||||
QModbusDataUnit unit(QModbusDataUnit::Coils, coilAddress, 1);
|
||||
unit.setValue(0, value ? 1 : 0);
|
||||
|
||||
if (auto *reply = modbusDevice->sendWriteRequest(unit, Boards[boardId].adr)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, boardId, reply]() {
|
||||
if (reply->error() != QModbusDevice::NoError) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardId+1).arg(Boards[boardId].adr),
|
||||
reply->errorString(), ++Boards[boardId].error_TX,
|
||||
"Single coil write");
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void M3KTE::writeSingleRegister(int boardID, int regAddress, quint16 value)
|
||||
{
|
||||
if (!modbusDevice || !Boards[boardID].isActive)
|
||||
return;
|
||||
|
||||
QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters, regAddress, 1);
|
||||
unit.setValue(0, value);
|
||||
|
||||
if (auto *reply = modbusDevice->sendWriteRequest(unit, Boards[boardID].adr)) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, this, [this, boardID, reply]() {
|
||||
if (reply->error() != QModbusDevice::NoError) {
|
||||
logError(tr("Плата %1 (ID %2)").arg(boardID+1).arg(Boards[boardID].adr),
|
||||
reply->errorString(), ++Boards[boardID].error_TX,
|
||||
"Single register write");
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
} else {
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QModbusReply* M3KTE::readSingleCoil(int boardID, int coilAddress)
|
||||
{
|
||||
if (!modbusDevice || !Boards[boardID].isActive)
|
||||
return nullptr;
|
||||
|
||||
QModbusDataUnit unit(QModbusDataUnit::Coils, coilAddress, 1);
|
||||
|
||||
auto *reply = modbusDevice->sendReadRequest(unit, Boards[boardID].adr);
|
||||
return reply;
|
||||
}
|
||||
|
||||
void M3KTE::selectPositionOnTree(unsigned int index)
|
||||
{
|
||||
ui->boardSelectBox->setCurrentIndex(index/85);
|
||||
int maxReg = 85 - (ui->boardSelectBox->currentIndex()/3*20);
|
||||
QModelIndex selected = ui->writeValueTable->model()->index(index%maxReg + maxReg*(ui->writeTable->currentIndex()/2), 0);
|
||||
ui->writeValueTable->selectionModel()->select(selected, QItemSelectionModel::ClearAndSelect |QItemSelectionModel::Rows);
|
||||
ui->writeValueTable->scrollTo(selected);
|
||||
}
|
||||
|
||||
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, [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);
|
||||
//Запрос типа устройства.
|
||||
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));
|
||||
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) {
|
||||
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) {
|
||||
onConnectClicked();
|
||||
bar->close();
|
||||
bar->deleteLater();
|
||||
return false;
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
if(subreply->error()!=QModbusDevice::NoError) {
|
||||
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;
|
||||
}
|
||||
157
M3KTE_TERM/m3kte.h
Normal file
157
M3KTE_TERM/m3kte.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#ifndef M3KTE_H
|
||||
#define M3KTE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QModbusDataUnit>
|
||||
#include <qprogressbar.h>
|
||||
|
||||
#include <QtSerialBus/QModbusDataUnit>
|
||||
#include "writeregistermodel.h"
|
||||
#include "debugterminaldialog.h"
|
||||
#include "devicesettingsdialog.h"
|
||||
#include "multiplesettings.h"
|
||||
#include "scanboard.h"
|
||||
#include "lineringer.h"
|
||||
|
||||
#include <QModbusTcpClient>
|
||||
#include <QModbusRtuSerialMaster>
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QTimer>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <QErrorMessage>
|
||||
#include <QPushButton>
|
||||
#include <QGroupBox>
|
||||
#include <QTableWidget>
|
||||
#include <QTime>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include <QtSerialBus/qtserialbusglobal.h>
|
||||
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
#include <QSerialPort>
|
||||
#endif
|
||||
|
||||
#define MODBUS_REQUEST_PROTOCOL_INFO_LENGTH 8
|
||||
|
||||
extern "C" __declspec(dllexport) QWidget* init(QWidget *parent);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class M3KTE; class SettingsDialog; class DebugTerminalDialog;}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#define LOCAL_STATE_POLL 0
|
||||
#define LOCAL_STATE_WARN 1
|
||||
#define LOCAL_STATE_ERR 2
|
||||
|
||||
class SettingsDialog;
|
||||
class DebugTerminalDialog;
|
||||
class WriteRegisterModel;
|
||||
|
||||
class M3KTE : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
void initActions();
|
||||
QModbusDataUnit readRequest() const;
|
||||
QModbusDataUnit writeRequest() const;
|
||||
void changeTable(int board, int tabletype);
|
||||
bool event(QEvent* event);
|
||||
bool pingNetworkDevices();
|
||||
void beginScanBoards();
|
||||
void stopScanBoard();
|
||||
void displayResultOfScan(QModbusReply *reply, int boardID, int status);
|
||||
void applySettingsFromScan(QModbusReply *reply);
|
||||
void multipleRegWrite();
|
||||
void multipleRegSend();
|
||||
void writeSingleCoil(int boardId, int coilAddress, bool value);
|
||||
void writeSingleRegister(int boardId, int regAddress, quint16 value);
|
||||
bool autoBaudRateScan();
|
||||
void selectPositionOnTree(unsigned index);
|
||||
signals:
|
||||
void successAtCheckBoards();
|
||||
void errorAtCheckBoards();
|
||||
void boardReading(int boardID);
|
||||
private slots:
|
||||
void clearLogger();
|
||||
void logError(const QString &errorPlace, const QString &errorString, unsigned errorCount, const QString &description);
|
||||
void slotmultipleRegWrite();
|
||||
void slotmultipleRegWriteAndSend();
|
||||
void onConnectClicked();
|
||||
void onReadButtonClicked();
|
||||
void onReadReady();
|
||||
void checkAdrChange(QModbusReply *reply, unsigned boardNum);
|
||||
void onWriteButtonClicked();
|
||||
void onSelectedBoardChanged(int index);
|
||||
void onWriteTableChanged(int index);
|
||||
void checkBoards();
|
||||
void onSpeedUpdate();
|
||||
void revertToOldSpeedAndRestart();
|
||||
void onParityUpdate();
|
||||
void boardScan(unsigned boardID);
|
||||
public:
|
||||
M3KTE(QWidget *parent = nullptr);
|
||||
~M3KTE();
|
||||
QModbusClient* getModbusDevice() const { return modbusDevice; }
|
||||
QModbusReply* readSingleCoil(int boardID, int coilAddress);
|
||||
private:
|
||||
Ui::M3KTE *ui;
|
||||
QTableWidget *loggerTable = nullptr;
|
||||
int CurrentConnectedDevice = 0;
|
||||
QProgressBar *m_ProgressBar[320];
|
||||
QPushButton *ThePhantomMenace[320];
|
||||
QModbusReply *lastRequest = nullptr;
|
||||
QModbusClient *modbusDevice = nullptr;
|
||||
DeviceSettingsDialog *m_deviceSettingsDialog = nullptr;
|
||||
DebugTerminalDialog *m_debugTerminalDialog = nullptr;
|
||||
SettingsDialog *m_settingsDialog = nullptr;
|
||||
MultipleSettings *m_regMultipleSettings = nullptr;
|
||||
ScanBoard *m_scanBoard = nullptr;
|
||||
LineRinger *m_lineRinger = nullptr;
|
||||
QGroupBox *Boards_Fields[4];
|
||||
struct StatusM3KTE{
|
||||
bool Warnings[4];
|
||||
bool Accidents[4];
|
||||
}statusM3KTE;
|
||||
unsigned error_terminal;
|
||||
struct BoardModbusRegisters {
|
||||
bool isActive = false;
|
||||
bool pollIsActive = true;
|
||||
int adr;
|
||||
int _tmp_adr;
|
||||
bool coil[85];
|
||||
unsigned HR[170];
|
||||
unsigned error_W = 0;
|
||||
unsigned error_A = 0;
|
||||
unsigned error_modbus = 0;
|
||||
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;
|
||||
QLabel *localError = nullptr;
|
||||
QCheckBox *localState[3] = {nullptr, nullptr, nullptr};
|
||||
WriteRegisterModel *ModbusModelCoil;
|
||||
WriteRegisterModel *ModbusModelHoldingReg;
|
||||
QTimer *boardScanners;
|
||||
bool isScan = false;
|
||||
QElapsedTimer timerToStatusResponse;
|
||||
QElapsedTimer timerToDataResponse;
|
||||
}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
|
||||
14703
M3KTE_TERM/m3kte.ui
Normal file
14703
M3KTE_TERM/m3kte.ui
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qputenv("QT_FATAL_WARNINGS", "0"); // отключает падение от ASSERT
|
||||
QApplication a(argc, argv);
|
||||
M3KTE w;
|
||||
w.show();
|
||||
70
M3KTE_TERM/multiplesettings.cpp
Normal file
70
M3KTE_TERM/multiplesettings.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "multiplesettings.h"
|
||||
#include "ui_multiplesettings.h"
|
||||
|
||||
MultipleSettings::MultipleSettings(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::MultipleSettings)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->buttonBox->button(QDialogButtonBox::Ok)->setText("Записать");
|
||||
ui->buttonBox->button(QDialogButtonBox::SaveAll)->setText("Записать и установить");
|
||||
selectedBoard = 0;
|
||||
}
|
||||
|
||||
MultipleSettings::~MultipleSettings()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void MultipleSettings::on_buttonBox_clicked(QAbstractButton *button)
|
||||
{
|
||||
if(button == ui->buttonBox->button(QDialogButtonBox::Ok)) {
|
||||
newValue = ui->regValueLine->text().toInt(nullptr, 16);
|
||||
typeReg = ui->regTypeBox->currentIndex();
|
||||
startAdr = ui->adrBox->value();
|
||||
countReg = ui->countBox->value();
|
||||
boardId = ui->boardBox->currentIndex();
|
||||
emit write();
|
||||
} else if (button == ui->buttonBox->button(QDialogButtonBox::SaveAll)) {
|
||||
newValue = ui->regValueLine->text().toInt(nullptr, 16);
|
||||
typeReg = ui->regTypeBox->currentIndex();
|
||||
startAdr = ui->adrBox->value();
|
||||
countReg = ui->countBox->value();
|
||||
boardId = ui->boardBox->currentIndex();
|
||||
emit writeAndSend();
|
||||
} else {}
|
||||
}
|
||||
|
||||
void MultipleSettings::on_regTypeBox_currentIndexChanged(int index)
|
||||
{
|
||||
short maxRange = 0;
|
||||
switch (ui->boardBox->currentIndex()) {
|
||||
case 3:
|
||||
maxRange = 64;
|
||||
break;
|
||||
default:
|
||||
maxRange = 84;
|
||||
}
|
||||
switch (index) {
|
||||
case 0:
|
||||
case 1:
|
||||
ui->adrBox->setRange(0, maxRange);
|
||||
ui->adrBox->setValue(0);
|
||||
break;
|
||||
case 2:
|
||||
ui->adrBox->setRange(85, 85+maxRange);
|
||||
ui->adrBox->setValue(85);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MultipleSettings::on_boardBox_currentIndexChanged(int index)
|
||||
{
|
||||
selectedBoard = index;
|
||||
on_regTypeBox_currentIndexChanged(ui->regTypeBox->currentIndex());
|
||||
}
|
||||
|
||||
void MultipleSettings::on_adrBox_valueChanged(int arg1)
|
||||
{
|
||||
ui->countBox->setRange(1, ((85-(20*(ui->boardBox->currentIndex()/3)))*(1+(ui->regTypeBox->currentIndex()/2))-arg1));
|
||||
}
|
||||
46
M3KTE_TERM/multiplesettings.h
Normal file
46
M3KTE_TERM/multiplesettings.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef MULTIPLESETTINGS_H
|
||||
#define MULTIPLESETTINGS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace Ui {
|
||||
class MultipleSettings;
|
||||
}
|
||||
|
||||
class MultipleSettings : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultipleSettings(QWidget *parent = nullptr);
|
||||
~MultipleSettings();
|
||||
quint16 getNewValue() {return newValue;}
|
||||
unsigned getStartAdr() {return startAdr;}
|
||||
unsigned getCountReg() {return countReg;}
|
||||
short getTypeReg() {return typeReg;}
|
||||
short getBoardId() {return boardId;}
|
||||
signals:
|
||||
void write();
|
||||
void writeAndSend();
|
||||
|
||||
private slots:
|
||||
void on_buttonBox_clicked(QAbstractButton *button);
|
||||
|
||||
void on_regTypeBox_currentIndexChanged(int index);
|
||||
|
||||
void on_boardBox_currentIndexChanged(int index);
|
||||
|
||||
void on_adrBox_valueChanged(int arg1);
|
||||
|
||||
private:
|
||||
Ui::MultipleSettings *ui;
|
||||
quint16 newValue = 0;
|
||||
unsigned startAdr;
|
||||
unsigned countReg;
|
||||
short typeReg;
|
||||
short boardId;
|
||||
short selectedBoard;
|
||||
};
|
||||
|
||||
#endif // MULTIPLESETTINGS_H
|
||||
198
M3KTE_TERM/multiplesettings.ui
Normal file
198
M3KTE_TERM/multiplesettings.ui
Normal file
@@ -0,0 +1,198 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MultipleSettings</class>
|
||||
<widget class="QDialog" name="MultipleSettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>128</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Уставка</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="countLabel">
|
||||
<property name="text">
|
||||
<string>Кол-во</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QLabel" name="adrLabel">
|
||||
<property name="text">
|
||||
<string>Стартовый</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="boardLabel">
|
||||
<property name="text">
|
||||
<string>Плата</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSpinBox" name="adrBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>84</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="boardBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QSpinBox" name="countBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>85</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QLineEdit" name="regValueLine"/>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QLabel" name="regValueLabel">
|
||||
<property name="text">
|
||||
<string>Значение (HEX)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="regTypeBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Coil</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Warning</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Accident</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="regTypeLabel">
|
||||
<property name="text">
|
||||
<string>Тип Регистра</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::SaveAll</set>
|
||||
</property>
|
||||
<property name="centerButtons">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>MultipleSettings</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>MultipleSettings</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>
|
||||
39
M3KTE_TERM/scanboard.cpp
Normal file
39
M3KTE_TERM/scanboard.cpp
Normal 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
33
M3KTE_TERM/scanboard.h
Normal 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
81
M3KTE_TERM/scanboard.ui
Normal 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>
|
||||
77
M3KTE_TERM/settingsdialog.cpp
Normal file
77
M3KTE_TERM/settingsdialog.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "settingsdialog.h"
|
||||
#include "ui_settingsdialog.h"
|
||||
|
||||
SettingsDialog::SettingsDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::SettingsDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->parityCombo->setCurrentIndex(0);
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
ui->baudCombo->setCurrentText(QString::number(m_settings.baud));
|
||||
ui->dataBitsCombo->setCurrentText(QString::number(m_settings.dataBits));
|
||||
ui->stopBitsCombo->setCurrentText(QString::number(m_settings.stopBits));
|
||||
on_updateComBox_clicked();
|
||||
#endif
|
||||
ui->timeoutSpinner->setValue(m_settings.responseTime);
|
||||
ui->retriesSpinner->setValue(m_settings.numberOfRetries);
|
||||
connect(ui->AcceptOrRejectButtonBox, &QDialogButtonBox::accepted, [this]() {
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
m_settings.portName = ui->comBox->currentData().toString();
|
||||
m_settings.parity = ui->parityCombo->currentIndex();
|
||||
if (m_settings.parity > 0)
|
||||
m_settings.parity++;
|
||||
m_settings.baud = ui->baudCombo->currentText().toInt();
|
||||
m_settings.dataBits = ui->dataBitsCombo->currentText().toInt();
|
||||
m_settings.stopBits = ui->stopBitsCombo->currentText().toInt();
|
||||
#endif
|
||||
m_settings.responseTime = ui->timeoutSpinner->value();
|
||||
m_settings.numberOfRetries = ui->retriesSpinner->value();
|
||||
hide();
|
||||
});
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
SettingsDialog::Settings SettingsDialog::settings() const
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
int SettingsDialog::UpdateBaud(int baud)
|
||||
{
|
||||
ui->baudCombo->setCurrentIndex(baud);
|
||||
return (m_settings.baud = ui->baudCombo->currentText().toInt());
|
||||
}
|
||||
|
||||
int SettingsDialog::UpdateParity(int parity)
|
||||
{
|
||||
ui->parityCombo->setCurrentIndex(parity);
|
||||
if(parity>0) {
|
||||
return (m_settings.parity = ++parity);
|
||||
} else {
|
||||
return (m_settings.parity = parity);
|
||||
}
|
||||
}
|
||||
|
||||
int SettingsDialog::curBaud()
|
||||
{
|
||||
return ui->baudCombo->currentIndex();
|
||||
}
|
||||
|
||||
int SettingsDialog::curParity()
|
||||
{
|
||||
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()));
|
||||
}
|
||||
}
|
||||
49
M3KTE_TERM/settingsdialog.h
Normal file
49
M3KTE_TERM/settingsdialog.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef SETTINGSDIALOG_H
|
||||
#define SETTINGSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QtSerialBus/QModbusDataUnit>
|
||||
#include <QtSerialBus/qtserialbusglobal.h>
|
||||
#if QT_CONFIG(modbus_serialport)
|
||||
#include <QSerialPort>
|
||||
#include <QSerialPortInfo>
|
||||
#endif
|
||||
|
||||
namespace Ui {
|
||||
class SettingsDialog;
|
||||
}
|
||||
|
||||
class SettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
struct Settings {
|
||||
QString portName;
|
||||
int parity = QSerialPort::NoParity;
|
||||
int baud = 115200;
|
||||
int dataBits = QSerialPort::Data8;
|
||||
int stopBits = QSerialPort::OneStop;
|
||||
int responseTime = 1000;
|
||||
int numberOfRetries = 0;
|
||||
};
|
||||
|
||||
explicit SettingsDialog(QWidget *parent = nullptr);
|
||||
~SettingsDialog();
|
||||
|
||||
Settings settings() const;
|
||||
|
||||
int UpdateBaud(int baud);
|
||||
int UpdateParity(int parity);
|
||||
|
||||
int curBaud();
|
||||
int curParity();
|
||||
private slots:
|
||||
void on_updateComBox_clicked();
|
||||
|
||||
private:
|
||||
Settings m_settings;
|
||||
Ui::SettingsDialog *ui;
|
||||
};
|
||||
|
||||
#endif // SETTINGSDIALOG_H
|
||||
315
M3KTE_TERM/settingsdialog.ui
Normal file
315
M3KTE_TERM/settingsdialog.ui
Normal file
@@ -0,0 +1,315 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SettingsDialog</class>
|
||||
<widget class="QDialog" name="SettingsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>311</width>
|
||||
<height>288</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="timeoutSpinner">
|
||||
<property name="suffix">
|
||||
<string> мс</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>200</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" rowspan="2" colspan="2">
|
||||
<widget class="QSpinBox" name="retriesSpinner">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="timeoutLabel">
|
||||
<property name="text">
|
||||
<string>Тайм-аут ответа:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>127</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Serial Parameters</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="parityLabel">
|
||||
<property name="text">
|
||||
<string>Чётность</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="baudCombo">
|
||||
<property name="currentIndex">
|
||||
<number>7</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>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="dataBitsLabel">
|
||||
<property name="text">
|
||||
<string>Биты данных</string>
|
||||
</property>
|
||||
</widget>
|
||||
</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">
|
||||
<widget class="QComboBox" name="dataBitsCombo">
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="portLabel">
|
||||
<property name="text">
|
||||
<string>Порт</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="stopBitsLabel">
|
||||
<property name="text">
|
||||
<string>Стоп-биты</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="retriesLabel">
|
||||
<property name="text">
|
||||
<string>Количество повторов:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QDialogButtonBox" name="AcceptOrRejectButtonBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>25</height>
|
||||
</size>
|
||||
</property>
|
||||
<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>AcceptOrRejectButtonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>SettingsDialog</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>AcceptOrRejectButtonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>SettingsDialog</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>
|
||||
131
M3KTE_TERM/writeregistermodel.cpp
Normal file
131
M3KTE_TERM/writeregistermodel.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "writeregistermodel.h"
|
||||
|
||||
#include "writeregistermodel.h"
|
||||
|
||||
enum { NumColumn = 0, NameColumn = 1, CoilsColumn = 2, HoldingColumn = 3, ColumnCount = 5, CurrentUColumn = 4};
|
||||
|
||||
WriteRegisterModel::WriteRegisterModel(QObject *parent, int _tmpRC, bool _isHR)
|
||||
: QAbstractTableModel(parent),
|
||||
m_coils(RowCount=_tmpRC, false), m_holdingRegisters(RowCount=_tmpRC, 0u), m_currentU(RowCount=_tmpRC)
|
||||
{
|
||||
isHR=_isHR;
|
||||
}
|
||||
|
||||
int WriteRegisterModel::rowCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return RowCount;
|
||||
}
|
||||
|
||||
int WriteRegisterModel::columnCount(const QModelIndex &/*parent*/) const
|
||||
{
|
||||
return ColumnCount;
|
||||
}
|
||||
|
||||
QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return QVariant();
|
||||
Q_ASSERT(m_coils.count() == RowCount);
|
||||
Q_ASSERT(m_holdingRegisters.count() == RowCount);
|
||||
if (index.column() == NumColumn && role == Qt::DisplayRole)
|
||||
return QString::number(index.row());
|
||||
if (index.column() == NameColumn && role == Qt::DisplayRole)
|
||||
return QString("ТЭ%1").arg(index.row()%(RowCount/(1+isHR))+1);
|
||||
if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils
|
||||
return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked;
|
||||
if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers
|
||||
return QString("%1 В").arg(QString::number((double)((double)m_holdingRegisters.at(index.row())/(double)1000), 'f', 3));
|
||||
if(index.column() == CurrentUColumn && role == Qt::DisplayRole)
|
||||
return QString("%1 В").arg(QString::number((double)((double)m_currentU.at(index.row())/(double)1000), 'f', 3));
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
if (orientation == Qt::Horizontal) {
|
||||
switch (section) {
|
||||
case NumColumn:
|
||||
return QStringLiteral("#Reg");
|
||||
case NameColumn:
|
||||
return QStringLiteral("Fuel Cell");
|
||||
case CoilsColumn:
|
||||
return QStringLiteral("Coils");
|
||||
case HoldingColumn:
|
||||
return QStringLiteral("Holding Registers");
|
||||
case CurrentUColumn:
|
||||
return QStringLiteral("Current U");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return false;
|
||||
Q_ASSERT(m_coils.count() == RowCount);
|
||||
Q_ASSERT(m_holdingRegisters.count() == RowCount);
|
||||
if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils
|
||||
auto s = static_cast<Qt::CheckState>(value.toUInt());
|
||||
s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row());
|
||||
emit dataChanged(index, index);
|
||||
return true;
|
||||
}
|
||||
if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers
|
||||
bool result = false;
|
||||
quint16 newValue = value.toString().toUShort(&result, 10);
|
||||
if (result)
|
||||
m_holdingRegisters[index.row()] = newValue;
|
||||
emit dataChanged(index, index);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount)
|
||||
return QAbstractTableModel::flags(index);
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
if ((index.row() < m_address) || (index.row() >= (m_address + m_number)))
|
||||
flags &= ~Qt::ItemIsEnabled;
|
||||
if (index.column() == CoilsColumn) // coils
|
||||
return flags | Qt::ItemIsUserCheckable;
|
||||
if (index.column() == HoldingColumn) // holding registers
|
||||
return flags | Qt::ItemIsEditable;
|
||||
return flags;
|
||||
}
|
||||
|
||||
void WriteRegisterModel::setStartAddress(int address)
|
||||
{
|
||||
m_address = address;
|
||||
//emit updateViewport();
|
||||
}
|
||||
|
||||
void WriteRegisterModel::setNumberOfValues(const QString &number)
|
||||
{
|
||||
m_number = number.toInt();
|
||||
//emit updateViewport();
|
||||
}
|
||||
|
||||
bool WriteRegisterModel::get_coil(const QModelIndex &index)
|
||||
{
|
||||
return m_coils.at(index.row());
|
||||
}
|
||||
|
||||
uint WriteRegisterModel::get_holreg(const QModelIndex &index)
|
||||
{
|
||||
return m_holdingRegisters.at(index.row());
|
||||
}
|
||||
|
||||
bool WriteRegisterModel::set_currentU(unsigned _tmpU, unsigned index)
|
||||
{
|
||||
m_currentU[index] = _tmpU;
|
||||
if(isHR)
|
||||
m_currentU[index + m_number] = _tmpU;
|
||||
return true;
|
||||
}
|
||||
43
M3KTE_TERM/writeregistermodel.h
Normal file
43
M3KTE_TERM/writeregistermodel.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef WRITEREGISTERMODEL_H
|
||||
#define WRITEREGISTERMODEL_H
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QBitArray>
|
||||
#include <QObject>
|
||||
|
||||
class WriteRegisterModel : public QAbstractTableModel
|
||||
{
|
||||
private:
|
||||
bool isHR;
|
||||
int RowCount;
|
||||
public:
|
||||
WriteRegisterModel(QObject *parent = nullptr, int _tmpRC = 85, bool _isHR = false);
|
||||
bool get_coil(const QModelIndex &index);
|
||||
uint get_holreg(const QModelIndex &index);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
bool set_currentU(unsigned _tmpU, unsigned index);
|
||||
|
||||
public slots:
|
||||
void setStartAddress(int address);
|
||||
void setNumberOfValues(const QString &number);
|
||||
|
||||
signals:
|
||||
void updateViewport();
|
||||
|
||||
public:
|
||||
int m_number = 0;
|
||||
int m_address = 0;
|
||||
QBitArray m_coils;
|
||||
QVector<quint16> m_holdingRegisters;
|
||||
QVector<quint16> m_currentU;
|
||||
};
|
||||
#endif // WRITEREGISTERMODEL_H
|
||||
BIN
MZKT_Test_Terminal.exe
Normal file
BIN
MZKT_Test_Terminal.exe
Normal file
Binary file not shown.
21
Release/.qmake.stash
Normal file
21
Release/.qmake.stash
Normal 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
Release/release/M3KTE_TERM.exe
Normal file
BIN
Release/release/M3KTE_TERM.exe
Normal file
Binary file not shown.
15
m3kte.cpp
15
m3kte.cpp
@@ -1,15 +0,0 @@
|
||||
#include "m3kte.h"
|
||||
#include "ui_m3kte.h"
|
||||
|
||||
M3KTE::M3KTE(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::M3KTE)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
M3KTE::~M3KTE()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
21
m3kte.h
21
m3kte.h
@@ -1,21 +0,0 @@
|
||||
#ifndef M3KTE_H
|
||||
#define M3KTE_H
|
||||
|
||||
#include <QMainWindow>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class M3KTE; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class M3KTE : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
M3KTE(QWidget *parent = nullptr);
|
||||
~M3KTE();
|
||||
|
||||
private:
|
||||
Ui::M3KTE *ui;
|
||||
};
|
||||
#endif // M3KTE_H
|
||||
22
m3kte.ui
22
m3kte.ui
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>M3KTE</class>
|
||||
<widget class="QMainWindow" name="M3KTE">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>M3KTE</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar"/>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
373
ТЗ/modbus_data.h
Normal file
373
ТЗ/modbus_data.h
Normal file
@@ -0,0 +1,373 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus_data.h
|
||||
* @brief Заголовочный файл с описанием даты MODBUS.
|
||||
* @details Данный файл необходимо подключается в rs_message.h. После rs_message.h
|
||||
* подключается к основному проекту.
|
||||
*
|
||||
* @defgroup MODBUS_DATA
|
||||
* @ingroup MODBUS
|
||||
* @brief Modbus data description
|
||||
*
|
||||
*************************************************************************/
|
||||
#include "stdint.h"
|
||||
//--------------DEFINES FOR REGISTERS---------------
|
||||
// DEFINES FOR ARRAYS
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for registers
|
||||
Структура дефайна адресов
|
||||
@verbatim
|
||||
Для массивов регистров:
|
||||
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
|
||||
R_<NAME_ARRAY>_QNT - количество регистров в массиве
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Скорость обмена
|
||||
*/
|
||||
typedef enum //MB_SpeedTypeDef
|
||||
{
|
||||
MB_9600bs = 0x0000, ///< Скорость 9600 б/с
|
||||
MB_14400bs = 0x0001, ///< Скорость 14400 б/с
|
||||
MB_19200bs = 0x0002, ///< Скорость 19200 б/с
|
||||
MB_31250bs = 0x0003, ///< Скорость 31250 б/с
|
||||
MB_38400bs = 0x0004, ///< Скорость 38400 б/с
|
||||
MB_56000bs = 0x0005, ///< Скорость 56000 б/с
|
||||
MB_57600bs = 0x0006, ///< Скорость 57600 б/с
|
||||
MB_115200bs = 0x0007, ///< Скорость 115200 б/с
|
||||
mb16bit = 0x1000, ///< костыль чтобы enum был 16-битный... или забить на enum, пока не определился
|
||||
}MB_SpeedTypeDef;
|
||||
|
||||
/**
|
||||
* @brief Контроль четности
|
||||
*/
|
||||
typedef enum //MB_ParityCtrlTypeDef
|
||||
{
|
||||
NoParityCtrl = 0x0000, ///< контроля нет
|
||||
EvenParityCtrl = 0x0400, ///< четный контроль
|
||||
OddParityCtrl = 0x0600, ///< нечетый контроль
|
||||
}MB_ParityCtrlTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Регистры хранения для уставок параметров МКЗТЭ
|
||||
*/
|
||||
typedef struct //MB_DataHoldRegsTypeDef
|
||||
{
|
||||
|
||||
uint16_t Warning_Setpoints[85]; /*!< @brief Адреса 0-84: Уставки «Предупреждение»
|
||||
@details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Предупреждение».
|
||||
|
||||
Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */
|
||||
|
||||
uint16_t Errors_Setpoints[85]; /*!< @brief Адреса 85-169: Уставки «Авария»
|
||||
@details Задает пороговое напряжение, при достижении которого будет сформирован сигнал «Авария».
|
||||
|
||||
Максимальное значение (записываемое в регистр) - 1100 (1,1 В *1000) */
|
||||
|
||||
uint16_t Commands_Mode; /*!< @brief Адрес 170: Уставка «Команды»
|
||||
@details Принимаемые значения:
|
||||
- 0x0000 – стандартная работа
|
||||
- 0x0001 – запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются) */
|
||||
|
||||
uint16_t reserved; ///< Адрес 171 зарезервирован
|
||||
|
||||
uint16_t MZKTE_Network_Adress; /*!< @brief Адрес 172: Уставка «Сетевой адрес МЗКТЭ»
|
||||
@details При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
|
||||
MB_SpeedTypeDef Modbus_Speed:16; /*!< @brief Адрес 173: Уставка «Скорость обмена»
|
||||
@details Принимаемые значения описаны в @ref MB_SpeedTypeDef.
|
||||
|
||||
При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
|
||||
MB_ParityCtrlTypeDef Parity_Control:16; /*!< @brief Адрес 174: Уставка «Команды»
|
||||
@details Принимаемые значения описаны в @ref MB_ParityCtrlTypeDef.
|
||||
|
||||
При удачной записи этого регистра ответный фрейм не отправляется */
|
||||
}MB_DataHoldRegsTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Номер неисправности МЗКТЭ
|
||||
*/
|
||||
typedef enum //MB_MZKTEErrorsTypeDef
|
||||
{
|
||||
No_Err = 0x00, ///< Неисправность отсутствует
|
||||
Err_Digit_5V_Power = 0x01, ///< Неисправность цифрового источника питания +5 В
|
||||
Err_Analog_15V_5V_3V_Power = 0x02, ///< Неисправность аналогового источника питания (±15 В/+5 В/+3,3 В)
|
||||
Err_SCI_5V_Power = 0x03, ///< Неисправность источника питания последовательных интерфейсов микроконтроллера +5 В
|
||||
Err_24V_Power = 0x04, ///< Неисправность источника питания +24 В
|
||||
Program_Err_1 = 0x05, ///< Программная ошибка 1
|
||||
Program_Err_2 = 0x06, ///< Программная ошибка 2
|
||||
Program_Err_3 = 0x07, ///< Программная ошибка 3
|
||||
Program_Err_4 = 0x08, ///< Программная ошибка 4
|
||||
Program_Err_5 = 0x09, ///< Программная ошибка 5
|
||||
Program_Err_6 = 0x0A, ///< Программная ошибка 6
|
||||
Program_Err_7 = 0x0B, ///< Программная ошибка 7
|
||||
Program_Err_8 = 0x0C, ///< Программная ошибка 8
|
||||
}MB_MZKTEErrorsTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Сборный параметр
|
||||
* @details Информация о состоянии МЗКТЭ
|
||||
*/
|
||||
typedef union //MB_MZKTEStatusTypeDef
|
||||
{
|
||||
uint16_t all; ///< Доступ к регистру целиком
|
||||
struct
|
||||
{
|
||||
unsigned TE_ErrActive:1; /*!< @brief Бит [0]: Авария на ТЭ
|
||||
@details Состояния:
|
||||
- 0 - напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария»
|
||||
- 1 - напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария» */
|
||||
|
||||
unsigned TE_WarnActive:1; /*!< @brief Бит [1]: Предупреждения на ТЭ
|
||||
@details Состояния:
|
||||
- 0 - напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение»
|
||||
- 1 - напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение» */
|
||||
|
||||
unsigned Opros_TE:1; /*!< @brief Бит [2]: Разрешение опроса ТЭ
|
||||
@details Состояния:
|
||||
- 0 – опрос ТЭ разрешен
|
||||
- 1 – опрос ТЭ запрещен */
|
||||
|
||||
unsigned MZKTE_ErrStatus:2; /*!< @brief Биты [4:3]: Состояние МЗКТЭ
|
||||
@details Состояния:
|
||||
- 0 - МЗКТЭ функционирует нормально. Идет опрос ТЭ.
|
||||
- 1 - неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции
|
||||
(некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef)
|
||||
- 2 - Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным
|
||||
(ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef) */
|
||||
|
||||
unsigned reserved:3; ///< Биты [7:5] зарезервированны
|
||||
|
||||
MB_MZKTEErrorsTypeDef MZKTE_Error:8; /*!< @brief Биты [15:8]: Номер неисправности МЗКТЭ
|
||||
@details Номера неисправностей описаны в @ref MB_MZKTEErrorsTypeDef */
|
||||
}param; ///< Доступ к регистру по параметрам
|
||||
}MB_MZKTEStatusTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Входные регистры для контроля состояния МЗКТЭ
|
||||
*/
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
|
||||
uint16_t U_TE[85]; /*!< @brief Адреса 0-84: Текущие значения напряжения ТЭ
|
||||
@details Значения передаются умноженными на 1000 (т.е. если Uтэ = 0,625 В, то будет передано число 625) */
|
||||
|
||||
MB_MZKTEStatusTypeDef Status; /*!< @brief Адрес 85: Сборный параметр
|
||||
@details Информация о состоянии МЗКТЭ @ref MB_MZKTEStatusTypeDef */
|
||||
}MB_DataInRegsTypeDef;
|
||||
|
||||
|
||||
// DEFINES FOR REGISTERS ARRAYS
|
||||
#define R_INREG_ADDR 0
|
||||
#define R_INREG_QNT 86
|
||||
|
||||
#define R_HOLDREG_ADDR 0
|
||||
#define R_HOLDREG_QNT 175
|
||||
|
||||
|
||||
// DEFINES FOR REGISTERS LOCAL ADDRESSES
|
||||
//#define R_SET_ERROR(_te_num_) 0
|
||||
|
||||
|
||||
/** MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
//----------------DEFINES FOR COILS-----------------
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_COILS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for coils
|
||||
@verbatim
|
||||
Структура дефайна
|
||||
Для массивов коилов:
|
||||
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
|
||||
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Флаги исключения ТЭ из алгоритма формирования сигналов «Предупреждение» и «Авария»
|
||||
* @details В случае установки нулевого значения конкретной ячейки значение напряжения ТЭ,
|
||||
* связанного с этой ячейкой, не будет учитываться при формировании сигналов «Предупреждение» и «Авария»
|
||||
*/
|
||||
typedef struct //MB_DataCoilsTypeDef
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t TE0_63; ///< Ячейки ТЭ №0-63
|
||||
uint32_t TE64_84:21; ///< Ячейки ТЭ №64-84
|
||||
}all;
|
||||
struct
|
||||
{
|
||||
unsigned TE0_Exclude:1;
|
||||
unsigned TE1_Exclude:1;
|
||||
unsigned TE2_Exclude:1;
|
||||
unsigned TE3_Exclude:1;
|
||||
unsigned TE4_Exclude:1;
|
||||
unsigned TE5_Exclude:1;
|
||||
unsigned TE6_Exclude:1;
|
||||
unsigned TE7_Exclude:1;
|
||||
unsigned TE8_Exclude:1;
|
||||
unsigned TE9_Exclude:1;
|
||||
unsigned TE10_Exclude:1;
|
||||
unsigned TE11_Exclude:1;
|
||||
unsigned TE12_Exclude:1;
|
||||
unsigned TE13_Exclude:1;
|
||||
unsigned TE14_Exclude:1;
|
||||
unsigned TE15_Exclude:1;
|
||||
unsigned TE16_Exclude:1;
|
||||
unsigned TE17_Exclude:1;
|
||||
unsigned TE18_Exclude:1;
|
||||
unsigned TE19_Exclude:1;
|
||||
unsigned TE20_Exclude:1;
|
||||
unsigned TE21_Exclude:1;
|
||||
unsigned TE22_Exclude:1;
|
||||
unsigned TE23_Exclude:1;
|
||||
unsigned TE24_Exclude:1;
|
||||
unsigned TE25_Exclude:1;
|
||||
unsigned TE26_Exclude:1;
|
||||
unsigned TE27_Exclude:1;
|
||||
unsigned TE28_Exclude:1;
|
||||
unsigned TE29_Exclude:1;
|
||||
unsigned TE30_Exclude:1;
|
||||
unsigned TE31_Exclude:1;
|
||||
unsigned TE32_Exclude:1;
|
||||
unsigned TE33_Exclude:1;
|
||||
unsigned TE34_Exclude:1;
|
||||
unsigned TE35_Exclude:1;
|
||||
unsigned TE36_Exclude:1;
|
||||
unsigned TE37_Exclude:1;
|
||||
unsigned TE38_Exclude:1;
|
||||
unsigned TE39_Exclude:1;
|
||||
unsigned TE40_Exclude:1;
|
||||
unsigned TE41_Exclude:1;
|
||||
unsigned TE42_Exclude:1;
|
||||
unsigned TE43_Exclude:1;
|
||||
unsigned TE44_Exclude:1;
|
||||
unsigned TE45_Exclude:1;
|
||||
unsigned TE46_Exclude:1;
|
||||
unsigned TE47_Exclude:1;
|
||||
unsigned TE48_Exclude:1;
|
||||
unsigned TE49_Exclude:1;
|
||||
unsigned TE50_Exclude:1;
|
||||
unsigned TE51_Exclude:1;
|
||||
unsigned TE52_Exclude:1;
|
||||
unsigned TE53_Exclude:1;
|
||||
unsigned TE54_Exclude:1;
|
||||
unsigned TE55_Exclude:1;
|
||||
unsigned TE56_Exclude:1;
|
||||
unsigned TE57_Exclude:1;
|
||||
unsigned TE58_Exclude:1;
|
||||
unsigned TE59_Exclude:1;
|
||||
unsigned TE60_Exclude:1;
|
||||
unsigned TE61_Exclude:1;
|
||||
unsigned TE62_Exclude:1;
|
||||
unsigned TE63_Exclude:1;
|
||||
unsigned TE64_Exclude:1;
|
||||
unsigned TE65_Exclude:1;
|
||||
unsigned TE66_Exclude:1;
|
||||
unsigned TE67_Exclude:1;
|
||||
unsigned TE68_Exclude:1;
|
||||
unsigned TE69_Exclude:1;
|
||||
unsigned TE70_Exclude:1;
|
||||
unsigned TE71_Exclude:1;
|
||||
unsigned TE72_Exclude:1;
|
||||
unsigned TE73_Exclude:1;
|
||||
unsigned TE74_Exclude:1;
|
||||
unsigned TE75_Exclude:1;
|
||||
unsigned TE76_Exclude:1;
|
||||
unsigned TE77_Exclude:1;
|
||||
unsigned TE78_Exclude:1;
|
||||
unsigned TE79_Exclude:1;
|
||||
unsigned TE80_Exclude:1;
|
||||
unsigned TE81_Exclude:1;
|
||||
unsigned TE82_Exclude:1;
|
||||
unsigned TE83_Exclude:1;
|
||||
unsigned TE84_Exclude:1;
|
||||
}bit; ///< Биты для доступа к каждой ячейке ТЭ
|
||||
}Exclude; ///< Юнион для исключения ТЭ
|
||||
}MB_DataCoilsTypeDef;
|
||||
|
||||
// DEFINES FOR COIL ARRAYS
|
||||
#define C_TE_EXCLUDE_ADDR 0
|
||||
#define C_TE_EXCLUDE_QNT 84
|
||||
|
||||
/** MODBUS_DATA_COILS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
//-----------MODBUS DEVICE DATA SETTING-------------
|
||||
// MODBUS DATA STRUCTTURE
|
||||
/**
|
||||
* @brief Структура со всеми регистрами и коилами модбас
|
||||
* @ingroup MODBUS_DATA
|
||||
*/
|
||||
typedef struct // mzkt modbus data
|
||||
{
|
||||
MB_DataInRegsTypeDef InRegs; ///< Modbus input registers @ref MB_DataInRegsTypeDef
|
||||
|
||||
MB_DataCoilsTypeDef Coils; ///< Modbus coils @ref MB_DataCoilsTypeDef
|
||||
|
||||
MB_DataHoldRegsTypeDef HoldRegs; ///< Modbus holding registers @ref MB_DataHoldRegsTypeDef
|
||||
}MB_DataStructureTypeDef;
|
||||
extern MB_DataStructureTypeDef MB_DATA;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
///////////////////////TEMP/OUTDATE/OTHER////////////////////
|
||||
|
||||
//typedef enum //MB_MZKTECommandsTypeDef
|
||||
//{
|
||||
// StandartMode = 0x00, ///< Стандартная работа
|
||||
// Opros_TE_Disable = 0x01, ///< Запрет опроса ТЭ (активен только обмен с ЛСУ ЭС, ТЭ не контролируются)
|
||||
//}MB_MZKTECommandsTypeDef;
|
||||
|
||||
///**
|
||||
// * @brief Состояние МЗКТЭ
|
||||
// */
|
||||
//typedef enum //MB_MZKTEErrStatusTypeDef
|
||||
//{
|
||||
// MZKTE_OK = 0x0, ///< МЗКТЭ функционирует нормально. Идет опрос ТЭ.
|
||||
// NonCritical_Err = 0x1, ///< Неисправность МЗКТЭ, при которой МЗКТЭ может выполнять свои основные функции (некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef).
|
||||
// Critical_Err = 0x2, ///< Неисправность МЗКТЭ, при которой выполнение основных функций не представляется возможным (ошибки 1-3 и некоторые программные ошибки из @ref MB_MZKTEErrorsTypeDef)
|
||||
//
|
||||
//}MB_MZKTEErrStatusTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// TE_No_Err = 0x0, ///< Напряжения на всех ТЭ выше аварийных порогов, задаваемых уставками «Авария»
|
||||
// TE_Err = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже аварийного порога, задаваемого уставкой «Авария»
|
||||
//}MB_TEErrActiveTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// TE_No_Warn = 0x0, ///< Напряжения на всех ТЭ выше предупредительных порогов, задаваемых уставкой «Предупреждение»
|
||||
// TE_Warn = 0x1, ///< Напряжение на одном или нескольких ТЭ достигло или ниже предупредительного порога, задаваемого уставкой «Предупреждение»
|
||||
//}MB_TEWarnActiveTypeDef;
|
||||
//typedef enum
|
||||
//{
|
||||
// OprosTE_Enable = 0x0, ///< Опрос ТЭ разрешен
|
||||
// OprosTE_Disable = 0x1, ///< Опрос ТЭ запрещен (см. регистр хранения 170)
|
||||
//}MB_OprosTETypeDef;
|
||||
37
ТЗ/неофтз.txt
Normal file
37
ТЗ/неофтз.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
По модбасу: нужна терминалка для общения с МЗКТЭ. Вот краткое ТЗ
|
||||
|
||||
Команды:
|
||||
0x01 Read Coils
|
||||
0x03 Read Holding Registers
|
||||
0x04 Read Input Registers
|
||||
0x05 Write Single Coil
|
||||
0x06 Write Single Register
|
||||
0x0F Write Multiple Coils
|
||||
0x10 Write Multiple Registers
|
||||
|
||||
Т.е. обращение будет к следующим типам данных:
|
||||
- Входные регистры (MB_DataInRegsTypeDef),
|
||||
- Регистры хранения (MB_DataHoldRegsTypeDef),
|
||||
- Коилы (MB_DataCoilsTypeDef).
|
||||
|
||||
Там некоторые регистры еще парсяться, поэтому скидываю файл с структурой данных, который я сделал. В скобках указал имя typedef соответствующего типа данных в файле. Можешь его использовать, заодно мб придумаешь че можно улучшить.
|
||||
|
||||
|
||||
По программе:
|
||||
Там идет управление и контроль ТЭ (топливные элементы), которых всего 85 штук. С них снимается задаются две уставки: предупреждение и авария. Коилами можно исключать ТЭ из работы.
|
||||
Также есть пару управляющих настроек и статус-регистр.
|
||||
|
||||
Соответственно можно сделать два окна:
|
||||
- одно небольшое - для статуса МЗКТЭ
|
||||
- второе большое - для ТЭ. Можно сделать 4 вкладки, в каждой 85 ячеек:
|
||||
- Напряжение на ТЭ,
|
||||
- Уставки "Предупреждение",
|
||||
- Уставки "Авария",
|
||||
- Исключения ТЭ
|
||||
|
||||
И можно сделать одно открываемое окно для настроек. Типа по кнопке "Настройки МЗКТЭ". Это для регистров хранения 170-174. И если что их запись должна быть только по команде 0x06 (сингл). Остальные уставки поддерживают запись 0x10 (мультипл).
|
||||
|
||||
Статус МКЗТЭ и Напряжения на ТЭ только считывается (команда 0x04)
|
||||
Уставки "Предупреждение" и "Авария" можно считать и записать всеми способами (0x03, 0x06, 0x10)
|
||||
Настройки МЗКТЭ можно считывать и записать только по одному регистру (0x03, 0x06)
|
||||
Исключения ТЭ можно считывать и записывать всеми способами (0x01, 0x05, 0x0F)
|
||||
BIN
ТЗ/прил.MODBUS.pdf
Normal file
BIN
ТЗ/прил.MODBUS.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user