Cuando recibes AT+PRECIO=1150\0 en tu búfer UART, la cadena se divide lógicamente en tres bloques: la Cabecera (AT+PRECIO), el Delimitador (=), y el Payload (1150). Para extraer el Payload, debemos pedirle a un puntero que "camine" por el arreglo de caracteres hasta chocar con el delimitador, y luego dar un paso más hacia adelante.
Una vez que nuestro puntero se sitúa sobre el carácter '1', nos enfrentamos a un problema matemático. En código ASCII, '1' no vale uno; vale 49. '5' vale 53. Para convertir estos caracteres en un uint32_t real para nuestras matemáticas de metrología, debemos restarles el valor de '0' (que es 48). De este modo, '5' - '0' = 5 matemático puro.
Para ensamblar "1150", no podemos sumar sus partes sin más. Debemos construir el número de izquierda a derecha. Tomamos el primer dígito, lo multiplicamos por 10 y le sumamos el siguiente.
Paso 1: 0 * 10 + 1 = 1.
Paso 2: 1 * 10 + 1 = 11.
Paso 3: 11 * 10 + 5 = 115.
Paso 4: 115 * 10 + 0 = 1150. ¡Y así obtenemos nuestro número de punto fijo sin requerir procesadores complejos!
Ejercicio 1: Construye dos herramientas maestras en C puro. Una para localizar un carácter específico (como una versión ligera de strchr) y otra para convertir cadenas ASCII a enteros no signados de 32 bits (como tu propio atoi optimizado).
#include <stdint.h>
#include <stdbool.h>
// --- 1. LOCALIZADOR DE DELIMITADORES ---
/**
* @brief Busca la primera aparición de un carácter en un string.
* @param cadena Puntero al inicio del buffer UART.
* @param delimitador El carácter a buscar (Ej. '=' o ',').
* @return Puntero a la ubicación del delimitador, o 0x00 (NULL) si no existe.
*/
char* Buscar_Caracter(char* cadena, char delimitador) {
while (*cadena != '\0') {
if (*cadena == delimitador) {
return cadena; // Retorna la dirección de memoria exacta
}
cadena++; // Avanza al siguiente byte en la SRAM
}
return 0x00; // NULL
}
// --- 2. CONVERSOR ASCII A ENTERO (El Sustituto de atoi) ---
/**
* @brief Convierte caracteres ASCII numéricos en un uint32_t matemático.
* @param cadena Puntero al inicio de los números.
* @return El valor matemático en formato entero.
*/
uint32_t Extraer_Entero(char* cadena) {
uint32_t resultado = 0;
// Mientras el carácter sea un dígito válido entre '0' y '9'
while (*cadena >= '0' && *cadena <= '9') {
// Multiplicar el acumulado por 10 y sumar el dígito real
resultado = (resultado * 10) + (*cadena - '0');
cadena++;
}
return resultado;
}
// --- 3. APLICACIÓN EN EL PARSER DEL DÍA 41 ---
extern volatile char uart_rx_buffer[];
volatile uint32_t precio_gas_lp_centavos = 1000; // Ej: $10.00 base
void Parsear_Comando_Actualizacion(void) {
// Ejemplo de buffer en este instante: "AT+PRECIO=1150\0"
// 1. Validar la cabecera (Implementado ayer)
if (uart_rx_buffer[0] == 'A' && uart_rx_buffer[1] == 'T') {
// 2. Comprobar si es el comando de actualización de precio
// Buscamos si existe el delimitador de asignación '='
char* puntero_igual = Buscar_Caracter((char*)uart_rx_buffer, '=');
if (puntero_igual != 0x00) {
// 3. ¡Extracción de carga útil!
// Avanzamos el puntero una posición para saltar el '='
// y que apunte directamente al '1' de "1150"
uint32_t nuevo_precio = Extraer_Entero(puntero_igual + 1);
// 4. Validar integridad de hardware antes de aplicar
// No podemos aceptar un precio de $0.00 ni un número destructivo.
if (nuevo_precio > 0 && nuevo_precio < 9999) {
precio_gas_lp_centavos = nuevo_precio;
// Aquí podrías disparar el evento a tu matriz I2C para guardarlo en la EEPROM
// UART_Transmitir_Texto("OK: Precio Actualizado\r\n");
}
}
}
}
Objetivo del día: Parsing Numérico para Parámetros Metrológicos de Red.
Al dominar la aritmética de punteros, tu microcontrolador ahora es capaz de recibir parámetros críticos de calibración (como factores de temperatura o precios por litro) directamente desde la nube vía el módulo ESP32. En lugar de incluir la enorme librería <stdlib.h> para usar atoi(), o peor aún, usar float para manejar fracciones monetarias, tu Despachador emplea lógica de punto fijo y multiplicaciones limpias que se ejecutan en escasos ciclos de reloj dentro del núcleo ARM, preservando la memoria Flash indispensable para la lógica de seguridad y el arranque ininterrumpido de tus relés.
ptr++) en un arreglo de caracteres equivale a decirle al procesador que lea el siguiente byte físico de la memoria SRAM.while, desplazamos las unidades hacia las decenas y centenas, empujando el número para integrar los nuevos dígitos extraídos.1. ¿Qué pasaría si el módulo Wi-Fi tiene un error de hardware y transmite AT+PRECIO=11A50 (con una letra 'A' infiltrada en los números)?
Respuesta: Gracias a nuestro diseño defensivo, la función Extraer_Entero cuenta con la condición restrictiva while (*cadena >= '0' && *cadena <= '9'). Al encontrar la letra 'A' (cuyo ASCII es 65, fuera de ese rango), el bucle while se abortaría de inmediato. La función devolvería el valor parcialmente acumulado hasta ese punto (que sería 11). La validación lógica de la aplicación debería configurarse para descartar cambios drásticos o inválidos.