Un módulo Bluetooth no es solo una radio. Bajo el escudo hay un MCU real con GPIO, I2C, SPI, UART, ADC, PWM y timers. Como cableas sensores y perifericos a ese MCU – y como estructuras el software del driver – decide si el producto es fiable, de bajo consumo y mantenible. Este articulo es una guia practica de campo.

Los buses, comparados

Bus Hilos Velocidad Topologia Direccion Mejor para
GPIO 1-2 n/a punto ninguna botones, LEDs, enable
I2C 2 (SDA/SCL) 100 k-1 MHz multi-drop addr 7/10-bit muchos sensores, regs config
SPI 4 (MOSI/MISO/SCK/CS) 1-32 MHz punto (CS por dev) pin CS alto ritmo, pantallas, flash
UART 2 (TX/RX) hasta pocos Mbps punto ninguna GNSS, debug, legado

Regla general: I2C para muchos sensores lentos en pocos pines, SPI cuando importan ritmo o latencia, UART para hablar con la consola serie de otro chip.

Detalles de I2C que muerden

  • Pull-ups: 4.7 kOhm es el valor clasico de inicio para 100 kHz con capacidad de bus moderada. Calcula R_min por corriente de hundimiento maxima y R_max por tiempo de subida: R_max <= t_r / (0.847 * C_bus). Un bus largo de 200 pF y 1 us de subida necesita R <= ~5.9 kOhm.
  • Estiramiento de reloj: los esclavos pueden mantener SCL bajo. Tu maestro debe soportarlo o un sensor lento cuelga el bus.
  • Recuperacion de bloqueo: si un esclavo se resetea a mitad de transferencia puede congelar SCL bajo. La recuperacion conmuta SCL (9 pulsos) hasta que suelta, luego manda STOP. Incluyelo en el driver.
  • Conflictos de direccion: dos sensores con la misma direccion fija necesitan un mux (p.ej. TCA9548A) o variante con strap de pines.

Detalles de SPI que muerden

  • Temporizacion CS: activa CS, respeta setup antes de reloj, manten tras el ultimo bit. Muchos flashes necesitan CS alto entre comandos o se quedan en estado.
  • Modo (CPOL/CPHA): mal y cada byte se desplaza. Documentalo por dispositivo.
  • DMA: SPI a 8 MHz mueve 1 MB/s; hacerlo con bytes pokeados por CPU quema ambos nucleos. Usa DMA con buffer circular para streaming (fusion de sensores, audio).
  • Contencion MISO: solo el dispositivo seleccionado debe conducir MISO; un CS mal cableado deja pelear a dos dispositivos.

Detalles de UART que muerden

  • Desajuste de baud: 2% es la tolerancia usual; un oscilador RC del modulo al 3% corrupte a 115200. Usa cristal o tolera baud menor.
  • Control de flujo: activa RTS/CTS antes de fiar alto ritmo, o pierdes bytes bajo carga.
  • Overrun: si la ISR no vacia la FIFO suficientemente rapido, sube el trigger de FIFO o pasa a DMA.

Presupuesto de latencia de interrupcion

Desde un cambio de pin hasta tu ISR corriendo:

  • SoC despierta de bajo consumo: 1-10 us (segun estado de retencion)
  • Entrada ISR + prologo: < 1 us
  • Secciones criticas: el asesino. Un bloque disable_irq() largo retrasa toda otra interrupcion. Manten secciones criticas en microsegundos; difiere el trabajo a una tarea.

En un nRF52840 a 64 MHz, una ISR limpia dispara en pocos microsegundos. Una seccion critica de 5 ms en una funcion de log puede romper un plazo de muestreo de 1 kHz.

Clock gating y potencia de perifericos

Los perifericos sin usar consumen uA incluso idle. Un UART habilitado a 3 uA, una referencia ADC a 10 uA, un timer sobrante a 2 uA – eso son 15 uA de pura perdida en un tag que debe sorber 5 uA. Deshabilita perifericos que no usas y corta el reloj HF cuando la radio esta idle.

Arquitectura de driver

Prefiere un diseno por capas y no bloqueante:

<h1>pseudo: lectura I2C no bloqueante con DMA + timeout</h1>

def read_sensor(dev, reg, buf):
i2c.start_write(dev, [reg])
i2c.start_read_dma(dev, buf, done_cb)
return  # no bloquees


def done_cb(buf):
queue.put(("sensor", buf))   # tarea RTOS procesa luego
  • Capa HAL: wrappers finos sobre registros, misma API entre chips.
  • Capa driver: init especifico de sensor, calibracion, conversion de unidades.
  • Capa servicio: una tarea RTOS que posee el bus, serializa acceso y expone una cola.
  • Nunca bloquees dentro de una interrupcion; solo senala.

Esto evita que la pila de radio (que tiene necesidades de tiempo real duro) se vea ahogada por una lectura de sensor lenta.

Level shifting

Un modulo de 1.8 V hablando con sensor de 3.3 V necesita level shifter en cada linea (o sensor tolerante a 1.8 V). Olvidarlo causa corruption intermitente que desaparece en el analizador logico.

Tabla de fallos comunes

Sintoma Causa probable
Bus se congela al azar Esclavo I2C atascado bajo, sin recuperacion
Lecturas SPI desplazadas CPOL/CPHA incorrecto
UART pierde bytes Sin control de flujo / FIFO pequena
Alta corriente idle Periferico no apagado
Plazos perdidos Seccion critica larga
Datos intermitentes Falta level shifter

Conclusion

Un módulo Bluetooth triunfa o fracasa en las partes alrededor de la radio. Elige el bus por velocidad y numero de pines, calcula pull-ups I2C, respeta la temporizacion CS de SPI, usa DMA para ritmo, manten secciones criticas diminutas y corta todo periferico sin usar. Un capado limpio – HAL, driver, tarea de servicio, cola – mantiene la pila de radio en tiempo real y tu firmware depurable.