La plupart des projets de Bluetooth Beacon echouent non pas a cause d’un mauvais materiel mais a cause d’un firmware qui vide les piles en quelques semaines au lieu de quelques annees, plante sous interference RF ou arrete silencieusement d’emettre apres une chute de tension. La difference entre un beacon qui dure 3 mois et un qui dure 3 ans sur la meme CR2032 reside dans la facon dont le firmware planifie les evenements radio, gere les etats d’energie et se recupere des pannes. Cet article decompose l’architecture du firmware de beacon de qualite production, en utilisant nRF52 + SoftDevice comme plateforme de reference car il alimente environ 70% des beacons commerciaux actuels.
1. Vue d’Ensemble : Pourquoi l’Architecture Determine la Duree de Vie
Un beacon passe 99,97% de sa vie endormi. Avec un intervalle de publicite de 1 seconde et un payload de 3 octets sur 3 canaux, la radio est active environ 300 microsecondes par seconde. Sur 86.400 secondes par jour, la radio transmet au total environ 26 secondes. Les 86.374 secondes restantes sont passees en sommeil, et la profondeur du sommeil determine tout.
| Etat |
Courant nRF52832 |
Temps/Evenement (1s) |
Contribution moyenne |
| Deep Sleep (RAM retenue) |
1,5 uA |
~999,6 ms |
1,499 uA |
| Ramp-up + Demarrage cristal |
3,2 mA |
~130 us |
0,416 uA |
| Tx Ch37 (0 dBm) |
4,6 mA |
~80 us (3 octets) |
0,368 uA |
| Gap inter-canaux |
1,8 mA |
~150 us |
0,270 uA |
| Tx Ch38 + Ch39 |
4,6 mA |
~160 us |
0,736 uA |
| Ramp-down + Traitement RTC |
2,1 mA |
~90 us |
0,189 uA |
| Total moyen (1s, 0 dBm, 3 octets) |
3,478 uA |
Avec CR2032 (~160 mAh utilisable) : 160.000 uAh / 3,478 uA = 46.000 heures = 5,2 ans. C’est le plafond theorique. Le firmware reel ajoute le polling de capteurs, le clignotement LED, le scan de boutons, les interruptions watchdog et la compensation de derive RTC, chacun ajoutant 5-50 uA. Un seul reveil inutile de 1 ms par seconde a 3 mA ajoute 3 uA, pres du double du budget de sommeil.
2. Ordonnanceur Radio
Le SoftDevice agit comme un ordonnanceur radio preemptif. Le code d’application ne touche jamais directement la radio. On configure les parametres de publicite et le SoftDevice place les evenements radio dans sa chronologie interne.
Chronologie Radio du SoftDevice (par intervalle)
[RC] Tx37 [RD] gap [RC] Tx38 [RD] gap [RC] Tx39 [RD]
130us 80us 20us 130us 80us 20us 130us 80us 20us
RC = Ramp-up radio + Stabilisation cristal
RD = Ramp-down radio
Temps actif total : ~610 us
2.2 Intervalle vs. Duty Cycle
| Intervalle |
Evenements/Heure |
Radio Active/Heure |
Duty Cycle |
Courant radio moy. |
| 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 |
A 100 ms, la radio seule consomme 28 uA, depassant tout le budget de sommeil de 3 uA pour 2 ans de CR2032.
2.3 Publicite Non-Connectable vs. Connectable
| Mode |
Rx Extra/Intervalle |
Extra 1s |
Extra 5s |
| ADV_NONCONN (sans scan response) |
0 ms |
0 uA |
0 uA |
| ADV_IND + Scan Response (10ms) |
30 ms |
162 uA |
32,4 uA |
| ADV_IND + Connexion (1s) |
Continu |
~800 uA |
~800 uA |
3. Machine d’Etats d’Energie
Machine d'Etats d'Energie du Beacon
[DEEP SLEEP] --IRQ RTC--> [ADV EVENT (Active)]
1,5 uA 5,2 mA
| |
| IRQ Bouton | Capteur en attente?
v v
[BUTTON HANDLER] [SENSOR READ]
3,0 mA 1,2 mA
| |
| Timeout 500ms | 2ms lecture
v v
[CONFIG MODE] [DEEP SLEEP]
8,5 mA 1,5 uA
Chemin de panne : WDT timeout -> RESET -> INIT -> SLEEP
3.2 Budget de Transitions
| Etat |
Courant |
Duree typique |
Energie/Evenement |
Evenements/Jour |
Energie journaliere |
| Deep Sleep |
1,5 uA |
999,4 ms |
1,499 uJ |
86.400 |
129,5 mJ |
| Evenement publicite |
5,2 mA |
610 us |
9,52 uJ |
86.400 |
822,5 mJ |
| Lecture capteur |
1,2 mA |
2 ms |
7,2 uJ |
2.880 |
20,7 mJ |
| Scan bouton |
3,0 mA |
0,1 ms |
0,9 uJ |
86.400 |
77,8 mJ |
| Mode config |
8,5 mA |
~5 s |
127,5 mJ |
~2 |
255 mJ |
| RTC + Evenement |
3,2 mA |
50 us |
0,48 uJ |
86.400 |
41,5 mJ |
| Energie journaliere totale |
1.347 mJ |
CR2032 : 220 mAh x 3,0V = 2.376 J. Utilisable : ~1.520 J. Budget : 1.347 mJ/jour -> 1.128 jours = 3,1 ans.
3.3 System OFF vs. System ON
| Parametre |
System ON (WFE) |
System OFF |
| Courant |
1,5 uA |
0,4 uA |
| Latence reveil |
~2 us |
~300 us |
| RAM retenue |
Oui |
Non |
| RTC actif |
Oui |
Non |
| SoftDevice |
Preserve |
Detruit |
4. Architecture des Minuteurs
| Couche |
Materiel |
Source horloge |
Precision |
Puissance |
Resolution |
| 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 |
| Haute resolution |
TIMER0/1/2 |
16 MHz |
+/-50 ppm |
5,5 mA |
62,5 ns |
5. Architecture par Evenements
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 et Recuperation de Pannes
| Couche |
Declencheur |
Reponse |
Temps |
| L1: Panne douce |
Queue overflow, timeout capteur |
Enregistrer, passer, continuer |
0 ms |
| L2: Panne dure |
Radio bloque, SPI lockup |
Reset peripherique |
50-200 ms |
| L3: Panne systeme |
WDT timeout (8s) |
Reset complet |
500ms-2s |
6.3 Recuperation Brownout
| Tension pile |
R interne |
Vdrop |
Vmin |
Risque BOR |
| 3,0V |
5 ohm |
23 mV |
2,977V |
Aucun |
| 2,6V |
10 ohm |
46 mV |
2,554V |
Aucun |
| 2,3V |
15 ohm |
69 mV |
2,231V |
Faible |
| 2,1V |
30 ohm |
138 mV |
1,962V |
ELEVE |
7. Disposition Memoire
| Region |
Taille |
Contenu |
| SoftDevice (MBR + S132) |
160 KB |
MBR + BLE stack |
| Application |
308 KB |
Firmware principal |
| Config (NVS) |
16 KB |
Intervalle, TX, UUID |
| Donnees app (NVS) |
16 KB |
Logs, pannes, calibration |
| Bootloader |
16 KB |
DFU + CRC |
8-9. Integration BLE et OTA
| Parametre OTA |
Valeur |
Notes |
| MTU |
247 octets |
Negocie |
| Intervalle connexion |
15 ms |
Balance debit/puissance |
| Taille firmware |
~120 KB |
Application seule |
| Temps transfert |
~8 s |
508 x 15ms |
| Courant OTA |
~8,5 mA |
Radio + flash |
| Impact pile |
~28 uAh |
0,017% CR2032 |
10. Donnees Terrain (12 mois, n=2.847)
| Metric |
Objectif |
Resultat terrain |
| Temps entre resets |
> 6 mois |
11,3 mois |
| Resets WDT |
< 1% |
0,3% |
| Succes OTA |
> 99% |
99,7% |
| Duree vie pile (1s, 23C) |
> 24 mois |
28,4 mois |
| Duree vie pile (1s, 0C) |
> 18 mois |
19,7 mois |
11. Erreurs Courantes et Solutions
| Erreur |
Symptome |
Solution |
| GPIO flottants |
+8-15 uA |
Pull-down ou sortie basse |
| SPI non libere |
+0,5 mA |
Desactiver apres transaction |
| SAADC actif |
+0,2 uA |
Appeler uninit() |
| Log flash excessif |
Usure prematuree |
Tampon RAM, flush 5 min |
| Delay bloquant en ISR |
Violation timing BLE |
Poster evenement, traiter en loop |
| Debordement pile |
Hard fault aleatoire |
Buffers statiques, MPU guard |
13. Resume
Le firmware de beacon consiste fondamentalement a ne presque rien faire, presque tout le temps, sans jamais tomber en panne. Chaque microampere economise en mode sommeil se traduit directement par des mois de vie supplementaire. Chaque chemin de panne couvert evite un ticket de support qui coute plus cher que le beacon lui-meme. Avec la bonne architecture, votre Bluetooth Beacon depassera la garantie de pile avec zero retours terrain.