#include "modbussimulator.h" #include #include #include #include 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 &addresses) { qDebug() <<"执行到此"; qDebug() << "setCoilAddresses called, this:" << this; // 打印对象地址 QMutexLocker locker(&m_mutex); // 必须加锁 m_coilAddresses = QSet(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 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>::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; } } }