|
- #include "ModbusManager.h"
- #include <QModbusDataUnit>
- #include <QModbusReply>
- #include <QSerialPort>
- #include <QVariant>
-
- 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;
- }
|