[Qt5.15.2] [更新0.1] [modbus rtu master ]

modbus.h

#ifndef MODBUS_H
#define MODBUS_H

#include <QDebug>
#include <QObject>

#include <QModbusReply>
#include <QModbusRtuSerialMaster>
#include <QSerialPort>

class modbus : public QObject {
  Q_OBJECT
public:
  explicit modbus(QObject *parent = nullptr);

  void SerialPortUpdate();                  // 更新串口信息
  void Conn(QString portName, qint32 baud); // 连接串口
  void Disconn();                           // 断开连接
  // void ReadReady();
  void ReadCoil(quint8 SlaveAddr, quint8 StartAddr, quint8 Number); // 01
  void ReadDiscreteInputs(quint8 SlaveAddr, quint8 StartAddr,
                          quint8 Number); // 02
  void ReadHoldingRegister(quint8 SlaveAddr, quint8 StartAddr,
                           quint8 Number); // 03
  void ReadInputRegister(quint8 SlaveAddr, quint8 StartAddr,
                         quint8 Number);                                   // 04
  void WriteSingleCoil(quint8 SlaveAddr, quint8 CoilAddr, quint8 Data);    // 05
  void WriteSingleRegister(quint8 SlaveAddr, quint8 RegAddr, qint16 Data); // 06
  void WriteMultipleCoil(quint8 SlaveAddr, quint8 StartAddr, qint8 *Data); // 0f
  void WriteMultipleRegisters(quint8 SlaveAddr, quint8 StartAddr,
                              qint16 *Data); // 10
signals:
  void Error_signal(QString ErrorString);
  void StateChanged_signal(int State);
  void ReadData_signal(int Address, int Value);
public slots:
  void DeviceErrorHandle(QModbusDevice::Error newError);
  void GetState(int State);
  void ReadReady(); // 接收

private:
  QModbusRtuSerialMaster *master;
};

#endif // MODBUS_H

modbus.cpp

#include "modbus.h"

modbus::modbus(QObject *parent) : QObject{parent} {}

void modbus::SerialPortUpdate() // 更新串口list
{
  qInfo() << "modbus::mbSerialPortUpdate()";
  // 更新端口号
  foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
    QSerialPort serial;
    serial.setPort(info);
    if (serial.open(QIODevice::ReadWrite)) {
      serial.close();
    }
    qDebug("调试:端口更新完成");
  }
  const auto infos = QSerialPortInfo::availablePorts();
  qDebug("串口信息:");
  for (const QSerialPortInfo &info : infos) {
    QString s = QObject::tr("Port: ") + info.portName() +
                QObject::tr("Location: ") + info.systemLocation() +
                QObject::tr("Description: ") + info.description() +
                QObject::tr("Manufacturer: ") + info.manufacturer() +
                QObject::tr("Serial number: ") + info.serialNumber() +
                QObject::tr("Vendor Identifier: ") +
                (info.hasVendorIdentifier()
                     ? QString::number(info.vendorIdentifier(), 16)
                     : QString()) +
                QObject::tr("Product Identifier: ") +
                (info.hasProductIdentifier()
                     ? QString::number(info.productIdentifier(), 16)
                     : QString());
    qDebug() << s;
  }
}

void modbus::Conn(QString portName, qint32 baud) {
  qInfo() << "modbus::Conn(QString portName, qint32 baud)" << portName << baud;
  master = new QModbusRtuSerialMaster(); // new 主站对象
  connect(master, &QModbusClient::errorOccurred, this,
          [=](QModbusDevice::Error) { qDebug() << master->errorString(); });
  if (!master) {
    qDebug() << "Could not create Modbus master";
  }
  if (master->state() == QModbusDevice::UnconnectedState) {
    // 设置串口参数
    master->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
                                   portName);
    master->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
                                   baud);
    master->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
                                   QSerialPort::Data8);
    master->setConnectionParameter(QModbusDevice::SerialParityParameter,
                                   QSerialPort::Parity::NoParity);
    master->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
                                   QSerialPort::OneStop);
    master->setTimeout(1000);      // 超时时间
    master->setNumberOfRetries(3); // 重试3次
    if (master->connectDevice()) {
      qDebug() << "连接成功";
    } else {
      qDebug() << "连接失败" << master->errorString();
    }
  }
}

