emsApplication/applications/EmsShow/modbuscontroller.cpp

191 lines
5.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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() << "无数据";
}
}