|
- #include "modbussimulator.h"
- #include <QSerialPort>
- #include <QDebug>
- #include <algorithm>
- #include<QThread>
- ModbusSimulator::ModbusSimulator(QObject *parent)
- : QObject(parent), m_coilAddresses(),m_running(false), m_mutex()
- {
- m_modbusClient = new QModbusRtuSerialMaster(this);
- m_readTimer = new QTimer(this);
- connect(m_readTimer, &QTimer::timeout, this, &ModbusSimulator::readCoils);
- }
-
- ModbusSimulator::~ModbusSimulator()
- {
- stopSimulation();
- }
-
- bool ModbusSimulator::isRunning() const
- {
- return m_running;
- }
-
- void ModbusSimulator::startSimulation()
- {
- qDebug() << "进入 startSimulation() 函数";
- if (m_running) return;
- qDebug() << "启动Modbus仿真555...";
- // 配置Modbus连接
- m_modbusClient->setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM1");
- m_modbusClient->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
- m_modbusClient->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud9600);
- m_modbusClient->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
- m_modbusClient->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
-
- if (!m_modbusClient->connectDevice())
- {
- emit errorOccurred("无法连接Modbus设备");
- return;
- }
- qDebug() << "Modbus设备连接成功";
- m_running = true;
- m_readTimer->start(1000); // 每秒读取一次
- }
-
- void ModbusSimulator::stopSimulation()
- {
- if (!m_running) return;
-
- m_readTimer->stop();
- m_modbusClient->disconnectDevice();
- m_running = false;
- }
-
- void ModbusSimulator::setCoilAddresses(const QSet<int> &addresses)
- {
- qDebug() <<"执行到此";
- qDebug() << "setCoilAddresses called, this:" << this; // 打印对象地址
- QMutexLocker locker(&m_mutex); // 必须加锁
- m_coilAddresses = QSet<int>(addresses);
- }
-
- void ModbusSimulator::writeCoil(int address, bool state)
- {
- if (!m_running) return;
-
- if (auto reply = m_modbusClient->sendWriteRequest(
- QModbusDataUnit(QModbusDataUnit::Coils, address, {state}), 1)) {
-
- connect(reply, &QModbusReply::finished, [reply, address]() {
- if (reply->error() != QModbusDevice::NoError) {
- qWarning() << "写线圈失败:" << reply->errorString() << "地址:" << address;
- }
- reply->deleteLater();
- });
- }
- }
-
- void ModbusSimulator::readCoils()
- {
- QSet<int> addressesCopy;
- {
- QMutexLocker locker(&m_mutex);
- if (!m_running || m_coilAddresses.isEmpty()) return;
- addressesCopy = m_coilAddresses; // 在锁保护下复制
- }
- int minAddress = *std::min_element(addressesCopy.begin(), addressesCopy.end());
- int maxAddress = *std::max_element(addressesCopy.begin(), addressesCopy.end());
- int count = maxAddress - minAddress + 1;
-
- // 创建读请求
- QModbusDataUnit readUnit(QModbusDataUnit::Coils, minAddress, count);
- if (auto *reply = m_modbusClient->sendReadRequest(readUnit, 1)) {
- if (!reply->isFinished()) {
- // 使用智能指针确保地址集合在回调中有效
- auto safeAddresses = QSharedPointer<QSet<int>>::create(addressesCopy);
- connect(reply, &QModbusReply::finished, this, [this, reply, safeAddresses]() {
- if (reply->error() == QModbusDevice::NoError) {
- const QModbusDataUnit unit = reply->result();
- for (int i = 0; i < unit.valueCount(); ++i) {
- int address = unit.startAddress() + i;
- bool state = unit.value(i);
- if (safeAddresses->contains(address)) {
- emit coilStatusRead(address, state);
- }
- }
- }
- reply->deleteLater();
- });
- } else {
- delete reply;
- }
- }
- }
|