void modbus::Disconn() {
  qInfo() << "modbus::Disconn()";
  if (master->state() != QModbusDevice::UnconnectedState) {
    master->disconnectDevice();
    delete master;
    master = nullptr;
    qDebug() << "断开连接";
  }
}
void modbus::GetState(int state) {
  if (state == QModbusDevice::UnconnectedState)
    emit StateChanged_signal(0);
  else if (state == QModbusDevice::ConnectedState)
    emit StateChanged_signal(1);
}
void modbus::DeviceErrorHandle(QModbusDevice::Error newError) {
  if (newError == QModbusDevice::NoError || !master)
    return;
  emit Error_signal(master->errorString());
}
void modbus::ReadReady() {
  qInfo() << "modbus::ReadReady()";
  auto reply = qobject_cast<QModbusReply *>(sender());

  if (!reply)
    return;
  if (reply->error() == QModbusDevice::NoError) {
    const QModbusDataUnit unit = reply->result();
    for (uint i = 0; i < unit.valueCount(); i++) {
      const QString entry = tr("Address:%1,Value:%2")
                                .arg(unit.startAddress() + i)
                                .arg(QString::number(unit.value(i)));
      qDebug() << entry;
      emit ReadData_signal(unit.startAddress() + i, unit.value(i));
    }
  } else if (reply->error() == QModbusDevice::ProtocolError) {
    qDebug() << "ProtocolError:" << reply->errorString();
  } else {
    qDebug() << "Error:" << reply->errorString();
  }
  reply->deleteLater();
}
// 01
void modbus::ReadCoil(quint8 SlaveAddr, quint8 StartAddr, quint8 Number) {
  qInfo()
      << "modbus::ReadCoil(quint8 SlaveAddr, quint8 StartAddr, quint8 Number)"
      << SlaveAddr << StartAddr << Number;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::Coils, StartAddr, Number);

  if (auto *reply = master->sendReadRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 02
void modbus::ReadDiscreteInputs(quint8 SlaveAddr, quint8 StartAddr,
                                quint8 Number) {
  qInfo() << "modbus::ReadDiscreteInputs(quint8 SlaveAddr, quint8 StartAddr, "
             "quint8 Number)"
          << SlaveAddr << StartAddr << Number;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::DiscreteInputs, StartAddr, Number);

  if (auto *reply = master->sendReadRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 03
void modbus::ReadHoldingRegister(quint8 SlaveAddr, quint8 StartAddr,
                                 quint8 Number) {
  qInfo() << "modbus::ReadHoldingRegister(quint8 SlaveAddr, quint8 "
             "StartAddr, quint8 Number)"
          << SlaveAddr << StartAddr << Number;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::HoldingRegisters, StartAddr, Number);

  if (auto *reply = master->sendReadRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 04
void modbus::ReadInputRegister(quint8 SlaveAddr, quint8 StartAddr,
                               quint8 Number) {
  qInfo() << "modbus::ReadInputRegister(quint8 SlaveAddr, quint8 StartAddr, "
             "quint8 Number)"
          << SlaveAddr << StartAddr << Number;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::InputRegisters, StartAddr, Number);

  if (auto *reply = master->sendReadRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 05
void modbus::WriteSingleCoil(quint8 SlaveAddr, quint8 CoilAddr, quint8 Data) {
  qInfo() << "modbus::WriteSingleCoil(quint8 SlaveAddr, quint8 StartAddr, "
             "quint8 Data)"
          << SlaveAddr << CoilAddr << Data;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::Coils, CoilAddr, 1);
  mdu.setValue(0, Data);
  if (auto *reply = master->sendWriteRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 06
void modbus::WriteSingleRegister(quint8 SlaveAddr, quint8 RegAddr,
                                 qint16 Data) {
  qInfo() << "modbus::WriteSingleRegister(quint8 SlaveAddr, quint8 RegAddr, "
             "int Data)"
          << SlaveAddr << RegAddr << Data;

  if (!master)
    return;

  QModbusDataUnit mdu(QModbusDataUnit::HoldingRegisters, RegAddr, 1);
  mdu.setValue(0, Data);
  if (auto *reply = master->sendWriteRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 15
void modbus::WriteMultipleCoil(quint8 SlaveAddr, quint8 StartAddr,
                               qint8 *Data) {
  qInfo() << "modbus::WriteMultipleCoil(quint8 SlaveAddr, quint8 StartAddr, "
             "quint8 *Data)"
          << SlaveAddr << StartAddr << Data;

  if (!master)
    return;

  // 获取数据长度
  qint16 Num = sizeof(Data);

  QModbusDataUnit mdu(QModbusDataUnit::Coils, StartAddr, Num);
  // 设定数据
  for (int i = 0; i < Num; ++i) {
    mdu.setValue(i, Data[i]);
  }
  if (auto *reply = master->sendWriteRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}
// 16
void modbus::WriteMultipleRegisters(quint8 SlaveAddr, quint8 StartAddr,
                                    qint16 *Data) {
  qInfo()
      << "modbus::WriteMultipleRegisters(quint8 SlaveAddr, quint8 StartAddr, "
         "qint16 *Data)"
      << SlaveAddr << StartAddr << Data;

  if (!master)
    return;

  // 获取数据长度
  qint16 Num = sizeof(Data);

  QModbusDataUnit mdu(QModbusDataUnit::HoldingRegisters, StartAddr, Num);
  // 设定数据
  for (int i = 0; i < Num; ++i) {
    mdu.setValue(i, Data[i]);
  }
  if (auto *reply = master->sendWriteRequest(mdu, SlaveAddr)) {
    if (!reply->isFinished()) {
      connect(reply, &QModbusReply::finished, this, &modbus::ReadReady);
    } else {
      delete reply;
    }
  } else {
    qDebug() << master->errorString();
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值