This commit is contained in:
Вячеслав Штейбезандт 2025-03-11 14:41:08 +03:00
parent 538399f665
commit 2fda1036bd
35 changed files with 17115 additions and 0 deletions

72
ProjectSettings.h Normal file
View File

@ -0,0 +1,72 @@
#ifndef PROJECTSETTINGS_H
#define PROJECTSETTINGS_H
#define CMD_TO_LOAD_FILE "SENDFILE"
#define FRAMES 512 // размер буфера для чтения, кол-во кадров
#define READDELAY 5000
#define MAX_DLC_SIZE 1
#define MAX_MACROS_RTR_SIZE 1
#define MAX_MACROS_EID_SIZE 1
#define MAX_MACROS_ID_SIZE 8
#define MAX_MACROS_HEX_SIZE 1
#define MAX_MACROS_NAME_SIZE 8
#define MAX_MACROS_SIZE 256
#define NORMAL_MSG_TO_LOGGER 0
#define WARNING_TO_LOGGER 1
#define GHOST_TO_LOGGER 2
#define TX_ERROR_EVENT 3
#define RX_ERROR_EVENT 4
#define RX_CAN_GROUP_TABLE_COUNT_COLUMN 0
#define RX_CAN_GROUP_TABLE_TIME_COLUMN 1
#define RX_CAN_GROUP_TABLE_PERIOD_COLUMN 2
#define RX_CAN_GROUP_TABLE_ID_COLUMN 3
#define RX_CAN_GROUP_TABLE_E_COLUMN 4
#define RX_CAN_GROUP_TABLE_R_COLUMN 5
#define RX_CAN_GROUP_TABLE_DLC_COLUMN 6
#define RX_CAN_GROUP_TABLE_DATA_COLUMN 7
#define RX_CAN_GROUP_TABLE_TMPS 8
#define RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN 0
#define RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN 1
#define RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN 2
#define RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN 3
#define RX_CAN_REQUESTER_GROUP_TABLE_ROUTE 4
#define RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE 5
#define RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE 6
#define RX_CAN_REQUESTER_GROUP_TABLE_SENSORID 7
#define RX_CAN_REQUESTER_GROUP_TABLE_DEVICE 8
#define RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN 9
#define RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN 10
#define RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN 11
#define RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN 12
#define RX_CAN_REQUESTER_GROUP_TABLE_TMPS 13
#include "chrono"
#include "QDebug"
#include "QTime"
#include "QMessageBox"
#include <QFileDialog>
#include "QTimer"
#include "QLineEdit"
#include "QCheckBox"
#include "QThread"
#include "QtConcurrent/QtConcurrent"
//#include "QTextCodec"
#include <QSerialPort>
#include "crc16.h"
#include "writeregistermodel.h"
#include "canusb.h"
#include "mainmenu.h"
#include "unioncom.h"
#include "usettingsrs.h"
#include "macrossetting.h"
#include "union_modbus.h"
#include "union_modbus_slave.h"
#endif // PROJECTSETTINGS_H

81
UnionCom.pro Normal file
View File

@ -0,0 +1,81 @@
QT -= gui
QT += core gui
QT += widgets serialport
QT += serialbus widgets
requires(qtConfig(combobox))
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
QT += serialport
TEMPLATE = lib
DEFINES += UNIONCOM_LIBRARY
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# 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 += \
canidcalc.cpp \
canusb.cpp \
crc16.cpp \
macrossetting.cpp \
main.cpp \
mainmenu.cpp \
union_modbus.cpp \
union_modbus_slave.cpp \
unioncom.cpp \
usettingsrs.cpp \
writeregistermodel.cpp
HEADERS += \
ProjectSettings.h \
canidcalc.h \
canusb.h \
crc16.h \
macrossetting.h \
mainmenu.h \
slcan.h \
union_modbus.h \
union_modbus_slave.h \
unioncom.h \
usettingsrs.h \
writeregistermodel.h
FORMS += \
canidcalc.ui \
canusb.ui \
crc16.ui \
macrossetting.ui \
mainmenu.ui \
union_modbus.ui \
union_modbus_slave.ui \
unioncom.ui \
usettingsrs.ui
# Default rules for deployment.
unix {
target.path = /usr/lib
}
!isEmpty(target.path): INSTALLS += target
win32: LIBS += -L$$PWD/./ -lslcan
#win32:CONFIG(release, debug|release): LIBS += -L$$PWD/./ -lslcan
#else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/./ -lslcand
#else:unix: LIBS += -L$$PWD/./ -lslcan
#INCLUDEPATH += $$PWD/.
#DEPENDPATH += $$PWD/.

12
UnionCom_global.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef UNIONCOM_GLOBAL_H
#define UNIONCOM_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(UNIONCOM_LIBRARY)
# define UNIONCOM_EXPORT Q_DECL_EXPORT
#else
# define UNIONCOM_EXPORT Q_DECL_IMPORT
#endif
#endif // UNIONCOM_GLOBAL_H

137
canidcalc.cpp Normal file
View File

@ -0,0 +1,137 @@
#include "canidcalc.h"
#include "ui_canidcalc.h"
CanIdCalc::CanIdCalc(QWidget *parent) :
QWidget(parent),
ui(new Ui::CanIdCalc)
{
ui->setupUi(this);
CanId.ID_All = 0;
CanIdModbus.ID_All = 0;
ui->StrAdrBox->setValue(0);
on_DataTypeBox_currentIndexChanged(0);
}
CanIdCalc::~CanIdCalc()
{
delete ui;
}
void CanIdCalc::on_DataTypeBox_currentIndexChanged(int index)
{
isModbus = false;
ui->SensorTypeBox->clear();
ui->SensorTypeBox->setEnabled(true);
ui->SensorIdBox->setEnabled(true);
ui->SensorTypeLabel->show();
ui->SensorTypeBox->show();
ui->StrAdrLabel->hide();
ui->StrAdrBox->hide();
ui->SensorTypeLabel->setText("Sensor Type");
ui->SensorIdLabel->setText("Sensor ID");
ui->SensorIdBox->setMaximum(2047);
ui->SensorIdBox->setValue(CanId.Fields.SensorID);
CanId.Fields.DataType = index;
CanIdModbus.Fields.DataType = index;
switch (index) {
case 0:
ui->SensorTypeBox->addItem("Статус");
ui->SensorTypeBox->addItem("Запрос на вкл/выкл");
ui->SensorTypeBox->addItem("Рестарт устройств");
ui->SensorTypeBox->addItem("Установка времени");
break;
case 1:
ui->SensorTypeBox->addItem("Аварии");
ui->SensorTypeBox->addItem("Предупреждения");
ui->SensorTypeBox->addItem("Управляющие сигналы");
ui->SensorTypeBox->addItem("Флаги");
ui->SensorTypeBox->addItem("Рестарт устройства");
ui->SensorTypeBox->addItem("Изменение режима работы устройства");
ui->SensorTypeBox->addItem("Перечень параметров");
break;
case 2:
ui->SensorTypeBox->addItem("Универсальный запрос");
ui->SensorTypeBox->addItem("Уставки");
ui->SensorTypeBox->addItem("Напряжение");
ui->SensorTypeBox->addItem("Ток");
ui->SensorTypeBox->addItem("Температура");
break;
case 3:
case 4:
case 5:
case 6:
isModbus = true;
ui->SensorTypeLabel->hide();
ui->SensorTypeBox->hide();
ui->StrAdrLabel->show();
ui->StrAdrBox->show();
ui->SensorIdLabel->setText("Кол-во регистров");
ui->SensorIdBox->setMaximum(255);
ui->SensorIdBox->setValue(CanIdModbus.Fields.CountReg);
on_StrAdrBox_valueChanged(ui->StrAdrBox->value());
break;
case 7:
CanId.Fields.DataType = 0xF;
ui->SensorTypeBox->addItem("Пульс");
ui->SensorTypeBox->setEnabled(false);
ui->SensorIdBox->setEnabled(false);
ui->SensorIdBox->setValue(0);
break;
}
id_Calc();
}
void CanIdCalc::on_SensorTypeBox_currentIndexChanged(int index)
{
CanId.Fields.SensorType = index;
id_Calc();
}
void CanIdCalc::on_SensorIdBox_valueChanged(int arg1)
{
CanId.Fields.SensorID = arg1;
CanIdModbus.Fields.CountReg = arg1;
id_Calc();
}
void CanIdCalc::on_DeviceIdBox_valueChanged(int arg1)
{
CanId.Fields.Device = arg1;
CanIdModbus.Fields.Device = arg1;
id_Calc();
}
void CanIdCalc::id_Calc()
{
if(isModbus)
{
ui->ResultLine->setText(QStringLiteral("%1").arg(CanIdModbus.ID_All, 8, 16, QLatin1Char('0')).toUpper());
}
else
{
ui->ResultLine->setText(QStringLiteral("%1").arg(CanId.ID_All, 8, 16, QLatin1Char('0')).toUpper());
}
}
void CanIdCalc::on_StrAdrBox_valueChanged(int arg1)
{
CanIdModbus.Fields.StrAdr = arg1;
id_Calc();
}
void CanIdCalc::on_routeBox_stateChanged(int arg1)
{
switch (arg1) {
case Qt::Unchecked:
ui->routeBox->setText("Master");
CanId.Fields.Route = 0;
CanIdModbus.Fields.Route = 0;
break;
case Qt::Checked:
ui->routeBox->setText("Slave");
CanId.Fields.Route = 1;
CanIdModbus.Fields.Route = 1;
break;
}
id_Calc();
}

65
canidcalc.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef CANIDCALC_H
#define CANIDCALC_H
#include <QWidget>
namespace Ui {
class CanIdCalc;
}
class CanIdCalc : public QWidget
{
Q_OBJECT
public:
explicit CanIdCalc(QWidget *parent = nullptr);
~CanIdCalc();
private slots:
void on_DataTypeBox_currentIndexChanged(int index);
void on_SensorTypeBox_currentIndexChanged(int index);
void on_SensorIdBox_valueChanged(int arg1);
void on_DeviceIdBox_valueChanged(int arg1);
void on_StrAdrBox_valueChanged(int arg1);
void on_routeBox_stateChanged(int arg1);
private:
void id_Calc();
bool isModbus = false;
union Can_ID{
struct Can_ID_Fields
{
uint Device:8;
uint SensorID:11;
uint SensorType:5;
uint DataType:4;
uint Route:1;
}Fields;
uint ID_All:29;
}CanId;
union Can_ID_Modbus{
struct Can_ID_Fields
{
uint Device:8;
uint CountReg:8;
uint StrAdr:8;
uint DataType:4;
uint Route:1;
}Fields;
uint ID_All:29;
}CanIdModbus;
Ui::CanIdCalc *ui;
};
#endif // CANIDCALC_H

323
canidcalc.ui Normal file
View File

@ -0,0 +1,323 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CanIdCalc</class>
<widget class="QWidget" name="CanIdCalc">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>994</width>
<height>67</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="6">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="7">
<widget class="QSpinBox" name="SensorIdBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="maximum">
<number>2047</number>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="StrAdrLabel">
<property name="text">
<string>Стартовый адрес</string>
</property>
</widget>
</item>
<item row="0" column="11">
<widget class="QLabel" name="ResultLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Result</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="SensorIdLabel">
<property name="text">
<string>Sensor ID</string>
</property>
</widget>
</item>
<item row="1" column="11">
<widget class="QLineEdit" name="ResultLine">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>8</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="SensorTypeLabel">
<property name="text">
<string>Sensor Type</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="routeBox">
<property name="text">
<string>Master</string>
</property>
</widget>
</item>
<item row="1" column="9">
<widget class="QSpinBox" name="DeviceIdBox">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="0" column="9">
<widget class="QLabel" name="DeviceIdLabel">
<property name="text">
<string>Device ID</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="DataTypeBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<item>
<property name="text">
<string>Широковещательные</string>
</property>
</item>
<item>
<property name="text">
<string>Дискретные</string>
</property>
</item>
<item>
<property name="text">
<string>Аналог</string>
</property>
</item>
<item>
<property name="text">
<string>Modbus Coil</string>
</property>
</item>
<item>
<property name="text">
<string>Modbus Discrete</string>
</property>
</item>
<item>
<property name="text">
<string>Modbus Holding</string>
</property>
</item>
<item>
<property name="text">
<string>Modbus Input</string>
</property>
</item>
<item>
<property name="text">
<string>Пульс</string>
</property>
</item>
</widget>
</item>
<item row="1" column="10">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="SensorTypeBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="DataTypeLabel">
<property name="text">
<string>Data Type</string>
</property>
</widget>
</item>
<item row="1" column="8">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="5">
<widget class="QSpinBox" name="StrAdrBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
<item row="1" column="3">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>5</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Route</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

153
canusb.cpp Normal file
View File

