@@ -30,6 +30,7 @@ SOURCES += \ | |||||
main.cpp \ | main.cpp \ | ||||
mainwindow.cpp \ | mainwindow.cpp \ | ||||
modbusmanager.cpp \ | modbusmanager.cpp \ | ||||
modbusworker.cpp \ | |||||
mygraphicsview.cpp \ | mygraphicsview.cpp \ | ||||
myscene.cpp \ | myscene.cpp \ | ||||
plc.cpp \ | plc.cpp \ | ||||
@@ -48,6 +49,7 @@ HEADERS += \ | |||||
light.h \ | light.h \ | ||||
mainwindow.h \ | mainwindow.h \ | ||||
modbusmanager.h \ | modbusmanager.h \ | ||||
modbusworker.h \ | |||||
mygraphicsview.h \ | mygraphicsview.h \ | ||||
myscene.h \ | myscene.h \ | ||||
plc.h \ | plc.h \ | ||||
@@ -1,6 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | ||||
<!DOCTYPE QtCreatorProject> | <!DOCTYPE QtCreatorProject> | ||||
<!-- Written by QtCreator 4.11.1, 2025-08-13T11:12:10. --> | |||||
<!-- Written by QtCreator 4.11.1, 2025-08-13T17:04:04. --> | |||||
<qtcreator> | <qtcreator> | ||||
<data> | <data> | ||||
<variable>EnvironmentId</variable> | <variable>EnvironmentId</variable> | ||||
@@ -8,6 +8,10 @@ int main(int argc, char *argv[]) | |||||
// 设置应用程序信息 | // 设置应用程序信息 | ||||
QApplication::setApplicationName("PLC梯形图编辑器"); | QApplication::setApplicationName("PLC梯形图编辑器"); | ||||
QApplication::setApplicationVersion("1.0"); | QApplication::setApplicationVersion("1.0"); | ||||
qRegisterMetaType<QSerialPort::BaudRate>("QSerialPort::BaudRate"); | |||||
qRegisterMetaType<QSerialPort::DataBits>("QSerialPort::DataBits"); | |||||
qRegisterMetaType<QSerialPort::Parity>("QSerialPort::Parity"); | |||||
qRegisterMetaType<QSerialPort::StopBits>("QSerialPort::StopBits"); | |||||
MainWindow w; | MainWindow w; | ||||
w.resize(1000, 600); | w.resize(1000, 600); | ||||
@@ -13,6 +13,7 @@ | |||||
#include <QAction> | #include <QAction> | ||||
#include <QFileDialog> | #include <QFileDialog> | ||||
#include "creatitem.h" | #include "creatitem.h" | ||||
#include <QDebug> | |||||
MainWindow::MainWindow(QWidget *parent) | MainWindow::MainWindow(QWidget *parent) | ||||
: QMainWindow(parent) | : QMainWindow(parent) | ||||
@@ -56,6 +57,12 @@ MainWindow::MainWindow(QWidget *parent) | |||||
connect(modbusManager, &ModbusManager::connectionStatusChanged, | connect(modbusManager, &ModbusManager::connectionStatusChanged, | ||||
this, &MainWindow::updateConnectionStatus); | this, &MainWindow::updateConnectionStatus); | ||||
connect(modbusManager, &ModbusManager::registerValueUpdated, | |||||
registerManager, &RegisterManager::updateRegisterValue); | |||||
connect(modbusManager, &ModbusManager::errorOccurred, | |||||
this, [this](const QString& error) { | |||||
ui->textEdit->append("错误: " + error); | |||||
}); | |||||
// connect(modbusManager, &ModbusManager::connectionStatusChanged, | // connect(modbusManager, &ModbusManager::connectionStatusChanged, | ||||
// this, &PLC::updateConnectionStatus); | // this, &PLC::updateConnectionStatus); | ||||
// connect(modbusManager, &ModbusManager::errorOccurred, | // connect(modbusManager, &ModbusManager::errorOccurred, | ||||
@@ -1,58 +1,53 @@ | |||||
#include "modbusmanager.h" | #include "modbusmanager.h" | ||||
#include <QModbusDataUnit> | |||||
#include <QDebug> | |||||
#include <QThread> | |||||
ModbusManager::ModbusManager(RegisterManager* regManager, QObject *parent) | ModbusManager::ModbusManager(RegisterManager* regManager, QObject *parent) | ||||
: QObject(parent), registerManager(regManager) | |||||
: QObject(parent) | |||||
{ | { | ||||
modbusDevice = new QModbusRtuSerialMaster(this); | |||||
modbusThread = new QThread(this); | |||||
worker = new ModbusWorker(regManager); | |||||
pollTimer = new QTimer(this); | pollTimer = new QTimer(this); | ||||
worker->moveToThread(modbusThread); | |||||
connect(modbusDevice, &QModbusClient::errorOccurred, this, | |||||
[this](QModbusDevice::Error) { | |||||
emit errorOccurred(modbusDevice->errorString()); | |||||
}); | |||||
// 连接工作线程信号 | |||||
connect(worker, &ModbusWorker::connectionStatusChanged, | |||||
this, &ModbusManager::connectionStatusChanged); | |||||
connect(worker, &ModbusWorker::errorOccurred, | |||||
this, &ModbusManager::errorOccurred); | |||||
connect(worker, &ModbusWorker::registerValueUpdated, | |||||
this, &ModbusManager::registerValueUpdated); | |||||
connect(pollTimer, &QTimer::timeout, this, &ModbusManager::readRegisters); | connect(pollTimer, &QTimer::timeout, this, &ModbusManager::readRegisters); | ||||
connect(modbusThread, &QThread::started, worker, &ModbusWorker::initModbusDevice); | |||||
modbusThread->start(); | |||||
} | } | ||||
ModbusManager::~ModbusManager() | ModbusManager::~ModbusManager() | ||||
{ | { | ||||
stopSimulation(); | |||||
disconnectDevice(); | |||||
modbusThread->quit(); | |||||
modbusThread->wait(); | |||||
delete worker; | |||||
pollTimer->stop(); | |||||
} | } | ||||
bool ModbusManager::connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate, | |||||
QSerialPort::DataBits dataBits, | |||||
QSerialPort::Parity parity, | |||||
QSerialPort::StopBits stopBits) | |||||
void ModbusManager::connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate, | |||||
QSerialPort::DataBits dataBits, | |||||
QSerialPort::Parity parity, | |||||
QSerialPort::StopBits stopBits) | |||||
{ | { | ||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
disconnectDevice(); | |||||
} | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, portName); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); | |||||
if (!modbusDevice->connectDevice()) { | |||||
emit errorOccurred(tr("连接失败: %1").arg(modbusDevice->errorString())); | |||||
return false; | |||||
} | |||||
emit connectionStatusChanged(true); | |||||
return true; | |||||
QMetaObject::invokeMethod(worker, "connectToDevice", Qt::QueuedConnection, | |||||
Q_ARG(QString, portName), | |||||
Q_ARG(QSerialPort::BaudRate, baudRate), | |||||
Q_ARG(QSerialPort::DataBits, dataBits), | |||||
Q_ARG(QSerialPort::Parity, parity), | |||||
Q_ARG(QSerialPort::StopBits, stopBits)); | |||||
} | } | ||||
void ModbusManager::disconnectDevice() | void ModbusManager::disconnectDevice() | ||||
{ | { | ||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
modbusDevice->disconnectDevice(); | |||||
emit connectionStatusChanged(false); | |||||
} | |||||
QMetaObject::invokeMethod(worker, "disconnectDevice", Qt::QueuedConnection); | |||||
} | } | ||||
void ModbusManager::startSimulation(int interval) | void ModbusManager::startSimulation(int interval) | ||||
@@ -65,123 +60,14 @@ void ModbusManager::stopSimulation() | |||||
pollTimer->stop(); | pollTimer->stop(); | ||||
} | } | ||||
void ModbusManager::readRegisters() | |||||
{ | |||||
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | |||||
return; | |||||
// 获取所有已注册的寄存器ID | |||||
QStringList regIds = registerManager->getAllRegisteredRegisters(); | |||||
QMap<QString, QSet<int>> regMap; // 按类型分组存储地址 | |||||
// 分组寄存器地址 | |||||
for (const QString &id : regIds) { | |||||
if (id.startsWith("D") || id.startsWith("M")) { | |||||
bool ok; | |||||
int addr = id.mid(1).toInt(&ok); | |||||
if (ok && addr >= 0 && addr <= 4000) { | |||||
regMap[id.left(1)].insert(addr); | |||||
} | |||||
} | |||||
} | |||||
// 读取D寄存器 (保持寄存器) | |||||
if (regMap.contains("D")) { | |||||
readRegisterGroup(QModbusDataUnit::HoldingRegisters, regMap["D"].values()); | |||||
} | |||||
// 读取M寄存器 (线圈) | |||||
if (regMap.contains("M")) { | |||||
readRegisterGroup(QModbusDataUnit::Coils, regMap["M"].values()); | |||||
} | |||||
} | |||||
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses) | |||||
{ | |||||
if (addresses.isEmpty()) return; | |||||
QList<int> sortedAddrs = addresses; | |||||
std::sort(sortedAddrs.begin(), sortedAddrs.end()); | |||||
// 合并连续地址范围 | |||||
int start = sortedAddrs.first(); | |||||
int end = start; | |||||
for (int i = 1; i < sortedAddrs.size(); i++) { | |||||
if (sortedAddrs[i] == end + 1) { | |||||
end = sortedAddrs[i]; | |||||
} else { | |||||
readAddressRange(type, start, end - start + 1); | |||||
start = sortedAddrs[i]; | |||||
end = start; | |||||
} | |||||
} | |||||
readAddressRange(type, start, end - start + 1); | |||||
} | |||||
void ModbusManager::readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
{ | |||||
const int MAX_REG_PER_REQUEST = 120; | |||||
for (int offset = 0; offset < count; offset += MAX_REG_PER_REQUEST) { | |||||
int readCount = qMin(MAX_REG_PER_REQUEST, count - offset); | |||||
QModbusDataUnit unit(type, startAddr + offset, readCount); | |||||
if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | |||||
QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | |||||
pendingRequests[reply] = regType; | |||||
connect(reply, &QModbusReply::finished, this, &ModbusManager::processModbusReply); | |||||
} | |||||
} | |||||
} | |||||
void ModbusManager::processModbusReply() | |||||
void ModbusManager::writeRegister(const QString& registerId, quint16 value) | |||||
{ | { | ||||
auto *reply = qobject_cast<QModbusReply*>(sender()); | |||||
if (!reply) return; | |||||
if (reply->error() == QModbusDevice::NoError) { | |||||
const QModbusDataUnit unit = reply->result(); | |||||
QString regType = pendingRequests.value(reply); | |||||
int startAddr = unit.startAddress(); | |||||
for (uint i = 0; i < unit.valueCount(); i++) { | |||||
int regAddr = startAddr + i; | |||||
quint16 value = unit.value(i); | |||||
QString regId = QString("%1%2").arg(regType).arg(regAddr); | |||||
// 更新图元状态 | |||||
registerManager->updateRegisterValue(regId, value); | |||||
} | |||||
} else { | |||||
emit errorOccurred(tr("Modbus错误: %1").arg(reply->errorString())); | |||||
} | |||||
pendingRequests.remove(reply); | |||||
reply->deleteLater(); | |||||
QMetaObject::invokeMethod(worker, "writeRegister", Qt::QueuedConnection, | |||||
Q_ARG(QString, registerId), | |||||
Q_ARG(quint16, value)); | |||||
} | } | ||||
void ModbusManager::writeRegister(const QString& registerId, quint16 value) | |||||
void ModbusManager::readRegisters() | |||||
{ | { | ||||
if (registerId.isEmpty()) return; | |||||
QModbusDataUnit::RegisterType regType = registerId.startsWith("D") | |||||
? QModbusDataUnit::HoldingRegisters | |||||
: QModbusDataUnit::Coils; | |||||
int regAddr = registerId.mid(1).toInt(); | |||||
QModbusDataUnit writeUnit(regType, regAddr, 1); | |||||
writeUnit.setValue(0, value); | |||||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, slaveAddress)) { | |||||
connect(reply, &QModbusReply::finished, this, [this, reply]() { | |||||
if (reply->error() != QModbusDevice::NoError) { | |||||
emit errorOccurred(tr("写入失败: %1").arg(reply->errorString())); | |||||
} | |||||
reply->deleteLater(); | |||||
}); | |||||
} | |||||
QMetaObject::invokeMethod(worker, "readRegisters", Qt::QueuedConnection); | |||||
} | } |
@@ -2,11 +2,10 @@ | |||||
#define MODBUSMANAGER_H | #define MODBUSMANAGER_H | ||||
#include <QObject> | #include <QObject> | ||||
#include <QModbusRtuSerialMaster> | |||||
#include <QSerialPort> | |||||
#include <QTimer> | |||||
#include <QMap> | |||||
#include "registermanager.h" | |||||
#include "modbusworker.h" | |||||
class RegisterManager; | |||||
class QThread; | |||||
class ModbusManager : public QObject | class ModbusManager : public QObject | ||||
{ | { | ||||
@@ -16,7 +15,7 @@ public: | |||||
~ModbusManager(); | ~ModbusManager(); | ||||
// 串口连接管理 | // 串口连接管理 | ||||
bool connectToDevice(const QString& portName, | |||||
void connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate = QSerialPort::Baud9600, | QSerialPort::BaudRate baudRate = QSerialPort::Baud9600, | ||||
QSerialPort::DataBits dataBits = QSerialPort::Data8, | QSerialPort::DataBits dataBits = QSerialPort::Data8, | ||||
QSerialPort::Parity parity = QSerialPort::NoParity, | QSerialPort::Parity parity = QSerialPort::NoParity, | ||||
@@ -32,24 +31,20 @@ public: | |||||
void writeRegister(const QString& registerId, quint16 value); | void writeRegister(const QString& registerId, quint16 value); | ||||
// 设置从站地址 | // 设置从站地址 | ||||
void setSlaveAddress(int address) { slaveAddress = address; } | |||||
// void setSlaveAddress(int address) { worker->setSlaveAddress(address); } | |||||
signals: | signals: | ||||
void connectionStatusChanged(bool connected); | void connectionStatusChanged(bool connected); | ||||
void errorOccurred(const QString& error); | void errorOccurred(const QString& error); | ||||
void registerValueUpdated(const QString& registerId, quint16 value); | |||||
private slots: | |||||
public slots: | |||||
void readRegisters(); | void readRegisters(); | ||||
void processModbusReply(); | |||||
void readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses); | |||||
void readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count); | |||||
private: | private: | ||||
QModbusRtuSerialMaster *modbusDevice; | |||||
RegisterManager* registerManager; | |||||
ModbusWorker* worker; | |||||
QTimer* pollTimer; | QTimer* pollTimer; | ||||
int slaveAddress = 1; // 默认从站地址 | |||||
QMap<QModbusReply*, QString> pendingRequests; | |||||
QThread* modbusThread; | |||||
}; | }; | ||||
#endif // MODBUSMANAGER_H | #endif // MODBUSMANAGER_H |
@@ -0,0 +1,184 @@ | |||||
#include "modbusworker.h" | |||||
#include <QModbusDataUnit> | |||||
#include <QDebug> | |||||
#include <QSerialPort> | |||||
ModbusWorker::ModbusWorker(RegisterManager* regManager, QObject *parent) | |||||
: QObject(parent), registerManager(regManager) | |||||
{ | |||||
// modbusDevice = new QModbusRtuSerialMaster(this); | |||||
// connect(modbusDevice, &QModbusClient::errorOccurred, this, | |||||
// [this](QModbusDevice::Error) { | |||||
// emit errorOccurred(modbusDevice->errorString()); | |||||
// }); | |||||
} | |||||
ModbusWorker::~ModbusWorker() | |||||
{ | |||||
disconnectDevice(); | |||||
} | |||||
bool ModbusWorker::connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate, | |||||
QSerialPort::DataBits dataBits, | |||||
QSerialPort::Parity parity, | |||||
QSerialPort::StopBits stopBits) | |||||
{ | |||||
if (!modbusDevice) { // 新增检查 | |||||
emit errorOccurred("Modbus设备未初始化"); | |||||
return false; | |||||
} | |||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
disconnectDevice(); | |||||
} | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, portName); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); | |||||
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); | |||||
if (!modbusDevice->connectDevice()) { | |||||
emit errorOccurred(tr("连接失败: %1").arg(modbusDevice->errorString())); | |||||
return false; | |||||
} | |||||
emit connectionStatusChanged(true); | |||||
return true; | |||||
} | |||||
void ModbusWorker::disconnectDevice() | |||||
{ | |||||
if (modbusDevice->state() != QModbusDevice::UnconnectedState) { | |||||
modbusDevice->disconnectDevice(); | |||||
emit connectionStatusChanged(false); | |||||
} | |||||
} | |||||
void ModbusWorker::initModbusDevice() | |||||
{ | |||||
modbusDevice = new QModbusRtuSerialMaster(this); | |||||
connect(modbusDevice, &QModbusClient::errorOccurred, this, | |||||
[this](QModbusDevice::Error) { | |||||
emit errorOccurred(modbusDevice->errorString()); | |||||
}); | |||||
} | |||||
void ModbusWorker::readRegisters() | |||||
{ | |||||
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState) | |||||
return; | |||||
// 获取所有已注册的寄存器ID | |||||
QStringList regIds = registerManager->getAllRegisteredRegisters(); | |||||
QMap<QString, QSet<int>> regMap; | |||||
for (const QString &id : regIds) { | |||||
if (id.startsWith("D") || id.startsWith("M")) { | |||||
bool ok; | |||||
int addr = id.mid(1).toInt(&ok); | |||||
if (ok && addr >= 0 && addr <= 4000) { | |||||
regMap[id.left(1)].insert(addr); | |||||
} | |||||
} | |||||
} | |||||
if (regMap.contains("D")) { | |||||
readRegisterGroup(QModbusDataUnit::HoldingRegisters, regMap["D"].values()); | |||||
} | |||||
if (regMap.contains("M")) { | |||||
readRegisterGroup(QModbusDataUnit::Coils, regMap["M"].values()); | |||||
} | |||||
} | |||||
void ModbusWorker::readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses) | |||||
{ | |||||
if (addresses.isEmpty()) return; | |||||
QList<int> sortedAddrs = addresses; | |||||
std::sort(sortedAddrs.begin(), sortedAddrs.end()); | |||||
int start = sortedAddrs.first(); | |||||
int end = start; | |||||
for (int i = 1; i < sortedAddrs.size(); i++) { | |||||
if (sortedAddrs[i] == end + 1) { | |||||
end = sortedAddrs[i]; | |||||
} else { | |||||
readAddressRange(type, start, end - start + 1); | |||||
start = sortedAddrs[i]; | |||||
end = start; | |||||
} | |||||
} | |||||
readAddressRange(type, start, end - start + 1); | |||||
} | |||||
void ModbusWorker::readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count) | |||||
{ | |||||
const int MAX_REG_PER_REQUEST = 120; | |||||
for (int offset = 0; offset < count; offset += MAX_REG_PER_REQUEST) { | |||||
int readCount = qMin(MAX_REG_PER_REQUEST, count - offset); | |||||
QModbusDataUnit unit(type, startAddr + offset, readCount); | |||||
if (auto *reply = modbusDevice->sendReadRequest(unit, slaveAddress)) { | |||||
QString regType = (type == QModbusDataUnit::HoldingRegisters) ? "D" : "M"; | |||||
pendingRequests[reply] = regType; | |||||
connect(reply, &QModbusReply::finished, this, &ModbusWorker::processModbusReply); | |||||
} | |||||
} | |||||
} | |||||
void ModbusWorker::processModbusReply() | |||||
{ | |||||
auto *reply = qobject_cast<QModbusReply*>(sender()); | |||||
if (!reply) return; | |||||
if (reply->error() == QModbusDevice::NoError) { | |||||
const QModbusDataUnit unit = reply->result(); | |||||
QString regType = pendingRequests.value(reply); | |||||
int startAddr = unit.startAddress(); | |||||
for (uint i = 0; i < unit.valueCount(); i++) { | |||||
int regAddr = startAddr + i; | |||||
quint16 value = unit.value(i); | |||||
QString regId = QString("%1%2").arg(regType).arg(regAddr); | |||||
emit registerValueUpdated(regId, value); | |||||
} | |||||
} else { | |||||
emit errorOccurred(tr("Modbus错误: %1").arg(reply->errorString())); | |||||
} | |||||
pendingRequests.remove(reply); | |||||
reply->deleteLater(); | |||||
} | |||||
void ModbusWorker::writeRegister(const QString& registerId, quint16 value) | |||||
{ | |||||
if (!modbusDevice) { | |||||
emit errorOccurred("Modbus设备未初始化"); | |||||
return; | |||||
} | |||||
if (registerId.isEmpty()) return; | |||||
QModbusDataUnit::RegisterType regType = registerId.startsWith("D") | |||||
? QModbusDataUnit::HoldingRegisters | |||||
: QModbusDataUnit::Coils; | |||||
int regAddr = registerId.mid(1).toInt(); | |||||
QModbusDataUnit writeUnit(regType, regAddr, 1); | |||||
writeUnit.setValue(0, value); | |||||
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, slaveAddress)) { | |||||
connect(reply, &QModbusReply::finished, this, [this, reply]() { | |||||
if (reply->error() != QModbusDevice::NoError) { | |||||
emit errorOccurred(tr("写入失败: %1").arg(reply->errorString())); | |||||
} | |||||
reply->deleteLater(); | |||||
}); | |||||
} | |||||
} |
@@ -0,0 +1,47 @@ | |||||
#ifndef MODBUSWORKER_H | |||||
#define MODBUSWORKER_H | |||||
#include <QObject> | |||||
#include <QTimer> | |||||
#include <QModbusRtuSerialMaster> | |||||
#include <QSerialPort> | |||||
#include "registermanager.h" | |||||
class ModbusWorker : public QObject | |||||
{ | |||||
Q_OBJECT | |||||
public: | |||||
explicit ModbusWorker(RegisterManager* regManager, QObject *parent = nullptr); | |||||
~ModbusWorker(); | |||||
public slots: | |||||
// void startSimulation(int interval = 500); | |||||
// void stopSimulation(); | |||||
void writeRegister(const QString& registerId, quint16 value); | |||||
bool connectToDevice(const QString& portName, | |||||
QSerialPort::BaudRate baudRate, | |||||
QSerialPort::DataBits dataBits, | |||||
QSerialPort::Parity parity, | |||||
QSerialPort::StopBits stopBits); | |||||
void disconnectDevice(); | |||||
void initModbusDevice(); | |||||
private slots: | |||||
void readRegisters(); | |||||
void processModbusReply(); | |||||
void readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses); | |||||
void readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count); | |||||
signals: | |||||
void connectionStatusChanged(bool connected); | |||||
void errorOccurred(const QString& error); | |||||
void registerValueUpdated(const QString& registerId, quint16 value); | |||||
private: | |||||
QModbusRtuSerialMaster *modbusDevice = nullptr; | |||||
RegisterManager* registerManager; | |||||
int slaveAddress = 1; | |||||
QMap<QModbusReply*, QString> pendingRequests; | |||||
}; | |||||
#endif // MODBUSWORKER_H |