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_menu.c (10977B)
   1 /*
   2  * Copyright (c) 2023 Juan Manuel Cruz <jcruz@fi.uba.ar> <jcruz@frba.utn.edu.ar>.
   3  * Copyright (c) 2026 Martin Javier Klöckner <mklockner@fi.uba.ar>
   4  *
   5  * All rights reserved
   6  *
   7  * See file `LICENSE` for full details
   8  */
   9 
  10 #include "main.h"
  11 
  12 #include "logger.h"
  13 #include "dwt.h"
  14 
  15 #include "app.h"
  16 #include "task_menu_attribute.h"
  17 #include "task_menu_interface.h"
  18 #include "display_i2c.h"
  19 
  20 #define G_TASK_MEN_TICK_INI                0ul
  21 #define G_TASK_MEN_TICK_CNT_INI            0ul
  22 #define G_TASK_MEN_DISPLAY_UPDATE_RATE_MS  1000ul
  23 
  24 static task_menu_dta_t task_menu_dta = {
  25     G_TASK_MEN_TICK_INI, ST_MEN_IDLE, EV_MEN_ST_IDLE, false
  26 };
  27 
  28 // Private functions declaration
  29 static void task_menu_statechart(void *parameters);
  30 static void task_menu_set_state(task_menu_st_t new_state);
  31 static uint8_t task_menu_count_digits(int16_t n);
  32 
  33 // Private variables
  34 static bool g_display_update;
  35 static task_menu_st_t g_menu_prev_state;
  36 static int16_t temp_sensor_prev;
  37 static uint8_t temp_ctrl_pwm_dc_prev;
  38 
  39 // Public variables
  40 volatile uint32_t g_task_menu_tick_cnt;
  41 
  42 // External variables
  43 extern uint16_t g_ds18b20_temp;
  44 extern uint16_t g_ds18b20_update_count;
  45 extern uint16_t g_ds18b20_dma_error_count;
  46 
  47 // Public functions
  48 void task_menu_init(void *parameters)
  49 {
  50     task_menu_dta_t *p_task_menu_dta;
  51     shared_data_type *p_shared_data = (shared_data_type *)parameters;
  52 
  53     LOGGER_INFO("Initializing `task_menu`...");
  54 
  55     task_menu_interface_init_event_queue();
  56 
  57     g_menu_prev_state = ST_MEN_IDLE;
  58     p_task_menu_dta = &task_menu_dta;
  59     p_task_menu_dta->state = ST_MEN_IDLE;
  60     p_task_menu_dta->event = EV_MEN_ST_IDLE;
  61     p_task_menu_dta->event_flag = false;
  62     temp_sensor_prev = p_shared_data->temp_sensor;
  63     temp_ctrl_pwm_dc_prev = p_shared_data->temp_ctrl_pwm_dc;
  64 
  65     display_i2c_init();
  66     display_i2c_set_cursor_pos(0, 0);
  67     display_i2c_write_string("Initializing...");
  68     g_display_update = true;
  69 
  70     LOGGER_INFO("Done initializing `task_menu`");
  71 }
  72 
  73 void task_menu_update(void *parameters)
  74 {
  75     bool b_time_update_required = false;
  76 
  77     __asm("CPSID i");
  78     if (G_TASK_MEN_TICK_CNT_INI < g_task_menu_tick_cnt)
  79     {
  80         /* Update Tick Counter */
  81         g_task_menu_tick_cnt--;
  82         b_time_update_required = true;
  83     }
  84     __asm("CPSIE i");
  85 
  86     while (b_time_update_required)
  87     {
  88         display_i2c_async_tick();
  89         task_menu_statechart(parameters);
  90 
  91         __asm("CPSID i");
  92         if (G_TASK_MEN_TICK_CNT_INI < g_task_menu_tick_cnt)
  93         {
  94             g_task_menu_tick_cnt--;
  95             b_time_update_required = true;
  96         }
  97         else
  98         {
  99             b_time_update_required = false;
 100         }
 101         __asm("CPSIE i");
 102     }
 103 }
 104 
 105 static void task_menu_set_state(task_menu_st_t new_state)
 106 {
 107     task_menu_dta_t *p_task_menu_dta;
 108     p_task_menu_dta = &task_menu_dta;
 109 
 110     g_menu_prev_state = p_task_menu_dta->state;
 111     p_task_menu_dta->state = new_state;
 112 
 113     g_display_update = true;
 114 
 115     switch(new_state)
 116     {
 117         case ST_MEN_CLOCK_SET:
 118             p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
 119         break;
 120         default: break;
 121     }
 122 }
 123 
 124 static uint8_t task_menu_count_digits(int16_t n)
 125 {
 126     uint8_t count = 0;
 127 
 128     if (n == 0) return 1;
 129     if (n < 0) n = -n;
 130 
 131     while (n > 0) {
 132         n /= 10;
 133         count++;
 134     }
 135 
 136     return count;
 137 }
 138 
 139 static void task_menu_statechart(void *parameters)
 140 {
 141     task_menu_dta_t *p_task_menu_dta;
 142     shared_data_type *p_shared_data = (shared_data_type *)parameters;
 143     char menu_row_str[32];
 144 
 145     p_task_menu_dta = &task_menu_dta;
 146 
 147     if (true == task_menu_interface_any_event())
 148     {
 149         p_task_menu_dta->event_flag = true;
 150         p_task_menu_dta->event = task_menu_interface_get_event();
 151     }
 152 
 153     if (true == p_task_menu_dta->event_flag)
 154     {
 155         p_task_menu_dta->event_flag = false;
 156         switch (p_task_menu_dta->event)
 157         {
 158             case EV_MEN_ST_IDLE:
 159             case EV_MEN_INACTIVE_TIMEOUT:
 160                 task_menu_set_state(ST_MEN_IDLE);
 161             break;
 162 
 163             case EV_MEN_DISPLAY_UPDATE:
 164                 g_display_update = true;
 165             break;
 166 
 167             case EV_MEN_ST_CLOCK_SET:
 168                 task_menu_set_state(ST_MEN_CLOCK_SET);
 169             break;
 170 
 171             case EV_MEN_ST_TEMP_SET:
 172                 task_menu_set_state(ST_MEN_TEMP_SET);
 173             break;
 174 
 175             case EV_MEN_ST_TIMER_SET_STATUS:
 176                 task_menu_set_state(ST_MEN_TIMER_SET_STATUS);
 177             break;
 178 
 179             case EV_MEN_ST_TIMER_SET_START:
 180                 task_menu_set_state(ST_MEN_TIMER_SET_START);
 181             break;
 182 
 183             case EV_MEN_ST_TIMER_SET_END:
 184                 task_menu_set_state(ST_MEN_TIMER_SET_END);
 185             break;
 186 
 187             default: break;
 188         }
 189     }
 190 
 191     switch (p_task_menu_dta->state)
 192     {
 193         case ST_MEN_IDLE:
 194 
 195             if (0 == p_task_menu_dta->tick)
 196             {
 197                 if ((p_shared_data->temp_sensor != temp_sensor_prev) ||
 198                         (p_shared_data->temp_ctrl_pwm_dc != temp_ctrl_pwm_dc_prev))
 199                 {
 200                     g_display_update = true;
 201                 }
 202                 temp_sensor_prev = p_shared_data->temp_sensor;
 203                 temp_ctrl_pwm_dc_prev = p_shared_data->temp_ctrl_pwm_dc;
 204                 p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
 205             }
 206             else 
 207             {
 208                 p_task_menu_dta->tick--;
 209             }
 210 
 211             if (g_display_update)
 212             {
 213                 g_display_update = false;
 214                 display_i2c_async_clear();
 215                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 216 
 217                 if (p_shared_data->temp_ctrl_enabled)
 218                 {
 219                     display_i2c_async_write_string("On");
 220                     display_i2c_async_set_cursor_pos(10, 0);
 221                     sprintf(menu_row_str, "%5d%%",
 222                             p_shared_data->temp_ctrl_pwm_dc);
 223                     display_i2c_async_write_string(menu_row_str);
 224                 }
 225                 else
 226                 {
 227                     sprintf(menu_row_str, "Off");
 228                     display_i2c_async_write_string(menu_row_str);
 229                 }
 230 
 231                 display_i2c_async_set_cursor_pos(0, 1);
 232                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 233                 uint8_t aux = (8 - task_menu_count_digits(p_shared_data->temp_set_point));
 234                 aux = ((aux < 0) ? 0 : ((aux > 8) ? 8 : aux));
 235                 sprintf(menu_row_str, "%s %*d(%d)%cC",
 236                         p_shared_data->timer->enabled ? "[P]" : "   ", aux,
 237                         p_shared_data->temp_sensor,
 238                         p_shared_data->temp_set_point,
 239                         G_DISPLAY_CHAR_DEGREE_CODE);
 240                 display_i2c_async_write_string(menu_row_str);
 241             }
 242 
 243         break;
 244 
 245         case ST_MEN_CLOCK_SET:
 246 
 247             if (0 == p_task_menu_dta->tick)
 248             {
 249                 g_display_update = true;
 250                 p_task_menu_dta->tick = G_TASK_MEN_DISPLAY_UPDATE_RATE_MS;
 251             }
 252             else 
 253             {
 254                 p_task_menu_dta->tick--;
 255             }
 256 
 257             if (g_display_update)
 258             {
 259                 g_display_update = false;
 260                 display_i2c_async_clear();
 261                 display_i2c_async_write_string("Clock>");
 262                 display_i2c_async_set_cursor_pos(8, 0);
 263 
 264                 HAL_RTC_GetTime(&hrtc, &s_time, RTC_FORMAT_BIN);
 265                 HAL_RTC_GetDate(&hrtc, &s_date, RTC_FORMAT_BIN);
 266 
 267                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 268                 sprintf(menu_row_str, "%2d:%02d:%02d",
 269                         s_time.Hours, s_time.Minutes, s_time.Seconds);
 270                 display_i2c_async_write_string(menu_row_str);
 271             }
 272 
 273         break;
 274 
 275         case ST_MEN_TEMP_SET:
 276 
 277             if (g_display_update)
 278             {
 279                 g_display_update = false;
 280                 display_i2c_async_clear();
 281                 display_i2c_async_write_string("Temp>");
 282                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 283                 sprintf(menu_row_str, "%9d%cC",
 284                         p_shared_data->temp_set_point, G_DISPLAY_CHAR_DEGREE_CODE);
 285                 display_i2c_async_write_string(menu_row_str);
 286             }
 287 
 288         break;
 289 
 290         case ST_MEN_TIMER_SET_STATUS:
 291 
 292             if (g_display_update)
 293             {
 294                 g_display_update = false;
 295                 display_i2c_async_clear();
 296                 display_i2c_async_write_string("Timer>");
 297                 display_i2c_async_set_cursor_pos(13, 0);
 298                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 299                 sprintf(menu_row_str, "%3s", 
 300                         p_shared_data->timer->enabled ? "On" : "Off");
 301                 display_i2c_async_write_string(menu_row_str);
 302 
 303                 display_i2c_async_set_cursor_pos(3, 1);
 304                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 305                 sprintf(menu_row_str, "%s%2d:%02d - %d:%02d",
 306                         (p_shared_data->timer->end_hour >= 10) ? "" : " ",
 307                         p_shared_data->timer->start_hour,
 308                         p_shared_data->timer->start_min,
 309                         p_shared_data->timer->end_hour,
 310                         p_shared_data->timer->end_min);
 311                 display_i2c_async_write_string(menu_row_str);
 312             }
 313 
 314         break;
 315 
 316         case ST_MEN_TIMER_SET_START:
 317 
 318             if (g_display_update)
 319             {
 320                 g_display_update = false;
 321                 display_i2c_async_clear();
 322                 display_i2c_async_write_string("Timer>start>");
 323                 display_i2c_async_set_cursor_pos(11, 1);
 324                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 325                 sprintf(menu_row_str, "%2d:%02d",
 326                         p_shared_data->timer->start_hour,
 327                         p_shared_data->timer->start_min);
 328                 display_i2c_async_write_string(menu_row_str);
 329             }
 330 
 331         break;
 332 
 333         case ST_MEN_TIMER_SET_END:
 334 
 335             if (g_display_update)
 336             {
 337                 g_display_update = false;
 338                 display_i2c_async_clear();
 339                 display_i2c_async_write_string("Timer>end>");
 340                 display_i2c_async_set_cursor_pos(11, 1);
 341                 memset(menu_row_str, '\0', sizeof(menu_row_str));
 342                 sprintf(menu_row_str, "%2d:%02d",
 343                         p_shared_data->timer->end_hour,
 344                         p_shared_data->timer->end_min);
 345                 display_i2c_async_write_string(menu_row_str);
 346             }
 347 
 348         break;
 349 
 350         default:
 351 
 352             p_task_menu_dta->tick  = G_TASK_MEN_TICK_INI;
 353             p_task_menu_dta->state = ST_MEN_IDLE;
 354             p_task_menu_dta->event = EV_MEN_ST_IDLE;
 355             p_task_menu_dta->event_flag  = false;
 356             g_display_update = false;
 357 
 358         break;
 359     }
 360 }