Prusa3d Marlin fork
thermal_model.h
1 // model-based temperature safety checker declarations
2 #ifndef TEMP_MGR_INTV
3 #error "this file is not a public interface, it should be used *only* within temperature.cpp!"
4 #endif
5 
6 #include "planner.h"
7 
8 // shortcuts to get model defaults
9 #define __THERMAL_MODEL_DEF(MODEL, VAR) THERMAL_MODEL_##MODEL##_##VAR
10 #define _THERMAL_MODEL_DEF(MODEL, VAR) __THERMAL_MODEL_DEF(MODEL, VAR)
11 #define THERMAL_MODEL_DEF(VAR) _THERMAL_MODEL_DEF(THERMAL_MODEL_DEFAULT, VAR)
12 
13 constexpr uint8_t THERMAL_MODEL_CAL_S = 60; // Maximum recording length during calibration (s)
14 constexpr uint8_t THERMAL_MODEL_CAL_R_STEP = 4; // Fan interpolation steps during calibration
15 constexpr float THERMAL_MODEL_fE = 0.05; // error filter (1st-order IIR factor)
16 
17 // transport delay buffer size (samples)
18 constexpr uint8_t THERMAL_MODEL_MAX_LAG_SIZE = 8; // * TEMP_MGR_INTV = 2160
19 
20 // resistance values for all fan levels
21 constexpr uint8_t THERMAL_MODEL_R_SIZE = (1 << FAN_SOFT_PWM_BITS);
22 static const float THERMAL_MODEL_R_DEFAULT[THERMAL_MODEL_R_SIZE] PROGMEM = THERMAL_MODEL_DEF(Rv);
23 
24 namespace thermal_model {
25 
26 struct model_data
27 {
28  // temporary buffers
29  float dT_lag_buf[THERMAL_MODEL_MAX_LAG_SIZE]; // transport delay buffer
30  uint8_t dT_lag_size = 0; // transport delay buffer size
31  uint8_t dT_lag_idx = 0; // transport delay buffer index
32  float dT_err_prev = 0; // previous temperature delta error
33  float T_prev = 0; // last temperature extruder
34 
35  // configurable parameters
36  float P; // heater power (W)
37  float U; // linear temperature coefficient (W/K/W)
38  float V; // linear temperature intercept (W/W)
39  float C; // heatblock capacitance (J/K)
40  float fS; // sim. 1st order IIR filter factor (f=100/27)
41  uint16_t L; // sim. response lag (ms)
42  float R[THERMAL_MODEL_R_SIZE]; // heatblock resistance for all fan levels (K/W)
43  float Ta_corr; // ambient temperature correction (K)
44 
45  // thresholds
46  float warn; // warning threshold (K/s)
47  float err; // error threshold (K/s)
48 
49  // status flags
50  union
51  {
52  bool flags;
53  struct
54  {
55  bool uninitialized: 1; // model is not initialized
56  bool error: 1; // error threshold set
57  bool warning: 1; // warning threshold set
58  } flag_bits;
59  };
60 
61  // pre-computed values (initialized via reset)
62  float C_i; // heatblock capacitance (precomputed dT/C)
63  float warn_s; // warning threshold (per sample)
64  float err_s; // error threshold (per sample)
65 
66  // simulation functions
67  void reset(uint8_t heater_pwm, uint8_t fan_pwm, float heater_temp, float ambient_temp);
68  void step(uint8_t heater_pwm, uint8_t fan_pwm, float heater_temp, float ambient_temp);
69 };
70 
71 static bool enabled; // model check enabled
72 static bool warn_beep = true; // beep on warning threshold
73 static model_data data; // default heater data
74 
75 static bool calibrated(); // return calibration/model validity status
76 static void check(); // check and trigger errors or warnings based on current state
77 
78 // warning state (updated from from isr context)
79 volatile static struct
80 {
81  float dT_err; // temperature delta error (per sample)
82  bool warning: 1; // warning condition
83  bool assert: 1; // warning is still asserted
84 } warning_state;
85 
86 static void handle_warning(); // handle warnings from user context
87 
88 #ifdef THERMAL_MODEL_DEBUG
89 static struct
90 {
91  volatile struct
92  {
93  uint32_t stamp;
94  int8_t delta_ms;
95  uint8_t counter;
96  uint8_t cur_pwm;
97  float cur_temp;
98  float cur_amb;
99  } entry;
100 
101  uint8_t serial;
102  bool enabled;
103 } log_buf;
104 
105 static void log_usr(); // user log handler
106 static void log_isr(); // isr log handler
107 #endif
108 
109 } // namespace thermal_model
110 
111 namespace thermal_model_cal {
112 
113 // recording scratch buffer
114 struct rec_entry
115 {
116  float temp; // heater temperature
117  uint8_t pwm; // heater PWM
118 };
119 
120 constexpr uint16_t REC_BUFFER_SIZE = THERMAL_MODEL_CAL_S / TEMP_MGR_INTV;
121 static rec_entry* const rec_buffer = (rec_entry*)block_buffer; // oh-hey, free memory!
122 static_assert(sizeof(rec_entry[REC_BUFFER_SIZE]) <= sizeof(block_buffer),
123  "recording length too long to fit within available buffer");
124 
125 } // namespace thermal_model_cal
Definition: thermal_model.h:27
Definition: thermal_model.h:115