瀏覽代碼

优化了读取寄存器的功能,现在只会读取需要的寄存器

master
鹏鹏 李 2 天之前
父節點
當前提交
962596f6ac
共有 6 個文件被更改,包括 110 次插入15 次删除
  1. +1
    -1
      editor.pro.user
  2. +1
    -1
      mainwindow.cpp
  3. +79
    -9
      modbusmanager.cpp
  4. +2
    -2
      modbusmanager.h
  5. +25
    -0
      mygraphicsview.cpp
  6. +2
    -2
      mygraphicsview.h

+ 1
- 1
editor.pro.user 查看文件

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.11.1, 2025-08-11T13:08:22. -->
<!-- Written by QtCreator 4.11.1, 2025-08-11T14:46:36. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>


+ 1
- 1
mainwindow.cpp 查看文件

@@ -444,7 +444,7 @@ void MainWindow::saveProject()
void MainWindow::connection()
{
modbusManager->connectToDevice("COM1",QSerialPort::BaudRate(9600),QSerialPort::DataBits(8),QSerialPort::EvenParity,QSerialPort::StopBits(1));
modbusManager->startSimulation(2000);
modbusManager->startSimulation(1000);
}

void MainWindow::disconnection()


+ 79
- 9
modbusmanager.cpp 查看文件

@@ -65,26 +65,96 @@ void ModbusManager::stopSimulation()
pollTimer->stop();
}

//void ModbusManager::readRegisters()
//{
// if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState)
// return;

// // 读取所有D寄存器 (保持寄存器)
// readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000);

// // 读取所有M寄存器 (线圈)
// readRegisterGroup(QModbusDataUnit::Coils, 0, 4000);
//}

//void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count)
//{
// const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制

// for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) {
// int readCount = qMin(MAX_REG_PER_REQUEST, count - addr);

// QModbusDataUnit unit(type, addr, 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::readRegisters()
{
if (!modbusDevice || modbusDevice->state() != QModbusDevice::ConnectedState)
return;

// 读取所有D寄存器 (保持寄存器)
readRegisterGroup(QModbusDataUnit::HoldingRegisters, 0, 4000);
// 获取所有已注册的寄存器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寄存器 (线圈)
readRegisterGroup(QModbusDataUnit::Coils, 0, 4000);
// 读取M寄存器 (线圈)
if (regMap.contains("M")) {
readRegisterGroup(QModbusDataUnit::Coils, regMap["M"].values());
}
}

void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count)
void ModbusManager::readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses)
{
const int MAX_REG_PER_REQUEST = 125; // Modbus RTU限制
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);
}

for (int addr = startAddr; addr < count; addr += MAX_REG_PER_REQUEST) {
int readCount = qMin(MAX_REG_PER_REQUEST, count - addr);
void ModbusManager::readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count)
{
const int MAX_REG_PER_REQUEST = 120;

QModbusDataUnit unit(type, addr, readCount);
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";


+ 2
- 2
modbusmanager.h 查看文件

@@ -41,6 +41,8 @@ signals:
private slots:
void readRegisters();
void processModbusReply();
void readRegisterGroup(QModbusDataUnit::RegisterType type, const QList<int> &addresses);
void readAddressRange(QModbusDataUnit::RegisterType type, int startAddr, int count);

private:
QModbusRtuSerialMaster *modbusDevice;
@@ -48,8 +50,6 @@ private:
QTimer* pollTimer;
int slaveAddress = 1; // 默认从站地址
QMap<QModbusReply*, QString> pendingRequests;

void readRegisterGroup(QModbusDataUnit::RegisterType type, int startAddr, int count);
};

#endif // MODBUSMANAGER_H

+ 25
- 0
mygraphicsview.cpp 查看文件

@@ -311,3 +311,28 @@ void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
}
QGraphicsView::mouseReleaseEvent(event);
}

void MyGraphicsView::wheelEvent(QWheelEvent *event)
{
// 检查是否按下了 Ctrl 键
if (event->modifiers() & Qt::ControlModifier) {
// 计算缩放因子 (每滚动一步缩放 10%)
const double zoomFactor = 1.1;
double scaleFactor = (event->angleDelta().y() > 0) ? zoomFactor : 1.0 / zoomFactor;

// 获取鼠标在场景中的位置
QPointF scenePos = mapToScene(event->position().toPoint());

// 执行缩放
scale(scaleFactor, scaleFactor);

// 调整视图中心点,使缩放以鼠标位置为中心
QPointF delta = scenePos - mapToScene(viewport()->rect().center());
centerOn(scenePos - delta * (scaleFactor - 1));

event->accept(); // 表示事件已处理
} else {
// 没有按下 Ctrl 键,执行默认的滚动行为
QGraphicsView::wheelEvent(event);
}
}

+ 2
- 2
mygraphicsview.h 查看文件

@@ -16,8 +16,7 @@ class MyGraphicsView : public QGraphicsView
Q_OBJECT
public:
explicit MyGraphicsView(QWidget *parent = nullptr);

protected:
//protected:
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dropEvent(QDropEvent *event) override;
@@ -27,6 +26,7 @@ protected:
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void wheelEvent(QWheelEvent *event) override;

signals:
void itemBoundToRegister(Item*, QString);


Loading…
取消
儲存