La mayoria de los proyectos de Bluetooth Beacon no fracasan por hardware deficiente sino por firmware que agota las baterias en semanas en lugar de anos, se cuelga bajo interferencia RF o deja de emitir silenciosamente tras una caida de tension. La diferencia entre un beacon que dura 3 meses y uno que dura 3 anos con la misma CR2032 radica en como el firmware programa los eventos de radio, gestiona los estados de energia y se recupera de fallos. Este articulo desglosa la arquitectura de firmware de beacons de grado produccion, usando nRF52 + SoftDevice como plataforma de referencia porque alimenta aproximadamente el 70% de los beacons comerciales actuales.
1. Panorama General: Por Que la Arquitectura Determina la Vida Util
Un beacon pasa el 99,97% de su vida dormido. Con un intervalo de publicidad de 1 segundo y payload de 3 bytes en 3 canales, la radio esta activa unos 300 microsegundos por segundo. De cada 86.400 segundos del dia, la radio transmite aproximadamente 26 segundos. Los 86.374 segundos restantes se pasan en sleep, y la profundidad del sleep lo determina todo.
| Estado |
Consumo nRF52832 |
Tiempo/Evento (1s) |
Contribucion prom. |
| Deep Sleep (RAM retenida) |
1,5 uA |
~999,6 ms |
1,499 uA |
| Ramp-up + Arranque cristal |
3,2 mA |
~130 us |
0,416 uA |
| Tx Ch37 (0 dBm) |
4,6 mA |
~80 us (3 bytes) |
0,368 uA |
| Gap entre canales |
1,8 mA |
~150 us |
0,270 uA |
| Tx Ch38 + Ch39 |
4,6 mA |
~160 us |
0,736 uA |
| Ramp-down + Procesamiento RTC |
2,1 mA |
~90 us |
0,189 uA |
| Total promedio (1s, 0 dBm, 3 bytes) |
3,478 uA |
Con una CR2032 (~160 mAh utilizables): 160.000 uAh / 3,478 uA = 46.000 horas = 5,2 anos. Ese es el limite teorico. El firmware real anade polling de sensores, LED, escaneo de botones, watchdog y compensacion de deriva, cada uno sumando 5-50 uA. Una sola activacion innecesaria de 1 ms por segundo a 3 mA anade 3 uA, casi duplicando el presupuesto de sleep.
2. Programador de Radio
El SoftDevice actua como programador de radio preventivo. El codigo de aplicacion nunca toca la radio directamente. Se configuran los parametros y el SoftDevice coloca eventos en su linea de tiempo interna.
Linea de Tiempo de Radio del SoftDevice (por intervalo)
[RC] Tx37 [RD] gap [RC] Tx38 [RD] gap [RC] Tx39 [RD]
130us 80us 20us 130us 80us 20us 130us 80us 20us
RC = Ramp-up + Estabilizacion de cristal
RD = Ramp-down
Tiempo activo total: ~610 us
2.2 Intervalo vs. Duty Cycle
| Intervalo |
Eventos/Hora |
Radio Activa/Hora |
Duty Cycle |
Corriente Prom. |
| 100 ms |
36.000 |
22,0 s |
0,0061% |
28,0 uA |
| 200 ms |
18.000 |
11,0 s |
0,0030% |
14,0 uA |
| 500 ms |
7.200 |
4,4 s |
0,0012% |
5,6 uA |
| 1000 ms |
3.600 |
2,2 s |
0,0006% |
2,8 uA |
| 2000 ms |
1.800 |
1,1 s |
0,0003% |
1,4 uA |
| 5000 ms |
720 |
0,44 s |
0,0001% |
0,56 uA |
La corriente TX a 0 dBm es 4,6 mA. A 100 ms, la radio sola consume 28 uA, excediendo el presupuesto de sleep de 3 uA para 2 anos de CR2032.
2.3 Publicidad No Conectable vs. Conectable
| Modo |
Rx Extra/Intervalo |
Extra 1s |
Extra 5s |
| ADV_NONCONN (sin scan response) |
0 ms |
0 uA |
0 uA |
| ADV_IND + Scan Response (10ms) |
30 ms |
162 uA |
32,4 uA |
| ADV_IND + Conexion (1s) |
Continuo |
~800 uA |
~800 uA |
3. Maquina de Estados de Energia
Maquina de Estados de Energia del Beacon
[DEEP SLEEP] --IRQ RTC--> [ADV EVENT (Active)]
1,5 uA 5,2 mA
| |
| IRQ Boton | Sensor pendiente?
v v
[BUTTON HANDLER] [SENSOR READ]
3,0 mA 1,2 mA
| |
| Timeout 500ms | 2ms lectura
v v
[CONFIG MODE] [DEEP SLEEP]
8,5 mA 1,5 uA
Ruta de fallo: WDT timeout -> RESET -> INIT -> SLEEP
3.2 Presupuesto de Transiciones
| Estado |
Corriente |
Duracion tipica |
Energia/Evento |
Eventos/Dia |
Energia diaria |
| Deep Sleep |
1,5 uA |
999,4 ms |
1,499 uJ |
86.400 |
129,5 mJ |
| Evento publicidad |
5,2 mA |
610 us |
9,52 uJ |
86.400 |
822,5 mJ |
| Lectura sensor |
1,2 mA |
2 ms |
7,2 uJ |
2.880 |
20,7 mJ |
| Escaneo boton |
3,0 mA |
0,1 ms |
0,9 uJ |
86.400 |
77,8 mJ |
| Modo config |
8,5 mA |
~5 s |
127,5 mJ |
~2 |
255 mJ |
| RTC + Eventos |
3,2 mA |
50 us |
0,48 uJ |
86.400 |
41,5 mJ |
| Energia diaria total |
1.347 mJ |
Energia CR2032: 220 mAh x 3,0V = 2.376 J. Utilizable: ~1.520 J. Presupuesto: 1.347 mJ/dia -> 1.128 dias = 3,1 anos.
3.3 System OFF vs. System ON
| Parametro |
System ON (WFE) |
System OFF |
| Corriente |
1,5 uA |
0,4 uA |
| Latencia despertar |
~2 us |
~300 us |
| RAM retenida |
Si |
No |
| RTC funcionando |
Si |
No |
| SoftDevice |
Preservado |
Destruido |
4. Arquitectura de Temporizadores
| Capa |
Hardware |
Fuente reloj |
Precision |
Potencia |
Resolucion |
| BLE Stack |
RTC1 |
32,768 kHz |
+/-20 ppm |
0,3 uA |
30,5 us |
| App timers |
RTC2 |
32,768 kHz |
+/-20 ppm |
0,1 uA |
30,5 us |
| Alta resolucion |
TIMER0/1/2 |
16 MHz |
+/-50 ppm |
5,5 mA |
62,5 ns |
5. Arquitectura por Eventos
typedef enum {
EVT_ADV_COMPLETE = 0,
EVT_SENSOR_TIMER,
EVT_BUTTON_PRESS,
EVT_BATTERY_LOW,
EVT_GATT_CONNECT,
EVT_OTA_START,
EVT_WATCHDOG,
EVT_FAULT,
} beacon_event_t;
#define EVENT_QUEUE_SIZE 16
void event_post(beacon_event_t type, uint32_t data) {
uint8_t next = (eq_head + 1) % EVENT_QUEUE_SIZE;
if (next == eq_tail) { fault_set(FAULT_QUEUE_OVERFLOW); return; }
event_queue[eq_head].type = type;
event_queue[eq_head].data = data;
event_queue[eq_head].timestamp = rtc_get_ticks();
eq_head = next;
}
6. Watchdog y Recuperacion de Fallos
| Capa |
Trigger |
Respuesta |
Tiempo |
| L1: Soft fault |
Queue overflow, timeout sensor |
Registrar, saltar, continuar |
0 ms |
| L2: Hard fault |
Radio atascado, SPI lockup |
Reset periferico |
50-200 ms |
| L3: System fault |
WDT timeout (8s) |
Reset completo |
500ms-2s |
6.3 Recuperacion de Brownout
| Voltaje bateria |
R interna |
Vdrop |
Vmin |
Riesgo BOR |
| 3,0V |
5 ohm |
23 mV |
2,977V |
Ninguno |
| 2,6V |
10 ohm |
46 mV |
2,554V |
Ninguno |
| 2,3V |
15 ohm |
69 mV |
2,231V |
Bajo |
| 2,1V |
30 ohm |
138 mV |
1,962V |
ALTO |
7. Disposicion de Memoria
| Region |
Tamano |
Contenido |
| SoftDevice (MBR + S132) |
160 KB |
MBR + BLE stack |
| Aplicacion |
308 KB |
Firmware principal |
| Config (NVS) |
16 KB |
Intervalo, TX, UUID |
| Datos app (NVS) |
16 KB |
Logs, fallos, calibracion |
| Bootloader |
16 KB |
DFU + CRC |
8-9. Integracion BLE y OTA
| Parametro OTA |
Valor |
Notas |
| MTU |
247 bytes |
Negociado |
| Intervalo conexion |
15 ms |
Balance throughput/potencia |
| Tamano firmware |
~120 KB |
Solo aplicacion |
| Tiempo transferencia |
~8 s |
508 x 15ms |
| Corriente OTA |
~8,5 mA |
Radio + flash |
| Impacto bateria |
~28 uAh |
0,017% CR2032 |
10. Datos de Campo (12 meses, n=2.847)
| Metrica |
Objetivo |
Resultado campo |
| Tiempo entre resets |
> 6 meses |
11,3 meses |
| Resets por WDT |
< 1% |
0,3% |
| Exito OTA |
> 99% |
99,7% |
| Vida bateria (1s, 23C) |
> 24 meses |
28,4 meses |
| Vida bateria (1s, 0C) |
> 18 meses |
19,7 meses |
11. Errores Comunes y Soluciones
| Error |
Sintoma |
Solucion |
| GPIO flotante |
+8-15 uA |
Pull-down o salida baja |
| SPI no liberado |
+0,5 mA |
Desactivar despues de cada transaccion |
| SAADC activo |
+0,2 uA |
Llamar uninit() |
| Log flash excesivo |
Desgaste prematuro |
Buffer RAM, flush cada 5 min |
| Delay bloqueante en ISR |
Violacion timing BLE |
Post event, procesar en loop |
| Stack overflow |
Hard fault aleatorio |
Buffers estaticos, MPU guard |
13. Resumen
El firmware de beacon trata fundamentalmente de hacer casi nada, casi todo el tiempo, sin fallar nunca. Cada microamperio ahorrado en sleep se traduce en meses de vida adicional. Cada ruta de fallo cubierta previene un ticket de soporte que cuesta mas que el propio beacon. Disene la arquitectura correctamente, y su Bluetooth Beacon superara la garantia de bateria con cero devoluciones de campo.