tdse-tf_3-02

Controlador PID para derretidor de miel con control local via botones y remoto via WiFi
Index Commits Files Refs Submodules README
firmware-nucleo/App/Src/task_temp_ctrl.c (4471B)
   1 /*
   2  * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
   3  *
   4  * See file `LICENSE` for full details
   5  */
   6 
   7 #include <stdio.h>
   8 #include <stdint.h>
   9 #include <stdbool.h>
  10 #include <string.h>
  11 
  12 #include "main.h"
  13 #include "app.h"
  14 #include "task_temp_ctrl.h"
  15 #include "logger.h"
  16 
  17 #define G_TASK_TEMP_CTRL_TICK_CNT_INI  0ul
  18 
  19 #define G_TASK_TEMP_CTRL_PID_KP 40.0f
  20 #define G_TASK_TEMP_CTRL_PID_KI 0.75f
  21 #define G_TASK_TEMP_CTRL_PID_KD 0.01f
  22 #define G_TASK_TEMP_CTRL_PID_DT 250 // 100 ms
  23 
  24 // Private data definition
  25 typedef struct {
  26     TIM_HandleTypeDef *htim;
  27     uint32_t tim_channel;
  28 } task_temp_ctrl_cfg_t;
  29 
  30 typedef struct {
  31     float pid_kp, pid_ki, pid_kd;
  32     float pid_p, pid_i, pid_d;
  33     float error, prev_error;
  34     uint32_t tick;
  35 } task_temp_ctrl_pid_t;
  36 
  37 static const task_temp_ctrl_cfg_t task_temp_ctrl_cfg = {&htim1, TIM_CHANNEL_1};
  38 static task_temp_ctrl_pid_t task_temp_ctrl_pid = {
  39     G_TASK_TEMP_CTRL_PID_KP, G_TASK_TEMP_CTRL_PID_KI, G_TASK_TEMP_CTRL_PID_KD 
  40 };
  41 
  42 // Private functions declaration
  43 static inline int16_t clampf(float val, float min, float max);
  44 static void task_temp_ctrl_set_duty(TIM_HandleTypeDef *htim, uint32_t ch, uint8_t duty);
  45 
  46 // Public data definition
  47 volatile uint32_t g_task_temp_ctrl_tick_cnt; // Incremented by HAL_SysTick callback
  48 
  49 // Public functions definition
  50 void task_temp_ctrl_init(void *parameters)
  51 {
  52     LOGGER_INFO("Initializing `task_temp_ctrl`...");
  53 
  54     const task_temp_ctrl_cfg_t *p_task_cfg = &task_temp_ctrl_cfg;
  55     shared_data_type *p_shared_data = (shared_data_type *)parameters;
  56 
  57     task_temp_ctrl_set_duty(p_task_cfg->htim,
  58             p_task_cfg->tim_channel,
  59             p_shared_data->temp_ctrl_pwm_dc);
  60 
  61     // __HAL_TIM_SET_COMPARE(p_task_cfg->htim,
  62     //         p_task_cfg->tim_channel,
  63     //         p_shared_data->temp_ctrl_pwm_dc);
  64     HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  65 
  66     LOGGER_INFO("Done initializing `task_temp_ctrl`");
  67 }
  68 
  69 void task_temp_ctrl_update(void *parameters)
  70 {
  71     bool b_time_update_required;
  72     shared_data_type *p_shared_data = (shared_data_type *)parameters;
  73     const task_temp_ctrl_cfg_t *p_task_cfg = &task_temp_ctrl_cfg;
  74     task_temp_ctrl_pid_t *p_pid = &task_temp_ctrl_pid;
  75 
  76     __asm("CPSID i");
  77     if (G_TASK_TEMP_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
  78     {
  79         g_task_temp_ctrl_tick_cnt--;
  80         b_time_update_required = true;
  81     }
  82     __asm("CPSIE i");
  83 
  84     while (b_time_update_required)
  85     {
  86         __asm("CPSID i");
  87         if (G_TASK_TEMP_CTRL_TICK_CNT_INI < g_task_temp_ctrl_tick_cnt)
  88         {
  89             g_task_temp_ctrl_tick_cnt--;
  90             b_time_update_required = true;
  91         }
  92         else
  93         {
  94             b_time_update_required = false;
  95         }
  96         __asm("CPSIE i");
  97 
  98         if (false == p_shared_data->temp_ctrl_enabled)
  99         {
 100             if (0 != __HAL_TIM_GET_COMPARE(p_task_cfg->htim, p_task_cfg->tim_channel))
 101             {
 102                 task_temp_ctrl_set_duty(p_task_cfg->htim, p_task_cfg->tim_channel, 0);
 103             }
 104         }
 105         else
 106         {
 107             if (0 < p_pid->tick)
 108             {
 109                 p_pid->tick--;
 110             }
 111             else
 112             {
 113                 p_pid->tick = G_TASK_TEMP_CTRL_PID_DT;
 114                 float dt = (p_pid->tick / 1000.0f);
 115 
 116                 p_pid->prev_error = p_pid->error;
 117                 p_pid->error = p_shared_data->temp_set_point - p_shared_data->temp_sensor;
 118 
 119                 p_pid->pid_p = p_pid->error * p_pid->pid_kp;
 120                 p_pid->pid_i = (p_pid->pid_i + (p_pid->error*dt)) * p_pid->pid_ki;
 121                 p_pid->pid_d = ((p_pid->error - p_pid->prev_error)/dt) * p_pid->pid_kd;
 122 
 123                 p_shared_data->temp_ctrl_pwm_dc = clampf(
 124                         p_pid->pid_p + p_pid->pid_i + p_pid->pid_d,
 125                         0.0f,
 126                         100.0f);
 127 
 128                 task_temp_ctrl_set_duty(p_task_cfg->htim,
 129                         p_task_cfg->tim_channel,
 130                         p_shared_data->temp_ctrl_pwm_dc);
 131             }
 132         }
 133     }
 134 }
 135 
 136 // Public functions declaration
 137 static inline int16_t clampf(float val, float min, float max)
 138 {
 139     return (val > max) ? max : ((val < min) ? min : val);
 140 }
 141 
 142 static void task_temp_ctrl_set_duty(TIM_HandleTypeDef *htim, uint32_t ch, uint8_t duty)
 143 {
 144     uint32_t ARR = __HAL_TIM_GET_AUTORELOAD(htim);     // Auto Reload Reg
 145     uint32_t CCR = (uint32_t)((ARR + 1) * duty / 100); // Capture/Compare Reg
 146     __HAL_TIM_SET_COMPARE(htim, ch, CCR);
 147 }