DÍA 333 DE 365

Fase 5: Diseño Industrial y Hardware

📖 Teoría a Estudiar

Product Lifecycle Management (PLM)

A diferencia del software, donde un error se arregla con una actualización gratuita, un error en hardware cuesta miles de dólares en componentes arruinados. El PLM es el sistema empresarial que rastrea qué componentes van en qué versión física de la tarjeta. Las revisiones se clasifican en:

La Regla de FFF (Form, Fit, Function)

Antes de lanzar un cambio (ECO - Engineering Change Order), debes preguntarte: ¿Cambia la Forma (Form)? ¿Cambia el encaje mecánico en el gabinete (Fit)? ¿Cambia cómo se comporta (Function)? Si la respuesta a cualquiera de estas tres es SÍ, es una Revisión Mayor, y el número de parte (SKU) del producto final debe cambiar obligatoriamente en tu inventario.

DETECCIÓN FÍSICA DE REVISIONES: HARDWARE STRAPPING (3-BIT) PCB MAIN - REV A HW_REV Pads (Strapping) 0 0 0 Código: 000 (Dec: 0) PCB MAIN - REV B HW_REV Pads (Strapping) 0 0 1 Código: 001 (Dec: 1) ESQUEMÁTICO: PUERTOS GPIO AL ARRANQUE (BOOT) STM32 MCU PB0 (REV_0) PB1 (REV_1) PB2 (REV_2) DNP 3.3V 0 (LOW) DNP 3.3V 0 (LOW) 10 kΩ 3.3V 1 (HIGH) Firmware Unified: En el arranque (Boot), el firmware lee PB0, PB1 y PB2. Construye un entero (0-7). Ajusta pines o pantallas según el hardware detectado.

⚙️ Procedimiento Práctico: El Hardware Strapping

Paso 1: Diseño de los Pads (DNP).
En el esquemático (KiCad), reservas 3 pines de tu microcontrolador (Ej. PB0, PB1, PB2). A cada uno le conectas una resistencia apuntando hacia 3.3V (Pull-up). Pero en la Lista de Materiales (BOM) inicial, marcas estas resistencias como DNP (Do Not Populate). La fábrica entregará la placa sin esas resistencias soldadas.

Paso 2: Configuraciones Pull-Down internas.
Dado que los pines no tienen resistencias externas, en el firmware configuramos esos pines con el resistor Pull-Down interno del STM32. Si nadie inyecta voltaje, leerán LOW (0). La placa inicial (Rev A) se leerá lógicamente como `000`. Cuando lances la Revisión B, simplemente cambias el BOM para que la fábrica suelde la resistencia en PB0. La placa leerá `001`. Tienes capacidad para 8 revisiones de hardware usando 3 pines.

💻 Firmware: Autodetección Universal de Placa

Escribiremos una función de lectura rápida. Si mantienes un Unified Firmware (Un solo código para todas las placas), tu servidor OTA nunca tendrá que preguntarse: "¿A esta máquina le mando el binario de Rev A o de Rev B?". Le manda el mismo binario a todas, y cada placa adapta su código en el arranque basándose en sus resistencias físicas.


/**
 * @file hardware_plm_revision.c
 * @brief Detección automática de la Revisión Física de la PCB (Strapping)
 */

#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <stdint.h>

// Definición de Pines de Strapping (Ej. GPIOB, Pines 0, 1, 2)
#define HW_REV_PORT   GPIOB
#define REV_PIN_0     GPIO_PIN_0
#define REV_PIN_1     GPIO_PIN_1
#define REV_PIN_2     GPIO_PIN_2

// Enum para legibilidad
typedef enum {
    BOARD_REV_A = 0, // 000
    BOARD_REV_B = 1, // 001
    BOARD_REV_C = 2, // 010
    BOARD_REV_D = 3, // 011
    // ... Hasta 7
    BOARD_UNKNOWN = 0xFF
} HardwareRevision_t;

HardwareRevision_t Current_Board_Revision = BOARD_UNKNOWN;

// =========================================================================
// INICIALIZACIÓN Y DETECCIÓN
// =========================================================================
/**
 * @brief Lee los pines físicos y decodifica el número de versión de la placa.
 * Esta función debe llamarse inmediatamente después de SystemClock_Config().
 */
