cursada_mc2
Base de control de temperatura para EDU-CIAA-NXP
Loading...
Searching...
No Matches
hmi.c
Go to the documentation of this file.
1
6#include "hmi/hmi.h"
7
10#include "drivers/lcd_driver.h"
11
12#include <stdbool.h>
13#include <stdint.h>
14#include <stdio.h>
15#include <stdlib.h>
16
17#define HMI_LCD_COLUMNAS 16U
18#define HMI_TICK_MS 20U
19#define HMI_BEEP_MS 20U
20#define HMI_BEEP_TICKS (HMI_BEEP_MS / HMI_TICK_MS)
21
27
36
44
45typedef struct {
46 const char* titulo;
47 int16_t minimo;
48 int16_t maximo;
49 int16_t paso;
50 bool ciclico;
52
65
70
72 .parametros = {
74 .histeresis_deci_celsius = 20U,
75 .tiempo_minimo_encendido_ms = 0U,
76 .tiempo_minimo_apagado_ms = 0U,
77 .modo_calentar = true,
78 },
79 .ui = {
80 .pantalla = HMI_PANTALLA_INICIO,
81 .menu_index = HMI_PARAM_SETPOINT,
82 .editando = HMI_PARAM_SETPOINT,
83 .valor_edicion = 0,
84 .necesita_redibujado = true,
85 .ticks_buzzer_restantes = 0U,
86 },
87};
88
90 [HMI_PARAM_SETPOINT] = {.titulo = "Setpoint", .minimo = 0, .maximo = 1200, .paso = 1, .ciclico = false},
91 [HMI_PARAM_HISTERESIS] = {.titulo = "Histeresis", .minimo = 1, .maximo = 200, .paso = 1, .ciclico = false},
92 [HMI_PARAM_TMIN_ON] = {.titulo = "Tmin ON", .minimo = 0, .maximo = 6000, .paso = 1, .ciclico = false},
93 [HMI_PARAM_TMIN_OFF] = {.titulo = "Tmin OFF", .minimo = 0, .maximo = 6000, .paso = 1, .ciclico = false},
94 [HMI_PARAM_MODO] = {.titulo = "Modo", .minimo = 0, .maximo = 1, .paso = 1, .ciclico = true},
95};
96
97static void hmi_escribir_linea(uint8_t fila, const char* texto)
98{
99 char linea[HMI_LCD_COLUMNAS + 1U];
100
101 (void) snprintf(linea, sizeof(linea), "%-*.*s", HMI_LCD_COLUMNAS, HMI_LCD_COLUMNAS, texto);
102 driver_lcd_set_position(1U, fila);
103 driver_lcd_printf(linea);
104}
105
106static void hmi_formatear_deci(char* salida, size_t tam_salida, int16_t valor_deci)
107{
108 const bool negativo = (valor_deci < 0);
109 const int16_t absoluto = (int16_t) abs(valor_deci);
110 const int16_t entera = (int16_t) (absoluto / 10);
111 const int16_t decimal = (int16_t) (absoluto % 10);
112
113 if (negativo) {
114 (void) snprintf(salida, tam_salida, "-%d.%1d", entera, decimal);
115 } else {
116 (void) snprintf(salida, tam_salida, "%d.%1d", entera, decimal);
117 }
118}
119
121{
122 // Convierte el parametro seleccionado a la representacion entera usada en la pantalla de edicion.
123 switch (hmi_.ui.editando) {
127 return (int16_t) hmi_.parametros.histeresis_deci_celsius;
129 return (int16_t) (hmi_.parametros.tiempo_minimo_encendido_ms / 100U);
131 return (int16_t) (hmi_.parametros.tiempo_minimo_apagado_ms / 100U);
132 case HMI_PARAM_MODO:
133 default:
134 return hmi_.parametros.modo_calentar ? 1 : 0;
135 }
136}
137
139{
140 // Lleva el valor editado de vuelta al parametro persistible correspondiente.
141 switch (hmi_.ui.editando) {
144 break;
147 break;
150 break;
153 break;
154 case HMI_PARAM_MODO:
156 break;
157 default:
158 break;
159 }
160}
161
162static void hmi_dibujar_inicio(void)
163{
164 char temp_con_unidad[8];
165 char sp[8];
166 char h[8];
167 char linea1[HMI_LCD_COLUMNAS + 1U];
168 char linea2[HMI_LCD_COLUMNAS + 1U];
169 const char* salida = hmi_.ui.salida_activa ? "ON" : "OFF";
170 const char* modo = hmi_.parametros.modo_calentar ? "CAL" : "ENF";
171
173 char temp[8];
175 (void) snprintf(temp_con_unidad, sizeof(temp_con_unidad), "%sC", temp);
176 } else {
177 (void) snprintf(temp_con_unidad, sizeof(temp_con_unidad), "--.-C");
178 }
179
182
183 (void) snprintf(linea1, sizeof(linea1), "T:%s %s %s", temp_con_unidad, salida, modo);
184 (void) snprintf(linea2, sizeof(linea2), "SP:%s H:%s", sp, h);
185
186 hmi_escribir_linea(1U, linea1);
187 hmi_escribir_linea(2U, linea2);
188}
189
190static void hmi_dibujar_menu(void)
191{
192 hmi_escribir_linea(1U, "MENU:Param control");
194}
195
196static void hmi_dibujar_edicion(void)
197{
198 char valor[12];
199 char linea2[HMI_LCD_COLUMNAS + 1U];
200 const hmi_parametro_t parametro = hmi_.ui.editando;
201
202 hmi_escribir_linea(1U, "EDITAR");
203
204 if (parametro == HMI_PARAM_MODO) {
205 (void) snprintf(
206 linea2,
207 sizeof(linea2),
208 "Modo:%s",
209 (hmi_.ui.valor_edicion != 0) ? "Calentar" : "Enfriar"
210 );
211 hmi_escribir_linea(2U, linea2);
212 return;
213 }
214
215 hmi_formatear_deci(valor, sizeof(valor), hmi_.ui.valor_edicion);
216
217 if ((parametro == HMI_PARAM_TMIN_ON) || (parametro == HMI_PARAM_TMIN_OFF)) {
218 (void) snprintf(linea2, sizeof(linea2), "%s:%ss", hmi_param_descs_[parametro].titulo, valor);
219 } else {
220 (void) snprintf(linea2, sizeof(linea2), "%s:%s", hmi_param_descs_[parametro].titulo, valor);
221 }
222
223 hmi_escribir_linea(2U, linea2);
224}
225
226static void hmi_dibujar(void)
227{
229 return;
230 }
231
232 switch (hmi_.ui.pantalla) {
235 break;
238 break;
241 break;
242 default:
243 break;
244 }
245
247}
248
261
262void hmi_process(void)
263{
265 const uint8_t tecla = button_get_event();
266
267 if (tecla == TECLA1) {
268 evento = HMI_EVENTO_MENU;
269 } else if (tecla == TECLA2) {
270 evento = HMI_EVENTO_SUBIR;
271 } else if (tecla == TECLA3) {
272 evento = HMI_EVENTO_BAJAR;
273 } else if (tecla == TECLA4) {
274 evento = HMI_EVENTO_ACEPTAR;
275 }
276
277 if (hmi_.ui.ticks_buzzer_restantes > 0U) {
279 if (hmi_.ui.ticks_buzzer_restantes == 0U) {
281 }
282 }
283
284 if (evento != HMI_EVENTO_NINGUNO) {
287 }
288
289 switch (hmi_.ui.pantalla) {
291 if (evento == HMI_EVENTO_MENU) {
294 }
295 break;
296
298 if (evento == HMI_EVENTO_MENU) {
301 } else if (evento == HMI_EVENTO_SUBIR) {
302 if (hmi_.ui.menu_index == 0U) {
304 } else {
306 }
308 } else if (evento == HMI_EVENTO_BAJAR) {
311 } else if (evento == HMI_EVENTO_ACEPTAR) {
316 }
317 break;
318
320 if (evento == HMI_EVENTO_MENU) {
323 } else if (evento == HMI_EVENTO_SUBIR) {
325 hmi_.ui.valor_edicion = (int16_t) (hmi_.ui.valor_edicion + desc->paso);
326 // Limita el valor editado al rango permitido y hace wrap solo en Modo.
327 if (hmi_.ui.valor_edicion > desc->maximo) {
328 hmi_.ui.valor_edicion = desc->ciclico ? desc->minimo : desc->maximo;
329 }
331 } else if (evento == HMI_EVENTO_BAJAR) {
333 hmi_.ui.valor_edicion = (int16_t) (hmi_.ui.valor_edicion - desc->paso);
334 // Limita el valor editado al rango permitido y hace wrap solo en Modo.
335 if (hmi_.ui.valor_edicion < desc->minimo) {
336 hmi_.ui.valor_edicion = desc->ciclico ? desc->maximo : desc->minimo;
337 }
339 } else if (evento == HMI_EVENTO_ACEPTAR) {
343 }
344 break;
345
346 default:
347 break;
348 }
349
350 hmi_dibujar();
351}
352
354{
355 if (parametros == 0) {
356 return;
357 }
358
359 hmi_.parametros = *parametros;
361}
362
364{
365 const bool hubo_cambios = (estado != 0)
368 || (hmi_.ui.salida_activa != estado->salida_activa)
370
371 if (estado == 0) {
372 return;
373 }
374
379
380 if (hubo_cambios && (hmi_.ui.pantalla == HMI_PANTALLA_INICIO)) {
382 }
383}
384
uint8_t button_get_event(void)
Devuelve y consume el siguiente evento de tecla confirmado.
Interfaz del driver de pulsadores discretos.
#define TECLA4
Identificador de la tecla 4.
#define TECLA1
Identificador de la tecla 1.
#define TECLA2
Identificador de la tecla 2.
#define TECLA3
Identificador de la tecla 3.
void buzzer_turn_off()
Desactiva el buzzer.
void buzzer_turn_on()
Activa el buzzer.
Interfaz del driver de buzzer.
static hmi_estado_t hmi_
Definition hmi.c:71
static void hmi_guardar_valor_editado(void)
Definition hmi.c:138
hmi_pantalla_t
Definition hmi.c:22
@ HMI_PANTALLA_INICIO
Definition hmi.c:23
@ HMI_PANTALLA_MENU
Definition hmi.c:24
@ HMI_PANTALLA_EDICION
Definition hmi.c:25
hmi_parametro_t
Definition hmi.c:28
@ HMI_PARAM_HISTERESIS
Definition hmi.c:30
@ HMI_PARAM_MODO
Definition hmi.c:33
@ HMI_PARAM_SETPOINT
Definition hmi.c:29
@ HMI_PARAM_TMIN_OFF
Definition hmi.c:32
@ HMI_PARAM_COUNT
Definition hmi.c:34
@ HMI_PARAM_TMIN_ON
Definition hmi.c:31
static const hmi_param_desc_t hmi_param_descs_[HMI_PARAM_COUNT]
Definition hmi.c:89
static void hmi_dibujar_menu(void)
Definition hmi.c:190
static void hmi_escribir_linea(uint8_t fila, const char *texto)
Definition hmi.c:97
static void hmi_dibujar(void)
Definition hmi.c:226
void hmi_init(void)
Inicializa el estado interno de la HMI y dibuja la pantalla inicial.
Definition hmi.c:249
static int16_t hmi_cargar_valor_edicion_actual(void)
Definition hmi.c:120
static void hmi_formatear_deci(char *salida, size_t tam_salida, int16_t valor_deci)
Definition hmi.c:106
#define HMI_LCD_COLUMNAS
Definition hmi.c:17
parametros_control_t hmi_obtener_parametros_control(void)
Obtiene todos los parametros de control actualmente cargados en la HMI.
Definition hmi.c:385
void hmi_process(void)
Procesa la navegacion de la interfaz y actualiza el LCD si es necesario.
Definition hmi.c:262
#define HMI_BEEP_TICKS
Definition hmi.c:20
static void hmi_dibujar_edicion(void)
Definition hmi.c:196
void hmi_cargar_parametros_control(const parametros_control_t *parametros)
Carga en la HMI los parametros de control vigentes.
Definition hmi.c:353
hmi_evento_t
Definition hmi.c:37
@ HMI_EVENTO_ACEPTAR
Definition hmi.c:42
@ HMI_EVENTO_BAJAR
Definition hmi.c:41
@ HMI_EVENTO_NINGUNO
Definition hmi.c:38
@ HMI_EVENTO_MENU
Definition hmi.c:39
@ HMI_EVENTO_SUBIR
Definition hmi.c:40
static void hmi_dibujar_inicio(void)
Definition hmi.c:162
void hmi_cargar_estado_proceso(const hmi_estado_proceso_t *estado)
Carga en la HMI el estado visible actual del proceso.
Definition hmi.c:363
Interfaz publica de la HMI.
void driver_lcd_write_char(char C)
Escribe un caracter en la posicion actual del LCD.
Definition lcd_driver.c:139
void driver_lcd_set_position(uint8_t x, uint8_t y)
Posiciona el cursor dentro de la matriz visible del LCD.
Definition lcd_driver.c:128
void driver_lcd_printf(const char *string)
Escribe una cadena a partir de la posicion actual del cursor.
Definition lcd_driver.c:157
Interfaz del driver para LCD alfanumerico.
bool salida_activa
Definition hmi.h:16
bool temperatura_valida
Definition hmi.h:14
int16_t temperatura_deci_celsius
Definition hmi.h:15
bool sensor_disponible
Definition hmi.h:17
parametros_control_t parametros
Definition hmi.c:67
hmi_ui_t ui
Definition hmi.c:68
const char * titulo
Definition hmi.c:46
int16_t paso
Definition hmi.c:49
bool ciclico
Definition hmi.c:50
int16_t minimo
Definition hmi.c:47
int16_t maximo
Definition hmi.c:48
Definition hmi.c:53
int16_t temperatura_deci_celsius
Definition hmi.c:55
uint8_t ticks_buzzer_restantes
Definition hmi.c:63
bool salida_activa
Definition hmi.c:56
bool sensor_disponible
Definition hmi.c:57
bool temperatura_valida
Definition hmi.c:54
hmi_parametro_t menu_index
Definition hmi.c:59
bool necesita_redibujado
Definition hmi.c:62
hmi_pantalla_t pantalla
Definition hmi.c:58
int16_t valor_edicion
Definition hmi.c:61
hmi_parametro_t editando
Definition hmi.c:60
uint32_t tiempo_minimo_apagado_ms
Definition parametros.h:16
uint16_t histeresis_deci_celsius
Definition parametros.h:14
uint32_t tiempo_minimo_encendido_ms
Definition parametros.h:15
int16_t setpoint_deci_celsius
Definition parametros.h:13