#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QDateTime>
#include <QTime>
#include <QIcon>
#include <QPixmap>
#include <QPainter>
#include <QSerialPortInfo>
#include <QFileDialog>
#include <QDateTime>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QTextStream>
#include <QCalendarWidget>
#include <QHeaderView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, battery(new BatteryData(this))
, m_serialInterface(new SerialInterface(this))
, m_serialConnected(false)
,canDevice(nullptr) //明确初始化
{
ui->setupUi(this);
// 初始化页面切换功能
initPageSwitcher();
setWindowTitle("电池组状态数据显示界面");
this->setWindowIcon(QIcon(":/new/prefix1/alBatteryMonitor/logo1.bmp"));
// 默认显示第一个页面
ui->stackedWidget->setCurrentIndex(0);
// 设置第一个按钮为选中状态
ui->BatteryStatusButton->setChecked(true);
// 填充串口列表
const auto ports = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &port : ports) {
ui->portComboBox->addItem(port.portName());
}
//setupConnections();
connect(ui->connectButton, &QPushButton::clicked, this, &MainWindow::connect_clicked);
connect(ui->disconnectButton, &QPushButton::clicked, this, &MainWindow::disconnect_clicked);
connect(ui->changePathButton, &QPushButton::clicked, this, &MainWindow::changePathButton_clicked);
connect(ui->serialConnectButton,&QPushButton::clicked, this, &MainWindow::serialconnect_clicked);
connect(ui->serialDisconnectButton, &QPushButton::clicked, this, &MainWindow::serialdisconnect_clicked);
// 初始化存储路径
currentSavePath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/BatteryData";
connect(m_serialInterface, &SerialInterface::dataReceived, this, &MainWindow::handleSerialDataReceived);
connect(m_serialInterface, &SerialInterface::errorOccurred, this, &MainWindow::handleSerialError);
connect(m_serialInterface, &SerialInterface::connectionStatusChanged, this, &MainWindow::updateSerialConnectionStatus);
refreshSerialPorts();
// 设置日历控件的样式表
ui->calendarWidget->setStyleSheet(
"QCalendarWidget {" //整体边框与背景
" background-color: #418ef6;"
" border: 1px solid #070655;"
" border-radius: 5px;"
"}"
"#qt_calendar_navigationbar {" //导航栏
" background-color: #0883cb;"
" color: white;"
"}"
"QCalendarWidget QToolButton {" //导航栏中的工具按钮
" background-color: transparent;"
" color: white;"
" font-size: 12pt;"
" icon-size: 0px;"
"}"
"QCalendarWidget QAbstractItemView::item {"
" border: 0.5px solid white;" // 添加单元格边框
"}"
"QCalendarWidget QHeaderView {"
" background-color: #ff0000 !important;" // 测试用红色,确认是否生效
"}"
"QCalendarWidget QHeaderView::section {" //表头单元格
" background-color: #6384ee;"
" color: #333;"
" padding: 5px;"
"}"
"QCalendarWidget QTableView {" //日期单元格
" alternate-background-color: #f8f8f8;"
" gridline-color: #d0d0d0 ;"
"}"
"QCalendarWidget QAbstractItemView:enabled {" //日期项通用样式
" color: #333;"
" selection-background-color: #3498db;"
" selection-color: white;"
"}"
"QCalendarWidget QAbstractItemView:enabled:section:last-child,"
"QCalendarWidget QAbstractItemView:enabled:section:nth-child(7) {"
" color: #c0392b;"
"}"
"QCalendarWidget QAbstractItemView:enabled:!selected:!current {" //非当月日期样式
" color: #e74c3c;"
"}"
"QCalendarWidget QAbstractItemView:enabled:current {" //当前日期样式
" background-color: #94d7fe;"
" color: white;"
"}"
);
// 初始化页面名称映射
initPageNames();
// 初始化历史数据模型
historyModel = new QStandardItemModel(this);
QStringList headers;
headers << "时间" << "页面" << "数据";
historyModel->setHorizontalHeaderLabels(headers);
ui->historyTableView->setModel(historyModel);
ui->historyTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
// 初始化数据记录定时器
dataLoggerTimer = new QTimer(this);
connect(dataLoggerTimer, &QTimer::timeout, this, &MainWindow::logCurrentPageData);
dataLoggerTimer->start(1000); // 每1秒记录一次
// 连接日历控件的点击信号
connect(ui->calendarWidget, &QCalendarWidget::clicked, this, &MainWindow::loadHistoryData);
}
MainWindow::~MainWindow()
{
if (m_serialInterface) {
m_serialInterface->disconnect();
}
if (canDevice) {
// 断开设备的所有信号
canDevice->disconnect();
if (canDevice->state() == QCanBusDevice::ConnectedState) {
canDevice->disconnectDevice();
}
delete canDevice;
canDevice = nullptr;
}
delete ui;
}
void MainWindow::initPageNames()
{
pageNames["0"] = "电池单体电压";
pageNames["1"] = "基础状态和温度";
pageNames["2"] = "故障信息";
pageNames["3"] = "控制状态";
pageNames["4"] = "历史记录";
pageNames["5"] = "串口连接";
}
QString MainWindow::getCellInfoData()
{
CellVoltageInfo1 cellvoltage1 = battery->getCellVoltageInfo1();
CellVoltageInfo2 cellvoltage2 = battery->getCellVoltageInfo2();
CellVoltageInfo3 cellvoltage3 = battery->getCellVoltageInfo3();
CellVoltageInfo4 cellvoltage4 = battery->getCellVoltageInfo4();
CellVoltageInfo5 cellvoltage5 = battery->getCellVoltageInfo5();
CellVoltageInfo6 cellvoltage6 = battery->getCellVoltageInfo6();
CellVoltageInfo7 cellvoltage7 = battery->getCellVoltageInfo7();
VoltageInfo voltageinfo = battery->getVoltageInfo();
return QString("单体电压1: %1 mV, 单体电压2: %2 mV, 单体电压3: %3 mV, 单体电压4: %4 mV, "
"单体电压5: %5 mV, 单体电压6: %6 mV, 单体电压7: %7 mV, 单体电压8: %8 mV, "
"单体电压9: %9 mV, 单体电压10: %10 mV, 单体电压11: %11 mV, 单体电压12: %12 mV"
"单体电压13: %13 mV, 单体电压14: %14 mV, 单体电压15: %15 mV, 单体电压16: %16 mV"
"单体电压17: %17 mV, 单体电压18: %18 mV, 单体电压19: %19 mV, 单体电压20: %20 mV"
"单体电压21: %21 mV, 单体电压22: %22 mV, 单体电压23: %23 mV, 单体电压24: %24 mV"
"单体电压25: %25 mV"
"最高单体电压: %26 mV (电芯%27), 最低单体电压: %28 mV (电芯%29), ")
.arg(QString::number(cellvoltage1.cellVoltage1))
.arg(QString::number(cellvoltage1.cellVoltage2))
.arg(QString::number(cellvoltage1.cellVoltage3))
.arg(QString::number(cellvoltage1.cellVoltage4))
.arg(QString::number(cellvoltage2.cellVoltage5))
.arg(QString::number(cellvoltage2.cellVoltage6))
.arg(QString::number(cellvoltage2.cellVoltage7))
.arg(QString::number(cellvoltage2.cellVoltage8))
.arg(QString::number(cellvoltage3.cellVoltage9))
.arg(QString::number(cellvoltage3.cellVoltage10))
.arg(QString::number(cellvoltage3.cellVoltage11))
.arg(QString::number(cellvoltage3.cellVoltage12))
.arg(QString::number(cellvoltage4.cellVoltage13))
.arg(QString::number(cellvoltage4.cellVoltage14))
.arg(QString::number(cellvoltage4.cellVoltage15))
.arg(QString::number(cellvoltage4.cellVoltage16))
.arg(QString::number(cellvoltage5.cellVoltage17))
.arg(QString::number(cellvoltage5.cellVoltage18))
.arg(QString::number(cellvoltage5.cellVoltage19))
.arg(QString::number(cellvoltage5.cellVoltage20))
.arg(QString::number(cellvoltage6.cellVoltage21))
.arg(QString::number(cellvoltage6.cellVoltage22))
.arg(QString::number(cellvoltage6.cellVoltage23))
.arg(QString::number(cellvoltage6.cellVoltage24))
.arg(QString::number(cellvoltage7.cellVoltage25))
.arg(QString::number(voltageinfo.maxVoltage))
.arg(QString::number(voltageinfo.maxVoltageCellNo))
.arg(QString::number(voltageinfo.minVoltage))
.arg(QString::number(voltageinfo.minVoltageCellNo));
}
QString MainWindow::getBatteryStatusData()
{
BMSInfo bmsinfo = battery->getBMSInfo();
BatteryStatus1 status1 = battery->getBatteryStatus1();
BatteryStatus2 status2 = battery->getBatteryStatus2();
TEMPInfo tempInfo = battery->getTEMPInfo();
return QString("运行时间: %1 S, 加热电流: %2 A, SOH: %3%, "
"总电压: %4 V, 总电流: %5 A, SOC: %6, "
"循环次数: %7, 剩余容量: %8 Ah, 实际容量: %9 Ah, 循环容量: %10 Ah, "
"最高温度: %11°C (电芯%12), 最低温度: %13°C (电芯%14), 平均温度: %15°C")
.arg(QString::number(bmsinfo.runningTime))
.arg(QString::number(bmsinfo.HeatCurrent))
.arg(QString::number(bmsinfo.SOH))
.arg(QString::number(status1.totalVoltage, 'f', 1))
.arg(QString::number(status1.totalCurrent, 'f', 1))
.arg(QString::number(status1.SOC))
.arg(QString::number(status2.cycleCount))
.arg(QString::number(status2.remainingCapacity))
.arg(QString::number(status2.actualCapacity))
.arg(QString::number(status2.cycleCapacity))
.arg(QString::number(tempInfo.maxTemp))
.arg(QString::number(tempInfo.maxTempCellNo))
.arg(QString::number(tempInfo.minTemp))
.arg(QString::number(tempInfo.minTempCellNo))
.arg(QString::number(tempInfo.avgTemp));
}
QString MainWindow::getFaultData()
{
FaultInfo faultInfo = battery->getFaultInfo();
AlarmInfo alarmInfo = battery->getAlarmInfo();
QStringList alarms;
if (alarmInfo.cellOverVoltage) alarms << "单体过压";
if (alarmInfo.cellUnderVoltage) alarms << "单体欠压";
if (alarmInfo.cellDiffVoltage) alarms << "单体压差大";
if (alarmInfo.dischargeOverCurrent) alarms << "放电过流";
if (alarmInfo.chargeOverCurrent) alarms << "充电过流";
if (alarmInfo.overTemperature) alarms << "温度过高";
if (alarmInfo.underTemperature) alarms << "温度过低";
if (alarmInfo.socLow) alarms << "SOC过低";
if (alarmInfo.internalCommFault) alarms << "通信故障";
QStringList faults;
if (faultInfo.OverLineResistance) faults << "过线电阻";
if (faultInfo.MOSoverTEMP) faults << "MOS过热";
if (faultInfo.Cellnumber) faults << "电芯数量";
if (faultInfo.CurrentSensor) faults << "电流传感器";
if (faultInfo.CellOverVol) faults << "电芯过压";
if (faultInfo.OverTotalVoltage) faults << "总电压过高";
if (faultInfo.ChargeOverCur) faults << "充电过流";
if (faultInfo.ChargeShortCircuit) faults << "充电短路";
if (faultInfo.ChargeOverTEMP) faults << "充电过温";
if (faultInfo.ChargeUnderTEMP) faults << "充电低温";
if (faultInfo.InternalCom) faults << "内部通信";
if (faultInfo.CellUnderVol) faults << "电芯欠压";
if (faultInfo.UnderTotalVol) faults << "总电压过低";
if (faultInfo.DischargeOverCur) faults << "放电过流";
if (faultInfo.DischargeShortCircuit) faults << "放电短路";
if (faultInfo.DischargeOverTEMP) faults << "放电过温";
if (faultInfo.ChargeMOS) faults << "充电MOS";
if (faultInfo.DischargeMOS) faults << "放电MOS";
return QString("告警: %1\n故障: %2")
.arg(alarms.isEmpty() ? "无" : alarms.join(", "))
.arg(faults.isEmpty() ? "无" : faults.join(", "));
}
QString MainWindow::getControlStatusData()
{
ControlStatus controlStatus = battery->getControlStatus();
SwitchStatus switchStatus = battery->getSwitchStatus();
return QString("充电使能: %1, 放电使能: %2, 均衡使能: %3, "
"充电开关: %4, 放电开关: %5, 均衡开关: %6, "
"充电MOS状态: %7, 放电MOS状态: %8, 均衡状态: %9, 加热状态: %10")
.arg(controlStatus.chargeEnabled ? "是" : "否")
.arg(controlStatus.dischargeEnabled ? "是" : "否")
.arg(controlStatus.balanceEnabled ? "是" : "否")
.arg(controlStatus.chargeSwitch ? "开" : "关")
.arg(controlStatus.dischargeSwitch ? "开" : "关")
.arg(controlStatus.balanceSwitch ? "开" : "关")
.arg(switchStatus.ChargeMOSStatus ? "开" : "关")
.arg(switchStatus.DischargeMOSStatus ? "开" : "关")
.arg(switchStatus.BalanceStatus ? "开" : "关")
.arg(switchStatus.HeatStatus ? "开" : "关");
}
// 保存数据到文件
void MainWindow::saveDataToFile(const QString ×tamp, const QString &pageName, const QString &data)
{
// 确保目录存在
QDir dir(currentSavePath);
if (!dir.exists()) {
dir.mkpath(".");
}
// 创建日期子目录
QString dateDir = QDateTime::currentDateTime().toString("yyyyMMdd");
if (!dir.cd(dateDir)) {
dir.mkdir(dateDir);
dir.cd(dateDir);
}
// 创建文件名 (格式: 页面名称_日期.csv)
QString fileName = QString("%1/%2_%3.csv")
.arg(dir.absolutePath())
.arg(pageName)
.arg(QDateTime::currentDateTime().toString("yyyyMMdd"));
QFile file(fileName);
if (file.open(QIODevice::Append | QIODevice::Text)) {
QTextStream stream(&file);
stream << timestamp << "," << pageName << "," << data << "\n";
file.close();
} else {
qDebug() << "无法打开文件:" << fileName;
}
}
// 添加到历史模型
void MainWindow::addToHistoryModel(const QString ×tamp, const QString &pageName, const QString &data)
{
QList<QStandardItem*> items;
items << new QStandardItem(timestamp);
items << new QStandardItem(pageName);
items << new QStandardItem(data);
historyModel->appendRow(items);
}
// 加载历史数据
void MainWindow::loadHistoryData(const QDate &date)
{
// 清空当前模型
historyModel->removeRows(0, historyModel->rowCount());
// 构造目录路径
QString dateDir = QString("%1/%2")
.arg(currentSavePath)
.arg(date.toString("yyyyMMdd"));
QDir dir(dateDir);
if (!dir.exists()) {
QMessageBox::information(this, "提示", "该日期没有历史数据");
return;
}
// 查找所有CSV文件
QStringList filters;
filters << "*.csv";
QStringList files = dir.entryList(filters, QDir::Files);
// 读取每个文件的数据
foreach (const QString &file, files) {
QString filePath = dir.filePath(file);
QFile dataFile(filePath);
if (dataFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QTextStream stream(&dataFile);
while (!stream.atEnd()) {
QString line = stream.readLine();
QStringList parts = line.split(",");
if (parts.size() >= 3) {
// 提取页面名称(从文件名中)
QString pageName = file;
pageName.replace(".csv", "");
pageName.replace("_"+date.toString("yyyyMMdd"), "");
// 添加到模型
QList<QStandardItem*> items;
items << new QStandardItem(parts[0]); // 时间戳
items << new QStandardItem(pageName); // 页面名称
// 合并剩余部分作为数据
QString data = parts.mid(2).join(",");
items << new QStandardItem(data);
historyModel->appendRow(items);
}
}
dataFile.close();
}
}
// 按时间排序
historyModel->sort(0, Qt::DescendingOrder);
// 显示记录数量
ui->statusBar->showMessage(QString("已加载 %1 条历史记录").arg(historyModel->rowCount()));
}
void MainWindow::changePathButton_clicked()
{
QString dir = QFileDialog::getExistingDirectory(this, tr("选择数据存储目录"),
currentSavePath,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty()) {
currentSavePath = dir;
ui->labelPath->setText(currentSavePath);
ui->labelPath->setToolTip(currentSavePath);
// 重新加载当前日期的历史数据
loadHistoryData(ui->calendarWidget->selectedDate());
QMessageBox::information(this, "提示", "数据存储路径已更改为:\n" + currentSavePath);
}
}
void MainWindow::refreshSerialPorts()
{
ui->serialportBox->clear();
const auto ports = QSerialPortInfo::availablePorts();
for (const QSerialPortInfo &port : ports) {
ui->serialportBox->addItem(port.portName());
}
}
void MainWindow::setupConnections()
{
// 连接数据更新信号
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateBatteryStatus1Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateVoltageInfoDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateTEMPInfoDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateAlarmInfoDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateBatteryStatus2Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellTempInfoDiaplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateFaultInfoDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateBMSInfoDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateSwitchStatusDisplay);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo1Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo2Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo3Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo4Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo5Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo6Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateCellVoltageInfo7Display);
connect(battery, &BatteryData::dataUpdated, this, &MainWindow::updateControlStatusDisplay);
}
void MainWindow::initPageSwitcher()
{
// 连接按钮信号到槽函数
connect(ui->BatteryStatusButton, &QPushButton::clicked, this, &MainWindow::switchToCellVoltagepage);
connect(ui->TEMPButton, &QPushButton::clicked, this, &MainWindow::switchToBaseStatusAndTEMPpage);
connect(ui->FaultButton, &QPushButton::clicked, this, &MainWindow::switchToFaultpage);
connect(ui->ControButton, &QPushButton::clicked, this, &MainWindow::switchToControlStatuspage);
connect(ui->HistoryButton, &QPushButton::clicked, this, &MainWindow::switchToHistorypage);
connect(ui->changeconnectionButton, &QPushButton::clicked, this, &MainWindow::switchToSerialconnectpage);
//路径选择
currentSavePath = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/BatteryData";
ui->labelPath->setText(currentSavePath);
ui->labelPath->setFrameStyle(QFrame::Panel | QFrame::Sunken);
// 设置按钮可选中状态
ui->BatteryStatusButton->setCheckable(true);
ui->TEMPButton->setCheckable(true);
ui->FaultButton->setCheckable(true);
ui->ControButton->setCheckable(true);
ui->HistoryButton->setCheckable(true);
}
// 页面切换实现
void MainWindow::switchToCellVoltagepage()
{
ui->stackedWidget->setCurrentIndex(0);
updateButtonStates(0);
}
void MainWindow::switchToBaseStatusAndTEMPpage()
{
ui->stackedWidget->setCurrentIndex(1);
updateButtonStates(1);
}
void MainWindow::switchToFaultpage()
{
ui->stackedWidget->setCurrentIndex(2);
updateButtonStates(2);
}
void MainWindow::switchToControlStatuspage()
{
ui->stackedWidget->setCurrentIndex(3);
updateButtonStates(3);
}
void MainWindow::switchToHistorypage()
{
ui->stackedWidget->setCurrentIndex(4);
updateButtonStates(4);
}
void MainWindow::switchToSerialconnectpage()
{
ui->stackedWidget->setCurrentIndex(5);
updateButtonStates(5);
}
// 更新按钮选中状态
void MainWindow::updateButtonStates(int index)
{
ui->BatteryStatusButton->setChecked(index == 0);
ui->TEMPButton->setChecked(index == 1);
ui->FaultButton->setChecked(index == 2);
ui->ControButton->setChecked(index == 3);
ui->HistoryButton->setChecked(index == 4);
ui->changeconnectionButton->setChecked(index == 5);
}
void MainWindow::connect_clicked()
{
if(canDevice && canDevice->state() == QCanBusDevice::ConnectedState) {
QMessageBox::information(this,tr("Info"), tr("Already connected"));
return;
}
QString errorString;
QString plugin = "peakcan";
QString interface = ui->portComboBox->currentText();
canDevice = QCanBus::instance()->createDevice(plugin, interface, &errorString);
if(!canDevice){
QMessageBox::critical(this, tr("error"), errorString);
return;
}
connect(canDevice, &QCanBusDevice::framesReceived,
this, &MainWindow::handleCanFrameReceived);
connect(canDevice, &QCanBusDevice::errorOccurred,[this](QCanBusDevice::CanBusError error) {
Q_UNUSED(error)
QMessageBox::critical(this, tr("Error"), canDevice->errorString());
});
//配置CAN参数
canDevice->setConfigurationParameter(QCanBusDevice::BitRateKey,
ui->BaudBox->currentText().toInt());
if(!canDevice->connectDevice()){
QMessageBox::critical(this, tr("Error"), tr("Failed to connect to CAN device"));
delete canDevice;
canDevice = nullptr;
return;
}
ui->statusBar->showMessage(tr("connect to CAN bus on %1").arg(interface));
ui->connectButton->setEnabled(false);
ui->disconnectButton->setEnabled(true);
QMessageBox box;
box.setStyleSheet("QLabel{"
"font-size:12 px;"
"font-color: white;"
"}");
}
void MainWindow::disconnect_clicked()
{
if (canDevice) {
// 断开所有信号
disconnect(canDevice, nullptr, this, nullptr);
if (canDevice->state() == QCanBusDevice::ConnectedState) {
canDevice->disconnectDevice();
}
delete canDevice;
canDevice = nullptr;
}
ui->statusBar->showMessage(tr("Disconnected"));
//ui->statusBar->setStyleSheet("font-color:white");
ui->connectButton->setEnabled(true);
ui->disconnectButton->setEnabled(false);
}
void MainWindow::handleCanFrameReceived()
{
if (!this || !canDevice) return; // 关键检查
while (canDevice->framesAvailable()) {
const QCanBusFrame frame = canDevice->readFrame();
parseCanFrame(frame);
}
//parseCanFrame(frame);
// 记录原始CAN帧到日志
/*if (isLogging && logFile && logFile->isOpen()) {
QTextStream out(logFile);
out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") << ","
<< "0x" << QString::number(frame.frameId(), 16) << ","
<< frame.payload().toHex() << "\n";
}*/
}
void MainWindow::serialconnect_clicked()
{
qDebug() << "Serial connect clicked. Current state:" << m_serialConnected;
if (m_serialConnected) {
QMessageBox::information(this, tr("Info"), tr("Already connected"));
return;
}
QString portName = ui->serialportBox->currentText();
int baudRate = ui->serialBaudBox->currentText().toInt();
if (m_serialInterface->connectPort(portName, baudRate)) {
ui->statusBar->showMessage(tr("Connected to %1").arg(portName));
} else {
updateSerialConnectionStatus(false);
QMessageBox::critical(this, tr("Error"), tr("Failed to connect to serial port"));
}
}
// 串口断开按钮
void MainWindow::serialdisconnect_clicked()
{
qDebug() << "Serial disconnect clicked. Current state:" << m_serialConnected;
if (m_serialInterface && m_serialConnected) {
// 先断开所有信号
disconnect(m_serialInterface, nullptr, this, nullptr);
// 断开串口
m_serialInterface->disconnectPort();
// 手动更新状态
updateSerialConnectionStatus(false);
}
ui->statusBar->showMessage(tr("Disconnected"));
}
// 串口数据接收处理
void MainWindow::handleSerialDataReceived(const QByteArray &data)
{
if (!this) return;
// 这里添加485协议解析逻辑
// 示例:假设485协议与CAN协议兼容
parseProtocolData(data);
// 记录原始数据
/*if (logFile && logFile->isOpen()) {
QTextStream out(logFile);
out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")
<< ",SERIAL_RX," << data.toHex() << "\n";
}*/
}
void MainWindow::parseProtocolData(const QByteArray &data)
{
// 这里实现485协议解析逻辑
// 示例:简单的协议解析
/*if (data.size() >= 2) {
quint8 command = static_cast<quint8>(data[0]);
QByteArray payload = data.mid(1);
switch (command) {
case 0x01: // 电池状态
handleBattStatusFrame(payload);
break;
case 0x02: // 电芯电压
handleCellVoltageFrame(payload);
break;
// 其他命令...
default:
break;
}
}*/
}
// 串口错误处理
void MainWindow::handleSerialError(const QString &error)
{
QMessageBox::critical(this, tr("Serial Error"), error);
}
// 更新串口连接状态
void MainWindow::updateSerialConnectionStatus(bool connected)
{
m_serialConnected = connected;
// 更新按钮状态
ui->serialConnectButton->setEnabled(!connected);
ui->serialDisconnectButton->setEnabled(connected);
ui->serialportBox->setEnabled(!connected);
ui->serialBaudBox->setEnabled(!connected);
if (connected) {
ui->statusBar->showMessage(tr("已连接"));
ui->statusBar->setStyleSheet("color: green;");
} else {
ui->statusBar->showMessage(tr("未连接"));
ui->statusBar->setStyleSheet("color: red;");
ui->serialDisconnectButton->setEnabled(false); // 确保断开按钮被禁用
}
}
void MainWindow::parseCanFrame(const QCanBusFrame &frame)
{
const bool isExtended = frame.hasExtendedFrameFormat();
const quint32 id = frame.frameId();
const QByteArray data = frame.payload();
qDebug() << "Frame ID:" << id;
qDebug() << "Payload Data:" << data.toHex();
if (isExtended) {
// 处理扩展帧(29位ID)
qDebug() << "this is an extended frame.";
switch (id) {
case 0x18F128F4: // 电池状态2
handleBatteryStatus2Frame(data);
break;
case 0x18F228F4: // 单体温度
handleCellTempInfoFrame(data);
break;
case 0x18F328F4: // bms内部所有故障信息
handleFaultInfoFrame(data);
break;
case 0x18F428F4: // bms信息
handleBMSInfoFrame(data);
break;
case 0x18F528F4: // 开关状态
handleSwitchStatusFrame(data);
break;
case 0x18E028F4: // 单体电压
handleCellVoltageInfo1Frame(data);
break;
case 0x18E128F4:
handleCellVoltageInfo2Frame(data);
break;
case 0x18E228F4:
handleCellVoltageInfo3Frame(data);
break;
case 0x18E328F4:
handleCellVoltageInfo4Frame(data);
break;
case 0x18E428F4:
handleCellVoltageInfo5Frame(data);
break;
case 0x18E528F4:
handleCellVoltageInfo6Frame(data);
break;
case 0x18E628F4:
handleCellVoltageInfo7Frame(data);
break;
case 0x18F0F428: // 控制信息
handleControlStatusFrame(data);
break;
case 0x1806E5F4: // 充电请求信息
handleChargeInfoFrame(data);
break;
default:
break;
}
} else {
qDebug() << "this is an standard frame.";
// 处理标准帧(11位ID)
switch (id) {
case 0x02F4: // 电池状态
handleBatteryStatus1Frame(data);
break;
case 0x04F4: // 电芯电压
handleVoltageInfoFrame(data);
break;
case 0x05F4: // 电芯温度
handleTEMPInfoFrame(data);
break;
case 0x07F4: // 故障信息
handleAlarmInfoFrame(data);
break;
default:
break;
}
}
}
void MainWindow::handleBatteryStatus1Frame(const QByteArray &data)
{
if (data.size() < 5) return;
BatteryStatus1 status;
// 解析电压 (0-1字节,小端)
quint16 voltRaw = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
status.totalVoltage = voltRaw * 0.1;
// 解析电流 (2-3字节,小端)
qint16 currRaw = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
status.totalCurrent = (currRaw - 400) * 0.1;
// 解析SOC (4字节)
status.SOC = static_cast<quint8>(data[4]);
battery->updateBatteryStatus1(status);
}
void MainWindow::handleVoltageInfoFrame(const QByteArray &data)
{
if (data.size() < 5) return;
VoltageInfo info;
info.maxVoltage = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
qDebug() << "maxVoltage = " << QString::number(info.maxVoltage,16);
info.maxVoltageCellNo = static_cast<quint8>(data[3]);
info.minVoltage = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.minVoltageCellNo = static_cast<quint8>(data[6]);
battery->updateVoltageInfo(info);
}
void MainWindow::handleTEMPInfoFrame(const QByteArray &data)
{
if (data.size() < 5) return;
TEMPInfo info;
info.maxTemp = static_cast<quint8>(data[0]) - 50;
info.maxTempCellNo = static_cast<quint8>(data[1]);
info.minTemp = static_cast<quint8>(data[2]) - 50;
info.minTempCellNo = static_cast<quint8>(data[3]);
info.avgTemp = static_cast<quint8>(data[4]) - 50;
battery->updateTEMPInfo(info);
}
void MainWindow::handleAlarmInfoFrame(const QByteArray &data)
{
if (data.size() < 4) return;
AlarmInfo alarm;
quint32 alarmBits = (static_cast<quint8>(data[0]) << 24 |
(static_cast<quint8>(data[1]) << 16) |
(static_cast<quint8>(data[2]) << 8) |
(static_cast<quint8>(data[3])));
alarm.cellOverVoltage = (alarmBits >> 0) & 0x03;
alarm.cellUnderVoltage = (alarmBits >> 2) & 0x03;
alarm.cellDiffVoltage = (alarmBits >> 8) & 0x03;
alarm.dischargeOverCurrent = (alarmBits >> 10) & 0x03;
alarm.chargeOverCurrent = (alarmBits >> 12) & 0x03;
alarm.overTemperature = (alarmBits >> 14) & 0x03;
alarm.underTemperature = (alarmBits >> 16) & 0x03;
alarm.socLow = (alarmBits >> 20) & 0x03;
alarm.internalCommFault = (alarmBits >>28) & 0x03;
battery->updateAlarmInfo(alarm);
// 记录报警信息
/*if (logFile && logFile->isOpen()) {
QTextStream out(logFile);
out << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") << ","
<< "Alarms:";
if (alarm.cellOverVoltage) out << " 单体过压(" << alarm.cellOverVoltage << ")";
if (alarm.cellUnderVoltage) out << " 单体欠压(" << alarm.cellUnderVoltage << ")";
if (alarm.cellDiffVoltage) out << " 单体压差大(" << alarm.cellDiffVoltage << ")";
if (alarm.dischargeOverCurrent) out << " 放电过流(" << alarm.dischargeOverCurrent << ")";
if (alarm.chargeOverCurrent) out << " 充电过流(" << alarm.chargeOverCurrent << ")";
if (alarm.overTemperature) out << " 温度过高(" << alarm.overTemperature << ")";
if (alarm.underTemperature) out << " 温度过低(" << alarm.underTemperature << ")";
if (alarm.socLow) out << " SOC低(" << alarm.socLow << ")";
if (alarm.internalCommFault) out << " 通信故障(" << alarm.internalCommFault << ")";
out << "\n";
}*/
}
void MainWindow::handleBatteryStatus2Frame(const QByteArray &data)
{
if (data.size() < 8) return;
BatteryStatus2 status;
status.remainingCapacity = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1]))) * 0.1;
status.actualCapacity = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3]))) * 0.1;
status.cycleCapacity = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5]))) * 0.1;
status.cycleCount = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7]))) * 0.1;
battery->updateBatteryStatus2(status);
}
void MainWindow::handleCellTempInfoFrame(const QByteArray &data)
{
if (data.size() < 5) return;
CellTempInfo info;
info.cellTEMP1 = static_cast<quint8>(data[1]) - 50;
info.cellTEMP2 = static_cast<quint8>(data[2]) - 50;
info.cellTEMP3 = static_cast<quint8>(data[3]) - 50;
info.cellTEMP4 = static_cast<quint8>(data[4]) - 50;
info.cellTEMP5 = static_cast<quint8>(data[5]) - 50;
battery->updateCellTempInfo(info);
}
void MainWindow::handleFaultInfoFrame(const QByteArray &data)
{
if (data.size() < 3) return;
FaultInfo info;
quint8 faultByte1 = static_cast<quint8>(data[0]);
quint8 faultByte2 = static_cast<quint8>(data[1]);
quint8 faultByte3 = static_cast<quint8>(data[2]);
info.OverLineResistance = (faultByte1 >> 0) & 0x01;
info.MOSoverTEMP = (faultByte1 >> 1) & 0x01;
info.Cellnumber = (faultByte1 >> 2) & 0x01;
info.CurrentSensor = (faultByte1 >> 3) & 0x01;
info.CellOverVol = (faultByte1 >> 4) & 0x01;
info.OverTotalVoltage = (faultByte1 >> 5) &0x01;
info.ChargeOverCur = (faultByte1 >> 6) &0x01;
info.ChargeShortCircuit = (faultByte1 >> 7) &0x01;
info.ChargeOverTEMP = (faultByte2 >> 0) & 0x01;
info.ChargeUnderTEMP = (faultByte2 >> 1) & 0x01;
info.InternalCom = (faultByte2 >> 2) & 0x01;
info.CellUnderVol = (faultByte2 >> 3) & 0x01;
info.UnderTotalVol = (faultByte2 >> 4) & 0x01;
info.DischargeOverCur = (faultByte2 >> 5) & 0x01;
info.DischargeShortCircuit = (faultByte2 >> 6) & 0x01;
info.DischargeOverTEMP = (faultByte2 >> 7) & 0x01;
info.ChargeMOS = (faultByte3 >> 0) & 0x01;
info.DischargeMOS = (faultByte3 >> 1) & 0x01;
battery->updateFaultInfo(info);
}
void MainWindow::handleBMSInfoFrame(const QByteArray &data)
{
if (data.size() < 7) return;
BMSInfo info;
info.runningTime = (static_cast<quint8>(data[0]) << 24 |
(static_cast<quint8>(data[1]) << 16) |
(static_cast<quint8>(data[2]) << 8) |
(static_cast<quint8>(data[3])));
info.HeatCurrent = (static_cast<quint8>(data[4]) << 8 | static_cast<quint8>(data[5]));
info.SOH = static_cast<quint8>(data[6]);
battery->updateBMSInfo(info);
}
void MainWindow::handleSwitchStatusFrame(const QByteArray &data)
{
if (data.size() < 1) return;
SwitchStatus status;
quint8 statusByte = static_cast<quint8>(data[0]);
status.ChargeMOSStatus = (statusByte >> 0) & 0x01;
status.DischargeMOSStatus = (statusByte >> 1) & 0x01;
status.BalanceStatus = (statusByte >> 2) & 0x01;
status.HeatStatus = (statusByte >> 3) & 0x01;
status.ChgDevPlugStatus = (statusByte >> 4) & 0x01;
status.ACCStatus =(statusByte >> 5) & 0x01;
battery->updateSwitchStatus(status);
}
void MainWindow::handleCellVoltageInfo1Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo1 info;
info.cellVoltage1 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage2 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage3 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage4 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage1(info);
}
void MainWindow::handleCellVoltageInfo2Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo2 info;
info.cellVoltage5 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage6 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage7 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage8 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage2(info);
}
void MainWindow::handleCellVoltageInfo3Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo3 info;
info.cellVoltage9 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage10 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage11 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage12 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage3(info);
}
void MainWindow::handleCellVoltageInfo4Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo4 info;
info.cellVoltage13 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage14 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage15 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage16 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage4(info);
}
void MainWindow::handleCellVoltageInfo5Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo5 info;
info.cellVoltage17 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage18 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage19 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage20 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage5(info);
}
void MainWindow::handleCellVoltageInfo6Frame(const QByteArray &data)
{
if (data.size() < 8) return;
CellVoltageInfo6 info;
info.cellVoltage21 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
info.cellVoltage22 = (static_cast<quint8>(data[2]) << 8 | (static_cast<quint8>(data[3])));
info.cellVoltage23 = (static_cast<quint8>(data[4]) << 8 | (static_cast<quint8>(data[5])));
info.cellVoltage24 = (static_cast<quint8>(data[6]) << 8 | (static_cast<quint8>(data[7])));
battery->updateCellVoltage6(info);
}
void MainWindow::handleCellVoltageInfo7Frame(const QByteArray &data)
{
if (data.size() < 2) return;
CellVoltageInfo7 info;
info.cellVoltage25 = (static_cast<quint8>(data[0]) << 8 | (static_cast<quint8>(data[1])));
battery->updateCellVoltage7(info);
}
void MainWindow::handleControlStatusFrame(const QByteArray &data)
{
if (data.size() < 4) return;
ControlStatus status;
quint8 statusByte = static_cast<quint8>(data[0]);
status.chargeEnabled = statusByte & 0x01;
status.dischargeEnabled = statusByte & 0x02;
status.balanceEnabled = statusByte &0x04;
status.chargeSwitch = static_cast<quint8>(data[1]);
status.dischargeSwitch = static_cast<quint8>(data[2]);
status.balanceSwitch = static_cast<quint8>(data[3]);
battery->updateControlStatus(status);
}
void MainWindow::handleChargeInfoFrame(const QByteArray &data)
{
if(data.size() < 4) return;
ChargeInfo info;
info.chargeVoltage = static_cast<quint8>(data[0]);
info.chargeCurrent = static_cast<quint8>(data[1]);
info.chargeDeviceSwitch = static_cast<quint8>(data[2]);
info.chargeAndHeatMode = static_cast<quint8>(data[3]);
battery->updateChargeInfo(info);
}
void MainWindow::updateBatteryStatus1Display()
{
BatteryStatus1 status = battery->getBatteryStatus1();
ui->BatteryTotalVoltageLCD->display(QString::number(status.totalVoltage,'f',1));
ui->BatteryTotalCurrentLCD->display(QString::number(status.totalCurrent,'f',1));
ui->BatterySOCLCD->display(QString::number(status.SOC));
}
void MainWindow::updateVoltageInfoDisplay()
{
VoltageInfo info = battery->getVoltageInfo();
ui->MAXcellVoltangeLCD->display(QString::number(info.maxVoltage));
ui->MAXcvNoLCD->display(QString::number(info.maxVoltageCellNo));
ui->MINcellVoltangeLCD->display(QString::number(info.minVoltage));
ui->MINcvNoLCD->display(QString::number(info.minVoltageCellNo));
}
void MainWindow::updateTEMPInfoDisplay()
{
TEMPInfo info = battery->getTEMPInfo();
ui->MAXcellTEMPLCD->display(QString::number(info.maxTemp));
ui->MAXctNoLCD->display(QString::number(info.maxTempCellNo));
ui->MINcellTEMPLCD->display(QString::number(info.maxTemp));
ui->MINctNoLCD->display(QString::number(info.minTempCellNo));
ui->AVGcellTEMPLCD->display(QString::number(info.avgTemp));
}
void MainWindow::updateAlarmInfoDisplay()
{
AlarmInfo info = battery->getAlarmInfo();
updateAlarmLabel(ui->CellOverVoltageLabel, info.cellOverVoltage,"");
updateAlarmLabel(ui->CellUnderVoltageLabel,info.cellUnderVoltage,"");
updateAlarmLabel(ui->VoltageDifferenceLabel,info.cellDiffVoltage,"");
updateAlarmLabel(ui->DischargeOverCurrentLabel,info.dischargeOverCurrent,"");
updateAlarmLabel(ui->ChargeOverCurrentLabel,info.chargeOverCurrent,"");
updateAlarmLabel(ui->OverTEMPLabel,info.overTemperature,"");
updateAlarmLabel(ui->underTEMPLabel,info.underTemperature,"");
updateAlarmLabel(ui->UnderSOCLabel,info.socLow,"");
updateAlarmLabel(ui->InternalCommunicationLabel,info.internalCommFault,"");
}
void MainWindow::updateAlarmLabel(QLabel *label, int level, const QString &text)
{
if (level == 0) {
label->setText(text + ": 正常");
label->setStyleSheet("color: green");
} else {
QString levelText;
QString color;
switch (level) {
case 1: levelText = "严重"; color = "red"; break;
case 2: levelText = "重要"; color = "orange"; break;
case 3: levelText = "一般"; color = "yellow"; break;
}
label->setText(text + ": " + levelText + "告警");
label->setStyleSheet("color: " + color + "; font-weight: bold");
}
}
void MainWindow::updateBatteryStatus2Display()
{
BatteryStatus2 status = battery->getBatteryStatus2();
ui->CapRemainLCD->display(QString::number(status.remainingCapacity));
ui->FulChargeCapLCD->display(QString::number(status.actualCapacity));
ui->CycleCapLCD->display(QString::number(status.cycleCapacity));
ui->CycleCountLCD->display(QString::number(status.cycleCount));
}
void MainWindow::updateCellTempInfoDiaplay()
{
CellTempInfo info = battery->getCellTempInfo();
ui->cellTEMP1LCD->display(QString::number(info.cellTEMP1));
ui->cellTEMP2LCD->display(QString::number(info.cellTEMP2));
ui->cellTEMP3LCD->display(QString::number(info.cellTEMP3));
ui->cellTEMP4LCD->display(QString::number(info.cellTEMP4));
ui->cellTEMP5LCD->display(QString::number(info.cellTEMP5));
}
void MainWindow::updateFaultInfoDisplay()
{
FaultInfo info = battery->getFaultInfo();
updateFaultLabel(ui->OverLineResistanceLabel,info.OverLineResistance,"");
updateFaultLabel(ui->MOSoverTEMPLabel,info.MOSoverTEMP,"");
updateFaultLabel(ui->CellnumberLabel,info.Cellnumber,"");
updateFaultLabel(ui->CurrentSensorLabel,info.CurrentSensor,"");
updateFaultLabel(ui->CellOverVolLabel,info.CellOverVol,"");
updateFaultLabel(ui->OverTotalVoltageLabel,info.OverTotalVoltage,"");
updateFaultLabel(ui->ChargeOverCurLabel,info.ChargeOverCur,"");
updateFaultLabel(ui->ChargeShortCircuitLabel,info.ChargeShortCircuit,"");
updateFaultLabel(ui->ChargeOverTEMPLabel,info.ChargeOverTEMP,"");
updateFaultLabel(ui->ChargeUnderTEMPLabel,info.ChargeUnderTEMP,"");
updateFaultLabel(ui->InternalComLabel,info.InternalCom,"");
updateFaultLabel(ui->CellUnderVolLabel,info.CellUnderVol,"");
updateFaultLabel(ui->UnderTotalVolLabel,info.UnderTotalVol,"");
updateFaultLabel(ui->DischargeOverCurLabel,info.DischargeOverCur,"");
updateFaultLabel(ui->DischargeShortCircuitLabel,info.DischargeShortCircuit,"");
updateFaultLabel(ui->DischargeOverTEMPLabel,info.DischargeOverTEMP,"");
updateFaultLabel(ui->ChargeMOSLabel,info.ChargeMOS,"");
updateFaultLabel(ui->DischargeMOSLabel,info.DischargeMOS,"");
}
void MainWindow::updateFaultLabel(QLabel *label, int state, const QString &text)
{
if (state == 0) {
label->setText(text + ": 正常");
label->setStyleSheet("color: green");
} else {
label->setText(text + ": 报警");
label->setStyleSheet("color: red; font-weight: bold");
}
}
void MainWindow::updateBMSInfoDisplay()
{
BMSInfo info = battery->getBMSInfo();
ui->BMSRunTimeLCD->display(QString::number(info.runningTime));
ui->HeatCurrentLCD->display(QString::number(info.HeatCurrent));
ui->SOHLCD->display(QString::number(info.SOH));
}
void MainWindow::updateSwitchStatusDisplay()
{
SwitchStatus status = battery->getSwitchStatus();
updateSwitchLabel(ui->ChargeMOSStatusLabel,status.ChargeMOSStatus,"");
updateSwitchLabel(ui->DischargeMOSStatusLabel,status.DischargeMOSStatus,"");
updateSwitchLabel(ui->BalanceStatusLabel,status.BalanceStatus,"");
updateSwitchLabel(ui->HeatStatusLabel,status.HeatStatus,"");
updateSwitchLabel(ui->ChgDevPlugStatusLabel,status.ChgDevPlugStatus,"");
updateSwitchLabel(ui->ACCStatusLabel,status.ACCStatus,"");
}
void MainWindow::updateSwitchLabel(QLabel *label, bool isOn, const QString &text)
{
if (isOn) {
label->setText("打开");
label->setStyleSheet("color: green; font-weight: bold;");
} else {
label->setText("闭合");
label->setStyleSheet("color: gray;");
}
}
void MainWindow::updateCellVoltageInfo1Display()
{
CellVoltageInfo1 info = battery->getCellVoltageInfo1();
ui->cellVoltage1LCD->display(QString::number(info.cellVoltage1));
ui->cellVoltage2LCD->display(QString::number(info.cellVoltage2));
ui->cellVoltage3LCD->display(QString::number(info.cellVoltage3));
ui->cellVoltage4LCD->display(QString::number(info.cellVoltage4));
}
void MainWindow::updateCellVoltageInfo2Display()
{
CellVoltageInfo2 info = battery->getCellVoltageInfo2();
ui->cellVoltage5LCD->display(QString::number(info.cellVoltage5));
ui->cellVoltage6LCD->display(QString::number(info.cellVoltage6));
ui->cellVoltage7LCD->display(QString::number(info.cellVoltage7));
ui->cellVoltage8LCD->display(QString::number(info.cellVoltage8));
}
void MainWindow::updateCellVoltageInfo3Display()
{
CellVoltageInfo3 info = battery->getCellVoltageInfo3();
ui->cellVoltage9LCD->display(QString::number(info.cellVoltage9));
ui->cellVoltage10LCD->display(QString::number(info.cellVoltage10));
ui->cellVoltage11LCD->display(QString::number(info.cellVoltage11));
ui->cellVoltage12LCD->display(QString::number(info.cellVoltage12));
}
void MainWindow::updateCellVoltageInfo4Display()
{
CellVoltageInfo4 info = battery->getCellVoltageInfo4();
ui->cellVoltage13LCD->display(QString::number(info.cellVoltage13));
ui->cellVoltage14LCD->display(QString::number(info.cellVoltage14));
ui->cellVoltage15LCD->display(QString::number(info.cellVoltage15));
ui->cellVoltage16LCD->display(QString::number(info.cellVoltage16));
}
void MainWindow::updateCellVoltageInfo5Display()
{
CellVoltageInfo5 info = battery->getCellVoltageInfo5();
ui->cellVoltage17LCD->display(QString::number(info.cellVoltage17));
ui->cellVoltage18LCD->display(QString::number(info.cellVoltage18));
ui->cellVoltage19LCD->display(QString::number(info.cellVoltage19));
ui->cellVoltage20LCD->display(QString::number(info.cellVoltage20));
}
void MainWindow::updateCellVoltageInfo6Display()
{
CellVoltageInfo6 info = battery->getCellVoltageInfo6();
ui->cellVoltage21LCD->display(QString::number(info.cellVoltage21));
ui->cellVoltage22LCD->display(QString::number(info.cellVoltage22));
ui->cellVoltage23LCD->display(QString::number(info.cellVoltage23));
ui->cellVoltage24LCD->display(QString::number(info.cellVoltage24));
}
void MainWindow::updateCellVoltageInfo7Display()
{
CellVoltageInfo7 info = battery->getCellVoltageInfo7();
ui->cellVoltage25LCD->display(QString::number(info.cellVoltage25));
}
void MainWindow::updateControlStatusDisplay()
{
ControlStatus status = battery->getControlStatus();
updateEableLabel(ui->ChargeControlLabel,status.chargeEnabled,"");
updateEableLabel(ui->DischargeControlLabel,status.dischargeEnabled,"");
updateEableLabel(ui->BalanceControlLabel,status.balanceEnabled,"");
updateCSwitchLabel(ui->ChargeSwitchLabel,status.chargeSwitch,"",status.chargeEnabled);
updateCSwitchLabel(ui->DischargeSwitchLabel,status.dischargeSwitch,"",status.dischargeEnabled);
updateCSwitchLabel(ui->BalanceStatusLabel,status.balanceSwitch,"",status.balanceEnabled);
}
void MainWindow::updateEableLabel(QLabel *label, bool isOn, const QString &text)
{
if (isOn) {
label->setText("允许控制");
label->setStyleSheet("color: green; font-weight: bold;");
} else {
label->setText("禁止控制");
label->setStyleSheet("color: gray;");
}
}
void MainWindow::updateCSwitchLabel(QLabel *label, bool isOn, const QString &text, bool isEnableActive)
{
// 如果总开关禁止控制,则显示无效状态
if (!isEnableActive) {
label->setText("无效");
label->setStyleSheet("color: gray; font-style: italic;");
}
// 否则正常显示开关状态
else if (isOn) {
label->setText("打开");
label->setStyleSheet("color: green; font-weight: bold;");
} else {
label->setText("闭合");
label->setStyleSheet("color: gray;");
}
}
void MainWindow::updateChargeInfoDisplay()
{
ChargeInfo info = battery->getChargeInfo();
ui->ChargeVoltageLCD->display(QString::number(info.chargeVoltage));
ui->ChargeCurrentLCD->display(QString::number(info.chargeCurrent));
updateChgDevSwLabel(ui->ChgDevSwLabel,info.chargeDeviceSwitch,"");
updateModeLabel(ui->ChargeModeLabel,info.chargeAndHeatMode,"");
}
void MainWindow::updateChgDevSwLabel(QLabel *label, bool isOn, const QString &text)
{
if (isOn) {
label->setText("打开");
label->setStyleSheet("color: green; font-weight: bold;");
} else {
label->setText("关闭");
label->setStyleSheet("color: gray;");
}
}
void MainWindow::updateModeLabel(QLabel *label, bool isOn, const QString &text)
{
if (isOn) {
label->setText("充电");
label->setStyleSheet("color: green; font-weight: bold;");
} else {
label->setText("加热");
label->setStyleSheet("color: gray;");
}
}
运行后出现以下错误E:\JKBMS\CANeg\mainwindow.cpp:124: error: 'logCurrentPageData' is not a member of 'MainWindow'
..\..\mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)':
..\..\mainwindow.cpp:124:67: error: 'logCurrentPageData' is not a member of 'MainWindow'
124 | connect(dataLoggerTimer, &QTimer::timeout, this, &MainWindow::logCurrentPageData);
| ^~~~~~~~~~~~~~~~~~