#include "modbusworker.h" #include #include #include 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> 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 &addresses) { if (addresses.isEmpty()) return; QList 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(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(); }); } }