mirror of
https://github.com/vincentvdwal/crust-craft.git
synced 2026-08-18 17:26:39 +02:00
max ki 70p, adjust kp ki
This commit is contained in:
+7
-4
@@ -70,7 +70,7 @@ export class SpoofSocket {
|
|||||||
pwm_off: 4000,
|
pwm_off: 4000,
|
||||||
pid: 0,
|
pid: 0,
|
||||||
kp: 0.6,
|
kp: 0.6,
|
||||||
ki: 0.1,
|
ki: 0.03,
|
||||||
kd: 0.0,
|
kd: 0.0,
|
||||||
bake_phase: '',
|
bake_phase: '',
|
||||||
bake_remaining: 0
|
bake_remaining: 0
|
||||||
@@ -127,14 +127,16 @@ export class SpoofSocket {
|
|||||||
|
|
||||||
private applyMode(m: string): void {
|
private applyMode(m: string): void {
|
||||||
const s = this.s;
|
const s = this.s;
|
||||||
|
const wasPid = this.isPidMode(s.mode);
|
||||||
s.mode = m;
|
s.mode = m;
|
||||||
if (m === 'baking') this.bakeStart = Date.now();
|
if (m === 'baking') this.bakeStart = Date.now();
|
||||||
if (m === 'manual') {
|
if (m === 'manual') {
|
||||||
s.relais = 0;
|
s.relais = 0;
|
||||||
this.lastSwitch = Date.now();
|
this.lastSwitch = Date.now();
|
||||||
}
|
}
|
||||||
// Dump windup when the new target is below the current temp (e.g. -> pause)
|
// Reset integral arriving from a non-PID mode (stale value) or when the
|
||||||
if (this.isPidMode(m) && this.activeSetpoint() < s.temperature) this.integral = 0;
|
// new target is below the current temp (mirrors firmware applyMode).
|
||||||
|
if (this.isPidMode(m) && (!wasPid || this.activeSetpoint() < s.temperature)) this.integral = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private handle(cmd: string, value?: number | string): void {
|
private handle(cmd: string, value?: number | string): void {
|
||||||
@@ -208,7 +210,8 @@ export class SpoofSocket {
|
|||||||
const satHigh = output >= 100 && error > 0;
|
const satHigh = output >= 100 && error > 0;
|
||||||
const satLow = output <= 0 && error < 0;
|
const satLow = output <= 0 && error < 0;
|
||||||
if (!satHigh && !satLow) {
|
if (!satHigh && !satLow) {
|
||||||
this.integral = Math.max(-100, Math.min(100, this.integral + s.ki * error * dt));
|
// integral clamped to ±70 to match the firmware (anti-overshoot)
|
||||||
|
this.integral = Math.max(-70, Math.min(70, this.integral + s.ki * error * dt));
|
||||||
}
|
}
|
||||||
output = Math.max(0, Math.min(100, pTerm + this.integral));
|
output = Math.max(0, Math.min(100, pTerm + this.integral));
|
||||||
s.pid = output;
|
s.pid = output;
|
||||||
|
|||||||
+15
-7
@@ -27,7 +27,7 @@ unsigned long lastWebSocket = 0;
|
|||||||
const unsigned long WS_INTERVAL = 500;
|
const unsigned long WS_INTERVAL = 500;
|
||||||
|
|
||||||
float temperature = 0;
|
float temperature = 0;
|
||||||
float targetTemp = 370.0f; // default target temp for preheating, adjustable via UI
|
float targetTemp = 350.0f; // default target temp for preheating, adjustable via UI
|
||||||
|
|
||||||
unsigned long lastSwitch = 0;
|
unsigned long lastSwitch = 0;
|
||||||
float pwmSwitchDelayOn = 2000; // 2s
|
float pwmSwitchDelayOn = 2000; // 2s
|
||||||
@@ -35,8 +35,8 @@ float pwmSwitchDelayOff = 4000; // 4s
|
|||||||
|
|
||||||
float power = 100;
|
float power = 100;
|
||||||
|
|
||||||
float kp = 0.55;
|
float kp = 0.6;
|
||||||
float ki = 0.005;
|
float ki = 0.03;
|
||||||
float kd = 0.0;
|
float kd = 0.0;
|
||||||
|
|
||||||
// Heating modes. PREHEAT, PAUSE and BAKING are all PI-regulated and only
|
// Heating modes. PREHEAT, PAUSE and BAKING are all PI-regulated and only
|
||||||
@@ -55,7 +55,11 @@ unsigned long bakeStart = 0; // millis() when BAKING was entered
|
|||||||
|
|
||||||
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
|
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
|
||||||
|
|
||||||
PIDController pid(kp, ki, kd, 100.0, 0.0, 100.0); // Kp, Ki, Kd, max, min, max_integral
|
// integral capped at 70 (not 100): near the setpoint P≈0, so the integral alone
|
||||||
|
// supplies the holding power. Letting it reach 100 means full power right as we
|
||||||
|
// hit the setpoint → big overshoot on this high-lag oven. 70 still covers the
|
||||||
|
// steady-state duty needed at high setpoints.
|
||||||
|
PIDController pid(kp, ki, kd, 100.0, 0.0, 70.0); // Kp, Ki, Kd, max, min, max_integral
|
||||||
|
|
||||||
static const char *modeToStr(Mode m)
|
static const char *modeToStr(Mode m)
|
||||||
{
|
{
|
||||||
@@ -96,6 +100,7 @@ static float activeSetpoint()
|
|||||||
// Centralised mode switch so every entry point stays consistent and safe.
|
// Centralised mode switch so every entry point stays consistent and safe.
|
||||||
static void applyMode(Mode m)
|
static void applyMode(Mode m)
|
||||||
{
|
{
|
||||||
|
Mode prev = mode;
|
||||||
mode = m;
|
mode = m;
|
||||||
|
|
||||||
if (m == Mode::BAKING)
|
if (m == Mode::BAKING)
|
||||||
@@ -110,9 +115,12 @@ static void applyMode(Mode m)
|
|||||||
if (isPidMode(m))
|
if (isPidMode(m))
|
||||||
{
|
{
|
||||||
pid.setSetpoint(activeSetpoint());
|
pid.setSetpoint(activeSetpoint());
|
||||||
// Dump integral windup when the new target is below the current temp
|
// Reset the integral when arriving from a non-PID mode (its value is stale
|
||||||
// (e.g. PREHEAT -> PAUSE) so we don't keep heating into an overshoot.
|
// and would dump straight into an overshoot) or when the new target is
|
||||||
if (activeSetpoint() < temperature)
|
// below the current temp (e.g. PREHEAT -> PAUSE, or BAKING -> PREHEAT).
|
||||||
|
// A PID -> PID hand-off at a higher target (e.g. PREHEAT -> BAKING) keeps
|
||||||
|
// the integral so the boost adds to the existing holding power.
|
||||||
|
if (!isPidMode(prev) || activeSetpoint() < temperature)
|
||||||
pid.reset();
|
pid.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
let pwmOff = $state(4);
|
let pwmOff = $state(4);
|
||||||
|
|
||||||
let kp = $state(0.6);
|
let kp = $state(0.6);
|
||||||
let ki = $state(0.1);
|
let ki = $state(0.03);
|
||||||
|
|
||||||
let pauseGraphUpdate = $state(false);
|
let pauseGraphUpdate = $state(false);
|
||||||
let darkMode = $state(true);
|
let darkMode = $state(true);
|
||||||
|
|||||||
Reference in New Issue
Block a user