#include "pch.h" #include "WDACalibration.h" #include #include WDACalibration::WDACalibration() { } WDACalibration::~WDACalibration() { } int WDACalibration::ExecuteCalibration(QSerialPort* pSerialPort, double dTemperature) { if (!pSerialPort || !pSerialPort->isOpen()) { qDebug() << "Err:ExecuteCalibration - Serial port not open.Exit Code:1"; return 1; } // 将温度转换为5位数字格式,例如24.0 -> 00240 int iTempValue = static_cast(dTemperature * 10); char szTemp[16]; snprintf(szTemp, sizeof(szTemp), "%05d", iTempValue); std::string sTempValue = szTemp; qDebug() << QString("开始WDA校准流程,校准温度: %1℃ (编码: %2)").arg(dTemperature).arg(sTempValue.c_str()); CalibrationState eState = Calib_Step1_TC0; int iRetryCount = 0; int iTryCount = 0; // 执行校准流程 while (eState != Calib_Idle) { // 执行当前步骤 std::string sResponse; int iResult = ExecuteCalibrationStep(pSerialPort, eState, sTempValue, iRetryCount, iTryCount, sResponse); if (iResult != 0) { // 步骤执行失败 iRetryCount++; if (iRetryCount > 3) { // 错误码映射:ExecuteCalibrationStep返回1,2,3,4 -> ExecuteCalibration返回2,3,4,5 // (因为错误码1是串口未打开,错误码2由IrisSensor_WDA_P0返回表示WDA正在工作) qDebug() << "Err:ExecuteCalibration - Too many retries.Exit Code:" << (iResult + 1); return (iResult + 1); } qDebug() << "Warning:ExecuteCalibration - Step failed, retrying..."; continue; } // 步骤执行成功,重置重试计数 iRetryCount = 0; // 特殊处理:步骤5需要检查校准是否完成 if (eState == Calib_Step5_AC_Second) { if (CheckCalibrationComplete(sResponse)) { qDebug() << "WDA校准完成!所有值均小于10"; // 继续到下一步 eState = Calib_Step6_Restore_KY18; } else { iTryCount++; if (iTryCount > 1) { qDebug() << "Warning:ExecuteCalibration - Calibration not complete after retries, continuing..."; eState = Calib_Step6_Restore_KY18; } else { qDebug() << "WDA校准未完成,需要重复步骤2-3,等待5秒后重试..."; // 等待5秒 QThread::msleep(5000); // 重新开始步骤2 eState = Calib_Step2_KY18_First; iRetryCount = 0; } continue; } } // 更新到下一步状态 switch (eState) { case Calib_Step1_TC0: eState = Calib_Step2_KY18_First; break; case Calib_Step2_KY18_First: eState = Calib_Step3_AC_First; break; case Calib_Step3_AC_First: eState = Calib_Step4_KY18_Second; break; case Calib_Step4_KY18_Second: eState = Calib_Step5_AC_Second; break; case Calib_Step5_AC_Second: eState = Calib_Step6_Restore_KY18; break; case Calib_Step6_Restore_KY18: eState = Calib_Step7_Restore_TC; break; case Calib_Step7_Restore_TC: qDebug() << "WDA校准流程全部完成!"; return 0; default: break; } // 步骤之间等待500ms QThread::msleep(500); } return 0; } int WDACalibration::ExecuteCalibrationStep(QSerialPort* pSerialPort, CalibrationState eStep, const std::string& sTempValue, int& iRetryCount, int& iTryCount, std::string& sResponse) { // 发送当前步骤的命令 std::string sCommand; switch (eStep) { case Calib_Step1_TC0: sCommand = "$01,TC0\r\n"; break; case Calib_Step2_KY18_First: sCommand = "$01,KY18\r\n"; break; case Calib_Step3_AC_First: { char szCmd[64]; snprintf(szCmd, sizeof(szCmd), "$01,AC%s^**\r\n", sTempValue.c_str()); sCommand = szCmd; } break; case Calib_Step4_KY18_Second: sCommand = "$01,KY18\r\n"; break; case Calib_Step5_AC_Second: { char szCmd[64]; snprintf(szCmd, sizeof(szCmd), "$01,AC%s^**\r\n", sTempValue.c_str()); sCommand = szCmd; } break; case Calib_Step6_Restore_KY18: sCommand = "$01,KY18\r\n"; break; case Calib_Step7_Restore_TC: sCommand = "$01,TC00001^**\r\n"; break; default: return 1; } if (SendCalibrationCommand(pSerialPort, sCommand) != 0) { qDebug() << "Err:ExecuteCalibrationStep - SendCalibrationCommand failed.Exit Code:2"; return 2; } // 接收响应 sResponse.clear(); if (RecvCalibrationResponse(pSerialPort, sResponse, 5000) != 0) { qDebug() << "Err:ExecuteCalibrationStep - RecvCalibrationResponse timeout.Exit Code:3"; return 3; } // 检查响应 if (!CheckCalibrationResponse(sResponse, eStep)) { qDebug() << "Err:ExecuteCalibrationStep - Invalid response.Exit Code:4"; return 4; } return 0; } int WDACalibration::SendCalibrationCommand(QSerialPort* pSerialPort, const std::string& sCommand) { if (!pSerialPort || !pSerialPort->isOpen()) { return 1; } QByteArray qbaSend(sCommand.c_str(), (int)sCommand.length()); qint64 qi64Write = pSerialPort->write(qbaSend); pSerialPort->waitForBytesWritten(50); if (qi64Write != qbaSend.size()) { qDebug() << "Err:SendCalibrationCommand - Write failed"; return 1; } qDebug() << QString("发送: %1").arg(sCommand.c_str()); return 0; } int WDACalibration::RecvCalibrationResponse(QSerialPort* pSerialPort, std::string& sResponse, int iTimeoutMs) { if (!pSerialPort || !pSerialPort->isOpen()) { return 1; } sResponse.clear(); QByteArray qbData; qbData.clear(); // 清空接收缓冲区 pSerialPort->readAll(); // 等待数据到达 int iElapsed = 0; while (iElapsed < iTimeoutMs) { if (pSerialPort->waitForReadyRead(100)) { QByteArray qbTemp = pSerialPort->readAll(); qbData.append(qbTemp); // 检查是否收到完整的行(以\r\n或\n结尾) if (qbData.contains("\r\n") || qbData.contains('\n') || qbData.contains('\r')) { break; } } iElapsed += 100; } if (qbData.isEmpty()) { return 1; } // 提取一行数据 int iLineEnd = -1; int iLineLength = 0; if (qbData.contains("\r\n")) { iLineEnd = qbData.indexOf("\r\n"); iLineLength = 2; } else if (qbData.contains('\n')) { iLineEnd = qbData.indexOf('\n'); iLineLength = 1; } else if (qbData.contains('\r')) { iLineEnd = qbData.indexOf('\r'); iLineLength = 1; } else { // 没有换行符,使用全部数据 iLineEnd = qbData.size(); iLineLength = 0; } QByteArray qbLine = qbData.left(iLineEnd); QString qstrResponse = QString::fromUtf8(qbLine).trimmed(); sResponse = qstrResponse.toStdString(); if (!sResponse.empty()) { qDebug() << QString("接收: %1").arg(sResponse.c_str()); } return 0; } bool WDACalibration::CheckCalibrationResponse(const std::string& sResponse, CalibrationState eStep) { QString qstrResponse = QString::fromStdString(sResponse); switch (eStep) { case Calib_Step1_TC0: if (qstrResponse.contains("$WI,TC=0") || qstrResponse.contains("TC=0")) { qDebug() << "步骤1完成: TC0设置成功"; return true; } break; case Calib_Step2_KY18_First: if (qstrResponse.contains("$WI,KY=18") || qstrResponse.contains("KY=18")) { qDebug() << "步骤2完成: KY18设置成功"; return true; } break; case Calib_Step3_AC_First: if (qstrResponse.contains("$WI,AC=") || qstrResponse.contains("AC=")) { std::string sACValues = ExtractACValues(sResponse); qDebug() << QString("步骤3完成: 第一次AC校准,返回值: %1").arg(sACValues.c_str()); return true; } break; case Calib_Step4_KY18_Second: if (qstrResponse.contains("$WI,KY=18") || qstrResponse.contains("KY=18")) { qDebug() << "步骤4完成: 第二次KY18设置成功"; return true; } break; case Calib_Step5_AC_Second: if (qstrResponse.contains("$WI,AC=") || qstrResponse.contains("AC=")) { std::string sACValues = ExtractACValues(sResponse); qDebug() << QString("步骤5: 第二次AC校准,返回值: %1").arg(sACValues.c_str()); return true; } break; case Calib_Step6_Restore_KY18: if (qstrResponse.contains("$WI,KY=18") || qstrResponse.contains("KY=18")) { qDebug() << "步骤6完成: 恢复模式KY18设置成功"; return true; } break; case Calib_Step7_Restore_TC: if (qstrResponse.contains("$WI,TC=00001") || qstrResponse.contains("TC=00001")) { qDebug() << "步骤7完成: 恢复模式TC设置成功"; return true; } break; default: break; } return false; } bool WDACalibration::CheckCalibrationComplete(const std::string& sResponse) { std::string sACValues = ExtractACValues(sResponse); return AllValuesLessThan10(sACValues); } std::string WDACalibration::ExtractACValues(const std::string& sResponse) { QString qstrResponse = QString::fromStdString(sResponse); QRegularExpression re(R"(\$WI,AC=(.+))"); QRegularExpressionMatch match = re.match(qstrResponse); if (!match.hasMatch()) { re.setPattern(R"(AC=(.+))"); match = re.match(qstrResponse); } if (match.hasMatch()) { return match.captured(1).toStdString(); } return ""; } bool WDACalibration::AllValuesLessThan10(const std::string& sACValues) { if (sACValues.empty()) { return false; } QString qstrACValues = QString::fromStdString(sACValues); QStringList values = qstrACValues.split(','); if (values.isEmpty()) { return false; } // 检查从第5个值(索引4)到最后一个值 int iStartIndex = 4; if (iStartIndex >= values.size()) { qDebug() << QString("值数量不足5个,无法检查"); return false; } QStringList checkedValues; for (int i = iStartIndex; i < values.size(); i++) { QString valueStr = values[i].trimmed(); bool ok; int iValue = valueStr.toInt(&ok); if (!ok) { qDebug() << QString("无法解析值: %1").arg(valueStr); return false; } checkedValues << valueStr; if (iValue >= 10) { qDebug() << QString("检查值: %1 (第%2到最后一个值: %3),值 %4 >= 10,校准未完成") .arg(valueStr) .arg(iStartIndex + 1) .arg(checkedValues.join(",")) .arg(iValue); return false; } } qDebug() << QString("第%1到最后一个值均小于10 (值: %2),校准完成") .arg(iStartIndex + 1) .arg(checkedValues.join(",")); return true; }