#include "ModbusManager.h" #include #include #include #include ModbusManager::ModbusManager(QObject *parent) : QObject(parent) { } ModbusManager::~ModbusManager() { stopSimulation(); } bool ModbusManager::startSimulation(const QString &serialPortName, int baudRate, int parity, int dataBits, int stopBits) { if (m_running) { emit logMessage("仿真已经在运行"); return true; } m_modbusDevice = new QModbusRtuSerialClient(this); if (!m_modbusDevice) return false; m_modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, serialPortName); m_modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, parity); m_modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, baudRate); m_modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, dataBits); m_modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, stopBits); m_modbusDevice->setTimeout(1000); m_modbusDevice->setNumberOfRetries(3); if (!m_modbusDevice->connectDevice()) { emit logMessage("无法连接到 Modbus RTU 从站"); delete m_modbusDevice; m_modbusDevice = nullptr; return false; } // 定时轮询 m_pollingTimer = new QTimer(this); connect(m_pollingTimer, &QTimer::timeout, this, &ModbusManager::pollModbusCoils); m_pollingTimer->start(200); // 200毫秒轮询 m_running = true; emit logMessage(QString("开始仿真:串口 ") + serialPortName); return true; } void ModbusManager::stopSimulation() { if (!m_running) return; if (m_pollingTimer) { m_pollingTimer->stop(); m_pollingTimer->deleteLater(); m_pollingTimer = nullptr; } if (m_modbusDevice) { m_modbusDevice->disconnectDevice(); m_modbusDevice->deleteLater(); m_modbusDevice = nullptr; } m_running = false; emit logMessage("停止仿真"); } void ModbusManager::pollModbusCoils() { if (!m_modbusDevice) return; int startAddress = 0; int numberOfCoils = 9; // 根据需要修改 QModbusDataUnit readUnit(QModbusDataUnit::Coils, startAddress, numberOfCoils); if (auto *reply = m_modbusDevice->sendReadRequest(readUnit, 1)) { // 1 = 从站ID if (!reply->isFinished()) { connect(reply, &QModbusReply::finished, this, [this, reply]() { if (reply->error() == QModbusDevice::NoError) { auto result = reply->result(); for (uint i = 0; i < result.valueCount(); ++i) { int addr = result.startAddress() + i; bool val = result.value(i); if (m_coilValues.value(addr) != val) { m_coilValues[addr] = val; emit coilUpdated(addr, val); } } } else { emit logMessage("读取线圈失败: " + reply->errorString()); } reply->deleteLater(); }); } else { reply->deleteLater(); } } } void ModbusManager::writeCoil(int address, bool value) { if (!m_running || !m_modbusDevice) return; QModbusDataUnit writeUnit(QModbusDataUnit::Coils, address, 1); writeUnit.setValue(0, value); if (auto *reply = m_modbusDevice->sendWriteRequest(writeUnit, 1)) { connect(reply, &QModbusReply::finished, reply, &QObject::deleteLater); } } bool ModbusManager::isRunning() const { return m_running; }