Files
VX5_KRO_GearPump/doc/开机自检分析.md
T
2026-04-29 14:10:10 +08:00

395 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 开机 60 秒自检逻辑分析
## 结论
这个项目的 **开机 60 秒自检**,确实和 **齿轮泵启动、压力建立、阀泵联动控制** 密切相关。
它不是单纯的软件倒计时,而是一个持续 **60 秒的供墨/压力建立过程**。在这段时间里,程序会:
- 禁止打印;
- 禁止部分回收控制;
- 启动并调节齿轮泵;
- 控制循环阀、主墨泵、压缩泵、泄压阀等;
- 根据压力反馈不断调整齿轮泵输出;
- 60 秒结束后才将自检标记为完成。
---
## 1. 60 秒是怎么定义的
在 `SysPara.h` 中有定义:
```cpp
#define MAX_SELF_CHECK_CNT 6000 // 60S, 以10ms为单位
```
也就是说:
- 自检计数单位:`10ms`
- 总计数:`6000`
- 总时长:`6000 × 10ms = 60 秒`
因此,这个“60 秒自检”是代码里明确写死的固定时长。
---
## 2. 自检主逻辑在哪里
核心逻辑在:
- `InkJetPrinter::timerHandler()`
- `InkJetPrinter::autoControlValvePump()`
- `InkJetPrinter::pressureAdj()`
- `DevOp::mainInkCtrl()`
- `DevOp::WriteMoterPump()`
其中,`timerHandler()` 是整个开机阶段的主状态机。
在 `InkJetPrinter.cpp` 中,自检逻辑大致如下:
```cpp
if(!sysPara->status.selfCheckDone)
{
/*开机自检*/
autoControlValvePump();
if(pulse_100ms){
pressureAdj();
}
if(!sysPara->status.selfCheckCnt) {
LogInfo::setRunStatusText(tr("开始自检,请等待60秒..............."));
m_MainWidget->enableReclaimCtrlButton(false);
m_MainWidget->enablePrintButton(false);
sysPara->devOp->mainInkCtrl();
}
if((++sysPara->status.selfCheckCnt % 100) == 0){
m_MainWidget->setRunStatus(tr("开始自检,请等待%1秒...")
.arg((MAX_SELF_CHECK_CNT - sysPara->status.selfCheckCnt)/100));
}
if(sysPara->status.selfCheckCnt >= MAX_SELF_CHECK_CNT)
{
sysPara->status.selfCheckDone = 1;
LogInfo::setRunStatusText(tr("自检完成!!!"));
m_MainWidget->enableReclaimCtrlButton(true);
sysPara->devOp->mainInkCtrl();
}
}
```
这说明:
### 自检期间持续执行的动作
- 调用 `autoControlValvePump()`:控制阀和泵;
- 每 `100ms` 调用一次 `pressureAdj()`:做压力闭环调节;
- 禁止打印按钮;
- 禁止回收控制按钮;
- UI 持续显示倒计时;
- 到 60 秒后,才置 `selfCheckDone = 1`。
---
## 3. 这 60 秒内是不是和齿轮泵启动有关
**是,直接相关。**
在 `timerHandler()` 里,开机初期会先给齿轮泵一个启动值:
```cpp
if(!(sysPara->status.statWarn & WARN_STATUS_INK_WARN) && !gearPumpRunFlag && !sysPara->status.isPumpValveControledByHand)
{
if(sysPara->para.gearPumpEnable) {
sysPara->para.gearPumpValue = 150;
if(tempFlag){
sysPara->devOp->WriteMoterPump();
tempFlag=0;
}
gearPumpStartFlag = true;
}
}
```
这段逻辑的含义是:
- 如果没有墨水报警;
- 齿轮泵尚未进入稳定运行状态;
- 当前不是手动控制;
- 并且启用了齿轮泵;
那么就先给齿轮泵一个初始驱动值 `150`,用于 **开机启动齿轮泵**。
然后 3 秒后:
```cpp
if(gearPumpStartFlag)
{
pulse_3s ++;
if(pulse_3s == 3)
{
pulse_3s = 0;
gearPumpRunFlag = true;
ControledSwitchFlag = true;
}
}
```
说明程序认为:
- 前 3 秒主要是齿轮泵启动阶段;
- 3 秒后进入可控运行阶段;
- 后续允许更正式的压力闭环控制。
---
## 4. 压力建立逻辑是什么
### 4.1 压力调节函数:`pressureAdj()`
`pressureAdj()` 是压力闭环调节核心。
它会读取:
- 目标压力:`sysPara->para.pressure`
- 当前压力:`sysPara->status.PRESSURE`
然后通过 PID 算法计算齿轮泵输出值:
```cpp
if(!sysPara->status.gearPumpRunStopFlag)
{
if(sysPara->para.gearPumpEnable && sysPara->para.flagOfReclaimPumEnable)
u=PID_realize2((float)sysPara->para.pressure,(float)sysPara->status.PRESSURE);
else if(u > 0 || ((sysPara->para.pressure - sysPara->status.PRESSURE) > 0) )
{
u=PID_realize((float)sysPara->para.pressure,(float)sysPara->status.PRESSURE);
}
}
```
然后把计算结果写回齿轮泵控制值:
```cpp
sysPara->para.gearPumpValue = (unsigned short)u;
sysPara->devOp->WriteMoterPump();
```
也就是说:
### 压力建立过程的本质
1. 读取当前压力;
2. 与设定压力比较;
3. 用 PID 算法算出新的齿轮泵输出;
4. 将新的齿轮泵值下发给电机;
5. 周期性重复,直到压力逐渐建立并稳定。
因此,**60 秒自检的核心目标之一,就是把系统压力建立起来并趋于稳定。**
---
## 5. 自检期间阀泵还做了什么
`autoControlValvePump()` 负责阀和泵的联动。
从代码搜索结果可以看到,自检期间会执行:
- 循环阀控制;
- 主墨泵控制;
- 泄压阀控制;
- 压缩泵控制;
- 自检特殊过程中的循环阀交替动作。
其中有一段很关键:
```cpp
if(!sysPara->status.selfCheckDone || (sysPara->status.needPowerOffTimerout && sysPara->para.gearPumpEnable)){
cycleValveRunForSelfCheck();
}
```
并且代码注释明确写了:
```cpp
// 在开机自检过程中交替打开和关闭循环阀
void InkJetPrinter::cycleValveRunForSelfCheck()
```
这说明:
### 自检不是只有齿轮泵在转
同时还包含:
- 循环阀交替开关;
- 供墨路径切换;
- 主墨泵动作;
- 压缩泵辅助建立压力;
- 泄压阀根据压力状态切换。
也就是说,这 60 秒更像是一个 **整套流体系统的上电初始化过程**。
---
## 6. 压力建立成功后,程序如何判断“运行正常”
在 `timerHandler()` 里有一段逻辑:
```cpp
if(pushButtonStartFlag && sysPara->status.selfCheckDone)
{
if((sysPara->status.PRESSURE > (sysPara->para.pressure -10)) && (sysPara->status.PRESSURE < (sysPara->para.pressure +10)))
{
if(pulse_1s)
{
pulse_5s++;
}
if(pulse_5s == 5)
{
pulse_5s = 0;
gearPumpRunNormalFlag = true;
gearPumpRunNormalValue = u;
}
}
}
```
说明:
- 当前压力进入目标压力 ±10 范围;
- 并且持续 5 秒;
- 才会认为齿轮泵运行正常,置 `gearPumpRunNormalFlag = true`。
这说明系统不仅要求“压力到达”,还要求“稳定一段时间”。
---
## 7. 如果压力建立失败,会发生什么
代码中有一套异常判断:
```cpp
if(gearPumpRunNormalFlag && !sysPara->status.isPumpValveControledByHand && sysPara->para.gearPumpEnable)
{
if(u > gearPumpRunNormalValue*1.5)
{
if(pulse_1s)
{
count_3s++;
if(count_3s == 3)
{
sysPara->status.gearPumpRunStopFlag = true;
gearPumpRunNormalFlag = false;
}
}
}
}
```
含义是:
- 如果原本已经进入正常运行;
- 但后面为了维持压力,齿轮泵输出突然需要比正常值高很多(超过 1.5 倍);
- 并持续 3 秒;
程序就会认为:
- 可能有压力泄漏;
- 或者压力传感器异常;
- 然后置 `gearPumpRunStopFlag = true`,停泵保护。
所以从设计意图看,系统在持续监控:
- 压力是否能建立;
- 建立后是否能稳定;
- 若不能稳定,是否可能存在泄漏或故障。
---
## 8. `mainInkCtrl()` 里和自检有什么关系
在 `DevOp::mainInkCtrl()` 中:
```cpp
dataOfmainInkCtrl[0] =
(isReleaseValveOpen()?(1<<3):0)
+ (isMainInkPumpOpen()?(1<<2):0)
+ (sysPara->status.selfCheckDone?(1<<1):0)
+ (sysPara->status.isPumpValveControledByHand?1:0);
```
这里把 `selfCheckDone` 编码到发送给底层控制板的数据位中。
说明:
- 下位机/控制板也知道“自检是否完成”;
- 自检完成前后,底层控制行为可能不同;
- 这进一步证明自检不是单纯界面逻辑,而是参与底层泵阀控制状态机的。
---
## 9. 最终结论
### 这 60 秒内做了什么?
它主要在做:
1. **禁止打印与部分人工操作**;
2. **启动齿轮泵**,先给初始值;
3. **切换并控制循环阀、主墨泵、压缩泵、泄压阀**;
4. **每 100ms 根据压力反馈调节齿轮泵输出**;
5. **持续尝试建立并稳定系统压力**;
6. **监测压力异常、泄漏、转速异常等问题**;
7. **满 60 秒后置自检完成标志**。
### 是否和齿轮泵启动、压力建立有关?
**是,明确相关,而且这就是主线逻辑。**
可以理解为:
> 开机 60 秒自检 = 齿轮泵启动 + 阀泵联动 + 压力建立 + 状态稳定确认 的初始化阶段。
---
## 10. 一个更直观的时序理解
可以粗略理解为:
### 第 0~3 秒
- 给齿轮泵一个初始驱动值;
- 启动供墨相关执行机构;
- 为后续闭环控制做准备。
### 第 3 秒以后到 60 秒内
- 进入正常自检控制阶段;
- 循环阀交替动作;
- 主墨泵/压缩泵/泄压阀按状态联动;
- 每 100ms 调整齿轮泵输出;
- 持续建立和稳定压力。
### 到 60 秒
- 不管压力是否已经很早达标,代码仍会继续走完整个自检窗口;
- 计时结束后才标记 `selfCheckDone = 1`;
- 允许进入正常工作阶段。
所以它更像:
> **固定时长的初始化窗口 + 期间持续进行压力闭环建立**
而不是:
> **压力一达标就立刻结束自检**
---
## 11. 补充说明
从代码风格上看,这套逻辑明显是“设备控制型状态机”:
- 上位机负责状态判断与策略;
- `DevOp` 负责向底层板卡发送控制命令;
- `selfCheckDone`、`gearPumpRunFlag`、`gearPumpRunNormalFlag`、`gearPumpRunStopFlag` 这些标志位共同构成了开机阶段的控制流程。
如果还要继续深挖,下一步最值得分析的是:
1. `autoControlValvePump()` 的完整阀泵切换条件;
2. `cycleValveRunForSelfCheck()` 的开关节奏;
3. `checkPressureControl()` 对压力异常的判定规则;
4. 回收泵使能 `flagOfReclaimPumEnable` 对压力控制模型的影响。