generated from hulk/gd32f4xx_template_cmake_vscode
Heater: force output off in overtemp region (err<0); Kp 4->10
This commit is contained in:
@@ -152,6 +152,9 @@
|
||||
截图确认);改为纯阶梯(变更时刻垂直落变+水平延伸),数据本身无误。
|
||||
- v0.2.5:排版调整——串口连接卡片从右列移到左列顶部,左列图表卡/右列日志卡
|
||||
弹性拉伸填充,两列底边对齐。
|
||||
- v0.2.6:对齐修复——双列改放同一滚动容器(整页统一滚动):原先两列各自包
|
||||
QScrollArea 独立滚动,窗口化下底边错位(全屏正常);现两列高度锁定一致,
|
||||
不足一屏各自拉伸到底、超出一屏整页滚动。
|
||||
- selftest 全过(累计新增 14 项回归用例);exe 已本地打包冒烟,Gitea 发布
|
||||
待用户确认后执行。
|
||||
遗留见其 README"已知事项":应用图标、USB-RS485 适配器更换。
|
||||
|
||||
+18
-11
@@ -60,7 +60,7 @@ import config
|
||||
import filmforge_rs485 as ff
|
||||
|
||||
APP_NAME = "FilmForge"
|
||||
APP_VERSION = "0.2.5"
|
||||
APP_VERSION = "0.2.6"
|
||||
REPO_URL = "https://gitea.hulk.wang/hulk/FilmForge"
|
||||
MONO = QFont("Consolas", 10)
|
||||
CHIP_IDLE = "#666666"
|
||||
@@ -470,27 +470,34 @@ class App(QMainWindow):
|
||||
header.addWidget(self._button("关于", self._about))
|
||||
outer.addLayout(header)
|
||||
|
||||
split = QSplitter(Qt.Horizontal, root)
|
||||
# 双列放进同一滚动容器: 两列高度锁定一致——不足一屏时各自拉伸到底边,
|
||||
# 超出一屏时整页一起滚动; 各列独立滚动会让底边在窗口化下错位(实测)
|
||||
split = QSplitter(Qt.Horizontal)
|
||||
split.setChildrenCollapsible(False)
|
||||
split.addWidget(self._scroll_column(self._build_left))
|
||||
split.addWidget(self._scroll_column(self._build_right))
|
||||
split.addWidget(self._column_host(self._build_left))
|
||||
split.addWidget(self._column_host(self._build_right))
|
||||
split.setStretchFactor(0, 3)
|
||||
split.setStretchFactor(1, 2)
|
||||
outer.addWidget(split, 1)
|
||||
page = QWidget()
|
||||
page_lay = QHBoxLayout(page)
|
||||
page_lay.setContentsMargins(0, 0, 0, 0)
|
||||
page_lay.addWidget(split)
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setFrameShape(QScrollArea.NoFrame)
|
||||
scroll.setWidget(page)
|
||||
outer.addWidget(scroll, 1)
|
||||
self.setCentralWidget(root)
|
||||
|
||||
def _scroll_column(self, builder):
|
||||
def _column_host(self, builder):
|
||||
"""构建一列的宿主 QWidget(不再各自包 QScrollArea, 整页统一滚动)"""
|
||||
host = QWidget()
|
||||
layout = QVBoxLayout(host)
|
||||
layout.setContentsMargins(2, 2, 8, 2)
|
||||
layout.setSpacing(10)
|
||||
builder(layout)
|
||||
layout.addStretch(1)
|
||||
scroll = QScrollArea()
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setFrameShape(QScrollArea.NoFrame)
|
||||
scroll.setWidget(host)
|
||||
return scroll
|
||||
return host
|
||||
|
||||
# ---------------- 左列: 串口 + 监视 ----------------
|
||||
def _build_serial_card(self, layout):
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ void usart1_irq_handler(void);
|
||||
#define HEATER_PWM_PERIOD_MS 1000U /* PWM 载波周期(1s,恒 1Hz 开关频率) */
|
||||
#define HEATER_PWM_STEP_PCT 10U /* 占空比步进(每档脉宽 = 100ms) */
|
||||
#define HEATER_PID_PERIOD_MS 500U /* PID 计算周期 */
|
||||
#define HEATER_PID_KP 4.0f /* PID 参数:小 Kp 换取低过冲(接近目标时减速) */
|
||||
#define HEATER_PID_KP 10.0f /* PID 参数:超温前退功率更快(配合超温强制关断) */
|
||||
#define HEATER_PID_KI 0.05f
|
||||
#define HEATER_PID_KD 30.0f /* 微分阻尼:按误差变化率提前刹车(抑制爬升惯性) */
|
||||
#define HEATER_RAMP_CPS 0.8f /* 目标斜坡速率(℃/s):内部设定值缓升,抑制热滞后过冲 */
|
||||
|
||||
+13
-8
@@ -111,21 +111,26 @@ static void pid_compute(void) {
|
||||
float u_noi = HEATER_PID_KP * err
|
||||
+ HEATER_PID_KD * (err - s_prev_err); /* 比例 + 微分 */
|
||||
float integ_new = s_integral + err;
|
||||
/* 超温区间(实际温度高于内部目标):加热器只能加热、不能制冷,
|
||||
输出必须为 0(此前积分正残量会算出小占空在超调段续灌加热);
|
||||
积分按负误差同步回退,为温度回落后的重新加热保留正确初始态 */
|
||||
if (err < 0.0f) {
|
||||
s_integral = integ_new;
|
||||
s_prev_err = err;
|
||||
s_duty10 = 0;
|
||||
} else {
|
||||
/* 误差为正(未达/低于内部目标):正常 PID + 抗积分饱和 */
|
||||
float u = u_noi + HEATER_PID_KI * integ_new;
|
||||
|
||||
if (u > 100.0f) {
|
||||
u = 100.0f;
|
||||
if (err < 0.0f) s_integral = integ_new; /* 超上限:仅误差为负(降温方向)才吸收 */
|
||||
} else if (u < 0.0f) {
|
||||
u = 0.0f;
|
||||
if (err > 0.0f) s_integral = integ_new; /* 超下限:仅误差为正(升温方向)才吸收 */
|
||||
/* 超上限:仅误差为负才吸收——err>=0 分支不会发生,保持积分不动 */
|
||||
} else {
|
||||
s_integral = integ_new; /* 未饱和:正常积分 */
|
||||
s_integral = integ_new;
|
||||
}
|
||||
s_prev_err = err;
|
||||
|
||||
/* 输出量化到 10% 档位(四舍五入) */
|
||||
s_duty10 = (uint8_t)((u + (float)HEATER_PWM_STEP_PCT / 2.0f) / (float)HEATER_PWM_STEP_PCT);
|
||||
}
|
||||
s_prev_err = err;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user