@ -0,0 +1,153 @@
#include "canusb.h"
#include "ui_canusb.h"
#include <QFileDialog>
#include <QLineEdit>
#include <QDebug>
#include <QTime>
#include "ui_send_cmd.h"
#include "ProjectSettings.h"
CanUsb *target;
CB_FLAGS cb_flags;
CanUsb::CanUsb(QWidget *parent)
: QWidget(parent)
, ui(new Ui::CanUsb)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
init();
}
CanUsb::~CanUsb()
{
delete ui;
}
void CanUsb::init()
{
target=this;
Refresh();
ui->dataBitsBox->setEditText("1CE0E1");
}
unsigned CanUsb::div_up(unsigned x, unsigned y)
{
return (x - 1) / y + 1;
}
void CanUsb::Refresh()
{
ui->serialPortInfoListBox->setDisabled(TRUE);
int count = SlCan_GetDeviceCount();
QString currPort = ui->serialPortInfoListBox->currentText();
ui->serialPortInfoListBox->clear();
for (int i = 0; i < count; ++i)
{
HSLCAN device = SlCan_GetDevice(i);
char* buff = new char[30];
SlCan_DeviceGetProperty(device, 0x0000000D, buff, 30);
QString str(buff);
ui->serialPortInfoListBox->addItem(str);
delete[] buff;
}
ui->serialPortInfoListBox->setCurrentText(currPort);
ui->serialPortInfoListBox->setDisabled(FALSE);
}
static QString DeviceGetPropety(HSLCAN hDevice, DWORD dwIndex)
{
char pBuf[256];
SlCan_DeviceGetProperty(hDevice, dwIndex, pBuf, 256);
return QString(pBuf);
}
void CanUsb::on_serialPortInfoListBox_currentIndexChanged(int index)
{
device = SlCan_GetDevice(ui->serialPortInfoListBox->currentIndex());
ui->descriptionLabel->setText(tr("Description: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_DEVICEDESC)));
ui->descriptionLabel->setToolTip(QString("Description: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_DEVICEDESC)));
ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_MFG)));
ui->manufacturerLabel->setToolTip((QString("Manufacturer: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_MFG))));
ui->serialNumberLabel->setText(tr("Serial number: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_SERIAL)));
ui->serialNumberLabel->setToolTip(QString("Serial number: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_SERIAL)));
ui->locationLabel->setText(tr("Location: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_PORTNAME)));
ui->locationLabel->setToolTip(QString("Location: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_PORTNAME)));
QString VBuf = DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_INSTANCEID);
QString VID;
QString PID;
bool FirstFlag = FALSE;
bool SecondFlag = FALSE;
for(int i = 0; i < VBuf.size(); i++)
{
if(VBuf[i]=='_')
{
FirstFlag=TRUE;
i++;
}
if(FirstFlag)
{
if(VBuf[i]=='&')
{
FirstFlag=FALSE;
SecondFlag=TRUE;
}
else if(SecondFlag!=TRUE)
{
VID+=VBuf[i];
}
else
{
if(VBuf[i]==0x5C)
{
break;
}
else
{
PID+=VBuf[i];
}
}
}
}
ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(VID.toLower()));
ui->vidLabel->setToolTip(QString("Vendor Identifier: %1").arg(VID.toLower()));
ui->pidLabel->setText(tr("Product Identifier: %1").arg(PID.toLower()));
ui->pidLabel->setToolTip(QString("Product Identifier: %1").arg(PID.toLower()));
}
int CanUsb::GetID()
{
return ui->dataBitsBox->currentText().toInt(nullptr, 16);
}
int CanUsb::GetBR()
{
return ui->baudRateBox->currentIndex();
}
HSLCAN CanUsb::G_Device()
{
return device;
}
int CanUsb::GetMode()
{
return ui->modeBox->currentIndex()+1;
}
void CanUsb::AfterConnection()
{
ui->parametersBox->setEnabled(FALSE);
ui->selectBox->setEnabled(FALSE);
}
void CanUsb::AfterDisconnection()
{
ui->parametersBox->setEnabled(TRUE);
ui->selectBox->setEnabled(TRUE);
}
int CanUsb::GetCount()
{
return ui->serialPortInfoListBox->count();
}

67
canusb.h Normal file
View File

@ -0,0 +1,67 @@
#ifndef USBCAN_H
#define USBCAN_H
#include <QWidget>
#include <slcan.h>
#include "ProjectSettings.h"
class Send_CMD;
static void __stdcall Device_Callback(HSLCAN cbDevice, DWORD dwIndex, DWORD dwOperation, PVOID pContext, DWORD dwContextSize);
static void __stdcall DeviceList_Callback(HSLCAN cbDevice, DWORD dwIndex, PVOID pContext, DWORD dwContextSize);
QT_BEGIN_NAMESPACE
namespace Ui { class CanUsb; }
QT_END_NAMESPACE
struct CB_FLAGS{
unsigned AvailableDevicesListHasBeenChanged:1;
};
class CanUsb : public QWidget
{
Q_OBJECT
private:
DWORD ID; //идентификатор устройства
SLCAN_MESSAGE outMsg; //буфер для отправки сообщения
SLCAN_MESSAGE inputMsg[FRAMES]; //буфер для приёма сообщения
HSLCAN device;
SLCAN_BITRATE br;
DWORD cntrInput;
unsigned int Counter_of_suc_transmit=0;
unsigned int TX_error_counter=0;
unsigned div_up(unsigned x, unsigned y);
Send_CMD* send_cmd = nullptr;
SLCAN_STATE DeviceState;
int timerRefreshID = 0;
public:
int GetCount();
void AfterDisconnection();
void AfterConnection();
int GetMode();
int GetID();
int GetBR();
void device_connect();
HSLCAN G_Device();
HSLCAN GetDevice(){return device;}
CanUsb(QWidget *parent = nullptr);
~CanUsb();
void init();
void Refresh();
private slots:
void on_serialPortInfoListBox_currentIndexChanged(int index);
private:
Ui::CanUsb *ui;
};
#endif // USBCAN_H

258
canusb.ui Normal file
View File

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CanUsb</class>
<widget class="QWidget" name="CanUsb">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>200</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>CanUsb</string>
</property>
<property name="animated" stdset="0">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1">
<layout class="QVBoxLayout" name="SelectParameters">
<property name="spacing">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="parametersBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Select Parameters</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="dataBitsLabel">
<property name="text">
<string>ID</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="dataBitsBox">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="baudRateLabel">
<property name="text">
<string>BaudRate:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="baudRateBox">
<property name="currentIndex">
<number>3</number>
</property>
<item>
<property name="text">
<string>1000K</string>
</property>
</item>
<item>
<property name="text">
<string>800K</string>
</property>
</item>
<item>
<property name="text">
<string>500K</string>
</property>
</item>
<item>
<property name="text">
<string>250K</string>
</property>
</item>
<item>
<property name="text">
<string>125K</string>
</property>
</item>
<item>
<property name="text">
<string>50K</string>
</property>
</item>
<item>
<property name="text">
<string>20K</string>
</property>
</item>
<item>
<property name="text">
<string>10K</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="modeLabel">
<property name="text">
<string>Mode</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="modeBox">
<item>
<property name="text">
<string>Normal</string>
</property>
</item>
<item>
<property name="text">
<string>Listen Only</string>
</property>
</item>
<item>
<property name="text">
<string>Loop Back</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="selectBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Select Serial Port</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="serialPortInfoListBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="manufacturerLabel">
<property name="text">
<string>Manufacturer:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="serialNumberLabel">
<property name="text">
<string>Serial number:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="locationLabel">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="vidLabel">
<property name="text">
<string>Vendor ID:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="pidLabel">
<property name="text">
<string>Product ID:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
<action name="action">
<property name="text">
<string>Main menu</string>
</property>
</action>
<action name="actionBluetooth">
<property name="text">
<string>Bluetooth</string>
</property>
</action>
<action name="actionMain_menu">
<property name="text">
<string>Main menu</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

134
crc16.cpp Normal file
View File

@ -0,0 +1,134 @@
#include "crc16.h"
#include "ui_crc16.h"
CRC16::CRC16(QWidget *parent) :
QWidget(parent),
ui(new Ui::CRC16)
{
ui->setupUi(this);
arr[0] = ui->lineByte_0;
arr[1] = ui->lineByte_1;
arr[2] = ui->lineByte_2;
arr[3] = ui->lineByte_3;
arr[4] = ui->lineByte_4;
arr[5] = ui->lineByte_5;
arr[6] = ui->lineByte_6;
arr[7] = ui->lineByte_7;
}
CRC16::~CRC16()
{
delete ui;
}
static uint16_t getCRC_MODBUS(QByteArray buf, uint16_t len)
{
static const uint16_t table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 };
uint8_t x_or = 0;
uint16_t crc = 0xFFFF;
int i = 0;
while( len-- )
{
x_or = (buf.at(i++)) ^ crc;
crc >>= 8;
crc ^= table[x_or];
}
return crc;
}
uint16_t getCRC_ARC(QByteArray data, uint16_t size)
{
uint16_t out = 0;
int bits_read = 0, bit_flag;
if(data.size() == NULL)
return 0;
int data_i = 0;
while(size > 0)
{
bit_flag = out >> 15;
out <<= 1;
out |= (data.at(data_i) >> bits_read) & 1;
bits_read++;
if(bits_read > 7)
{
bits_read = 0;
data.at(data_i++);
size--;
}
if(bit_flag)
out ^= 0x8005;
}
int i;
for (i = 0; i < 16; ++i) {
bit_flag = out >> 15;
out <<= 1;
if(bit_flag)
out ^= 0x8005;
}
uint16_t crc = 0;
i = 0x8000;
int j = 0x0001;
for (; i != 0; i >>=1, j <<= 1) {
if (i & out) crc |= j;
}
return crc;
}
void CRC16::on_buttonShowCRC_clicked()
{
QByteArray crc;
for(int i = 0; i < ui->comboCountDLC->currentIndex()+1; i++)
{
crc += (BYTE)arr[i]->text().toInt(nullptr, 16);
}
ui->lineX25->setText("0x"+QString::number(qChecksum(crc, crc.size()), 16).toUpper());
ui->lineModbus->setText("0x"+QString::number(getCRC_MODBUS(crc, ui->comboCountDLC->currentIndex()+1), 16).toUpper());
ui->lineARC->setText("0x"+QString::number(getCRC_ARC(crc, crc.size()), 16).toUpper());
}
void CRC16::on_comboCountDLC_currentIndexChanged(int index)
{
for(int i = 0; i < 8; i++)
{
if(i > (index))
{
arr[i]->setEnabled(FALSE);
}
else
{
arr[i]->setEnabled(TRUE);
}
}
}

30
crc16.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef CRC16_H
#define CRC16_H
#include <QWidget>
#include "ProjectSettings.h"
namespace Ui {
class CRC16;
}
class CRC16 : public QWidget
{
Q_OBJECT
public:
explicit CRC16(QWidget *parent = nullptr);
~CRC16();
private slots:
void on_buttonShowCRC_clicked();
void on_comboCountDLC_currentIndexChanged(int index);
private:
QLineEdit *arr [8];
Ui::CRC16 *ui;
};
#endif // CRC16_H

549
crc16.ui Normal file
View File

@ -0,0 +1,549 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CRC16</class>
<widget class="QWidget" name="CRC16">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>90</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>90</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>90</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>6</number>
</property>
<property name="topMargin">
<number>6</number>
</property>
<property name="rightMargin">
<number>6</number>
</property>
<property name="bottomMargin">
<number>6</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Count</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>3</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QLabel" name="label_7">
<property name="text">
<string>6</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>2</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="lineByte_2">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineByte_0">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="text">
<string/>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="1" column="7">
<widget class="QLabel" name="label_8">
<property name="text">
<string>7</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QLineEdit" name="lineByte_7">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="0" column="10">
<widget class="QPushButton" name="buttonShowCRC">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="text">
<string>Рассчитать</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLineEdit" name="lineByte_4">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QLineEdit" name="lineByte_5">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="0" column="7">
<widget class="QLineEdit" name="lineByte_6">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="lineByte_1">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="1" column="8">
<widget class="QLabel" name="label_9">
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>1</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLabel" name="label_5">
<property name="text">
<string>4</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLineEdit" name="lineByte_3">
<property name="minimumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>25</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>hh</string>
</property>
<property name="maxLength">
<number>2</number>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="placeholderText">
<string>00</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QLabel" name="label_6">
<property name="text">
<string>5</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item row="2" column="1" colspan="10">
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="2">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Modbus:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_12">
<property name="text">
<string>ARC:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineX25">
<property name="minimumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="inputMask">
<string>9Ahhhh</string>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="lineModbus">
<property name="minimumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>CCITT (X-25):</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLineEdit" name="lineARC">
<property name="minimumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>25</height>
</size>
</property>
<property name="maxLength">
<number>6</number>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="comboCountDLC">
<property name="minimumSize">
<size>
<width>0</width>
<height>25</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="currentIndex">
<number>7</number>
</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>
<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>
</layout>
</widget>
<resources/>
<connections/>
</ui>

453
macrossetting.cpp Normal file
View File

@ -0,0 +1,453 @@
#include "macrossetting.h"
#include "ui_macrossetting.h"
MacrosSetting::MacrosSetting(QWidget *parent) :
QDialog(parent),
ui(new Ui::MacrosSetting)
{
ui->setupUi(this);
Init();
}
MacrosSetting::~MacrosSetting()
{
delete ui;
}
void MacrosSetting::Init()
{
//EID
{
MacrosSettingKit[0].EID = ui->checkEID_01;
MacrosSettingKit[1].EID = ui->checkEID_02;
MacrosSettingKit[2].EID = ui->checkEID_03;
MacrosSettingKit[3].EID = ui->checkEID_04;
MacrosSettingKit[4].EID = ui->checkEID_05;
MacrosSettingKit[5].EID = ui->checkEID_06;
MacrosSettingKit[6].EID = ui->checkEID_07;
MacrosSettingKit[7].EID = ui->checkEID_08;
MacrosSettingKit[8].EID = ui->checkEID_09;
MacrosSettingKit[9].EID = ui->checkEID_10;
MacrosSettingKit[10].EID = ui->checkEID_11;
MacrosSettingKit[11].EID = ui->checkEID_12;
MacrosSettingKit[12].EID = ui->checkEID_13;
MacrosSettingKit[13].EID = ui->checkEID_14;
MacrosSettingKit[14].EID = ui->checkEID_15;
}
//ID
{
MacrosSettingKit[0].ID = ui->lineID_01;
MacrosSettingKit[1].ID = ui->lineID_02;
MacrosSettingKit[2].ID = ui->lineID_03;
MacrosSettingKit[3].ID = ui->lineID_04;
MacrosSettingKit[4].ID = ui->lineID_05;
MacrosSettingKit[5].ID = ui->lineID_06;
MacrosSettingKit[6].ID = ui->lineID_07;
MacrosSettingKit[7].ID = ui->lineID_08;
MacrosSettingKit[8].ID = ui->lineID_09;
MacrosSettingKit[9].ID = ui->lineID_10;
MacrosSettingKit[10].ID = ui->lineID_11;
MacrosSettingKit[11].ID = ui->lineID_12;
MacrosSettingKit[12].ID = ui->lineID_13;
MacrosSettingKit[13].ID = ui->lineID_14;
MacrosSettingKit[14].ID = ui->lineID_15;
}
//IsHEX
{
MacrosSettingKit[0].IsHEX = ui->checkHEX_01;
MacrosSettingKit[1].IsHEX = ui->checkHEX_02;
MacrosSettingKit[2].IsHEX = ui->checkHEX_03;
MacrosSettingKit[3].IsHEX = ui->checkHEX_04;
MacrosSettingKit[4].IsHEX = ui->checkHEX_05;
MacrosSettingKit[5].IsHEX = ui->checkHEX_06;
MacrosSettingKit[6].IsHEX = ui->checkHEX_07;
MacrosSettingKit[7].IsHEX = ui->checkHEX_08;
MacrosSettingKit[8].IsHEX = ui->checkHEX_09;
MacrosSettingKit[9].IsHEX = ui->checkHEX_10;
MacrosSettingKit[10].IsHEX = ui->checkHEX_11;
MacrosSettingKit[11].IsHEX = ui->checkHEX_12;
MacrosSettingKit[12].IsHEX = ui->checkHEX_13;
MacrosSettingKit[13].IsHEX = ui->checkHEX_14;
MacrosSettingKit[14].IsHEX = ui->checkHEX_15;
}
//Name
{
MacrosSettingKit[0].Name = ui->lineMcrsName_01;
MacrosSettingKit[1].Name = ui->lineMcrsName_02;
MacrosSettingKit[2].Name = ui->lineMcrsName_03;
MacrosSettingKit[3].Name = ui->lineMcrsName_04;
MacrosSettingKit[4].Name = ui->lineMcrsName_05;
MacrosSettingKit[5].Name = ui->lineMcrsName_06;
MacrosSettingKit[6].Name = ui->lineMcrsName_07;
MacrosSettingKit[7].Name = ui->lineMcrsName_08;
MacrosSettingKit[8].Name = ui->lineMcrsName_09;
MacrosSettingKit[9].Name = ui->lineMcrsName_10;
MacrosSettingKit[10].Name = ui->lineMcrsName_11;
MacrosSettingKit[11].Name = ui->lineMcrsName_12;
MacrosSettingKit[12].Name = ui->lineMcrsName_13;
MacrosSettingKit[13].Name = ui->lineMcrsName_14;
MacrosSettingKit[14].Name = ui->lineMcrsName_15;
}
//Mcrs
{
MacrosSettingKit[0].Mcrs = ui->lineMcrs_01;
MacrosSettingKit[1].Mcrs = ui->lineMcrs_02;
MacrosSettingKit[2].Mcrs = ui->lineMcrs_03;
MacrosSettingKit[3].Mcrs = ui->lineMcrs_04;
MacrosSettingKit[4].Mcrs = ui->lineMcrs_05;
MacrosSettingKit[5].Mcrs = ui->lineMcrs_06;
MacrosSettingKit[6].Mcrs = ui->lineMcrs_07;
MacrosSettingKit[7].Mcrs = ui->lineMcrs_08;
MacrosSettingKit[8].Mcrs = ui->lineMcrs_09;
MacrosSettingKit[9].Mcrs = ui->lineMcrs_10;
MacrosSettingKit[10].Mcrs = ui->lineMcrs_11;
MacrosSettingKit[11].Mcrs = ui->lineMcrs_12;
MacrosSettingKit[12].Mcrs = ui->lineMcrs_13;
MacrosSettingKit[13].Mcrs = ui->lineMcrs_14;
MacrosSettingKit[14].Mcrs = ui->lineMcrs_15;
}
//Count
{
MacrosSettingKit[0].Count = ui->spinCount_01;
MacrosSettingKit[1].Count = ui->spinCount_02;
MacrosSettingKit[2].Count = ui->spinCount_03;
MacrosSettingKit[3].Count = ui->spinCount_04;
MacrosSettingKit[4].Count = ui->spinCount_05;
MacrosSettingKit[5].Count = ui->spinCount_06;
MacrosSettingKit[6].Count = ui->spinCount_07;
MacrosSettingKit[7].Count = ui->spinCount_08;
MacrosSettingKit[8].Count = ui->spinCount_09;
MacrosSettingKit[9].Count = ui->spinCount_10;
MacrosSettingKit[10].Count = ui->spinCount_11;
MacrosSettingKit[11].Count = ui->spinCount_12;
MacrosSettingKit[12].Count = ui->spinCount_13;
MacrosSettingKit[13].Count = ui->spinCount_14;
MacrosSettingKit[14].Count = ui->spinCount_15;
}
//IsPeriod
{
MacrosSettingKit[0].IsPeriod = ui->checkPeriod_01;
MacrosSettingKit[1].IsPeriod = ui->checkPeriod_02;
MacrosSettingKit[2].IsPeriod = ui->checkPeriod_03;
MacrosSettingKit[3].IsPeriod = ui->checkPeriod_04;
MacrosSettingKit[4].IsPeriod = ui->checkPeriod_05;
MacrosSettingKit[5].IsPeriod = ui->checkPeriod_06;
MacrosSettingKit[6].IsPeriod = ui->checkPeriod_07;
MacrosSettingKit[7].IsPeriod = ui->checkPeriod_08;
MacrosSettingKit[8].IsPeriod = ui->checkPeriod_09;
MacrosSettingKit[9].IsPeriod = ui->checkPeriod_10;
MacrosSettingKit[10].IsPeriod = ui->checkPeriod_11;
MacrosSettingKit[11].IsPeriod = ui->checkPeriod_12;
MacrosSettingKit[12].IsPeriod = ui->checkPeriod_13;
MacrosSettingKit[13].IsPeriod = ui->checkPeriod_14;
MacrosSettingKit[14].IsPeriod = ui->checkPeriod_15;
}
//Period
{
MacrosSettingKit[0].Period = ui->spinPeriod_01;
MacrosSettingKit[1].Period = ui->spinPeriod_02;
MacrosSettingKit[2].Period = ui->spinPeriod_03;
MacrosSettingKit[3].Period = ui->spinPeriod_04;
MacrosSettingKit[4].Period = ui->spinPeriod_05;
MacrosSettingKit[5].Period = ui->spinPeriod_06;
MacrosSettingKit[6].Period = ui->spinPeriod_07;
MacrosSettingKit[7].Period = ui->spinPeriod_08;
MacrosSettingKit[8].Period = ui->spinPeriod_09;
MacrosSettingKit[9].Period = ui->spinPeriod_10;
MacrosSettingKit[10].Period = ui->spinPeriod_11;
MacrosSettingKit[11].Period = ui->spinPeriod_12;
MacrosSettingKit[12].Period = ui->spinPeriod_13;
MacrosSettingKit[13].Period = ui->spinPeriod_14;
MacrosSettingKit[14].Period = ui->spinPeriod_15;
}
//RTR
{
MacrosSettingKit[0].RTR = ui->checkRTR_01;
MacrosSettingKit[1].RTR = ui->checkRTR_02;
MacrosSettingKit[2].RTR = ui->checkRTR_03;
MacrosSettingKit[3].RTR = ui->checkRTR_04;
MacrosSettingKit[4].RTR = ui->checkRTR_05;
MacrosSettingKit[5].RTR = ui->checkRTR_06;
MacrosSettingKit[6].RTR = ui->checkRTR_07;
MacrosSettingKit[7].RTR = ui->checkRTR_08;
MacrosSettingKit[8].RTR = ui->checkRTR_09;
MacrosSettingKit[9].RTR = ui->checkRTR_10;
MacrosSettingKit[10].RTR = ui->checkRTR_11;
MacrosSettingKit[11].RTR = ui->checkRTR_12;
MacrosSettingKit[12].RTR = ui->checkRTR_13;
MacrosSettingKit[13].RTR = ui->checkRTR_14;
MacrosSettingKit[14].RTR = ui->checkRTR_15;
}
//DLC
{
MacrosSettingKit[0].DLC = ui->comboDLC_01;
MacrosSettingKit[1].DLC = ui->comboDLC_02;
MacrosSettingKit[2].DLC = ui->comboDLC_03;
MacrosSettingKit[3].DLC = ui->comboDLC_04;
MacrosSettingKit[4].DLC = ui->comboDLC_05;
MacrosSettingKit[5].DLC = ui->comboDLC_06;
MacrosSettingKit[6].DLC = ui->comboDLC_07;
MacrosSettingKit[7].DLC = ui->comboDLC_08;
MacrosSettingKit[8].DLC = ui->comboDLC_09;
MacrosSettingKit[9].DLC = ui->comboDLC_10;
MacrosSettingKit[10].DLC = ui->comboDLC_11;
MacrosSettingKit[11].DLC = ui->comboDLC_12;
MacrosSettingKit[12].DLC = ui->comboDLC_13;
MacrosSettingKit[13].DLC = ui->comboDLC_14;
MacrosSettingKit[14].DLC = ui->comboDLC_15;
}
for(int i = 0; i < 15; i++)
{
MacrosSettingKit[i].Period->setEnabled(false);
MacrosSettingKit[i].DLC->setEnabled(false);
EnterErrors.ID[i] = EnterErrors.Mcrs[i] = 0;
}
}
void MacrosSetting::GetMcrs()
{
// for (int i = 0; i < 15; i++)
// {
// MacrosKit[i].IsHEX = MacrosSettingKit[i].IsHEX->checkState();
// MacrosKit[i].Name = MacrosSettingKit[i].Name->text();
// MacrosKit[i].Mcrs = MacrosSettingKit[i].Mcrs->text();
// }
// IsOK = TRUE;
}
void MacrosSetting::SetStart(Qt::CheckState *ptrEID, DWORD *ptrID, Qt::CheckState *ptrRTR,
Qt::CheckState *ptrHEX, int *ptrDLC, QString *ptrName, QString *ptrMcrs,
int *ptrCount, Qt::CheckState *ptrIsPeriod, int *ptrPeriod)
{
McrsReturn.EID = ptrEID;
McrsReturn.ID = ptrID;
McrsReturn.RTR = ptrRTR;
McrsReturn.IsHEX = ptrHEX;
McrsReturn.DLC = ptrDLC;
McrsReturn.Name = ptrName;
McrsReturn.Mcrs = ptrMcrs;
McrsReturn.Count = ptrCount;
McrsReturn.IsPeriod = ptrIsPeriod;
McrsReturn.Period = ptrPeriod;
for(int i = 0; i < 15; i++)
{
MacrosSettingKit[i].EID->setCheckState(ptrEID[i]);
if(ptrEID[i]==Qt::Checked)
{
MacrosSettingKit[i].ID->setText(QStringLiteral("%1").arg(ptrID[i], 8, 16, QLatin1Char('0')).toUpper());
}
else
{
MacrosSettingKit[i].ID->setText(QStringLiteral("%1").arg(ptrID[i], 3, 16, QLatin1Char('0')).toUpper());
}
MacrosSettingKit[i].RTR->setCheckState(ptrRTR[i]);
MacrosSettingKit[i].IsHEX->setCheckState(ptrHEX[i]);
MacrosSettingKit[i].DLC->setCurrentIndex(ptrDLC[i]);
comboDLC_stateChanged(i+1);
MacrosSettingKit[i].Name->setText(ptrName[i]);
MacrosSettingKit[i].Mcrs->setText(ptrMcrs[i]);
MacrosSettingKit[i].Count->setValue(ptrCount[i]);
MacrosSettingKit[i].IsPeriod->setCheckState(ptrIsPeriod[i]);
MacrosSettingKit[i].Period->setValue(ptrPeriod[i]);
}
}
void MacrosSetting::on_buttonBox_accepted()
{
for (int i = 0; i < 15; i++)
{
McrsReturn.EID[i] = MacrosSettingKit[i].EID->checkState();
McrsReturn.ID[i] = MacrosSettingKit[i].ID->text().toInt(nullptr, 16);
McrsReturn.RTR[i] = MacrosSettingKit[i].RTR->checkState();
McrsReturn.IsHEX[i] = MacrosSettingKit[i].IsHEX->checkState();
McrsReturn.DLC[i] = MacrosSettingKit[i].DLC->currentIndex();
McrsReturn.Name[i] = MacrosSettingKit[i].Name->text();
// if (!ValidationMcrs(i+1))
// {
// QDialog *McrsError = new QDialog;
// McrsError->setWindowTitle(QString("Ошибка заполнения"));
// McrsError->setMinimumSize(260, 70);
// McrsError->setMaximumSize(260, 70);
// QVBoxLayout *layoutCTX = new QVBoxLayout(McrsError);
// McrsError->setLayout(layoutCTX);
// QLabel *ErrorMSG = new QLabel;
// ErrorMSG->setText(QString("Некорректное значение поля макроса %1.").arg(MacrosSettingKit[i].Name->text()));
// layoutCTX->addWidget(ErrorMSG);
// QDialogButtonBox *yesOrNo = new QDialogButtonBox(McrsError);
// yesOrNo->addButton("Продолжить без HEX", QDialogButtonBox::AcceptRole);
// yesOrNo->addButton("Очистить макрос", QDialogButtonBox::RejectRole);
// layoutCTX->addWidget(yesOrNo);
// connect(yesOrNo, &QDialogButtonBox::accepted, McrsError, &QDialog::accept);
// connect(yesOrNo, &QDialogButtonBox::rejected, McrsError, &QDialog::reject);
// McrsError->exec();
// if(McrsError->result()==QDialog::Accepted)
// {
// MacrosSettingKit[i].IsHEX->setCheckState(Qt::Unchecked);
// McrsReturn.IsHEX[i] = Qt::Unchecked;
// McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text();
// }
// else
// {
// MacrosSettingKit[i].Mcrs->clear();
// McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text();
// }
// }
// else
// {
//
// }
McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text();
McrsReturn.Count[i] = MacrosSettingKit[i].Count->value();
McrsReturn.IsPeriod[i] = MacrosSettingKit[i].IsPeriod->checkState();
McrsReturn.Period[i] = MacrosSettingKit[i].Period->value();
}
IsOK = TRUE;
}
void MacrosSetting::on_buttonBox_rejected()
{
IsOK = FALSE;
}
void MacrosSetting::checkPeriod_stateChanged(int index, int arg1)
{
index--;
MacrosSettingKit[index].Period->setEnabled(arg1);
}
void MacrosSetting::ValidationID(unsigned int numID)
{
numID--;
QString buffer = QString::number(MacrosSettingKit[numID].ID->text().toUInt(nullptr, 16), 10);
int pos = 0;
unsigned long long maxRange;
if(MacrosSettingKit[numID].EID->checkState()==Qt::Checked)
{
maxRange = 0x1FFFFFFF;
}
else
{
maxRange = 0x7FF;
}
if((unsigned long long)buffer.toUInt(nullptr, 10) > (unsigned long long) maxRange)
{
MacrosSettingKit[numID].ID->setStyleSheet("border: 1px solid red");
MacrosSettingKit[numID].ID->setToolTip(QString("Valid ID: 0 - 0x%1").arg(QString::number(maxRange, 16).toUpper()));
EnterErrors.ID[numID] = true;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
else
{
MacrosSettingKit[numID].ID->setStyleSheet("");
MacrosSettingKit[numID].ID->setToolTip(QString());
EnterErrors.ID[numID] = false;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkErrors());
}
}
bool MacrosSetting::ValidationMcrs(unsigned int numID)
{
numID--;
if(MacrosSettingKit[numID].IsHEX->checkState()==Qt::Checked)
{
QString buffer = MacrosSettingKit[numID].Mcrs->text();
for(int i = 0; i < buffer.size(); i++)
{
if(buffer.at(i) < '0' || (buffer.at(i) > '9' && buffer.at(i) < 'A') || (buffer.at(i) > 'F' && buffer.at(i) < 'a') || buffer.at(i) > 'f')
{
MacrosSettingKit[numID].Mcrs->setStyleSheet("border: 1px solid red");
MacrosSettingKit[numID].Mcrs->setToolTip(QString("Hexadecimal character required. A-F, 0-9."));
EnterErrors.Mcrs[numID] = true;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
return false;
}
}
MacrosSettingKit[numID].Mcrs->setStyleSheet("");
MacrosSettingKit[numID].Mcrs->setToolTip(QString());
MacrosSettingKit[numID].Mcrs->setText(buffer.toUpper());
}
EnterErrors.Mcrs[numID] = false;
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkErrors());
return true;
}
void MacrosSetting::checkEID_stateChanged(int index)
{
index--;
if(MacrosSettingKit[index].EID->checkState()==Qt::Checked)
{
MacrosSettingKit[index].ID->setInputMask(">HHHHHHHH");
}
else
{
MacrosSettingKit[index].ID->setInputMask(">HHH");
}
}
void MacrosSetting::checkRTR_stateChanged(int index)
{
index--;
if(MacrosSettingKit[index].RTR->checkState()==Qt::Checked)
{
MacrosSettingKit[index].IsHEX->setEnabled(false);
MacrosSettingKit[index].Mcrs->setEnabled(false);
MacrosSettingKit[index].DLC->setEnabled(true);
}
else
{
MacrosSettingKit[index].IsHEX->setEnabled(true);
MacrosSettingKit[index].Mcrs->setEnabled(true);
if(MacrosSettingKit[index].IsHEX->checkState()!=Qt::Checked)
{
MacrosSettingKit[index].DLC->setEnabled(false);
}
}
}
void MacrosSetting::checkHEX_stateChanged(int index)
{
index--;
if(MacrosSettingKit[index].IsHEX->checkState()==Qt::Checked)
{
MacrosSettingKit[index].DLC->setEnabled(true);
comboDLC_stateChanged(index+1);
ValidationMcrs(index+1);
//MacrosSettingKit[index].Mcrs->setInputMask(">");
}
else
{
MacrosSettingKit[index].DLC->setEnabled(false);
MacrosSettingKit[index].Mcrs->setInputMask("");
MacrosSettingKit[index].Mcrs->setMaxLength(32767);
//MacrosSettingKit[index].Mcrs->setInputMask("");
}
}
void MacrosSetting::comboDLC_stateChanged(int index)
{
index--;
if(MacrosSettingKit[index].IsHEX->checkState()==Qt::Checked)
{
int currentDLC = MacrosSettingKit[index].DLC->currentIndex();
//QString buffer = ">";
// for (int i = 1; i < currentDLC; i++)
// {
// buffer += "HH";
// }
//MacrosSettingKit[index].Mcrs->setInputMask(buffer);
MacrosSettingKit[index].Mcrs->setMaxLength((MacrosSettingKit[index].DLC->currentIndex())*2);
}
}
bool MacrosSetting::checkErrors()
{
for(int i = 0; i < 15; i++)
{
if (EnterErrors.ID[i] || EnterErrors.Mcrs[i])
{
return false;
}
}
return true;
}

211
macrossetting.h Normal file
View File

@ -0,0 +1,211 @@
#ifndef MACROSSETTING_H
#define MACROSSETTING_H
#include <QDialog>
#include "unioncom.h"
#include "QLineEdit"
#include "QCheckBox"
#include "QSpinBox"
#include "QComboBox"
namespace Ui {
class MacrosSetting;
}
class MacrosSetting : public QDialog
{
Q_OBJECT
public:
// struct mcrs_stgs_kit{
// Qt::CheckState IsHEX;
// QString Name;
// QString Mcrs;
// } MacrosWindow[15];
struct MacrosSrting{
QCheckBox *EID;
QLineEdit *ID;
QCheckBox *RTR;
QCheckBox *IsHEX;
QComboBox *DLC;
QLineEdit *Name;
QLineEdit *Mcrs;
QSpinBox *Count;
QCheckBox *IsPeriod;
QSpinBox *Period;
} MacrosSettingKit[15];
struct mcrs_return{
Qt::CheckState *EID;
DWORD *ID;
Qt::CheckState *RTR;
Qt::CheckState *IsHEX;
int *DLC;
QString *Name;
QString *Mcrs;
int *Count;
Qt::CheckState *IsPeriod;
int *Period;
} McrsReturn;
struct error_enter{
bool ID[15];
bool Mcrs[15];
}EnterErrors;
explicit MacrosSetting(QWidget *parent = nullptr);
~MacrosSetting();
bool IsOK = false;
void SetStart(Qt::CheckState *ptrEID, DWORD *ptrID, Qt::CheckState *ptrRTR, Qt::CheckState *ptrHEX, int *ptrDLC,
QString *ptrName, QString *ptrMcrs, int *ptrCount, Qt::CheckState *ptrIsPeriod, int *ptrPeriod);
private slots:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
void on_checkPeriod_01_stateChanged(int arg1) {checkPeriod_stateChanged(1, arg1);};
void on_checkPeriod_02_stateChanged(int arg1) {checkPeriod_stateChanged(2, arg1);};
void on_checkPeriod_03_stateChanged(int arg1) {checkPeriod_stateChanged(3, arg1);};
void on_checkPeriod_04_stateChanged(int arg1) {checkPeriod_stateChanged(4, arg1);};
void on_checkPeriod_05_stateChanged(int arg1) {checkPeriod_stateChanged(5, arg1);};
void on_checkPeriod_06_stateChanged(int arg1) {checkPeriod_stateChanged(6, arg1);};
void on_checkPeriod_07_stateChanged(int arg1) {checkPeriod_stateChanged(7, arg1);};
void on_checkPeriod_08_stateChanged(int arg1) {checkPeriod_stateChanged(8, arg1);};
void on_checkPeriod_09_stateChanged(int arg1) {checkPeriod_stateChanged(9, arg1);};
void on_checkPeriod_10_stateChanged(int arg1) {checkPeriod_stateChanged(10, arg1);};
void on_checkPeriod_11_stateChanged(int arg1) {checkPeriod_stateChanged(11, arg1);};
void on_checkPeriod_12_stateChanged(int arg1) {checkPeriod_stateChanged(12, arg1);};
void on_checkPeriod_13_stateChanged(int arg1) {checkPeriod_stateChanged(13, arg1);};
void on_checkPeriod_14_stateChanged(int arg1) {checkPeriod_stateChanged(14, arg1);};
void on_checkPeriod_15_stateChanged(int arg1) {checkPeriod_stateChanged(15, arg1);};
void on_checkEID_01_stateChanged(int arg1) {checkEID_stateChanged(1);};
void on_checkEID_02_stateChanged(int arg1) {checkEID_stateChanged(2);};
void on_checkEID_03_stateChanged(int arg1) {checkEID_stateChanged(3);};
void on_checkEID_04_stateChanged(int arg1) {checkEID_stateChanged(4);};
void on_checkEID_05_stateChanged(int arg1) {checkEID_stateChanged(5);};
void on_checkEID_06_stateChanged(int arg1) {checkEID_stateChanged(6);};
void on_checkEID_07_stateChanged(int arg1) {checkEID_stateChanged(7);};
void on_checkEID_08_stateChanged(int arg1) {checkEID_stateChanged(8);};
void on_checkEID_09_stateChanged(int arg1) {checkEID_stateChanged(9);};
void on_checkEID_10_stateChanged(int arg1) {checkEID_stateChanged(10);};
void on_checkEID_11_stateChanged(int arg1) {checkEID_stateChanged(11);};
void on_checkEID_12_stateChanged(int arg1) {checkEID_stateChanged(12);};
void on_checkEID_13_stateChanged(int arg1) {checkEID_stateChanged(13);};
void on_checkEID_14_stateChanged(int arg1) {checkEID_stateChanged(14);};
void on_checkEID_15_stateChanged(int arg1) {checkEID_stateChanged(15);};
void on_checkRTR_01_stateChanged(int arg1) {checkRTR_stateChanged(1);};
void on_checkRTR_02_stateChanged(int arg1) {checkRTR_stateChanged(2);};
void on_checkRTR_03_stateChanged(int arg1) {checkRTR_stateChanged(3);};
void on_checkRTR_04_stateChanged(int arg1) {checkRTR_stateChanged(4);};
void on_checkRTR_05_stateChanged(int arg1) {checkRTR_stateChanged(5);};
void on_checkRTR_06_stateChanged(int arg1) {checkRTR_stateChanged(6);};
void on_checkRTR_07_stateChanged(int arg1) {checkRTR_stateChanged(7);};
void on_checkRTR_08_stateChanged(int arg1) {checkRTR_stateChanged(8);};
void on_checkRTR_09_stateChanged(int arg1) {checkRTR_stateChanged(9);};
void on_checkRTR_10_stateChanged(int arg1) {checkRTR_stateChanged(10);};
void on_checkRTR_11_stateChanged(int arg1) {checkRTR_stateChanged(11);};
void on_checkRTR_12_stateChanged(int arg1) {checkRTR_stateChanged(12);};
void on_checkRTR_13_stateChanged(int arg1) {checkRTR_stateChanged(13);};
void on_checkRTR_14_stateChanged(int arg1) {checkRTR_stateChanged(14);};
void on_checkRTR_15_stateChanged(int arg1) {checkRTR_stateChanged(15);};
void ValidationID(unsigned int numID);
void on_lineID_01_textChanged(const QString &arg1) {ValidationID(1);}
void on_lineID_02_textChanged(const QString &arg1) {ValidationID(2);}
void on_lineID_03_textChanged(const QString &arg1) {ValidationID(3);}
void on_lineID_04_textChanged(const QString &arg1) {ValidationID(4);}
void on_lineID_05_textChanged(const QString &arg1) {ValidationID(5);}
void on_lineID_06_textChanged(const QString &arg1) {ValidationID(6);}
void on_lineID_07_textChanged(const QString &arg1) {ValidationID(7);}
void on_lineID_08_textChanged(const QString &arg1) {ValidationID(8);}
void on_lineID_09_textChanged(const QString &arg1) {ValidationID(9);}
void on_lineID_10_textChanged(const QString &arg1) {ValidationID(10);}
void on_lineID_11_textChanged(const QString &arg1) {ValidationID(11);}
void on_lineID_12_textChanged(const QString &arg1) {ValidationID(12);}
void on_lineID_13_textChanged(const QString &arg1) {ValidationID(13);}
void on_lineID_14_textChanged(const QString &arg1) {ValidationID(14);}
void on_lineID_15_textChanged(const QString &arg1) {ValidationID(15);}
void on_checkHEX_01_stateChanged(int arg1) {checkHEX_stateChanged(1);};
void on_checkHEX_02_stateChanged(int arg1) {checkHEX_stateChanged(2);};
void on_checkHEX_03_stateChanged(int arg1) {checkHEX_stateChanged(3);};
void on_checkHEX_04_stateChanged(int arg1) {checkHEX_stateChanged(4);};
void on_checkHEX_05_stateChanged(int arg1) {checkHEX_stateChanged(5);};
void on_checkHEX_06_stateChanged(int arg1) {checkHEX_stateChanged(6);};
void on_checkHEX_07_stateChanged(int arg1) {checkHEX_stateChanged(7);};
void on_checkHEX_08_stateChanged(int arg1) {checkHEX_stateChanged(8);};
void on_checkHEX_09_stateChanged(int arg1) {checkHEX_stateChanged(9);};
void on_checkHEX_10_stateChanged(int arg1) {checkHEX_stateChanged(10);};
void on_checkHEX_11_stateChanged(int arg1) {checkHEX_stateChanged(11);};
void on_checkHEX_12_stateChanged(int arg1) {checkHEX_stateChanged(12);};
void on_checkHEX_13_stateChanged(int arg1) {checkHEX_stateChanged(13);};
void on_checkHEX_14_stateChanged(int arg1) {checkHEX_stateChanged(14);};
void on_checkHEX_15_stateChanged(int arg1) {checkHEX_stateChanged(15);};
// void on_comboDLC_01_stateChanged(int arg1) {comboDLC_stateChanged(1);};
// void on_comboDLC_02_stateChanged(int arg1) {comboDLC_stateChanged(2);};
// void on_comboDLC_03_stateChanged(int arg1) {comboDLC_stateChanged(3);};
// void on_comboDLC_04_stateChanged(int arg1) {comboDLC_stateChanged(4);};
// void on_comboDLC_05_stateChanged(int arg1) {comboDLC_stateChanged(5);};
// void on_comboDLC_06_stateChanged(int arg1) {comboDLC_stateChanged(6);};
// void on_comboDLC_07_stateChanged(int arg1) {comboDLC_stateChanged(7);};
// void on_comboDLC_08_stateChanged(int arg1) {comboDLC_stateChanged(8);};
// void on_comboDLC_09_stateChanged(int arg1) {comboDLC_stateChanged(9);};
// void on_comboDLC_10_stateChanged(int arg1) {comboDLC_stateChanged(10);};
// void on_comboDLC_11_stateChanged(int arg1) {comboDLC_stateChanged(11);};
// void on_comboDLC_12_stateChanged(int arg1) {comboDLC_stateChanged(12);};
// void on_comboDLC_13_stateChanged(int arg1) {comboDLC_stateChanged(13);};
// void on_comboDLC_14_stateChanged(int arg1) {comboDLC_stateChanged(14);};
// void on_comboDLC_15_stateChanged(int arg1) {comboDLC_stateChanged(15);};
bool ValidationMcrs(unsigned int numID);
void on_lineMcrs_01_textChanged(const QString &arg1) {ValidationMcrs(1);}
void on_lineMcrs_02_textChanged(const QString &arg1) {ValidationMcrs(2);}
void on_lineMcrs_03_textChanged(const QString &arg1) {ValidationMcrs(3);}
void on_lineMcrs_04_textChanged(const QString &arg1) {ValidationMcrs(4);}
void on_lineMcrs_05_textChanged(const QString &arg1) {ValidationMcrs(5);}
void on_lineMcrs_06_textChanged(const QString &arg1) {ValidationMcrs(6);}
void on_lineMcrs_07_textChanged(const QString &arg1) {ValidationMcrs(7);}
void on_lineMcrs_08_textChanged(const QString &arg1) {ValidationMcrs(8);}
void on_lineMcrs_09_textChanged(const QString &arg1) {ValidationMcrs(9);}
void on_lineMcrs_10_textChanged(const QString &arg1) {ValidationMcrs(10);}
void on_lineMcrs_11_textChanged(const QString &arg1) {ValidationMcrs(11);}
void on_lineMcrs_12_textChanged(const QString &arg1) {ValidationMcrs(12);}
void on_lineMcrs_13_textChanged(const QString &arg1) {ValidationMcrs(13);}
void on_lineMcrs_14_textChanged(const QString &arg1) {ValidationMcrs(14);}
void on_lineMcrs_15_textChanged(const QString &arg1) {ValidationMcrs(15);}
void on_comboDLC_01_currentIndexChanged(int arg1) {comboDLC_stateChanged(1);};
void on_comboDLC_02_currentIndexChanged(int arg1) {comboDLC_stateChanged(2);};
void on_comboDLC_03_currentIndexChanged(int arg1) {comboDLC_stateChanged(3);};
void on_comboDLC_04_currentIndexChanged(int arg1) {comboDLC_stateChanged(4);};
void on_comboDLC_05_currentIndexChanged(int arg1) {comboDLC_stateChanged(5);};
void on_comboDLC_06_currentIndexChanged(int arg1) {comboDLC_stateChanged(6);};
void on_comboDLC_07_currentIndexChanged(int arg1) {comboDLC_stateChanged(7);};
void on_comboDLC_08_currentIndexChanged(int arg1) {comboDLC_stateChanged(8);};
void on_comboDLC_09_currentIndexChanged(int arg1) {comboDLC_stateChanged(9);};
void on_comboDLC_10_currentIndexChanged(int arg1) {comboDLC_stateChanged(10);};
void on_comboDLC_11_currentIndexChanged(int arg1) {comboDLC_stateChanged(11);};
void on_comboDLC_12_currentIndexChanged(int arg1) {comboDLC_stateChanged(12);};
void on_comboDLC_13_currentIndexChanged(int arg1) {comboDLC_stateChanged(13);};
void on_comboDLC_14_currentIndexChanged(int arg1) {comboDLC_stateChanged(14);};
void on_comboDLC_15_currentIndexChanged(int arg1) {comboDLC_stateChanged(15);};
private:
Ui::MacrosSetting *ui;
void checkPeriod_stateChanged(int index, int arg1);
void checkEID_stateChanged(int index);
void checkRTR_stateChanged(int index);
void checkHEX_stateChanged(int index);
void comboDLC_stateChanged(int index);
bool checkErrors();
void GetMcrs();
void Init();
};
#endif // MACROSSETTING_H

4019
macrossetting.ui Normal file

File diff suppressed because it is too large Load Diff

23
main.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "ProjectSettings.h"
#include <QApplication>
#define WITH_MEM_LEAK_TESTING
#ifdef WITH_MEM_LEAK_TESTING
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#endif
int main(int argc, char *argv[])
{
#ifdef WITH_MEM_LEAK_TESTING
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
#endif
QApplication a(argc, argv);
setlocale(LC_ALL, "");
//Для отключения консоли при запуске нужно в файле .pro сделать: #CONFIG += console
UnionCOM w;
w.show();
return a.exec();
}

37
mainmenu.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "mainmenu.h"
#include "ui_mainmenu.h"
//#include "ProjectSettings.h"
//#include "QMenu"
MainMenu::MainMenu(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainMenu)
{
//CanUsb *wCan = new CanUsb(this);
ui->setupUi(this);
//ui->tabWidget->addTab(wCan, "CAN");
// connect(actionCAN, SIGNAL(activated()), this, SLOT(CAN));
}
MainMenu::~MainMenu()
{
delete ui;
}
void MainMenu::BackToMainMenu()
{
ui->gridLayoutWidget->show();
}
void MainMenu::CAN()
{
}
void MainMenu::Bluetooth()
{
}

28
mainmenu.h Normal file
View File

@ -0,0 +1,28 @@
#ifndef MAINMENU_H
#define MAINMENU_H
#include <QMainWindow>
namespace Ui {
class MainMenu;
}
class MainMenu : public QMainWindow
{
Q_OBJECT
public:
explicit MainMenu(QWidget *parent = nullptr);
~MainMenu();
private slots:
void CAN();
void BackToMainMenu();
void Bluetooth();
private:
Ui::MainMenu *ui;
};
#endif // MAINMENU_H

74
mainmenu.ui Normal file
View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainMenu</class>
<widget class="QMainWindow" name="MainMenu">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>445</width>
<height>410</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>445</width>
<height>410</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>445</width>
<height>410</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>445</width>
<height>20</height>
</rect>
</property>
</widget>
<action name="actionCAN">
<property name="text">
<string>CAN</string>
</property>
</action>
<action name="actionBluetooth">
<property name="text">
<string>Bluetooth</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>

510
slcan.h Normal file
View File

@ -0,0 +1,510 @@
#ifndef __SLCAN_H__
#define __SLCAN_H__
#include <windows.h>
#define STDCALL __stdcall
#ifdef SLCAN_EXPORT
#define SLCANAPI __declspec(dllexport)
#else
#define SLCANAPI __declspec(dllimport)
#endif
#define SLCAN_PROPERTY_INDEX_LINKNAME 0
#define SLCAN_PROPERTY_INDEX_INSTANCEID 1
#define SLCAN_PROPERTY_INDEX_DEVICEDESC 2
#define SLCAN_PROPERTY_INDEX_FRIENDLYNAME 3
#define SLCAN_PROPERTY_INDEX_PHOBJECTNAME 4
#define SLCAN_PROPERTY_INDEX_MFG 5
#define SLCAN_PROPERTY_INDEX_LOCATIONINFO 6
#define SLCAN_PROPERTY_INDEX_ENUMERATOR 7
#define SLCAN_PROPERTY_INDEX_CLASS 8
#define SLCAN_PROPERTY_INDEX_CLASSGUID 9
#define SLCAN_PROPERTY_INDEX_SERVICE 10
#define SLCAN_PROPERTY_INDEX_DRIVER 11
#define SLCAN_PROPERTY_INDEX_PORTNAME 12
#define SLCAN_PROPERTY_INDEX_PRODUCT 13L
#define SLCAN_PROPERTY_INDEX_MANUFACTURER 14L
#define SLCAN_PROPERTY_INDEX_CONFIGURATION 15L
#define SLCAN_PROPERTY_INDEX_INTERFACE 16L
#define SLCAN_PROPERTY_INDEX_SERIAL 17L
#define SLCAN_PROPERTY_INDEX_ALIAS 18L
#define SLCAN_PROPERTY_INDEX_CHANNELLINK 19L
#define SLCAN_PROPERTY_INDEX_SERIALID 20L
#define SLCAN_MODE_CONFIG 0x00
#define SLCAN_MODE_NORMAL 0x01
#define SLCAN_MODE_LISTENONLY 0x02
#define SLCAN_MODE_LOOPBACK 0x03
#define SLCAN_MODE_SLEEP 0x04
#define SLCAN_BR_CIA_1000K 0x8000
#define SLCAN_BR_CIA_800K 0x8001
#define SLCAN_BR_CIA_500K 0x8002
#define SLCAN_BR_CIA_250K 0x8003
#define SLCAN_BR_CIA_125K 0x8004
#define SLCAN_BR_CIA_50K 0x8005
#define SLCAN_BR_CIA_20K 0x8006
#define SLCAN_BR_CIA_10K 0x8007
#define SLCAN_BR_400K 0x8008
#define SLCAN_BR_200K 0x8009
#define SLCAN_BR_100K 0x800A
#define SLCAN_BR_83333 0x800B
#define SLCAN_BR_33333 0x800C
#define SLCAN_BR_25K 0x800D
#define SLCAN_BR_5K 0x800E
#define SLCAN_BR_30K 0x800F
#define SLCAN_BR_300K 0x8010
#define SLCAN_BR_LASTINDEX SLCAN_BR_300K
#define SLCAN_CAP_MODE_NORMAL 0x01
#define SLCAN_CAP_MODE_LISTEN_ONLY 0x02
#define SLCAN_CAP_MODE_LOOP_BACK 0x04
#define SLCAN_CAP_MODE_SLEEP 0x08
#define SLCAN_CAP_TXMODE_ONE_SHOT 0x01
#define SLCAN_CAP_TXMODE_TIMESTAMP 0x02
#define SLCAN_CAP_CONTR_EXTERNAL 0x00
#define SLCAN_CAP_CONTR_MCP2515 0x01
#define SLCAN_CAP_CONTR_SJA1000 0x02
#define SLCAN_CAP_CONTR_INTERNAL 0x80
#define SLCAN_CAP_CONTR_LPC 0x81
#define SLCAN_CAP_CONTR_STM32 0x82
#define SLCAN_CAP_CONTR_STM8 0x83
#define SLCAN_CAP_CONTR_PIC 0x84
#define SLCAN_CAP_CONTR_PIC_ECAN 0x85
#define SLCAN_CAP_PHYS_HS 0x01
#define SLCAN_CAP_PHYS_LS 0x02
#define SLCAN_CAP_PHYS_SW 0x04
#define SLCAN_CAP_PHYS_J1708 0x08
#define SLCAN_CAP_PHYS_LIN 0x10
#define SLCAN_CAP_PHYS_KLINE 0x20
#define SLCAN_CAP_PHYS_LOAD 0x01
#define SLCAN_CAP_BITRATE_INDEX 0x01
#define SLCAN_CAP_BITRATE_CUSTOM 0x02
#define SLCAN_CAP_BITRATE_AUTOMATIC 0x04
#define SLCAN_EVT_LEVEL_RX_MSG 0
#define SLCAN_EVT_LEVEL_TIME_STAMP 1
#define SLCAN_EVT_LEVEL_TX_MSG 2
#define SLCAN_EVT_LEVEL_BUS_STATE 3
#define SLCAN_EVT_LEVEL_COUNTS 4
#define SLCAN_EVT_LEVEL_ERRORS 5
#define SLCAN_EVT_TYPE_RX 0x0
#define SLCAN_EVT_TYPE_START_TX 0x1
#define SLCAN_EVT_TYPE_END_TX 0x2
#define SLCAN_EVT_TYPE_ABORT_TX 0x3
#define SLCAN_EVT_TYPE_BUS_STATE 0x4
#define SLCAN_EVT_TYPE_ERROR_COUNTS 0x5
#define SLCAN_EVT_TYPE_BUS_ERROR 0x6
#define SLCAN_EVT_TYPE_ARBITRATION_ERROR 0x7
#define SLCAN_EVT_STAMP_INC 0xF
#define SLCAN_BUS_STATE_ERROR_ACTIVE 0x00
#define SLCAN_BUS_STATE_ERROR_ACTIVE_WARN 0x01
#define SLCAN_BUS_STATE_ERROR_PASSIVE 0x02
#define SLCAN_BUS_STATE_BUSOFF 0x03
#define SLCAN_MES_INFO_EXT 0x01
#define SLCAN_MES_INFO_RTR 0x02
#define SLCAN_MES_INFO_ONESHOT 0x04
#define SLCAN_DEVOP_CREATE 0x00000000
#define SLCAN_DEVOP_CREATEHANDLE 0x00000001
#define SLCAN_DEVOP_OPEN 0x00000002
#define SLCAN_DEVOP_CLOSE 0x00000003
#define SLCAN_DEVOP_DESTROYHANDLE 0x00000004
#define SLCAN_DEVOP_DESTROY 0x00000005
#define SLCAN_INVALID_HANDLE_ERROR 0xE0001001
#define SLCAN_DEVICE_INVALID_HANDLE_ERROR 0xE0001120
#define SLCAN_HANDLE_INIT_ERROR 0xE0001017
#define SLCAN_DEVICE_NOTOPEN_ERROR 0xE0001121
#define SLCAN_EVT_ERR_TYPE_BIT 0x00
#define SLCAN_EVT_ERR_TYPE_FORM 0x01
#define SLCAN_EVT_ERR_TYPE_STUFF 0x02
#define SLCAN_EVT_ERR_TYPE_OTHER 0x03
#define SLCAN_EVT_ERR_DIR_TX 0x00
#define SLCAN_EVT_ERR_DIR_RX 0x01
#define SLCAN_EVT_ERR_FRAME_SOF 0x03
#define SLCAN_EVT_ERR_FRAME_ID28_ID21 0x02
#define SLCAN_EVT_ERR_FRAME_ID20_ID18 0x06
#define SLCAN_EVT_ERR_FRAME_SRTR 0x04
#define SLCAN_EVT_ERR_FRAME_IDE 0x05
#define SLCAN_EVT_ERR_FRAME_ID17_ID13 0x07
#define SLCAN_EVT_ERR_FRAME_ID12_ID5 0x0F
#define SLCAN_EVT_ERR_FRAME_ID4_ID0 0x0E
#define SLCAN_EVT_ERR_FRAME_RTR 0x0C
#define SLCAN_EVT_ERR_FRAME_RSRV0 0x0D
#define SLCAN_EVT_ERR_FRAME_RSRV1 0x09
#define SLCAN_EVT_ERR_FRAME_DLC 0x0B
#define SLCAN_EVT_ERR_FRAME_DATA 0x0A
#define SLCAN_EVT_ERR_FRAME_CRC_SEQ 0x08
#define SLCAN_EVT_ERR_FRAME_CRC_DEL 0x18
#define SLCAN_EVT_ERR_FRAME_ACK_SLOT 0x19
#define SLCAN_EVT_ERR_FRAME_ACK_DEL 0x1B
#define SLCAN_EVT_ERR_FRAME_EOF 0x1A
#define SLCAN_EVT_ERR_FRAME_INTER 0x12
#define SLCAN_EVT_ERR_FRAME_AER_FLAG 0x11
#define SLCAN_EVT_ERR_FRAME_PER_FLAG 0x16
#define SLCAN_EVT_ERR_FRAME_TDB 0x13
#define SLCAN_EVT_ERR_FRAME_ERR_DEL 0x17
#define SLCAN_EVT_ERR_FRAME_OVER_FLAG 0x1C
#define SLCAN_TX_STATUS_OK 0x00
#define SLCAN_TX_STATUS_TIMEOUT 0x01
#define SLCAN_TX_STATUS_BUSOFF 0x02
#define SLCAN_TX_STATUS_ABORT 0x03
#define SLCAN_TX_STATUS_NOT_ENA 0x04
#define SLCAN_TX_STATUS_ERROR_ONE_SHOT 0x05
#define SLCAN_TX_STATUS_INVALID_MODE 0x06
#define SLCAN_TX_STATUS_UNKNOWN 0x0F
#define SLCAN_PURGE_TX_ABORT 0x01
#define SLCAN_PURGE_RX_ABORT 0x02
#define SLCAN_PURGE_TX_CLEAR 0x04
#define SLCAN_PURGE_RX_CLEAR 0x08
#pragma pack(push,1)
#ifdef __cplusplus
extern "C"{
#endif
typedef PVOID HSLCAN;
typedef struct _SLCAN_CAPABILITIES{
BYTE bModes;
BYTE bTXModes;
BYTE bMaxEventLevel;
BYTE bController;
BYTE bPhysical;
BYTE bPhysicalLoad;
BYTE bBitrates;
BYTE bAdvancedModes;
DWORD dwCanBaseClk;
DWORD dwTimeStampClk;
WORD wMaxBRP;
}SLCAN_CAPABILITIES,*PSLCAN_CAPABILITIES;
typedef struct _SLCAN_BITRATE {
WORD BRP;
BYTE TSEG1;
BYTE TSEG2;
BYTE SJW;
BYTE SAM;
}SLCAN_BITRATE,*PSLCAN_BITRATE;
typedef void (STDCALL* SLCAN_DEVICE_CALLBACK)(
HSLCAN hDevice,
DWORD dwIndex,
DWORD dwOperation,
PVOID pContext,
DWORD dwContextSize
);
typedef VOID (STDCALL* SLCAN_DEVICELIST_CALLBACK)(
HSLCAN hDevice,
DWORD dwIndex,
PVOID pContext,
DWORD dwContextSize
);
typedef struct _SLCAN_MESSAGE{
BYTE Info;
DWORD ID;
BYTE DataCount;
BYTE Data[8];
}SLCAN_MESSAGE,*PSLCAN_MESSAGE;
typedef struct _SLCAN_TXMESSAGE{
LONG dwDelay;
SLCAN_MESSAGE Msg;
}SLCAN_TXMESSAGE,*PSLCAN_TXMESSAGE;
typedef struct _SLCAN_EVENT{
BYTE EventType;
DWORD TimeStampLo;
union {
SLCAN_MESSAGE Msg;
DWORD TimeStamp[2];
DWORD64 TimeStamp64;
struct {
BYTE BusMode;
BYTE Dummy1;
BYTE ErrCountRx;
BYTE ErrCountTx;
BYTE ErrType;
BYTE ErrDir;
BYTE ErrFrame;
BYTE LostArbitration;
};
};
}SLCAN_EVENT,*PSLCAN_EVENT;
typedef struct _SLCAN_STATE{
BYTE BusMode;
BYTE Dummy1;
BYTE ErrCountRX;
BYTE ErrCountTX;
}SLCAN_STATE,*PSLCAN_STATE;
typedef union _SLCAN_TIMESTAMP{
UINT64 Value;
DWORD dwValue[2];
USHORT wValue[4];
BYTE bValue[8];
}SLCAN_TIMESTAMP,*PSLCAN_TIMESTAMP;
SLCANAPI BOOL STDCALL SlCan_Load(
SLCAN_DEVICE_CALLBACK DeviceProc,
SLCAN_DEVICELIST_CALLBACK DeviceListProc
);
SLCANAPI BOOL STDCALL SlCan_Free(
BOOL bDoCallBack
);
SLCANAPI BOOL STDCALL SlCan_Update();
SLCANAPI HSLCAN STDCALL SlCan_GetDevice(
DWORD dwIndex
);
SLCANAPI DWORD STDCALL SlCan_GetDeviceCount();
SLCANAPI HANDLE STDCALL SlCan_DeviceGetHandle(
DWORD dwIndex
);
SLCANAPI DWORD STDCALL SlCan_DeviceGetProperty(
HSLCAN hDevice,
DWORD dwIndex,
PCHAR pBuf,
DWORD dwSize
);
SLCANAPI DWORD STDCALL SlCan_DeviceGetPropertyW(
HSLCAN hDevice,
DWORD dwIndex,
PWCHAR pBuf,
DWORD dwSize
);
SLCANAPI HKEY STDCALL SlCan_DeviceGetRegKey(
HSLCAN hDevice,
DWORD dwIndex
);
SLCANAPI PVOID STDCALL SlCan_DeviceSetContext(
HSLCAN hDevice,
PVOID pBuf,
DWORD dwBufSize
);
SLCANAPI PVOID STDCALL SlCan_DeviceGetContext(
HSLCAN hDevice
);
SLCANAPI DWORD STDCALL SlCan_DeviceGetContextSize(
HSLCAN hDevice
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetAlias(
HSLCAN hDevice,
PCHAR pBuf
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetAliasW(
HSLCAN hDevice,
PWCHAR pBuf
);
SLCANAPI DWORD STDCALL SlCan_DeviceGetAlias(
HSLCAN hDevice,
PCHAR pBuf,
DWORD dwSize
);
SLCANAPI DWORD STDCALL SlCan_DeviceGetAliasW(
HSLCAN hDevice,
PWCHAR pBuf,
DWORD dwSize
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetCapabilities(
HSLCAN hDevice,
PSLCAN_CAPABILITIES pCapabilities
);
SLCANAPI BOOL STDCALL SlCan_DeviceOpen(
HSLCAN hDevice
);
SLCANAPI BOOL STDCALL SlCan_DeviceClose(
HSLCAN hDevice
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetMode(
HSLCAN hDevice,
DWORD dwMode
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetMode(
HSLCAN hDevice,
PDWORD pdwMode
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetState(
HSLCAN hDevice,
PSLCAN_STATE pState
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetTXTimeOut(
HSLCAN hDevice,
DWORD dwMillisecond
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetTXTimeOut(
HSLCAN hDevice,
PDWORD pdwMillisecond
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetBitRate(
HSLCAN hDevice,
PSLCAN_BITRATE pBitRate
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetBitRate(
HSLCAN hDevice,
PSLCAN_BITRATE pBitRate
);
SLCANAPI BOOL STDCALL SlCan_DeviceEnaRec(
HSLCAN hDevice,
BYTE bValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetLatency(
HSLCAN hDevice,
BYTE bValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetLatency(
HSLCAN hDevice,
PBYTE pbValue
);
SLCANAPI BOOL STDCALL SlCan_DevicePurge(
HSLCAN hDevice,
BYTE bValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetEventLevel(
HSLCAN hDevice,
BYTE bValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetEventLevel(
HSLCAN hDevice,
PBYTE pbValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetStartTimeStamp(
HSLCAN hDevice,
PSLCAN_TIMESTAMP pValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetStartTimeStamp(
HSLCAN hDevice,
PSLCAN_TIMESTAMP pValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStamp(
HSLCAN hDevice,
PSLCAN_TIMESTAMP pValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetTimeStampPeriod(
HSLCAN hDevice,
LONG lValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStampPeriod(
HSLCAN hDevice,
PLONG plValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceSetExMode(
HSLCAN hDevice,
BYTE bValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceGetExMode(
HSLCAN hDevice,
PBYTE pbValue
);
SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessages(
HSLCAN hDevice,
PSLCAN_MESSAGE pMsg,
DWORD dwCount,
PBYTE pbStatus
);
SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessagesEx(
HSLCAN hDevice,
PSLCAN_TXMESSAGE pMsg,
DWORD dwCount,
PBYTE pbStatus,
PDWORD pdwCount
);
SLCANAPI BOOL STDCALL SlCan_DeviceReadMessages(
HSLCAN hDevice,
DWORD dwTimeOut,
PSLCAN_MESSAGE pMsg,
DWORD dwCount,
PDWORD pdwCount
);
SLCANAPI BOOL STDCALL SlCan_DeviceReadEvents(
HSLCAN hDevice,
DWORD dwTimeOut,
PSLCAN_EVENT pEvent,
DWORD dwCount,
PDWORD pdwCount
);
#ifdef __cplusplus
}
#endif
#pragma pack(pop)
#endif //__SLCAN_H

BIN
slcan.lib Normal file

Binary file not shown.

445
union_modbus.cpp Normal file
View File

@ -0,0 +1,445 @@
#include "union_modbus.h"
#include "ui_union_modbus.h"
#include "writeregistermodel.h"
#include <QtSerialBus/QModbusTcpClient>
#include <QtSerialBus/QModbusRtuSerialMaster>
#include <QStandardItemModel>
#include <QUrl>
enum ModbusConnection {
Serial,
Tcp
};
union_modbus *this_modbus;
static void stepToPeriodRequest()
{
this_modbus->readModbus();
}
union_modbus::union_modbus(QWidget *parent) :
QWidget(parent),
ui(new Ui::union_modbus)
{
ui->setupUi(this);
initActions();
writeModel = new WriteRegisterModel(this);
writeModel->setStartAddress(ui->spinTXStartAddress->value());
writeModel->setNumberOfValues(ui->comboTXNumberOfValues->currentText());
ui->writeValueTable->setModel(writeModel);
ui->writeValueTable->hideColumn(2);
connect(writeModel, &WriteRegisterModel::updateViewport,
ui->writeValueTable->viewport(), QOverload<>::of(&QWidget::update));
ui->comboTable->addItem(tr("Coils"), QModbusDataUnit::Coils);
ui->comboTable->addItem(tr("Discrete Inputs"), QModbusDataUnit::DiscreteInputs);
ui->comboTable->addItem(tr("Input Registers"), QModbusDataUnit::InputRegisters);
ui->comboTable->addItem(tr("Holding Registers"), QModbusDataUnit::HoldingRegisters);
this_modbus=this;
RequestPeriodTimer.setSingleShot(true);
connect(&RequestPeriodTimer, &QTimer::timeout, this, &stepToPeriodRequest);
#if QT_CONFIG(modbus_serialport)
ui->connectType->setCurrentIndex(0);
onConnectTypeChanged(0);
#else
// lock out the serial port option
ui->connectType->setCurrentIndex(1);
onConnectTypeChanged(1);
ui->connectType->setEnabled(false);
#endif
auto model = new QStandardItemModel(10, 1, this);
for (int i = 0; i < 100; ++i)
model->setItem(i, new QStandardItem(QStringLiteral("%1").arg(i + 1)));
ui->comboTXNumberOfValues->setModel(model);
connect(ui->comboTXNumberOfValues, &QComboBox::currentTextChanged,
writeModel, &WriteRegisterModel::setNumberOfValues);
ui->comboTXNumberOfValues->setCurrentText("10");
auto valueChanged = QOverload<int>::of(&QSpinBox::valueChanged);
connect(ui->spinTXStartAddress, valueChanged, writeModel, &WriteRegisterModel::setStartAddress);
connect(ui->spinTXStartAddress, valueChanged, this, [this, model](int i) {
int lastPossibleIndex = 0;
const int currentIndex = ui->comboTXNumberOfValues->currentIndex();
for (int ii = 0; ii < 10; ++ii) {
if (ii < (10 - i)) {
lastPossibleIndex = ii;
model->item(ii)->setEnabled(true);
} else {
model->item(ii)->setEnabled(false);
}
}
if (currentIndex > lastPossibleIndex)
ui->comboTXNumberOfValues->setCurrentIndex(lastPossibleIndex);
});
}
union_modbus::~union_modbus()
{
if(modbusDevice->state()==QModbusDevice::ConnectedState)
{
modbusDevice->disconnectDevice();
}
delete ui;
}
void union_modbus::statusBarClear()
{
ui->StatusBar->clear();
}
void union_modbus::initActions()
{
connect(ui->buttonConnectOrDisconnect, &QPushButton::clicked,
this, &union_modbus::onConnectButtonClicked);
connect(ui->buttonRead, &QPushButton::clicked,
this, &union_modbus::onReadButtonClicked);
connect(ui->buttonWrite, &QPushButton::clicked,
this, &union_modbus::onWriteButtonClicked);
connect(ui->buttonReadWrite, &QPushButton::clicked,
this, &union_modbus::onReadWriteButtonClicked);
connect(ui->comboTable, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &union_modbus::onWriteTableChanged);
connect(ui->connectType, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &union_modbus::onConnectTypeChanged);
statusBarTimeOut.setSingleShot(true);
connect(&statusBarTimeOut, &QTimer::timeout, this, &union_modbus::statusBarClear);
}
void union_modbus::onConnectTypeChanged(int index)
{
if (modbusDevice) {
modbusDevice->disconnectDevice();
delete modbusDevice;
modbusDevice = nullptr;
}
auto type = static_cast<ModbusConnection>(index);
if (type == Serial) {
#if QT_CONFIG(modbus_serialport)
ui->portEdit->clear();
modbusDevice = new QModbusRtuSerialMaster(this);
#endif
} else if (type == Tcp) {
modbusDevice = new QModbusTcpClient(this);
if (ui->portEdit->text().isEmpty())
ui->portEdit->setText(QLatin1String("127.0.0.1:502"));
}
connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) {
ui->StatusBar->setText(modbusDevice->errorString());
statusBarTimeOut.start(5000);
});
if (!modbusDevice) {
ui->buttonConnectOrDisconnect->setDisabled(true);
if (type == Serial)
{
ui->StatusBar->setText(tr("Could not create Modbus master."));
statusBarTimeOut.start(5000);
}
else
{
ui->StatusBar->setText(tr("Could not create Modbus client."));
statusBarTimeOut.start(5000);
}
} else {
connect(modbusDevice, &QModbusClient::stateChanged,
this, &union_modbus::onModbusStateChanged);
}
}
void union_modbus::ApplySettings()
{
#if QT_CONFIG(modbus_serialport)
m_settings.parity = ui->conboParity->currentIndex();
if (m_settings.parity > 0)
m_settings.parity++;
m_settings.baud = ui->comboBaudRate->currentText().toInt();
m_settings.dataBits = ui->comboDataBits->currentText().toInt();
m_settings.stopBits = ui->comboStopBits->currentText().toInt();
#endif
m_settings.responseTime = ui->spinResponseTimeout->value();
m_settings.numberOfRetries = ui->spinNumberOfRetries->value();
}
void union_modbus::onConnectButtonClicked()
{
if (!modbusDevice)
return;
statusBarTimeOut.stop();
ui->StatusBar->clear();
RequestPeriodTimer.stop();
if (modbusDevice->state() != QModbusDevice::ConnectedState) {
ApplySettings();
if (static_cast<ModbusConnection>(ui->connectType->currentIndex()) == Serial) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
ui->portEdit->text());
#if QT_CONFIG(modbus_serialport)
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
m_settings.parity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
m_settings.baud);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
m_settings.dataBits);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
m_settings.stopBits);
#endif
} else {
const QUrl url = QUrl::fromUserInput(ui->portEdit->text());
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());
}
modbusDevice->setTimeout(m_settings.responseTime);
modbusDevice->setNumberOfRetries(m_settings.numberOfRetries);
if (!modbusDevice->connectDevice()) {
ui->StatusBar->setText(tr("Connect failed: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
}
else
{
ui->frameSettings->setEnabled(false);
ui->frameSerialTCPPort->setEnabled(false);
}
} else {
modbusDevice->disconnectDevice();
ui->frameSettings->setEnabled(true);
ui->frameSerialTCPPort->setEnabled(true);
}
}
void union_modbus::onModbusStateChanged(int state)
{
bool connected = (state != QModbusDevice::UnconnectedState);
if (state == QModbusDevice::UnconnectedState)
ui->buttonConnectOrDisconnect->setText(tr("Connect"));
else if (state == QModbusDevice::ConnectedState)
ui->buttonConnectOrDisconnect->setText(tr("Disconnect"));
}
void union_modbus::onReadButtonClicked()
{
if(CurrentReadButtonPosition)
{
if(ui->checkPeriodRequest->checkState()==Qt::Checked)
{
ui->buttonRead->setText("Stop Read");
CurrentReadButtonPosition = false;
readModbus();
}
else
{
readModbus();
}
}
else
{
ui->buttonRead->setText("Read");
CurrentReadButtonPosition = true;
RequestPeriodTimer.stop();
}
}
void union_modbus::readModbus()
{
if (!modbusDevice)
return;
statusBarTimeOut.stop();
ui->StatusBar->clear();
if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {
if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady);
else
delete reply; // broadcast replies return immediately
} else {
ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
}
// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {
// if (!reply->isFinished())
// connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady);
// else
// delete reply; // broadcast replies return immediately
// } else {
// ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString());
// statusBarTimeOut.start(5000);
// }
// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) {
// if (!reply->isFinished())
// connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady);
// else
// delete reply; // broadcast replies return immediately
// } else {
// ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString());
// statusBarTimeOut.start(5000);
// }
}
void union_modbus::onReadReady()
{
auto reply = qobject_cast<QModbusReply *>(sender());
if (!reply)
return;
ui->readValue->clear();
if (reply->error() == QModbusDevice::NoError) {
ui->StatusBar->clear();
const QModbusDataUnit unit = reply->result();
for (int i = 0, total = int(unit.valueCount()); i < total; ++i) {
const QString entry = tr("Address: %1, Value: %2").arg(unit.startAddress() + i)
.arg(QString::number(unit.value(i),
unit.registerType() <= QModbusDataUnit::Coils ? 10 : 16));
ui->readValue->addItem(entry);
}
if(CurrentReadButtonPosition == false)
{
RequestPeriodTimer.start(ui->spinPeriodTime->value());
}
reply->deleteLater();
return;
} else if (reply->error() == QModbusDevice::ProtocolError) {
ui->StatusBar->setText(tr("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16));
statusBarTimeOut.start(5000);
} else {
ui->StatusBar->setText(tr("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()).
arg(reply->error(), -1, 16));
statusBarTimeOut.start(5000);
}
if(CurrentReadButtonPosition==false)
onReadButtonClicked();
reply->deleteLater();
}
void union_modbus::onWriteButtonClicked()
{
if (!modbusDevice)
return;
statusBarTimeOut.stop();
ui->StatusBar->clear();
QModbusDataUnit writeUnit = writeRequest();
QModbusDataUnit::RegisterType table = writeUnit.registerType();
for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) {
if (table == QModbusDataUnit::Coils)
writeUnit.setValue(i, writeModel->m_coils[i + writeUnit.startAddress()]);
else
writeUnit.setValue(i, writeModel->m_holdingRegisters[i + writeUnit.startAddress()]);
}
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, ui->serverEdit->value())) {
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, this, [this, reply]() {
if (reply->error() == QModbusDevice::ProtocolError) {
ui->StatusBar->setText(tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));
statusBarTimeOut.start(5000);
} else if (reply->error() != QModbusDevice::NoError) {
ui->StatusBar->setText(tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16));
statusBarTimeOut.start(5000);
}
reply->deleteLater();
});
} else {
// broadcast replies return immediately
reply->deleteLater();
}
} else {
ui->StatusBar->setText(tr("Write error: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
}
}
void union_modbus::onReadWriteButtonClicked()
{
if (!modbusDevice)
return;
ui->readValue->clear();
ui->StatusBar->clear();
statusBarTimeOut.stop();
QModbusDataUnit writeUnit = writeRequest();
QModbusDataUnit::RegisterType table = writeUnit.registerType();
for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) {
if (table == QModbusDataUnit::Coils)
writeUnit.setValue(i, writeModel->m_coils[i + writeUnit.startAddress()]);
else
writeUnit.setValue(i, writeModel->m_holdingRegisters[i + writeUnit.startAddress()]);
}
if (auto *reply = modbusDevice->sendReadWriteRequest(readRequest(), writeUnit,
ui->serverEdit->value())) {
if (!reply->isFinished())
connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady);
else
delete reply; // broadcast replies return immediately
} else {
ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
}
}
void union_modbus::onWriteTableChanged(int index)
{
const bool coilsOrHolding = index == 0 || index == 3;
if (coilsOrHolding) {
ui->writeValueTable->setColumnHidden(1, index != 0);
ui->writeValueTable->setColumnHidden(2, index != 3);
ui->writeValueTable->resizeColumnToContents(0);
}
ui->buttonReadWrite->setEnabled(index == 3);
ui->buttonWrite->setEnabled(coilsOrHolding);
ui->layoutTX->setEnabled(coilsOrHolding);
}
QModbusDataUnit union_modbus::readRequest() const
{
const auto table =
static_cast<QModbusDataUnit::RegisterType>(ui->comboTable->currentData().toInt());
int startAddress = ui->spinRXStartAddress->value();
Q_ASSERT(startAddress >= 0 && startAddress < 340);
// do not go beyond 10 entries
quint16 numberOfEntries = qMin(ui->comboRXNumberOfValues->currentText().toUShort(), quint16(340 - startAddress));
return QModbusDataUnit(table, startAddress, numberOfEntries);
}
QModbusDataUnit union_modbus::writeRequest() const
{
const auto table =
static_cast<QModbusDataUnit::RegisterType>(ui->comboTable->currentData().toInt());
int startAddress = ui->spinTXStartAddress->value();
Q_ASSERT(startAddress >= 0 && startAddress < 340);
// do not go beyond 10 entries
quint16 numberOfEntries = qMin(ui->comboTXNumberOfValues->currentText().toUShort(), quint16(340 - startAddress));
return QModbusDataUnit(table, startAddress, numberOfEntries);
}
void union_modbus::on_checkPeriodRequest_stateChanged(int arg1)
{
if (ui->checkPeriodRequest->checkState()==Qt::Checked)
{
ui->spinPeriodTime->setEnabled(true);
}
else
{
ui->spinPeriodTime->setEnabled(false);
RequestPeriodTimer.stop();
}
}

80
union_modbus.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef UNION_MODBUS_H
#define UNION_MODBUS_H
#include "QTimer"
#include <QWidget>
#include <QtSerialBus/QModbusDataUnit>
#include "writeregistermodel.h"
#include <QtSerialBus/qtserialbusglobal.h>
#include <QDialog>
#if QT_CONFIG(modbus_serialport)
#include <QSerialPort>
#endif
class QModbusClient;
class QModbusReply;
namespace Ui {
class union_modbus;
}
class union_modbus : public QWidget
{
Q_OBJECT
public:
explicit union_modbus(QWidget *parent = nullptr);
~union_modbus();
struct Settings {
#if QT_CONFIG(modbus_serialport)
int parity = QSerialPort::NoParity;
int baud = QSerialPort::Baud115200;
int dataBits = QSerialPort::Data8;
int stopBits = QSerialPort::OneStop;
#endif
int responseTime = 1000;
int numberOfRetries = 3;
};
public slots:
void onReadButtonClicked();
void readModbus();
private slots:
void onConnectButtonClicked();
void onModbusStateChanged(int state);
void onReadReady();
void onWriteButtonClicked();
void onReadWriteButtonClicked();
void onConnectTypeChanged(int);
void onWriteTableChanged(int);
void on_checkPeriodRequest_stateChanged(int arg1);
private:
bool CurrentReadButtonPosition = true;
void initActions();
void statusBarClear();
void ApplySettings();
QTimer RequestPeriodTimer;
QTimer statusBarTimeOut;
Settings m_settings;
QModbusDataUnit readRequest() const;
QModbusDataUnit writeRequest() const;
WriteRegisterModel *writeModel = nullptr;
QModbusReply *lastRequest = nullptr;
QModbusClient *modbusDevice = nullptr;
Ui::union_modbus *ui;
};
#endif // UNION_MODBUS_H

675
union_modbus.ui Normal file
View File

@ -0,0 +1,675 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>union_modbus</class>
<widget class="QWidget" name="union_modbus">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>390</width>
<height>350</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>390</width>
<height>350</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLabel" name="StatusBar">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>15</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QGroupBox" name="groupMain">
<layout class="QGridLayout" name="layoutMain">
<property name="spacing">
<number>3</number>
</property>
<item row="3" column="0">
<layout class="QGridLayout" name="layoutTXAndRX">
<item row="0" column="0">
<widget class="QGroupBox" name="boxRX">
<layout class="QGridLayout" name="layoutRX">
<item row="0" column="0">
<layout class="QGridLayout" name="layoutRXSettings">
<item row="1" column="1">
<widget class="QComboBox" name="comboRXNumberOfValues">
<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>
<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>
<item>
<property name="text">
<string>9</string>
</property>
</item>
<item>
<property name="text">
<string>10</string>
</property>
</item>
<item>
<property name="text">
<string>120</string>
</property>
</item>
<item>
<property name="text">
<string>240</string>
</property>
</item>
<item>
<property name="text">
<string>340</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinRXStartAddress"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelRXStartAddress">
<property name="text">
<string>Start address</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelRXNumberOfValues">
<property name="text">
<string>Number of values</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="checkPeriodRequest">
<property name="text">
<string>Period</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="spinPeriodTime">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>100</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QListWidget" name="readValue"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="boxTX">
<layout class="QGridLayout" name="layoutTX">
<item row="2" column="0">
<widget class="QTableView" name="writeValueTable">
<property name="showGrid">
<bool>true</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderHighlightSections">
<bool>false</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderHighlightSections">
<bool>false</bool>
</attribute>
</widget>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="layoutTXSettings">
<item row="1" column="1">
<widget class="QComboBox" name="comboTXNumberOfValues">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="currentText">
<string>1</string>
</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>
<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>
<item>
<property name="text">
<string>9</string>
</property>
</item>
<item>
<property name="text">
<string>10</string>
</property>
</item>
<item>
<property name="text">
<string>120</string>
</property>
</item>
<item>
<property name="text">
<string>240</string>
</property>
</item>
<item>
<property name="text">
<string>340</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinTXStartAddress">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="labelTXNumberOfValues">
<property name="text">
<string>Number of values</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelTXStartAddress">
<property name="text">
<string>Start address</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboTable">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelTable">
<property name="text">
<string>Table</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QFrame" name="frameSettings">
<layout class="QGridLayout" name="layoutSettings">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="2" column="3">
<widget class="QComboBox" name="comboStopBits">
<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="3" column="2">
<widget class="QLabel" name="labelResponseTimeout">
<property name="text">
<string>Response Timeout:</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="labelStopBits">
<property name="text">
<string>Stop Bits:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="labelBaudRate">
<property name="text">
<string>Baud Rate:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelNumberOfRetries">
<property name="text">
<string>Number of retries:</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="labelParity">
<property name="text">
<string>Parity:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBaudRate">
<property name="currentIndex">
<number>7</number>
</property>
<item>
<property name="text">
<string>1200</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</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="0" column="1">
<widget class="QComboBox" name="conboParity">
<property name="currentIndex">
<number>1</number>
</property>
<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>
<item>
<property name="text">
<string>Space</string>
</property>
</item>
<item>
<property name="text">
<string>Mark</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinNumberOfRetries">
<property name="value">
<number>3</number>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QSpinBox" name="spinResponseTimeout">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>5000</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelDataBits">
<property name="text">
<string>Data Bits:</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QComboBox" name="comboDataBits">
<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>
</layout>
</widget>
</item>
<item row="2" column="0">
<layout class="QGridLayout" name="layoutCMDButtons">
<item row="0" column="1">
<widget class="QPushButton" name="buttonRead">
<property name="text">
<string>Read</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="buttonReadWrite">
<property name="text">
<string>Read-Write</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="buttonWrite">
<property name="text">
<string>Write</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="buttonConnectOrDisconnect">
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QFrame" name="frameSerialTCPPort">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<layout class="QGridLayout" name="layoutSerialTCPPort" rowstretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="labelTypeOfConnection">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLineEdit" name="portEdit"/>
</item>
<item row="0" column="5">
<widget class="QLabel" name="labelServerAddress">
<property name="text">
<string>Server Address:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="connectType">
<item>
<property name="text">
<string>Serial</string>
</property>
</item>
<item>
<property name="text">
<string>TCP</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="labelPort">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
<item row="0" column="4">
<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="0" column="6">
<widget class="QSpinBox" name="serverEdit">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>247</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

335
union_modbus_slave.cpp Normal file
View File

@ -0,0 +1,335 @@
#include "union_modbus_slave.h"
#include "ui_union_modbus_slave.h"
#include <QtSerialBus/QModbusRtuSerialSlave>
#include <QtSerialBus/QModbusTcpServer>
#include <QRegularExpression>
#include <QRegularExpressionValidator>
#include <QStatusBar>
#include <QUrl>
enum ModbusConnection {
Serial,
Tcp
};
union_modbus_slave::union_modbus_slave(QWidget *parent) :
QWidget(parent),
ui(new Ui::union_modbus_slave)
{
ui->setupUi(this);
setupWidgetContainers();
#if QT_CONFIG(modbus_serialport)
ui->connectType->setCurrentIndex(0);
onCurrentConnectTypeChanged(0);
#else
// lock out the serial port option
ui->connectType->setCurrentIndex(1);
onCurrentConnectTypeChanged(1);
ui->connectType->setEnabled(false);
#endif
//m_settingsDialog = new SettingsDialog(this);
initActions();
}
union_modbus_slave::~union_modbus_slave()
{
if (modbusDevice)
modbusDevice->disconnectDevice();
delete modbusDevice;
delete ui;
}
void union_modbus_slave::statusBarClear()
{
statusBarTimeOut.stop();
ui->StatusBar->clear();
}
void union_modbus_slave::initActions()
{
// ui->actionConnect->setEnabled(true);
// ui->actionDisconnect->setEnabled(false);
// ui->actionExit->setEnabled(true);
// ui->actionOptions->setEnabled(true);
connect(ui->connectButton, &QPushButton::clicked,
this, &union_modbus_slave::onConnectButtonClicked);
// connect(ui->actionConnect, &QAction::triggered,
// this, &union_modbus_slave::onConnectButtonClicked);
// connect(ui->actionDisconnect, &QAction::triggered,
// this, &union_modbus_slave::onConnectButtonClicked);
connect(ui->connectType, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &union_modbus_slave::onCurrentConnectTypeChanged);
// connect(ui->actionExit, &QAction::triggered, this, &union_modbus_slave::close);
// connect(ui->actionOptions, &QAction::triggered, m_settingsDialog, &QDialog::show);
statusBarTimeOut.setSingleShot(true);
connect(&statusBarTimeOut, &QTimer::timeout, this, &union_modbus_slave::statusBarClear);
}
void union_modbus_slave::onCurrentConnectTypeChanged(int index)
{
if (modbusDevice) {
modbusDevice->disconnect();
delete modbusDevice;
modbusDevice = nullptr;
}
auto type = static_cast<ModbusConnection>(index);
if (type == Serial) {
#if QT_CONFIG(modbus_serialport)
modbusDevice = new QModbusRtuSerialSlave(this);
#endif
} else if (type == Tcp) {
modbusDevice = new QModbusTcpServer(this);
if (ui->portEdit->text().isEmpty())
ui->portEdit->setText(QLatin1String("127.0.0.1:502"));
}
ui->listenOnlyBox->setEnabled(type == Serial);
if (!modbusDevice) {
ui->connectButton->setDisabled(true);
if (type == Serial)
{
//statusBar()->showMessage(tr("Could not create Modbus ."), 5000);
ui->StatusBar->setText(tr("Could not create Modbus slave."));
statusBarTimeOut.start(5000);
}
else
{
ui->StatusBar->setText(tr("Could not create Modbus server."));
statusBarTimeOut.start(5000);
//statusBar()->showMessage(tr("Could not create Modbus ."), 5000);
}
} else {
QModbusDataUnitMap reg;
reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 100 });
reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 100 });
reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 100 });
reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 100 });
modbusDevice->setMap(reg);
connect(modbusDevice, &QModbusServer::dataWritten,
this, &union_modbus_slave::updateWidgets);
connect(modbusDevice, &QModbusServer::stateChanged,
this, &union_modbus_slave::onStateChanged);
connect(modbusDevice, &QModbusServer::errorOccurred,
this, &union_modbus_slave::handleDeviceError);
connect(ui->listenOnlyBox, &QCheckBox::toggled, this, [this](bool toggled) {
if (modbusDevice)
modbusDevice->setValue(QModbusServer::ListenOnlyMode, toggled);
});
emit ui->listenOnlyBox->toggled(ui->listenOnlyBox->isChecked());
connect(ui->setBusyBox, &QCheckBox::toggled, this, [this](bool toggled) {
if (modbusDevice)
modbusDevice->setValue(QModbusServer::DeviceBusy, toggled ? 0xffff : 0x0000);
});
emit ui->setBusyBox->toggled(ui->setBusyBox->isChecked());
setupDeviceData();
}
}
void union_modbus_slave::handleDeviceError(QModbusDevice::Error newError)
{
if (newError == QModbusDevice::NoError || !modbusDevice)
return;
//statusBar()->showMessage(modbusDevice->errorString(), 5000);
ui->StatusBar->setText(tr("Could not create Modbus master."));
statusBarTimeOut.start(5000);
}
void union_modbus_slave::onConnectButtonClicked()
{
bool intendToConnect = (modbusDevice->state() == QModbusDevice::UnconnectedState);
//statusBar()->clearMessage();
statusBarClear();
if (intendToConnect) {
if (static_cast<ModbusConnection>(ui->connectType->currentIndex()) == Serial) {
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
ui->portEdit->text());
#if QT_CONFIG(modbus_serialport)
short parityStep = ui->parityCombo->currentIndex();
if (parityStep>0) parityStep++;
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
parityStep);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
ui->baudCombo->currentText().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
ui->dataBitsCombo->currentText().toInt());
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
ui->stopBitsCombo->currentText().toInt());
#endif
} else {
const QUrl url = QUrl::fromUserInput(ui->portEdit->text());
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port());
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host());
}
modbusDevice->setServerAddress(ui->serverEdit->text().toInt());
if (!modbusDevice->connectDevice()) {
//statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000);
ui->StatusBar->setText(tr("Connect failed: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
} else {
ui->serverFrame->setEnabled(false);
ui->modbusSettings->setEnabled(false);
// ui->actionConnect->setEnabled(false);
// ui->actionDisconnect->setEnabled(true);
}
} else {
modbusDevice->disconnectDevice();
ui->serverFrame->setEnabled(true);
ui->modbusSettings->setEnabled(true);
// ui->actionConnect->setEnabled(true);
// ui->actionDisconnect->setEnabled(false);
}
}
void union_modbus_slave::onStateChanged(int state)
{
bool connected = (state != QModbusDevice::UnconnectedState);
// ui->actionConnect->setEnabled(!connected);
// ui->actionDisconnect->setEnabled(connected);
if (state == QModbusDevice::UnconnectedState)
ui->connectButton->setText(tr("Connect"));
else if (state == QModbusDevice::ConnectedState)
ui->connectButton->setText(tr("Disconnect"));
}
void union_modbus_slave::coilChanged(int id)
{
QAbstractButton *button = coilButtons.button(id);
bitChanged(id, QModbusDataUnit::Coils, button->isChecked());
}
void union_modbus_slave::discreteInputChanged(int id)
{
QAbstractButton *button = discreteButtons.button(id);
bitChanged(id, QModbusDataUnit::DiscreteInputs, button->isChecked());
}
void union_modbus_slave::bitChanged(int id, QModbusDataUnit::RegisterType table, bool value)
{
if (!modbusDevice)
return;
if (!modbusDevice->setData(table, quint16(id), value))
{
//statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000);
ui->StatusBar->setText(tr("Could not set data: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
}
}
void union_modbus_slave::setRegister(const QString &value)
{
if (!modbusDevice)
return;
const QString objectName = QObject::sender()->objectName();
if (registers.contains(objectName)) {
bool ok = true;
const quint16 id = quint16(QObject::sender()->property("ID").toUInt());
if (objectName.startsWith(QStringLiteral("inReg")))
ok = modbusDevice->setData(QModbusDataUnit::InputRegisters, id, value.toUShort(&ok, 16));
else if (objectName.startsWith(QStringLiteral("holdReg")))
ok = modbusDevice->setData(QModbusDataUnit::HoldingRegisters, id, value.toUShort(&ok, 16));
if (!ok)
{
ui->StatusBar->setText(tr("Could not set register: ") + modbusDevice->errorString());
statusBarTimeOut.start(5000);
//statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(),
// 5000);
}
}
}
void union_modbus_slave::updateWidgets(QModbusDataUnit::RegisterType table, int address, int size)
{
for (int i = 0; i < size; ++i) {
quint16 value;
QString text;
switch (table) {
case QModbusDataUnit::Coils:
modbusDevice->data(QModbusDataUnit::Coils, quint16(address + i), &value);
coilButtons.button(address + i)->setChecked(value);
break;
case QModbusDataUnit::HoldingRegisters:
modbusDevice->data(QModbusDataUnit::HoldingRegisters, quint16(address + i), &value);
registers.value(QStringLiteral("holdReg_%1").arg(address + i))->setText(text
.setNum(value, 16));
break;
default:
break;
}
}
}
// -- private
void union_modbus_slave::setupDeviceData()
{
if (!modbusDevice)
return;
for (quint16 i = 0; i < coilButtons.buttons().count(); ++i)
modbusDevice->setData(QModbusDataUnit::Coils, i, coilButtons.button(i)->isChecked());
for (quint16 i = 0; i < discreteButtons.buttons().count(); ++i) {
modbusDevice->setData(QModbusDataUnit::DiscreteInputs, i,
discreteButtons.button(i)->isChecked());
}
bool ok;
for (QLineEdit *widget : qAsConst(registers)) {
if (widget->objectName().startsWith(QStringLiteral("inReg"))) {
modbusDevice->setData(QModbusDataUnit::InputRegisters, quint16(widget->property("ID").toUInt()),
widget->text().toUShort(&ok, 16));
} else if (widget->objectName().startsWith(QStringLiteral("holdReg"))) {
modbusDevice->setData(QModbusDataUnit::HoldingRegisters, quint16(widget->property("ID").toUInt()),
widget->text().toUShort(&ok, 16));
}
}
}
void union_modbus_slave::setupWidgetContainers()
{
coilButtons.setExclusive(false);
discreteButtons.setExclusive(false);
//Массив указателей на чекбоксы.
//При установке значения в бокс, вызывается функция
//которая высчитывает номер регистра (Значение спинбокса + номер от 0 до 4)
//И передаёт в функцию bitChanged
QRegularExpression regexp(QStringLiteral("coils_(?<ID>\\d+)"));
const QList<QCheckBox *> coils = findChildren<QCheckBox *>(regexp);
for (QCheckBox *cbx : coils)
coilButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt());
connect(&coilButtons, SIGNAL(buttonClicked(int)), this, SLOT(coilChanged(int)));
regexp.setPattern(QStringLiteral("disc_(?<ID>\\d+)"));
const QList<QCheckBox *> discs = findChildren<QCheckBox *>(regexp);
for (QCheckBox *cbx : discs)
discreteButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt());
connect(&discreteButtons, SIGNAL(buttonClicked(int)), this, SLOT(discreteInputChanged(int)));
regexp.setPattern(QLatin1String("(in|hold)Reg_(?<ID>\\d+)"));
const QList<QLineEdit *> qle = findChildren<QLineEdit *>(regexp);
for (QLineEdit *lineEdit : qle) {
registers.insert(lineEdit->objectName(), lineEdit);
lineEdit->setProperty("ID", regexp.match(lineEdit->objectName()).captured("ID").toInt());
lineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9a-f]{0,4}"),
QRegularExpression::CaseInsensitiveOption), this));
connect(lineEdit, &QLineEdit::textChanged, this, &union_modbus_slave::setRegister);
}
}

77
union_modbus_slave.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef UNION_MODBUS_SLAVE_H
#define UNION_MODBUS_SLAVE_H
#include <QWidget>
#include <QButtonGroup>
#include <QModbusServer>
#include <QTimer>
QT_BEGIN_NAMESPACE
class QLineEdit;
namespace Ui {
class union_modbus_slave;
class SettingsDialog;
}
QT_END_NAMESPACE
//namespace Ui {
//class union_modbus_slave;
//}
//class union_modbus_slave : public QWidget
//{
// Q_OBJECT
//public:
// explicit union_modbus_slave(QWidget *parent = nullptr);
// ~union_modbus_slave();
//private:
// Ui::union_modbus_slave *ui;
//};
class SettingsDialog;
class union_modbus_slave : public QWidget
{
Q_OBJECT
public:
explicit union_modbus_slave(QWidget *parent = nullptr);
~union_modbus_slave();
private Q_SLOTS:
void onConnectButtonClicked();
void onStateChanged(int state);
void coilChanged(int id);
void discreteInputChanged(int id);
void bitChanged(int id, QModbusDataUnit::RegisterType table, bool value);
void setRegister(const QString &value);
void updateWidgets(QModbusDataUnit::RegisterType table, int address, int size);
void onCurrentConnectTypeChanged(int);
void handleDeviceError(QModbusDevice::Error newError);
private:
QTimer statusBarTimeOut;
void statusBarClear();
void initActions();
void setupDeviceData();
void setupWidgetContainers();
Ui::union_modbus_slave *ui = nullptr;
QModbusServer *modbusDevice = nullptr;
QButtonGroup coilButtons;
QButtonGroup discreteButtons;
QHash<QString, QLineEdit *> registers;
//SettingsDialog *m_settingsDialog = nullptr;
};
#endif // UNION_MODBUS_SLAVE_H

798
union_modbus_slave.ui Normal file
View File

@ -0,0 +1,798 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>union_modbus_slave</class>
<widget class="QWidget" name="union_modbus_slave">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>408</width>
<height>527</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="12" column="0">
<widget class="QLabel" name="StatusBar">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QGroupBox" name="regModbus">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="2">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="coils_7">
<property name="text">
<string>7</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="coils_8">
<property name="text">
<string>8</string>
</property>
</widget>
</item>
<item row="0" column="4">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Holding Registers</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="coils_0">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLineEdit" name="inReg_0">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Coils</string>
</property>
</widget>
</item>
<item row="1" column="4">
<widget class="QLineEdit" name="holdReg_0">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_13">
<property name="text">
<string>0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="coils_1">
<property name="text">
<string>1</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Input Registers</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Discrete Inputs</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QCheckBox" name="coils_2">
<property name="text">
<string>2</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="coils_3">
<property name="text">
<string>3</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="disc_1">
<property name="text">
<string>1</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="coils_6">
<property name="text">
<string>6</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="coils_4">
<property name="text">
<string>4</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="coils_5">
<property name="text">
<string>5</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="disc_0">
<property name="text">
<string>0</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="coils_9">
<property name="text">
<string>9</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="disc_2">
<property name="text">
<string>2</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="disc_3">
<property name="text">
<string>3</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="disc_4">
<property name="text">
<string>4</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="disc_5">
<property name="text">
<string>5</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="disc_6">
<property name="text">
<string>6</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QCheckBox" name="disc_7">
<property name="text">
<string>7</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="disc_8">
<property name="text">
<string>8</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="disc_9">
<property name="text">
<string>9</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="label_14">
<property name="text">
<string>1</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_15">
<property name="text">
<string>2</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="label_16">
<property name="text">
<string>3</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="label_17">
<property name="text">
<string>4</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="label_18">
<property name="text">
<string>5</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="2">
<widget class="QLabel" name="label_19">
<property name="text">
<string>6</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="8" column="2">
<widget class="QLabel" name="label_20">
<property name="text">
<string>7</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="9" column="2">
<widget class="QLabel" name="label_21">
<property name="text">
<string>8</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="10" column="2">
<widget class="QLabel" name="label_22">
<property name="text">
<string>9</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QLineEdit" name="inReg_1">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QLineEdit" name="inReg_2">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QLineEdit" name="inReg_3">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QLineEdit" name="inReg_4">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="6" column="3">
<widget class="QLineEdit" name="inReg_5">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QLineEdit" name="inReg_6">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="8" column="3">
<widget class="QLineEdit" name="inReg_7">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="9" column="3">
<widget class="QLineEdit" name="inReg_8">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="10" column="3">
<widget class="QLineEdit" name="inReg_9">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="2" column="4">
<widget class="QLineEdit" name="holdReg_1">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLineEdit" name="holdReg_2">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="4" column="4">
<widget class="QLineEdit" name="holdReg_3">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QLineEdit" name="holdReg_4">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QLineEdit" name="holdReg_5">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="7" column="4">
<widget class="QLineEdit" name="holdReg_6">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="8" column="4">
<widget class="QLineEdit" name="holdReg_7">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="9" column="4">
<widget class="QLineEdit" name="holdReg_8">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
<item row="10" column="4">
<widget class="QLineEdit" name="holdReg_9">
<property name="placeholderText">
<string>Hexadecimal A-F, a-f, 0-9.</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="serverSettingsBox">
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="2" column="0">
<widget class="QFrame" name="modbusSettings">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="3">
<widget class="QLabel" name="label_5">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Data Bits:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="4">
<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="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Baud Rate:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Stop Bits:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Parity:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="baudCombo">
<property name="currentIndex">
<number>7</number>
</property>
<item>
<property name="text">
<string>1200</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</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="0" column="4">
<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="2">
<widget class="QComboBox" name="parityCombo">
<property name="currentIndex">
<number>1</number>
</property>
<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>
<item>
<property name="text">
<string>Space</string>
</property>
</item>
<item>
<property name="text">
<string>Mark</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="0">
<layout class="QGridLayout" name="serverModeLayout">
<item row="0" column="3">
<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="0" column="2">
<widget class="QCheckBox" name="listenOnlyBox">
<property name="text">
<string>Set server listen only</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="setBusyBox">
<property name="text">
<string>Set server busy</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QPushButton" name="connectButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>90</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Connect</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="serverTurnOnLayout">
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="0">
<widget class="QFrame" name="serverFrame">
<layout class="QGridLayout" name="serverPort">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>3</number>
</property>
<item row="0" column="3">
<widget class="QLineEdit" name="portEdit"/>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="connectType">
<item>
<property name="text">
<string>Serial</string>
</property>
</item>
<item>
<property name="text">
<string>TCP</string>
</property>
</item>
</widget>
</item>
<item row="0" column="4">
<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 row="0" column="6">
<widget class="QSpinBox" name="serverEdit">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>247</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Server Address:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Port:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

3280
unioncom.cpp Normal file

File diff suppressed because it is too large Load Diff

316
unioncom.h Normal file
View File

@ -0,0 +1,316 @@
#ifndef UNIONCOM_H
#define UNIONCOM_H
#include <QWidget>
#include <QStandardItemModel>
#include <QTableWidgetItem>
#include "ProjectSettings.h"
#include "ui_unioncom.h"
#include <QEvent>
#define microsecondToMilliseconds(x) x/1000%1000
#define microsecondToSeconds(x) x/1000/1000%60
#define microsecondToMinutes(x) x/1000/1000/60%60
#define microsecondToHours(x) x/1000/1000/60/60
extern "C" __declspec(dllexport) QWidget* init(QWidget *parent);
class MyEvent : public QEvent
{
public:
MyEvent(const QString& message, const short msgType) : QEvent(QEvent::User) {_message = message; _msgType = msgType;}
~MyEvent() {}
QString message() const {return _message;}
short msgType() const {return _msgType;}
private:
QString _message;
short _msgType;
};
namespace Ui {
class UnionCOM;
}
class RxCanEvent : public QEvent
{
public:
static const QEvent::Type EventType = static_cast<QEvent::Type>(2000);
RxCanEvent(const SLCAN_MESSAGE& msg, const QTime timeEvent, const unsigned long long time_stamp) : QEvent(RxCanEvent::EventType) {_msg = msg; _time = timeEvent; _time_stamp = time_stamp;}
~RxCanEvent(){}
SLCAN_MESSAGE msg() const {return _msg;}
QTime time() const {return _time;}
unsigned long long time_stamp() const {return _time_stamp;}
private:
SLCAN_MESSAGE _msg;
QTime _time;
unsigned long long _time_stamp;
};
class UnionCOM : public QWidget
{
Q_OBJECT
public:
struct mcrs_kit{
Qt::CheckState EID;
DWORD ID;
Qt::CheckState RTR;
Qt::CheckState IsHEX;
byte DLC;
QString Name;
QString Mcrs;
int Count;
Qt::CheckState IsPeriod;
int Period;
} MacrosMain[15];
bool InitMcrsSetting = TRUE;
DWORD ID; //идентификатор устройства
SLCAN_MESSAGE outMsg; //буфер для отправки сообщения
SLCAN_MESSAGE inputMsg[FRAMES]; //буфер для приёма сообщения
SLCAN_EVENT inputEvents[FRAMES];
HSLCAN device;
SLCAN_BITRATE br;
DWORD cntrInput;
SLCAN_STATE DeviceState;
void Connect_Notification();
void Disconnect_Notification();
void Emergency_Disconnect_Notification();
void AfterDisconnection();
void AfterConnection();
void pushMcrs_CAN(int index);
void sendCMD_CAN();
void sendCMDHEX_CAN();
void sendFile_CAN();
void pushMcrs_RS(int index);
void sendCMD_RS();
void sendCMDHEX_RS();
void sendFile_RS();
void TimeToReadEvents();
void gotors();
explicit UnionCOM(QWidget *parent = nullptr);
~UnionCOM();
void startMCRSTX(int index);
bool TimeToStopCANRead;
bool canReadingInThread;
void stopCANReadThread();
bool notTimeToStopPeriodMcrs[15];
private slots:
void rxErrorTimer_anotherSec();
void txErrorTimer_anotherSec();
void on_cboxTypeConnection_currentIndexChanged(int index);
void on_buttonConnect_clicked();
void on_buttonDisconnect_clicked();
void on_buttonSendCMD_clicked();
void on_buttonSendCMDHex_clicked();
void on_buttonSendFile_clicked();
// void on_buttonSDCard_clicked();
// void on_buttonReturnToBootloader_clicked();
void on_buttonLoadFile_clicked();
void on_boxDataCount_currentIndexChanged(int index);
void on_buttonSetMcrs_clicked();
void on_buttonStopMacros_01_clicked() {stopMcrs(1);};
void on_buttonStopMacros_02_clicked() {stopMcrs(2);};
void on_buttonStopMacros_03_clicked() {stopMcrs(3);};
void on_buttonStopMacros_04_clicked() {stopMcrs(4);};
void on_buttonStopMacros_05_clicked() {stopMcrs(5);};
void on_buttonStopMacros_06_clicked() {stopMcrs(6);};
void on_buttonStopMacros_07_clicked() {stopMcrs(7);};
void on_buttonStopMacros_08_clicked() {stopMcrs(8);};
void on_buttonStopMacros_09_clicked() {stopMcrs(9);};
void on_buttonStopMacros_10_clicked() {stopMcrs(10);};
void on_buttonStopMacros_11_clicked() {stopMcrs(11);};
void on_buttonStopMacros_12_clicked() {stopMcrs(12);};
void on_buttonStopMacros_13_clicked() {stopMcrs(13);};
void on_buttonStopMacros_14_clicked() {stopMcrs(14);};
void on_buttonStopMacros_15_clicked() {stopMcrs(15);};
void on_buttonMacros_01_clicked() {isTxIdle_MCRS(1);};
void on_buttonMacros_02_clicked() {isTxIdle_MCRS(2);};
void on_buttonMacros_03_clicked() {isTxIdle_MCRS(3);};
void on_buttonMacros_04_clicked() {isTxIdle_MCRS(4);};
void on_buttonMacros_05_clicked() {isTxIdle_MCRS(5);};
void on_buttonMacros_06_clicked() {isTxIdle_MCRS(6);};
void on_buttonMacros_07_clicked() {isTxIdle_MCRS(7);};
void on_buttonMacros_08_clicked() {isTxIdle_MCRS(8);};
void on_buttonMacros_09_clicked() {isTxIdle_MCRS(9);};
void on_buttonMacros_10_clicked() {isTxIdle_MCRS(10);};
void on_buttonMacros_11_clicked() {isTxIdle_MCRS(11);};
void on_buttonMacros_12_clicked() {isTxIdle_MCRS(12);};
void on_buttonMacros_13_clicked() {isTxIdle_MCRS(13);};
void on_buttonMacros_14_clicked() {isTxIdle_MCRS(14);};
void on_buttonMacros_15_clicked() {isTxIdle_MCRS(15);};
void on_buttonSaveMcrsKit_clicked();
void on_buttonLoadMcrsKit_clicked();
void on_buttonClearLogger_clicked();
void on_checkModbusEnabled_stateChanged(int arg1);
void stepToStartCMDTX();
void stepToStartCMDHEXTX();
void stepToStartSendFile();
void on_buttonRXErrorCountErase_clicked();
void on_buttonTXErrorCountErase_clicked();
void appendToLogger(QString msgToLogger);
void on_buttonCRC_clicked();
void on_checkHEXRTR_stateChanged(int arg1);
void on_checkHEXEID_stateChanged(int arg1);
void on_lineHEXID_textChanged(const QString &arg1);
void on_pushButton_clicked();
void on_requestBox_stateChanged(int arg1);
signals:
void isTxFinished();
void notifToLogger(QString msgToLogger);
private:
QString errors_RS(int ConnectionError);
bool event(QEvent* event);
int OldCountOfRXError = 0;
int OldCountOfTXError = 0;
short counterOfLoggerMSG = 0;
void deleteTopLine();
int SLCAN_MODE;
void isTxIdle_MCRS(int index);
void isTxIdle_CMD();
void isTxIdle_CMDHEX();
void isTxIdle_FILE();
void startSendFile();
void startCMDTX();
void startCMDHEXTX();
bool isIdle = TRUE;
bool userTXInterruption = FALSE;
void stopMcrs(int index);
void (UnionCOM::*ptrButtonMcrs[15])(){&UnionCOM::on_buttonMacros_01_clicked,
&UnionCOM::on_buttonMacros_02_clicked, &UnionCOM::on_buttonMacros_03_clicked,
&UnionCOM::on_buttonMacros_04_clicked, &UnionCOM::on_buttonMacros_05_clicked,
&UnionCOM::on_buttonMacros_06_clicked, &UnionCOM::on_buttonMacros_07_clicked,
&UnionCOM::on_buttonMacros_08_clicked, &UnionCOM::on_buttonMacros_09_clicked,
&UnionCOM::on_buttonMacros_10_clicked, &UnionCOM::on_buttonMacros_11_clicked,
&UnionCOM::on_buttonMacros_12_clicked, &UnionCOM::on_buttonMacros_13_clicked,
&UnionCOM::on_buttonMacros_14_clicked, &UnionCOM::on_buttonMacros_15_clicked};
bool CheckFile(qint64 StatusOfRead, char *buffer, qint64 MaxByteToRead);
unsigned int Counter_of_suc_transmit=0;
unsigned int TX_error_counter = 0;
QLineEdit *HEXByteField[8];
QPushButton *McrsButtons[15];
QPushButton *McrsStopButtons[15];
void readData();
QTimer *TimerReadEvents;
QTimer *TransferEndTimer;
QTimer *McrsPeriodTransfer[15];
QTimer *timeFromTXErrorClear;
QTimer *timeFromRXErrorClear;
void rxErrorTimer_clear();
void txErrorTimer_clear();
BOOL UsartFileLoading = 0;
QString fileName;
QString BufferForLoadFile;
void EndOfUSARTLoadFile();
void clearMSG();
BYTE writeMSG();
void Device_Error(PSLCAN_STATE DeviceState);
void openCAN();
void Init();
void SettingWidget();
void openSerialPort();
QLabel *m_status = nullptr;
QSerialPort *m_serial = nullptr;
void tableInit();
QStandardItemModel* RxCanModel;
QStandardItemModel* RxCanRequesterModel;
union Requester_ID{
struct RequesterStandardID
{
uint Device:8;
uint SensorID:11;
uint SensorType:5;
uint DataType:4;
uint Route:1;
}Standard;
struct RequesterModbusID
{
uint Device:8;
uint CountReg:8;
uint StrAdr:8;
uint DataType:4;
uint Route:1;
}Modbus;
uint ID_All:29;
}RequesterID;
Ui::UnionCOM *ui;
};
#endif // UNIONCOM_H

3197
unioncom.ui Normal file

File diff suppressed because it is too large Load Diff

188
usettingsrs.cpp Normal file
View File

@ -0,0 +1,188 @@
#include "usettingsrs.h"
#include "ui_usettingsrs.h"
#include <QIntValidator>
#include <QLineEdit>
#include "QtSerialPort/QSerialPortInfo"
static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");
USettingsRS::USettingsRS(QWidget *parent) :
QWidget(parent),
m_ui(new Ui::USettingsRS),
m_intValidator(new QIntValidator(0, 4000000, this))
{
m_ui->setupUi(this);
m_ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert);
connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &USettingsRS::showPortInfo);
connect(m_ui->baudRateBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &USettingsRS::checkCustomBaudRatePolicy);
connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &USettingsRS::checkCustomDevicePathPolicy);
fillPortsParameters();
fillPortsInfo();
updateSettings();
}
USettingsRS::~USettingsRS()
{
delete m_ui;
}
void USettingsRS::showPortInfo(int idx)
{
if (idx == -1)
return;
const QStringList list = m_ui->serialPortInfoListBox->itemData(idx).toStringList();
m_ui->descriptionLabel->setText(tr("Description: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString)));
m_ui->descriptionLabel->setToolTip(QString("Description: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString)));
m_ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString)));
m_ui->manufacturerLabel->setToolTip((QString("Manufacturer: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString))));
m_ui->serialNumberLabel->setText(tr("Serial number: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString)));
m_ui->serialNumberLabel->setToolTip(QString("Serial number: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString)));
m_ui->locationLabel->setText(tr("Location: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString)));
m_ui->locationLabel->setToolTip(QString("Location: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString)));
m_ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString)));
m_ui->vidLabel->setToolTip(QString("Vendor Identifier: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString)));
m_ui->pidLabel->setText(tr("Product Identifier: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString)));
m_ui->pidLabel->setToolTip(QString("Product Identifier: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString)));
}
void USettingsRS::apply()
{
updateSettings();
hide();
}
void USettingsRS::device_connect()
{
updateSettings();
}
void USettingsRS::checkCustomBaudRatePolicy(int idx)
{
const bool isCustomBaudRate = !m_ui->baudRateBox->itemData(idx).isValid();
m_ui->baudRateBox->setEditable(isCustomBaudRate);
if (isCustomBaudRate) {
m_ui->baudRateBox->clearEditText();
QLineEdit *edit = m_ui->baudRateBox->lineEdit();
edit->setValidator(m_intValidator);
}
}
void USettingsRS::checkCustomDevicePathPolicy(int idx)
{
const bool isCustomPath = !m_ui->serialPortInfoListBox->itemData(idx).isValid();
m_ui->serialPortInfoListBox->setEditable(isCustomPath);
if (isCustomPath)
m_ui->serialPortInfoListBox->clearEditText();
}
void USettingsRS::fillPortsParameters()
{
m_ui->baudRateBox->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
m_ui->baudRateBox->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
m_ui->baudRateBox->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
m_ui->baudRateBox->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
m_ui->baudRateBox->addItem(tr("Custom"));
m_ui->dataBitsBox->addItem(QStringLiteral("5"), QSerialPort::Data5);
m_ui->dataBitsBox->addItem(QStringLiteral("6"), QSerialPort::Data6);
m_ui->dataBitsBox->addItem(QStringLiteral("7"), QSerialPort::Data7);
m_ui->dataBitsBox->addItem(QStringLiteral("8"), QSerialPort::Data8);
m_ui->dataBitsBox->setCurrentIndex(3);
m_ui->parityBox->addItem(tr("None"), QSerialPort::NoParity);
m_ui->parityBox->addItem(tr("Even"), QSerialPort::EvenParity);
m_ui->parityBox->addItem(tr("Odd"), QSerialPort::OddParity);
m_ui->parityBox->addItem(tr("Mark"), QSerialPort::MarkParity);
m_ui->parityBox->addItem(tr("Space"), QSerialPort::SpaceParity);
m_ui->stopBitsBox->addItem(QStringLiteral("1"), QSerialPort::OneStop);
#ifdef Q_OS_WIN
m_ui->stopBitsBox->addItem(tr("1.5"), QSerialPort::OneAndHalfStop);
#endif
m_ui->stopBitsBox->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
m_ui->flowControlBox->addItem(tr("None"), QSerialPort::NoFlowControl);
m_ui->flowControlBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl);
m_ui->flowControlBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl);
}
void USettingsRS::fillPortsInfo()
{
m_ui->serialPortInfoListBox->clear();
QString description;
QString manufacturer;
QString serialNumber;
const auto infos = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &info : infos) {
QStringList list;
description = info.description();
manufacturer = info.manufacturer();
serialNumber = info.serialNumber();
list << info.portName()
<< (!description.isEmpty() ? description : blankString)
<< (!manufacturer.isEmpty() ? manufacturer : blankString)
<< (!serialNumber.isEmpty() ? serialNumber : blankString)
<< info.systemLocation()
<< (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : blankString)
<< (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : blankString);
m_ui->serialPortInfoListBox->addItem(list.first(), list);
}
m_ui->serialPortInfoListBox->addItem(tr("Custom"));
}
void USettingsRS::updateSettings()
{
m_currentSettings.name = m_ui->serialPortInfoListBox->currentText();
if (m_ui->baudRateBox->currentIndex() == 4) {
m_currentSettings.baudRate = m_ui->baudRateBox->currentText().toInt();
} else {
m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>(
m_ui->baudRateBox->itemData(m_ui->baudRateBox->currentIndex()).toInt());
}
m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate);
m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>(
m_ui->dataBitsBox->itemData(m_ui->dataBitsBox->currentIndex()).toInt());
m_currentSettings.stringDataBits = m_ui->dataBitsBox->currentText();
m_currentSettings.parity = static_cast<QSerialPort::Parity>(
m_ui->parityBox->itemData(m_ui->parityBox->currentIndex()).toInt());
m_currentSettings.stringParity = m_ui->parityBox->currentText();
m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>(
m_ui->stopBitsBox->itemData(m_ui->stopBitsBox->currentIndex()).toInt());
m_currentSettings.stringStopBits = m_ui->stopBitsBox->currentText();
m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>(
m_ui->flowControlBox->itemData(m_ui->flowControlBox->currentIndex()).toInt());
m_currentSettings.stringFlowControl = m_ui->flowControlBox->currentText();
}
void USettingsRS::AfterConnection()
{
m_ui->parametersBox->setEnabled(false);
m_ui->selectBox->setEnabled(false);
}
void USettingsRS::AfterDisconnection()
{
m_ui->parametersBox->setEnabled(true);
m_ui->selectBox->setEnabled(true);
}

58
usettingsrs.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef USETTINGSRS_H
#define USETTINGSRS_H
#include <QWidget>
#include "QtSerialPort/QSerialPort"
namespace Ui {
class USettingsRS;
}
class QIntValidator;
class USettingsRS : public QWidget
{
Q_OBJECT
public:
void AfterDisconnection();
void AfterConnection();
struct Settings {
QString name;
qint32 baudRate;
QString stringBaudRate;
QSerialPort::DataBits dataBits;
QString stringDataBits;
QSerialPort::Parity parity;
QString stringParity;
QSerialPort::StopBits stopBits;
QString stringStopBits;
QSerialPort::FlowControl flowControl;
QString stringFlowControl;
bool localEchoEnabled;
};
explicit USettingsRS(QWidget *parent = nullptr);
~USettingsRS();
Settings m_currentSettings;
void device_connect();
private slots:
void showPortInfo(int idx);
void apply();
void checkCustomBaudRatePolicy(int idx);
void checkCustomDevicePathPolicy(int idx);
private:
void fillPortsParameters();
void fillPortsInfo();
void updateSettings();
private:
Ui::USettingsRS *m_ui = nullptr;
QIntValidator *m_intValidator = nullptr;
};
#endif // USETTINGSRS_H

175
usettingsrs.ui Normal file
View File

@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>USettingsRS</class>
<widget class="QWidget" name="USettingsRS">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>201</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>201</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QGroupBox" name="selectBox">
<property name="title">
<string>Select Serial Port</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="serialPortInfoListBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="descriptionLabel">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="manufacturerLabel">
<property name="text">
<string>Manufacturer:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="serialNumberLabel">
<property name="text">
<string>Serial number:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="locationLabel">
<property name="text">
<string>Location:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="vidLabel">
<property name="text">
<string>Vendor ID:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="pidLabel">
<property name="text">
<string>Product ID:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="SelectParameters">
<item>
<widget class="QGroupBox" name="parametersBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Select Parameters</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QLabel" name="parityLabel">
<property name="text">
<string>Parity:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="stopBitsLabel">
<property name="text">
<string>Stop bits:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="stopBitsBox"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="dataBitsBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="flowControlLabel">
<property name="text">
<string>Flow control:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="baudRateBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="baudRateLabel">
<property name="text">
<string>BaudRate:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="dataBitsLabel">
<property name="text">
<string>Data bits:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="parityBox"/>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="flowControlBox"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

167
writeregistermodel.cpp Normal file
View File

@ -0,0 +1,167 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the QtSerialBus module.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "writeregistermodel.h"
enum { NumColumn = 0, CoilsColumn = 1, HoldingColumn = 2, ColumnCount = 3, RowCount = 100 };
WriteRegisterModel::WriteRegisterModel(QObject *parent)
: QAbstractTableModel(parent),
m_coils(RowCount, false), m_holdingRegisters(RowCount, 0u)
{
}
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() == CoilsColumn && role == Qt::CheckStateRole) // coils
return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked;
if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers
return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16));
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("#");
case CoilsColumn:
return QStringLiteral("Coils ");
case HoldingColumn:
return QStringLiteral("Holding Registers");
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, 16);
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();
}

88
writeregistermodel.h Normal file
View File

@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the QtSerialBus module.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef WRITEREGISTERMODEL_H
#define WRITEREGISTERMODEL_H
#include <QAbstractItemModel>
#include <QBitArray>
#include <QObject>
class WriteRegisterModel : public QAbstractTableModel
{
Q_OBJECT
public:
WriteRegisterModel(QObject *parent = nullptr);
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;
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;
};
#endif // WRITEREGISTERMODEL_H