La familia de funciones printf/sprintf de la librería estándar de C (stdio.h) es sumamente compleja. Debe ser capaz de procesar múltiples argumentos variables (va_list), buscar patrones de texto especiales (como %d, %f, %s) en tiempo de ejecución, y a menudo enlaza soporte para números flotantes en el ejecutable, incluso si solo estás imprimiendo enteros.
sprintf por primera vez puede agregar entre 5KB y 20KB a tu código compilado.sprintf causará un Stack Overflow que reiniciará el microcontrolador.En el circuito, el STM32 se comunica con el ESP32 a través del puerto serie (UART). Ambos operan a 3.3V, por lo que puedes conectar TX a RX de manera directa sin conversores de nivel. El despachador debe enviarle al módulo de IoT las tramas de los totales para la nube. Haremos esto empaquetando bytes manualmente.
Vamos a construir una función simple que tome el total en centavos que calculamos ayer y lo convierta a una cadena de caracteres legible sin sprintf.
#include <stdint.h>
#include <stdbool.h>
// --- Prototipo de envío UART simulado ---
void UART_Transmit(const char* data);
/**
* @brief Convierte un entero (centavos) a cadena de texto con formato monetario.
* Evita el uso de sprintf para ahorrar ciclos de CPU y Flash.
* @param centavos El total a convertir (ej. 21008 = $210.08)
* @param buffer Arreglo donde se guardará el resultado (mínimo 16 bytes)
*/
void formatear_precio_ascii(uint32_t centavos, char* buffer) {
char temp[16];
int i = 0;
// Si el valor es cero, manejarlo directamente
if (centavos == 0) {
buffer[0] = '$'; buffer[1] = '0'; buffer[2] = '.';
buffer[3] = '0'; buffer[4] = '0'; buffer[5] = '\0';
return;
}
// 1. Extraer los dígitos de derecha a izquierda (módulo 10)
// El dígito ASCII se obtiene sumando '0' (0x30 en hexadecimal)
while (centavos > 0) {
temp[i++] = (centavos % 10) + '0';
centavos /= 10;
// Agregar el punto decimal al tener 2 dígitos extraídos (centavos)
if (i == 2) {
temp[i++] = '.';
}
}
// Si el valor era menor a 1 peso (ej. 8 centavos -> .08)
if (i == 2) { temp[i++] = '.'; temp[i++] = '0'; }
if (i == 3 && temp[2] == '.') { temp[i++] = '0'; }
// 2. Invertir la cadena y añadir el prefijo de moneda
int j = 0;
buffer[j++] = '$';
while (i > 0) {
buffer[j++] = temp[--i];
}
// Null-terminator obligatorio en C
buffer[j] = '\0';
}
// Integración con el cálculo de ayer
void enviar_venta_esp32(uint32_t importe_centavos) {
char tx_buffer[20];
formatear_precio_ascii(importe_centavos, tx_buffer);
// Envío por hardware directo
UART_Transmit(tx_buffer);
}
Al desterrar `sprintf` de tu firmware, has asegurado que la memoria RAM disponible para FreeRTOS sea abundante y predecible. Ahora, cada tarea (como la de las válvulas y el botón de emergencia) tiene su propio stack libre de amenazas. Tu código es más rápido y cumple con principios de arquitectura Bare-Metal industrial.
sprintf para tareas simples mata el rendimiento e infla la memoria Flash drásticamente.módulo 10 y sumar el caracter '0'.