emsApplication/applications/EmsShow/modbuscontroller.cpp

191 lines
5.7 KiB
C++
Raw Normal View History

2025-03-04 11:27:16 +08:00
#include "modbuscontroller.h"
#define _DEBUG_VSPD_
ModbusController::ModbusController():m_pModbusMaster(nullptr), m_pSettings(nullptr)
{
m_version= "1.0.0";
m_modbus_type = 1;
m_modbus_ip = "127.0.0.1";
m_modbus_port = 502;
m_modbus_com = "COM1";
m_modbus_baund = 9600;
m_modbus_data = 1;
m_modbus_parity = 0;
m_modbus_stop = 1;
}
ModbusController::~ModbusController()
{
if (m_pSettings!=nullptr)
{
delete m_pSettings;
m_pSettings = nullptr;
}
for (SlaveData* ptr : m_slaves)
{
delete ptr;
ptr = nullptr;
}
m_slaves.clear();
m_slaves.squeeze();
if (m_pModbusMaster != nullptr)
{
m_pModbusMaster->disconnectDevice();
delete m_pModbusMaster;
m_pModbusMaster = nullptr;
}
}
void ModbusController::getConfiguration(QString iniFilePath)
{
m_pSettings = new QSettings(iniFilePath, QSettings::IniFormat);
m_version = m_pSettings->value("general/ver").toString();
m_modbus_type = m_pSettings->value("modbus/type").toInt();
m_modbus_ip = m_pSettings->value("modbus/ip").toString();
m_modbus_port = m_pSettings->value("modbus/port").toInt();
m_modbus_com = m_pSettings->value("modbus/com").toString();
m_modbus_baund = m_pSettings->value("modbus/baund").toInt();
m_modbus_data = m_pSettings->value("modbus/data").toInt();
m_modbus_parity = m_pSettings->value("modbus/parity").toInt();
m_modbus_stop = m_pSettings->value("modbus/stop").toInt();
QStringList slaves_list = m_pSettings->value("slaves/slave_id").toString().split(":", Qt::SkipEmptyParts);
int slave_id = 0;
foreach (const QString &str, slaves_list)
{
QString app = QString("slave_%1/function_code_counts").arg(slave_id);
int functions_count = m_pSettings->value(app).toInt();
for(int i=0; i<functions_count; i++)
{
QString app2 = QString("slave_%1_function_%2").arg(slave_id).arg(i);
#ifndef _DEBUG_VSPD_
unsigned short equipmentCode = m_pSettings->value(app2 + "/equipment_code").toInt();
equipmentCode = equipmentCode << 9;
equipmentCode &= 0xFE00; // 二进制掩码: 1111 1110 0000 0000保留高7位
QStringList sn_list = m_pSettings->value(app2 + "/serial_number").toString().split(":", Qt::SkipEmptyParts);
QStringList quantity_list = m_pSettings->value(app2 + "/read_quantity").toString().split(":", Qt::SkipEmptyParts);
assert(sn_list.size() == quantity_list.size());
int j = 0;
foreach(const QString sn, sn_list)
{
SlaveData* pSlaveData = new SlaveData();
pSlaveData->id = str.toInt();
pSlaveData->function_code = m_pSettings->value(app2 + "/function_code").toInt();
pSlaveData->interval = m_pSettings->value(app2 + "/interval").toInt();
unsigned short serialNumber = sn.toInt();
serialNumber &= 0x01FF; // 二进制掩码: 0000 0001 1111 1111保留低9位
// 组合操作高7位左移9位低9位直接填充
unsigned short address = pSlaveData->start_address = (equipmentCode ) | serialNumber; // 关键位操作
pSlaveData->start_address = address;
pSlaveData->quantity = quantity_list.at(j).toInt();
m_slaves.push_back(pSlaveData);
j++;
}
#else
SlaveData* pSlaveData = new SlaveData();
pSlaveData->id = str.toInt();
pSlaveData->function_code = m_pSettings->value(app2 + "/function_code").toInt();
pSlaveData->interval = m_pSettings->value(app2 + "/interval").toInt();
pSlaveData->quantity = m_pSettings->value(app2 + "/quantity").toInt();
pSlaveData->start_address = m_pSettings->value(app2 + "/start_addr").toInt();
m_slaves.push_back(pSlaveData);
#endif
}
slave_id++;
}
}
bool ModbusController::Open()
{
if (m_modbus_type == 1)
{
return modbus_rtu();
}
else
{
return modbus_tcp();
}
}
bool ModbusController::modbus_rtu()
{
m_pModbusMaster = new QModbusRtuSerialClient();
m_pModbusMaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter, m_modbus_com); //串口号
m_pModbusMaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, m_modbus_baund); //波特率
m_pModbusMaster->setConnectionParameter(QModbusDevice::SerialParityParameter, m_modbus_parity); //无校验
m_pModbusMaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, m_modbus_data); //数据位
m_pModbusMaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, m_modbus_stop); //停止位
m_pModbusMaster->setTimeout(1000); // 设置超时2秒
return m_pModbusMaster->connectDevice();
}
bool ModbusController::modbus_tcp()
{
return false;
}
bool ModbusController::Read()
{
//对每一个从机进行操作
for( SlaveData* sd : m_slaves)
{
//定义读写单元
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters, sd->start_address, sd->quantity);
//发送请求
auto* reply = m_pModbusMaster->sendReadRequest(readUnit, sd->id);
if (reply)
{
connect(reply, &QModbusReply::finished, this, &ModbusController::readRegisters);
}
}
return true;
}
void ModbusController::readRegisters()
{
//接收信号
auto reply = qobject_cast<QModbusReply*>(sender());
if (!reply)
{
qDebug() << "无效回复";
return;
}
//处理响应
const QModbusDataUnit unit = reply->result();
// 将数据值转换为字符串
QString dataStr;
for (int i = 0; i < unit.valueCount(); ++i)
{
dataStr += QString::number(unit.value(i)) + " ";
}
if (dataStr.size() != 0)
{
qDebug() << "读取成功";
qDebug() << dataStr;
}
else
{
qDebug() << "无数据";
}
}