commit 4193f449ffb23cb8dc3f6c82f7ff5f19dcd47516
parent 12a09fe9b6f23d50750ddfa9c70b586b1a18a40d
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date: Tue, 7 Apr 2026 16:59:04 -0300
Implementar controlador PID para el control de temperatura
Diffstat:
1 file changed, 52 insertions(+), 23 deletions(-)
diff --git a/firmware/app/src/task_temp_ctrl.c b/firmware/app/src/task_temp_ctrl.c
@@ -14,7 +14,12 @@
#include "task_temp_ctrl.h"
#include "logger.h"
-#define G_TASK_CTRL_TICK_CNT_INI 0ul
+#define G_TASK_TEMP_CTRL_TICK_CNT_INI 0ul
+
+#define G_TASK_TEMP_CTRL_PID_KP 40.0f
+#define G_TASK_TEMP_CTRL_PID_KI 0.75f
+#define G_TASK_TEMP_CTRL_PID_KD 0.01f
+#define G_TASK_TEMP_CTRL_PID_DT 250 // 100 ms
// Private data definition
typedef struct {
@@ -22,10 +27,20 @@ typedef struct {
uint32_t tim_channel;
} task_temp_ctrl_cfg_t;
+typedef struct {
+ float pid_kp, pid_ki, pid_kd;
+ float pid_p, pid_i, pid_d;
+ float error, prev_error;
+ uint32_t tick;
+} task_temp_ctrl_pid_t;
+
static const task_temp_ctrl_cfg_t task_temp_ctrl_cfg = {&htim1, TIM_CHANNEL_1};
+static task_temp_ctrl_pid_t task_temp_ctrl_pid = {
+ G_TASK_TEMP_CTRL_PID_KP, G_TASK_TEMP_CTRL_PID_KI, G_TASK_TEMP_CTRL_PID_KD
+};
// Private functions declaration
-static inline int16_t ceil_i16(int16_t val, int16_t max_val);
+static inline int16_t clampf(float val, float min, float max);
static void task_temp_ctrl_set_duty(TIM_HandleTypeDef *htim, uint32_t ch, uint8_t duty);
// Public data definition
@@ -51,19 +66,15 @@ void task_temp_ctrl_init(void *parameters)
LOGGER_INFO("Done initializing `task_temp_ctrl`");
}
-static inline int16_t ceil_i16(int16_t val, int16_t max_val)
-{
- return val > max_val ? max_val : val;
-}
-
void task_temp_ctrl_update(void *parameters)
{
bool b_time_update_required;
shared_data_type *p_shared_data = (shared_data_type *)parameters;
const task_temp_ctrl_cfg_t *p_task_cfg = &task_temp_ctrl_cfg;
+ task_temp_ctrl_pid_t *p_pid = &task_temp_ctrl_pid;
__asm("CPSID i");
- if (G_TASK_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
+ if (G_TASK_TEMP_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
{
g_task_temp_ctrl_tick_cnt--;
b_time_update_required = true;
@@ -73,7 +84,7 @@ void task_temp_ctrl_update(void *parameters)
while (b_time_update_required)
{
__asm("CPSID i");
- if (G_TASK_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
+ if (G_TASK_TEMP_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
{
g_task_temp_ctrl_tick_cnt--;
b_time_update_required = true;
@@ -84,32 +95,50 @@ void task_temp_ctrl_update(void *parameters)
}
__asm("CPSIE i");
- int16_t error = p_shared_data->temp_set_point - p_shared_data->temp_sensor;
-
- if (error > 0)
+ if (false == p_shared_data->temp_ctrl_enabled)
{
- p_shared_data->temp_ctrl_pwm_dc = ceil_i16(error*error, 80);
- }
- else {
+ if (0 != __HAL_TIM_GET_COMPARE(p_task_cfg->htim, p_task_cfg->tim_channel))
+ {
task_temp_ctrl_set_duty(p_task_cfg->htim, p_task_cfg->tim_channel, 0);
+ }
}
-
- if (true == p_shared_data->temp_ctrl_enabled)
+ else
{
- if (p_shared_data->temp_ctrl_pwm_dc != TIM1->CCR1)
+ if (0 < p_pid->tick)
{
+ p_pid->tick--;
+ }
+ else
+ {
+ p_pid->tick = G_TASK_TEMP_CTRL_PID_DT;
+ float dt = (p_pid->tick / 1000.0f);
+
+ p_pid->prev_error = p_pid->error;
+ p_pid->error = p_shared_data->temp_set_point - p_shared_data->temp_sensor;
+
+ p_pid->pid_p = p_pid->error * p_pid->pid_kp;
+ p_pid->pid_i = (p_pid->pid_i + (p_pid->error*dt)) * p_pid->pid_ki;
+ p_pid->pid_d = ((p_pid->error - p_pid->prev_error)/dt) * p_pid->pid_kd;
+
+ p_shared_data->temp_ctrl_pwm_dc = clampf(
+ p_pid->pid_p + p_pid->pid_i + p_pid->pid_d,
+ 0.0f,
+ 100.0f);
+
task_temp_ctrl_set_duty(p_task_cfg->htim,
p_task_cfg->tim_channel,
p_shared_data->temp_ctrl_pwm_dc);
}
}
- else
- {
- __HAL_TIM_SET_COMPARE(p_task_cfg->htim,
- p_task_cfg->tim_channel, 0);
- }
}
}
+
+// Public functions declaration
+static inline int16_t clampf(float val, float min, float max)
+{
+ return (val > max) ? max : ((val < min) ? min : val);
+}
+
static void task_temp_ctrl_set_duty(TIM_HandleTypeDef *htim, uint32_t ch, uint8_t duty)
{
uint32_t ARR = __HAL_TIM_GET_AUTORELOAD(htim); // Auto Reload Reg