diff --git a/CableTool/common.h b/CableTool/common.h index c957c6a..8f57f8c 100644 --- a/CableTool/common.h +++ b/CableTool/common.h @@ -75,12 +75,13 @@ typedef unsigned uint32_t; #define DAU_PORT_POWER_CNT 8 #define DAU_PORT_DEFECT_MAX 4 #define DAU_PORT_FAULT_MAX 4 +/* ADC 校准点. */ +#define DAU_POWER_ADJ_CNT 5 /* ADC 通道数. */ #define CFG_ADC_CH_CNT 8 #define SENSOR_SUM 8 /* ADC 校准点. */ -#define CFG_ADC_ADJ_CNT 5 #define ADC_COLLECT_CNT 2000 // ADC 每个通道采样次数. /* RS485 传感器数量. */ @@ -419,6 +420,28 @@ typedef struct uint32_t scDownTime; // 超级电容放电时间. } devState; +/* 校准参数信息. */ +typedef struct +{ + uint16_t ADCRatio[DAU_PORT_POWER_CNT]; + uint32_t ADCBase_elec[DAU_PORT_POWER_CNT][DAU_POWER_ADJ_CNT]; + uint16_t ADCAdj[DAU_PORT_POWER_CNT][DAU_POWER_ADJ_CNT]; + float ADCBase[DAU_PORT_POWER_CNT][DAU_POWER_ADJ_CNT]; + uint16_t vin; + uint16_t vin_adj; + uint8_t ADC_turns[DAU_PORT_POWER_CNT]; +} dev_adj_t; + +/* 校准命令信息. */ +typedef struct +{ + uint8_t chSelecet; + uint8_t isVoltageSel; + uint8_t manualIndex; + uint8_t reserve[1]; +} adjSet; + + /* 高频校准信息. */ typedef struct { diff --git a/CableTool/widget.cpp b/CableTool/widget.cpp index 3325979..0fb9171 100644 --- a/CableTool/widget.cpp +++ b/CableTool/widget.cpp @@ -26,6 +26,12 @@ Widget::Widget(QWidget *parent) memset(powerFre, 0, sizeof(powerFre)); + memset(&clientDevState, 0, sizeof(devState)); + + memset(&clientAdjInfo, 0, sizeof(dev_adj_t)); + + memset(&clientAdjSet, 0, sizeof(adjSet)); + isConnected = 0; upFileRecvSize = 0; upFileSize = 0; @@ -606,6 +612,58 @@ void Widget::uiPowerFrequencyRefresh() } } +/* 手动校准界面刷新. */ +void Widget::uiManualAdjustRefresh() +{ + uint8_t ch = 0; + int index = 0; + + /* 获取校准通道. */ + for(uint8_t i = 0; i < ui->adjustTable->rowCount(); i++) + { + QCheckBox *checkBox = reinterpret_cast(ui->adjustTable->cellWidget(i, 0)); + if (checkBox->isChecked()) + { + ch = i; + break; + } + } + + if (ch >= ui->adjustTable->rowCount()) + { + ch = 0; + } + + index = ui->manualAdjBox->currentIndex(); + ui->manualAdjLabel->setText("输入电流" + QString::number(clientAdjInfo.ADCBase_elec[ch][index] / 1000) + "A"); + ui->manualAdjButton->setText("手动校准段" + QString::number(index + 1)); +} + +void Widget::uiAdjustInfoRefresh() +{ + QString temp; + + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + ui->adjustTable->item(i, 2)->setText(QString::number(clientAdjInfo.ADCRatio[i])); + ui->adjustTable->item(i, 3)->setText(QString::number(clientAdjInfo.ADC_turns[i])); + for(int j = 0; j < DAU_POWER_ADJ_CNT; j++) + { + ui->adjustTable->item(i, j * 3 + 4)->setText(QString::number(clientAdjInfo.ADCBase_elec[i][j])); + temp.sprintf("%.1f", static_cast(clientAdjInfo.ADCBase[i][j])); + ui->adjustTable->item(i, j * 3 + 5)->setText(temp); + ui->adjustTable->item(i, j * 3 + 6)->setText(QString::number(clientAdjInfo.ADCAdj[i][j])); + } + } + + ui->vinEdit->setText(QString::number(clientAdjInfo.vin_adj)); + ui->vinAdjEdit->setText(QString::number(clientAdjInfo.vin)); + + uiManualAdjustRefresh(); +} + + + void Widget::protoContact(char *data) { char *pbody = data + sizeof(proto_head_t); @@ -768,6 +826,48 @@ int Widget::protoState(char *data) return 0; } +int Widget::protoManualAdjust(char *data) +{ + int32_t rv = *reinterpret_cast(data + sizeof(proto_head_t)); + + sendMsgDeviceAdjustInfoGet(); + buttonEnable(true); + + /* 判断返回值. */ + if (0 == rv) + { + QMessageBox::information(this, "SUCCEED", "校准完成.", QMessageBox::Ok); + int index = ui->manualAdjBox->currentIndex(); + + index++; + if (index >= DAU_POWER_ADJ_CNT) + { + index = 0; + } + + ui->manualAdjBox->setCurrentIndex(index); + uiManualAdjustRefresh(); + } + else + { + QMessageBox::warning(this, "WARNING", "校准失败!", QMessageBox::Ok); + } + + return 0; +} + +int Widget::protoAdjustInfo(char *data) +{ + /* 获取参数. */ + memcpy(&clientAdjInfo, data + sizeof(proto_head_t), sizeof(dev_adj_t)); + + /* 更新界面. */ + protoManualAdjust(data); + return 0; +} + + + int Widget::paraseProtocols(char *data) { proto_head_t *header = reinterpret_cast(data); @@ -821,10 +921,11 @@ int Widget::paraseProtocols(char *data) protoWaveDataUploadReply(data); break; case DEBUG_PRV_ADJ_INFO: - //_debug_pkt_adj_get(); + protoAdjustInfo(data); break; case DEBUG_PRV_ADJ_INFO_SET: - //_debug_pkt_adj_set(); + /* 更新界面. */ + QMessageBox::information(this, "SUCCEED", "操作完成.", QMessageBox::Ok); break; case DEBUG_PRV_ADJ_AUTO: //_debug_pkt_adj_auto(); @@ -845,7 +946,7 @@ int Widget::paraseProtocols(char *data) //_debug_pkt_history_data_get(); break; case DEBUG_PRV_ADJ_MANUAL: - //_debug_pkt_adj_manual(); + protoManualAdjust(data); break; case DEBUG_PRV_CSG_CONFIG: // 获取配置成功后更新页面 protoCsgConfig(data); @@ -1138,6 +1239,65 @@ int Widget::sendMsgDevicePowerFrequencyGet() return 0; } +int Widget::sendMsgDeviceAdjustInfoSet() +{ + char buf[2048] = {0}; + uint32_t *crc = nullptr; + proto_head_t *header = reinterpret_cast(buf); + dev_adj_t *pdata = reinterpret_cast(buf + sizeof(proto_head_t)); + + /* 初始化报文头. */ + protoHeaderInit(header, sizeof(proto_head_t), clientDevInfo.id, DEBUG_CT_PRV_REQUEST, DEBUG_PRV_ADJ_INFO_SET); + memcpy(pdata, &clientAdjInfo, sizeof(dev_adj_t)); + + /* 计算校验位. */ + crc = reinterpret_cast(buf + header->len); + *crc = crc32(buf, header->len); + + HexPrint(__FUNCTION__, buf, header->len + 4); + writeData(buf, header->len + 4); + return 0; +} + +int Widget::sendMsgDeviceAdjustInfoGet() +{ + char buf[2048] = {0}; + uint32_t *crc = nullptr; + proto_head_t *header = reinterpret_cast(buf); + + /* 初始化报文头. */ + protoHeaderInit(header, sizeof(proto_head_t), clientDevInfo.id, DEBUG_CT_PRV_REQUEST, DEBUG_PRV_ADJ_INFO); + + /* 计算校验位. */ + crc = reinterpret_cast(buf + header->len); + *crc = crc32(buf, header->len); + + HexPrint(__FUNCTION__, buf, header->len + 4); + writeData(buf, header->len + 4); + return 0; +} + +int Widget::sendMsgDeviceAdjustMode(int cmd) +{ + char buf[2048] = {0}; + uint32_t *crc = nullptr; + proto_head_t *header = reinterpret_cast(buf); + adjSet *pdata = reinterpret_cast(buf + sizeof(proto_head_t)); + + /* 初始化报文头. */ + protoHeaderInit(header, sizeof(proto_head_t) + sizeof(adjSet), clientDevInfo.id, DEBUG_CT_PRV_REQUEST, cmd); + + memcpy(pdata, &clientAdjSet, sizeof(adjSet)); + + /* 计算校验位. */ + crc = reinterpret_cast(buf + header->len); + *crc = crc32(buf, header->len); + + HexPrint(__FUNCTION__, buf, header->len + 4); + writeData(buf, header->len + 4); + return 0; +} + int Widget::sendMsgWaveCol() @@ -1651,3 +1811,252 @@ void Widget::on_waveButton_clicked() } } + +void Widget::on_manualRatioSetButton_clicked() +{ + /* 获取参数. */ + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + clientAdjInfo.ADCRatio[i] = ui->adjustTable->item(i, 2)->text().toUShort(); + clientAdjInfo.ADC_turns[i] = static_cast(ui->adjustTable->item(i, 3)->text().toUShort()); + for(int j = 0; j < DAU_POWER_ADJ_CNT ; j++) + { + clientAdjInfo.ADCBase_elec[i][j] = ui->adjustTable->item(i, 4 + j * 3)->text().toUInt(); + } + + } + clientAdjInfo.vin_adj = ui->vinEdit->text().toUShort(); + clientAdjInfo.vin = ui->vinAdjEdit->text().toUShort(); + + /* 下发配置. */ + sendMsgDeviceAdjustInfoSet(); + + uiManualAdjustRefresh(); +} + + +void Widget::on_manualAdjBox_activated(int index) +{ + if (index < 10) + { + uiManualAdjustRefresh(); + } +} + +void Widget::on_manualAdjButton_clicked() +{ + adjSet adj; + + memset(&adj, 0, sizeof(adjSet)); + + /* 获取校准通道. */ + for(int32_t i = 0; i < ui->adjustTable->rowCount(); i++) + { + QCheckBox *checkBox = reinterpret_cast(ui->adjustTable->cellWidget(i, 0)); + if (checkBox->isChecked()) + { + adj.chSelecet |= 1 << i; + } + } + + adj.manualIndex = static_cast(ui->manualAdjBox->currentIndex()); + + /* 下发配置. */ + buttonEnable(false); + sendMsgDeviceAdjustMode(DEBUG_PRV_ADJ_MANUAL); +} + + +void Widget::on_RatioParamGetButton_clicked() +{ + QString fileWritePath; + fileWritePath.append(QCoreApplication::applicationDirPath() + "/adjParam.bin"); + QFile file_write(fileWritePath); + if (!file_write.open(QIODevice::WriteOnly)) + { + QMessageBox::warning(this, "WARNING", "文件 " + fileWritePath + " 创建失败!", QMessageBox::Ok); + return; + } + + QDataStream out(&file_write); + + /* 获取参数. */ + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + clientAdjInfo.ADCRatio[i] = ui->adjustTable->item(i, 2)->text().toUShort(); + clientAdjInfo.ADC_turns[i] = static_cast(ui->adjustTable->item(i, 3)->text().toUShort()); + for(int j = 0; j < DAU_POWER_ADJ_CNT ; j++) + { + clientAdjInfo.ADCBase_elec[i][j] = ui->adjustTable->item(i, 4 + j * 3)->text().toUInt(); + clientAdjInfo.ADCBase[i][j] = ui->adjustTable->item(i, 5 + j * 3)->text().toFloat(); + clientAdjInfo.ADCAdj[i][j] = ui->adjustTable->item(i, 6 + j * 3)->text().toUShort(); + } + } + clientAdjInfo.vin_adj = ui->vinEdit->text().toUShort(); + clientAdjInfo.vin = ui->vinAdjEdit->text().toUShort(); + + out.writeRawData(reinterpret_cast(&clientAdjInfo), sizeof(dev_adj_t)); + file_write.close(); + QMessageBox::information(this, "SUCCEED", "校准系数文件 " + fileWritePath + " 导出完成.", QMessageBox::Ok); +} + +void Widget::on_RatioParamSetButton_clicked() +{ + QString Path; + QString curPath = QCoreApplication::applicationDirPath(); + dev_adj_t tempAdj; + if (adjFilePath.isEmpty()) + { + curPath = QCoreApplication::applicationDirPath(); + } + else + { + QFileInfo fileinfo = QFileInfo(adjFilePath); + curPath = fileinfo.path(); + } + + Path = QFileDialog::getOpenFileName(this, "Select adj param File", curPath, "*.bin"); + if (Path.isEmpty()) + { + return; + } + + adjFilePath = Path; + settings->setValue("adjFile", adjFilePath); + + QFile file_read(adjFilePath); + if (!file_read.open(QIODevice::ReadOnly)) + { + QMessageBox::warning(this, "WARNING", "文件 " + adjFilePath +" 打开失败!", QMessageBox::Ok); + return; + } + + QDataStream in(&file_read); + + int len = in.readRawData(reinterpret_cast(&tempAdj), sizeof(dev_adj_t)); + if (len != sizeof(dev_adj_t)) + { + file_read.close(); + QMessageBox::warning(this, "WARNING", "文件 " + adjFilePath +" 读取失败!", QMessageBox::Ok); + return; + } + + file_read.close(); + + QString temp; + memcpy(&clientAdjInfo, &tempAdj, sizeof(dev_adj_t)); + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + ui->adjustTable->item(i, 2)->setText(QString::number(clientAdjInfo.ADCRatio[i])); + ui->adjustTable->item(i, 3)->setText(QString::number(clientAdjInfo.ADC_turns[i])); + for(int j = 0; j < DAU_POWER_ADJ_CNT; j++) + { + ui->adjustTable->item(i, j * 3 + 4)->setText(QString::number(clientAdjInfo.ADCBase_elec[i][j])); + temp.sprintf("%.1f", static_cast(clientAdjInfo.ADCBase[i][j])); + ui->adjustTable->item(i, j * 3 + 5)->setText(temp); + ui->adjustTable->item(i, j * 3 + 6)->setText(QString::number(clientAdjInfo.ADCAdj[i][j])); + } + } + + ui->vinEdit->setText(QString::number(clientAdjInfo.vin_adj)); + ui->vinAdjEdit->setText(QString::number(clientAdjInfo.vin)); + + /* 下发配置. */ + sendMsgDeviceAdjustInfoSet(); +} + +void Widget::on_ratioSetButton_clicked() +{ + uint16_t ratio = 0; + + /* 获取参数. */ + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + ratio = ui->adjustTable->item(i, 2)->text().toUShort(); + if (40 == ratio) + { + ui->adjustTable->item(i, 4)->setText(QString::number(1000)); + ui->adjustTable->item(i, 7)->setText(QString::number(5000)); + ui->adjustTable->item(i, 10)->setText(QString::number(10000)); + ui->adjustTable->item(i, 13)->setText(QString::number(50000)); + ui->adjustTable->item(i, 16)->setText(QString::number(100000)); + } + else if(60 == ratio) + { + ui->adjustTable->item(i, 4)->setText(QString::number(1000)); + ui->adjustTable->item(i, 7)->setText(QString::number(5000)); + ui->adjustTable->item(i, 10)->setText(QString::number(10000)); + ui->adjustTable->item(i, 13)->setText(QString::number(50000)); + ui->adjustTable->item(i, 16)->setText(QString::number(100000)); + } + else if(200 == ratio) + { + ui->adjustTable->item(i, 4)->setText(QString::number(1000)); + ui->adjustTable->item(i, 7)->setText(QString::number(10000)); + ui->adjustTable->item(i, 10)->setText(QString::number(50000)); + ui->adjustTable->item(i, 13)->setText(QString::number(100000)); + ui->adjustTable->item(i, 16)->setText(QString::number(200000)); + } + else if(400 == ratio) + { + ui->adjustTable->item(i, 4)->setText(QString::number(1000)); + ui->adjustTable->item(i, 7)->setText(QString::number(10000)); + ui->adjustTable->item(i, 10)->setText(QString::number(50000)); + ui->adjustTable->item(i, 13)->setText(QString::number(100000)); + ui->adjustTable->item(i, 16)->setText(QString::number(200000)); + } + else if(1000 == ratio) + { + ui->adjustTable->item(i, 4)->setText(QString::number(5000)); + ui->adjustTable->item(i, 7)->setText(QString::number(10000)); + ui->adjustTable->item(i, 10)->setText(QString::number(50000)); + ui->adjustTable->item(i, 13)->setText(QString::number(250000)); + ui->adjustTable->item(i, 16)->setText(QString::number(500000)); + } + } + + /* 获取参数. */ + for(int i = 0; i < ui->adjustTable->rowCount(); i++) + { + clientAdjInfo.ADCRatio[i] = ui->adjustTable->item(i, 2)->text().toUShort(); + clientAdjInfo.ADC_turns[i] = static_cast(ui->adjustTable->item(i, 3)->text().toUShort()); + for(int j = 0; j < DAU_POWER_ADJ_CNT ; j++) + { + clientAdjInfo.ADCBase_elec[i][j] = ui->adjustTable->item(i, 4 + j * 3)->text().toUInt(); + } + } + clientAdjInfo.vin_adj = ui->vinEdit->text().toUShort(); + clientAdjInfo.vin = ui->vinAdjEdit->text().toUShort(); + + /* 下发配置. */ + sendMsgDeviceAdjustInfoSet(); +} + +void Widget::on_adjButton_clicked() +{ + adjSet adj; + + memset(&adj, 0, sizeof(adjSet)); + + /* 获取校准通道. */ + for(int32_t i = 0; i < ui->adjustTable->rowCount(); i++) + { + QCheckBox *checkBox = reinterpret_cast(ui->adjustTable->cellWidget(i, 0)); + if (checkBox->isChecked()) + { + adj.chSelecet |= 1 << i; + + } + } + + if (ui->voltageAdjButtonBox->isChecked()) + { + adj.isVoltageSel = true; + } + + /* 下发配置. */ + //work->adjChSet(&adj); + buttonEnable(false); + //work->stateSet(CM_usart::WS_ADJ_AUTO); + sendMsgDeviceAdjustMode(DEBUG_PRV_ADJ_AUTO); +} diff --git a/CableTool/widget.h b/CableTool/widget.h index 7d96693..53903e1 100644 --- a/CableTool/widget.h +++ b/CableTool/widget.h @@ -69,6 +69,20 @@ private slots: void on_waveButton_clicked(); + void on_manualRatioSetButton_clicked(); + + void on_manualAdjBox_activated(int index); + + void on_manualAdjButton_clicked(); + + void on_RatioParamGetButton_clicked(); + + void on_RatioParamSetButton_clicked(); + + void on_ratioSetButton_clicked(); + + void on_adjButton_clicked(); + private: QString toHexadecimal(const QByteArray &byteArray); @@ -96,6 +110,10 @@ private: void uiPowerFrequencyRefresh(); + void uiManualAdjustRefresh(); + + void uiAdjustInfoRefresh(); + void protoContact(char *data); void protoConfig(char *data); @@ -111,6 +129,11 @@ private: int protoPowerFrequency(char *data); int protoState(char *data); + + int protoManualAdjust(char *data); + + int protoAdjustInfo(char *data); + int paraseProtocols(char *data); int snedMsgDeviceInfoGet(); int sendMsgDeviceInfoSet(); @@ -127,6 +150,12 @@ private: int sendMsgDeviceStateGet(); int sendMsgDevicePowerFrequencyGet(); + + int sendMsgDeviceAdjustInfoGet(); + + int sendMsgDeviceAdjustInfoSet(); + + int sendMsgDeviceAdjustMode(int cmd); int sendMsgWaveCol(); @@ -149,6 +178,8 @@ private: csgConfig_t csgConfig; realData_t clientRealData; devState clientDevState; + dev_adj_t clientAdjInfo; + adjSet clientAdjSet; QString energyMode[4]; int isConnected; // serial connect state int64_t upFileSize;