void Hardware_Detect_Board_Revision(void) {
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // 1. Activar reloj del puerto B
    __HAL_RCC_GPIOB_CLK_ENABLE();

    // 2. Configurar pines como entrada con Pull-Down interno
    // Si la fábrica no soldó la resistencia Pull-Up (DNP), el pin leerá 0 de forma segura.
    GPIO_InitStruct.Pin = REV_PIN_0 | REV_PIN_1 | REV_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    HAL_GPIO_Init(HW_REV_PORT, &GPIO_InitStruct);

    // 3. Dar tiempo de estabilización eléctrica a las líneas
    HAL_Delay(5);

    // 4. Leer los pines y construir el entero de 3 bits (0 a 7)
    uint8_t rev_code = 0;
    if (HAL_GPIO_ReadPin(HW_REV_PORT, REV_PIN_0) == GPIO_PIN_SET) rev_code |= (1 << 0); // Bit 0
    if (HAL_GPIO_ReadPin(HW_REV_PORT, REV_PIN_1) == GPIO_PIN_SET) rev_code |= (1 << 1); // Bit 1
    if (HAL_GPIO_ReadPin(HW_REV_PORT, REV_PIN_2) == GPIO_PIN_SET) rev_code |= (1 << 2); // Bit 2

    Current_Board_Revision = (HardwareRevision_t)rev_code;
    
    printf("\r\n[SYS] Hardware Físico Detectado: Rev %c (Código: %d)\r\n", 'A' + rev_code, rev_code);
}

// =========================================================================
// APLICACIÓN EN LA LÓGICA DE INICIALIZACIÓN
// =========================================================================
/**
 * @brief Inicializa los periféricos basándose en la versión física detectada.
 */
void Hardware_Adaptive_Init(void) {
    
    // Supongamos que en la Revisión A, la pantalla LCD usaba el bus I2C1.
    // Pero el chip I2C causaba ruido con la bomba, así que en la Revisión B 
    // lo rediseñaste para usar una pantalla SPI robusta.
    
    switch (Current_Board_Revision) {
        
        case BOARD_REV_A:
            printf("      -> Modo Rev A: Inicializando LCD via I2C1...\r\n");
            LCD_I2C_Init();
            break;
            
        case BOARD_REV_B:
        case BOARD_REV_C: // Mantenemos retrocompatibilidad con cambios menores
            printf("      -> Modo Rev B/C: Inicializando Display via SPI2...\r\n");
            LCD_SPI_Init();
            // Desactivamos el I2C que ya no existe en la placa para ahorrar energía
            HAL_I2C_DeInit(&hi2c1); 
            break;
            
        default:
            printf("[!] REVISIÓN NO SOPORTADA. Deteniendo Sistema.\r\n");
            // Entrar en Lockdown o Halt
            while(1);
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Sostenibilidad a Largo Plazo y Resiliencia en el Ciclo de Vida (PLM).

Las empresas mueren por el "Deuda Técnica". Si hoy liberas la placa 1.0, y en seis meses el proveedor te avisa que ya no fabricarán tu pantalla, te verás obligado a sacar la placa 1.1 con una pantalla diferente. Sin una estrategia, tus desarrolladores tendrán que bifurcar el código en dos proyectos (`Firmware_PantallaVieja` y `Firmware_PantallaNueva`). A los 5 años, tendrás 12 códigos fuente distintos. Un error humano en una actualización OTA colapsaría cientos de máquinas inyectando código de Rev C a una placa Rev A.

Al implementar el **Hardware Strapping (Detección por Resistencias)**, cortaste de raíz la pesadilla del mantenimiento corporativo. Tu Despachador de Gas LP ahora es "Autoconsciente" de su propio chasis. Cuando despierta, lee los 3 pines ocultos. El firmware analiza el entero y decide instintivamente qué pines activar y qué rutinas de metrología cargar. Esto te permite tener **Un Único Firmware Universal**. Tu equipo de software compila un solo archivo `.bin` y lo distribuye alegremente por AWS IoT (Día 331) a las 10,000 máquinas distribuidas en el país. El silicio hace la magia de adaptarse al cobre sobre el que está soldado. Esa es la marca de un Arquitecto Maestro.

📝 Resumen del Día