|
@ -60,53 +60,6 @@ typedef enum : int8_t { |
|
|
H_NONE = -128 |
|
|
H_NONE = -128 |
|
|
} heater_id_t; |
|
|
} heater_id_t; |
|
|
|
|
|
|
|
|
// PID storage
|
|
|
|
|
|
typedef struct { float Kp, Ki, Kd; } PID_t; |
|
|
|
|
|
typedef struct { float Kp, Ki, Kd, Kc; } PIDC_t; |
|
|
|
|
|
typedef struct { float Kp, Ki, Kd, Kf; } PIDF_t; |
|
|
|
|
|
typedef struct { float Kp, Ki, Kd, Kc, Kf; } PIDCF_t; |
|
|
|
|
|
|
|
|
|
|
|
typedef |
|
|
|
|
|
#if BOTH(PID_EXTRUSION_SCALING, PID_FAN_SCALING) |
|
|
|
|
|
PIDCF_t |
|
|
|
|
|
#elif ENABLED(PID_EXTRUSION_SCALING) |
|
|
|
|
|
PIDC_t |
|
|
|
|
|
#elif ENABLED(PID_FAN_SCALING) |
|
|
|
|
|
PIDF_t |
|
|
|
|
|
#else |
|
|
|
|
|
PID_t |
|
|
|
|
|
#endif |
|
|
|
|
|
hotend_pid_t; |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PID_EXTRUSION_SCALING) |
|
|
|
|
|
typedef IF<(LPQ_MAX_LEN > 255), uint16_t, uint8_t>::type lpq_ptr_t; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#define PID_PARAM(F,H) _PID_##F(TERN(PID_PARAMS_PER_HOTEND, H, 0 & H)) // Always use 'H' to suppress warning
|
|
|
|
|
|
#define _PID_Kp(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kp, NAN) |
|
|
|
|
|
#define _PID_Ki(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Ki, NAN) |
|
|
|
|
|
#define _PID_Kd(H) TERN(PIDTEMP, Temperature::temp_hotend[H].pid.Kd, NAN) |
|
|
|
|
|
#if ENABLED(PIDTEMP) |
|
|
|
|
|
#define _PID_Kc(H) TERN(PID_EXTRUSION_SCALING, Temperature::temp_hotend[H].pid.Kc, 1) |
|
|
|
|
|
#define _PID_Kf(H) TERN(PID_FAN_SCALING, Temperature::temp_hotend[H].pid.Kf, 0) |
|
|
|
|
|
#else |
|
|
|
|
|
#define _PID_Kc(H) 1 |
|
|
|
|
|
#define _PID_Kf(H) 0 |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(MPCTEMP) |
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float heater_power; // M306 P
|
|
|
|
|
|
float block_heat_capacity; // M306 C
|
|
|
|
|
|
float sensor_responsiveness; // M306 R
|
|
|
|
|
|
float ambient_xfer_coeff_fan0; // M306 A
|
|
|
|
|
|
#if ENABLED(MPC_INCLUDE_FAN) |
|
|
|
|
|
float fan255_adjustment; // M306 F
|
|
|
|
|
|
#endif |
|
|
|
|
|
float filament_heat_capacity_permm; // M306 H
|
|
|
|
|
|
} MPC_t; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
/**
|
|
|
* States for ADC reading in the ISR |
|
|
* States for ADC reading in the ISR |
|
|
*/ |
|
|
*/ |
|
@ -188,7 +141,15 @@ enum ADCSensorState : char { |
|
|
|
|
|
|
|
|
#define ACTUAL_ADC_SAMPLES _MAX(int(MIN_ADC_ISR_LOOPS), int(SensorsReady)) |
|
|
#define ACTUAL_ADC_SAMPLES _MAX(int(MIN_ADC_ISR_LOOPS), int(SensorsReady)) |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// PID
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct { float p, i, d; } raw_pid_t; |
|
|
|
|
|
typedef struct { float p, i, d, c, f; } raw_pidcf_t; |
|
|
|
|
|
|
|
|
#if HAS_PID_HEATING |
|
|
#if HAS_PID_HEATING |
|
|
|
|
|
|
|
|
#define PID_K2 (1-float(PID_K1)) |
|
|
#define PID_K2 (1-float(PID_K1)) |
|
|
#define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY)) |
|
|
#define PID_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY)) |
|
|
|
|
|
|
|
@ -197,10 +158,116 @@ enum ADCSensorState : char { |
|
|
#define unscalePID_i(i) ( float(i) / PID_dT ) |
|
|
#define unscalePID_i(i) ( float(i) / PID_dT ) |
|
|
#define scalePID_d(d) ( float(d) / PID_dT ) |
|
|
#define scalePID_d(d) ( float(d) / PID_dT ) |
|
|
#define unscalePID_d(d) ( float(d) * PID_dT ) |
|
|
#define unscalePID_d(d) ( float(d) * PID_dT ) |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float Kp, Ki, Kd; |
|
|
|
|
|
float p() const { return Kp; } |
|
|
|
|
|
float i() const { return unscalePID_i(Ki); } |
|
|
|
|
|
float d() const { return unscalePID_d(Kd); } |
|
|
|
|
|
float c() const { return 1; } |
|
|
|
|
|
float f() const { return 0; } |
|
|
|
|
|
void set_Kp(float p) { Kp = p; } |
|
|
|
|
|
void set_Ki(float i) { Ki = scalePID_i(i); } |
|
|
|
|
|
void set_Kd(float d) { Kd = scalePID_d(d); } |
|
|
|
|
|
void set_Kc(float) {} |
|
|
|
|
|
void set_Kf(float) {} |
|
|
|
|
|
void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); UNUSED(c); UNUSED(f); } |
|
|
|
|
|
void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } |
|
|
|
|
|
void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d); } |
|
|
|
|
|
} PID_t; |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if ENABLED(MPCTEMP) |
|
|
#if ENABLED(PIDTEMP) |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float Kp, Ki, Kd, Kc; |
|
|
|
|
|
float p() const { return Kp; } |
|
|
|
|
|
float i() const { return unscalePID_i(Ki); } |
|
|
|
|
|
float d() const { return unscalePID_d(Kd); } |
|
|
|
|
|
float c() const { return Kc; } |
|
|
|
|
|
float f() const { return 0; } |
|
|
|
|
|
void set_Kp(float p) { Kp = p; } |
|
|
|
|
|
void set_Ki(float i) { Ki = scalePID_i(i); } |
|
|
|
|
|
void set_Kd(float d) { Kd = scalePID_d(d); } |
|
|
|
|
|
void set_Kc(float c) { Kc = c; } |
|
|
|
|
|
void set_Kf(float) {} |
|
|
|
|
|
void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); set_Kc(c); set_Kf(f); } |
|
|
|
|
|
void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } |
|
|
|
|
|
void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c); } |
|
|
|
|
|
} PIDC_t; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float Kp, Ki, Kd, Kf; |
|
|
|
|
|
float p() const { return Kp; } |
|
|
|
|
|
float i() const { return unscalePID_i(Ki); } |
|
|
|
|
|
float d() const { return unscalePID_d(Kd); } |
|
|
|
|
|
float c() const { return 1; } |
|
|
|
|
|
float f() const { return Kf; } |
|
|
|
|
|
void set_Kp(float p) { Kp = p; } |
|
|
|
|
|
void set_Ki(float i) { Ki = scalePID_i(i); } |
|
|
|
|
|
void set_Kd(float d) { Kd = scalePID_d(d); } |
|
|
|
|
|
void set_Kc(float) {} |
|
|
|
|
|
void set_Kf(float f) { Kf = f; } |
|
|
|
|
|
void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); set_Kf(f); } |
|
|
|
|
|
void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } |
|
|
|
|
|
void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.f); } |
|
|
|
|
|
} PIDF_t; |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float Kp, Ki, Kd, Kc, Kf; |
|
|
|
|
|
float p() const { return Kp; } |
|
|
|
|
|
float i() const { return unscalePID_i(Ki); } |
|
|
|
|
|
float d() const { return unscalePID_d(Kd); } |
|
|
|
|
|
float c() const { return Kc; } |
|
|
|
|
|
float f() const { return Kf; } |
|
|
|
|
|
void set_Kp(float p) { Kp = p; } |
|
|
|
|
|
void set_Ki(float i) { Ki = scalePID_i(i); } |
|
|
|
|
|
void set_Kd(float d) { Kd = scalePID_d(d); } |
|
|
|
|
|
void set_Kc(float c) { Kc = c; } |
|
|
|
|
|
void set_Kf(float f) { Kf = f; } |
|
|
|
|
|
void set(float p, float i, float d, float c=1, float f=0) { set_Kp(p); set_Ki(i); set_Kd(d); set_Kc(c); set_Kf(f); } |
|
|
|
|
|
void set(const raw_pid_t &raw) { set(raw.p, raw.i, raw.d); } |
|
|
|
|
|
void set(const raw_pidcf_t &raw) { set(raw.p, raw.i, raw.d, raw.c, raw.f); } |
|
|
|
|
|
} PIDCF_t; |
|
|
|
|
|
|
|
|
|
|
|
typedef |
|
|
|
|
|
#if BOTH(PID_EXTRUSION_SCALING, PID_FAN_SCALING) |
|
|
|
|
|
PIDCF_t |
|
|
|
|
|
#elif ENABLED(PID_EXTRUSION_SCALING) |
|
|
|
|
|
PIDC_t |
|
|
|
|
|
#elif ENABLED(PID_FAN_SCALING) |
|
|
|
|
|
PIDF_t |
|
|
|
|
|
#else |
|
|
|
|
|
PID_t |
|
|
|
|
|
#endif |
|
|
|
|
|
hotend_pid_t; |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PID_EXTRUSION_SCALING) |
|
|
|
|
|
typedef IF<(LPQ_MAX_LEN > 255), uint16_t, uint8_t>::type lpq_ptr_t; |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if ENABLED(PID_PARAMS_PER_HOTEND) |
|
|
|
|
|
#define SET_HOTEND_PID(F,H,V) thermalManager.temp_hotend[H].pid.set_##F(V) |
|
|
|
|
|
#else |
|
|
|
|
|
#define SET_HOTEND_PID(F,_,V) do{ HOTEND_LOOP() thermalManager.temp_hotend[e].pid.set_##F(V); }while(0) |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#elif ENABLED(MPCTEMP) |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
|
|
float heater_power; // M306 P
|
|
|
|
|
|
float block_heat_capacity; // M306 C
|
|
|
|
|
|
float sensor_responsiveness; // M306 R
|
|
|
|
|
|
float ambient_xfer_coeff_fan0; // M306 A
|
|
|
|
|
|
#if ENABLED(MPC_INCLUDE_FAN) |
|
|
|
|
|
float fan255_adjustment; // M306 F
|
|
|
|
|
|
#endif |
|
|
|
|
|
float filament_heat_capacity_permm; // M306 H
|
|
|
|
|
|
} MPC_t; |
|
|
|
|
|
|
|
|
#define MPC_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY)) |
|
|
#define MPC_dT ((OVERSAMPLENR * float(ACTUAL_ADC_SAMPLES)) / (TEMP_TIMER_FREQUENCY)) |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if ENABLED(G26_MESH_VALIDATION) && EITHER(HAS_MARLINUI_MENU, EXTENSIBLE_UI) |
|
|
#if ENABLED(G26_MESH_VALIDATION) && EITHER(HAS_MARLINUI_MENU, EXTENSIBLE_UI) |
|
@ -218,7 +285,7 @@ public: |
|
|
inline void sample(const raw_adc_t s) { acc += s; } |
|
|
inline void sample(const raw_adc_t s) { acc += s; } |
|
|
inline void update() { raw = acc; } |
|
|
inline void update() { raw = acc; } |
|
|
void setraw(const raw_adc_t r) { raw = r; } |
|
|
void setraw(const raw_adc_t r) { raw = r; } |
|
|
raw_adc_t getraw() { return raw; } |
|
|
raw_adc_t getraw() const { return raw; } |
|
|
} temp_info_t; |
|
|
} temp_info_t; |
|
|
|
|
|
|
|
|
#if HAS_TEMP_REDUNDANT |
|
|
#if HAS_TEMP_REDUNDANT |
|
@ -393,6 +460,7 @@ class Temperature { |
|
|
static const celsius_t hotend_maxtemp[HOTENDS]; |
|
|
static const celsius_t hotend_maxtemp[HOTENDS]; |
|
|
static celsius_t hotend_max_target(const uint8_t e) { return hotend_maxtemp[e] - (HOTEND_OVERSHOOT); } |
|
|
static celsius_t hotend_max_target(const uint8_t e) { return hotend_maxtemp[e] - (HOTEND_OVERSHOOT); } |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if HAS_HEATED_BED |
|
|
#if HAS_HEATED_BED |
|
|
static bed_info_t temp_bed; |
|
|
static bed_info_t temp_bed; |
|
|
#endif |
|
|
#endif |
|
@ -965,12 +1033,16 @@ class Temperature { |
|
|
static constexpr bool adaptive_fan_slowing = true; |
|
|
static constexpr bool adaptive_fan_slowing = true; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
/**
|
|
|
// Update the temp manager when PID values change
|
|
|
* Update the temp manager when PID values change |
|
|
|
|
|
*/ |
|
|
|
|
|
#if ENABLED(PIDTEMP) |
|
|
#if ENABLED(PIDTEMP) |
|
|
static void updatePID() { |
|
|
static void updatePID() { TERN_(PID_EXTRUSION_SCALING, pes_e_position = 0); } |
|
|
TERN_(PID_EXTRUSION_SCALING, pes_e_position = 0); |
|
|
static void setPID(const uint8_t hotend, const_float_t p, const_float_t i, const_float_t d) { |
|
|
|
|
|
#if ENABLED(PID_PARAMS_PER_HOTEND) |
|
|
|
|
|
temp_hotend[hotend].pid.set(p, i, d); |
|
|
|
|
|
#else |
|
|
|
|
|
HOTEND_LOOP() temp_hotend[e].pid.set(p, i, d); |
|
|
|
|
|
#endif |
|
|
|
|
|
updatePID(); |
|
|
} |
|
|
} |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|