DÍA 016 DE 365

Fase 1: Fundamentos de C y Lógica de Software

📖 Teoría Explícita: Desplazamiento y Máscaras (Bit-shifting)

1. El Problema del Cuello de Botella

Un entero uint32_t mide 4 bytes (32 bits). Registros como el DR (Data Register) del bus SPI o UART en los microcontroladores generalmente envían 8 bits a la vez. Necesitamos desfragmentar nuestro número grande en 4 piezas pequeñas para poder transmitirlo por el cable, y luego reconstruirlo en el otro extremo (el ESP32 o la EEPROM).

2. Operadores `>>` (Shift Right) y `<<` (Shift Left)

El operador >> empuja todos los bits de una variable hacia la derecha, haciendo que los bits de la orilla se caigan al vacío. Por ejemplo, si tienes el volumen y le aplicas >> 8, estás empujando todo el número 8 posiciones hacia la derecha. Esto se ejecuta directamente en el *Barrel Shifter* del procesador ARM en 1 solo ciclo de reloj.

3. La Guillotina Lógica: `& 0xFF`

El operador Bitwise AND (&) compara dos números bit por bit. El valor hexadecimal 0xFF equivale a 11111111 en binario (8 unos). Al hacer variable & 0xFF, le estás diciendo al procesador: "Corta y consérvame únicamente los 8 bits de la extrema derecha, y convierte todo lo demás a ceros". Es la herramienta perfecta para extraer el byte inferior.

SERIALIZACIÓN (BIG-ENDIAN) USANDO BIT-SHIFTING uint32_t volumen = 287454020; (Hex: 0x11223344) 0x11 0x22 0x33 0x44 MSB (Bit 31..24) LSB (Bit 7..0) >> 24 & 0xFF 0x11 tx[0] >> 16 & 0xFF 0x22 tx[1] >> 8 & 0xFF 0x33 tx[2] & 0xFF 0x44 tx[3] Los 4 bytes (uint8_t) ya pueden enviarse por SPI/I2C/UART. 0% uso de strings. 100% velocidad Bare-Metal.

⚙️ Ejercicios Prácticos: Escribiendo tus Serializadores

Ejercicio 1: Empaquetar y Desempaquetar. Crearemos las funciones que descomponen el volumen del gas en 4 bytes para transmitirlos, y la función inversa que utilizará el ESP32 o el procesador esclavo para reconstruir el volumen a partir de los 4 bytes recibidos usando << (Shift Left) y | (Bitwise OR).


#include <stdint.h>

/**
 * @brief  Serializa un entero de 32 bits a un arreglo de 4 bytes (Big-Endian).
 * @param  volumen_ml Número grande a descomponer (Ej: Volumen del despacho).
 * @param  buffer     Puntero al arreglo de transmisión UART o I2C.
 */
void Empaquetar_Volumen_32_to_8(uint32_t volumen_ml, uint8_t *buffer) {
    if(buffer == 0x00) return; // Validación Anti-HardFault
    
    // Desplazamos los bits hacia la derecha y enmascaramos con 0xFF
    // Casteamos a (uint8_t) para asegurar el encaje en el arreglo
    buffer[0] = (uint8_t)((volumen_ml >> 24) & 0xFF); // MSB (Byte más significativo)
    buffer[1] = (uint8_t)((volumen_ml >> 16) & 0xFF);
    buffer[2] = (uint8_t)((volumen_ml >> 8)  & 0xFF);
    buffer[3] = (uint8_t)(volumen_ml & 0xFF);         // LSB (No necesita shift)
}

/**
 * @brief  Reconstruye un entero de 32 bits a partir de 4 bytes (Big-Endian).
 * @param  buffer Puntero al arreglo donde se recibieron los datos del UART.
 * @return El número original reconstruido.
 */
uint32_t Desempaquetar_Volumen_8_to_32(uint8_t *buffer) {
    if(buffer == 0x00) return 0;
    
    uint32_t volumen_reconstruido = 0;
    
    // Convertimos cada byte a 32 bits antes de desplazarlo a la izquierda
    // Usamos OR (|) lógico para ir "pegando" los bloques en su lugar original
    volumen_reconstruido |= ((uint32_t)buffer[0] << 24);
    volumen_reconstruido |= ((uint32_t)buffer[1] << 16);
    volumen_reconstruido |= ((uint32_t)buffer[2] << 8);
    volumen_reconstruido |= ((uint32_t)buffer[3]);       
    
    return volumen_reconstruido;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Hito Logrado: Serialización de datos sin uso de conversiones ASCII.

Convertir el volumen `10450` a texto ocuparía 5 bytes (uno por cada letra/número) más el carácter nulo (`'\0'`). Si el volumen sube a `10450000`, ocuparías 9 bytes. El ancho de banda necesario sería dinámico e inestable. Al usar Bit-Shifting, el volumen SIEMPRE ocupará exactamente 4 bytes, ya sea que despaches 1 mililitro o 4 billones de mililitros. Estás optimizando tu protocolo de comunicación para que la CPU gaste 0% de tiempo parseando strings y 100% de tiempo monitoreando la seguridad de las válvulas.

📝 Resumen del Día