Un module Bluetooth n’est pas qu’une radio. Sous le bouclier se cache un vrai MCU avec GPIO, I2C, SPI, UART, ADC, PWM et timers. Comment vous cablez capteurs et peripheriques a ce MCU – et comment le logiciel pilote est structure – decide si votre produit est fiable, basse conso et maintenable. Cet article est un guide de terrain pratique.
Les bus, compares
| Bus | Fils | Vitesse | Topologie | Adresse | Meilleur pour |
|---|---|---|---|---|---|
| GPIO | 1-2 | n/a | point | aucune | boutons, LEDs, enable |
| I2C | 2 (SDA/SCL) | 100 k-1 MHz | multi-drop | addr 7/10-bit | nombreux capteurs, regs config |
| SPI | 4 (MOSI/MISO/SCK/CS) | 1-32 MHz | point (CS par dev) | pin CS | debit eleve, ecrans, flash |
| UART | 2 (TX/RX) | jusqu’a quelques Mbps | point | aucune | GNSS, debug, heritage |
Regle geniale : I2C pour nombreux capteurs lents sur peu de broches, SPI quand debit ou latence comptent, UART pour parler a la console serie d’une autre puce.
Details I2C qui mordent
- Pull-ups : 4,7 kOhm est la valeur de depart classique pour 100 kHz avec capacite de bus modernee. Calculez R_min par courant de sink max et R_max par temps de montee : R_max <= t_r / (0,847 * C_bus). Un bus long de 200 pF et 1 us de montee exige R <= ~5,9 kOhm.
- Clock stretching : les esclaves peuvent maintenir SCL bas. Votre maitre doit le supporter ou un capteur lent bloque le bus.
- Recuperation de blocage : si un esclave est reset en plein transfert, il peut geler SCL bas. La recovery toggle SCL (9 impulsions) jusqu’a liberer, puis envoie STOP. Integrez-le au pilote.
- Conflits d’adresse : deux capteurs meme adresse fixe necessitent un mux (ex. TCA9548A) ou variante a strap de broches.
Details SPI qui mordent
- Timing CS : assert CS, respectez setup avant horloge, hold apres dernier bit. Beaucoup de flashes exigent CS haut entre commandes sinon restent dans un etat.
- Mode (CPOL/CPHA) : rate et chaque octet est decale. Documentez par device.
- DMA : SPI a 8 MHz deplace 1 MB/s ; le faire avec octets pokes par CPU brule les deux coeurs. Utilisez DMA avec buffer circulaire pour streaming (fusion capteurs, audio).
- Contention MISO : seul le device selectionne doit driver MISO ; un CS mal cable laisse deux devices se battre.
Details UART qui mordent
- Ecart baud : 2% est la tolerance usuelle ; un oscillateur RC du module a 3% corrompt a 115200. Utilisez un cristal ou tolerez un baud inferieur.
- Controle de flux : activez RTS/CTS avant de faire confiance au debit eleve, sinon vous perdez des octets sous charge.
- Overrun : si l’ISR ne vide pas la FIFO assez vite, montez le trigger FIFO ou passez au DMA.
Budget de latence d’interruption
D’un changement de pin jusqu’a votre ISR qui tourne :
- Wake SoC depuis low-power : 1-10 us (selon etat de retention)
- Entree ISR + prologue : < 1 us
- Sections critiques : le tueur. Un long bloc disable_irq() retarde toute autre interruption. Gardez les sections critiques en microsecondes ; reportez le travail a une tache.
Sur un nRF52840 a 64 MHz, une ISR propre declenche en quelques microsecondes. Une section critique de 5 ms dans une fonction de log peut exploser une deadline d’echantillonnage 1 kHz.
Clock gating et puissance peripherique
Les peripheriques inutilises consomment des uA meme idle. Un UART actif a 3 uA, une reference ADC a 10 uA, un timer en trop a 2 uA – ce sont 15 uA de pur gaspillage sur un tag qui doit siroter 5 uA. Desactivez les peripheriques inutilises et gatez l’horloge HF quand la radio est idle.
Architecture de pilote
Preferez une conception en couches et non bloquante :
<h1>pseudo : lecture I2C non bloquante avec DMA + timeout</h1>
def read_sensor(dev, reg, buf):
i2c.start_write(dev, [reg])
i2c.start_read_dma(dev, buf, done_cb)
return # ne bloquez pas
def done_cb(buf):
queue.put(("sensor", buf)) # la tache RTOS traite plus tard
- Couche HAL : wrappers minces sur registres, meme API entre puces.
- Couche pilote : init specifique capteur, calibration, conversion unite.
- Couche service : une tache RTOS possede le bus, serialise l’acces, expose une queue.
- Ne bloquez jamais dans une interruption ; signalez seulement.
Cela empeche la pile radio (qui a des besoins temps reel dur) d’etre affamee par une lecture capteur lente.
Level shifting
Un module 1,8 V parlant a un capteur 3,3 V a besoin d’un level shifter sur chaque ligne (ou capteur tolerant 1,8 V). L’oublier cause une corruption intermittente qui disparait a l’analyseur logique.
Tableau des pannes courantes
| Symptome | Cause probable |
|---|---|
| Bus gele aleatoirement | Esclave I2C bloque bas, sans recovery |
| Lectures SPI decalees | CPOL/CPHA incorrect |
| UART perd des octets | pas de controle de flux / petite FIFO |
| Courant idle eleve | Peripherique non coupe |
| Deadlines manquees | longue section critique |
| Donnees intermittentes | level shifter absent |
En bref
Un module Bluetooth reussit ou échoue sur les parties autour de la radio. Choisissez le bus par vitesse et nombre de broches, calculez les pull-ups I2C, respectez le timing CS SPI, utilisez DMA pour le debit, gardez les sections critiques minuscules et gatez tout peripherique inutilise. Un capage propre – HAL, pilote, tache service, queue – garde la pile radio temps reel et votre firmware debuggable.