Ein Bluetooth-Modul ist nicht nur ein Funkteil. Unter dem Shield sitzt ein echtes MCU mit GPIO, I2C, SPI, UART, ADC, PWM und Timern. Wie du Sensoren und Peripherie an dieses MCU anschliesst – und wie die Treibersoftware strukturiert ist – entscheidet, ob dein Produkt zuverlaessig, stromsparend und wartbar ist. Dieser Artikel ist ein praktischer Feldleitfaden.

Die Busse im Vergleich

Bus Leitungen Speed Topologie Adresse Gut fuer
GPIO 1-2 n/a Punkt keine Taster, LEDs, Enable
I2C 2 (SDA/SCL) 100 k-1 MHz Multi-Drop 7/10-bit viele Sensoren, Config-Reg
SPI 4 (MOSI/MISO/SCK/CS) 1-32 MHz Punkt (CS pro Dev) CS-Pin hoher Rate, Displays, Flash
UART 2 (TX/RX) bis wenige Mbps Punkt keine GNSS, Debug, Legacy

Faustregel: I2C fuer viele langsame Sensoren an wenigen Pins, SPI wenn Durchsatz oder Latenz zaehlen, UART um mit der seriellen Konsole eines anderen Chips zu reden.

I2C-Details, die beissen

  • Pull-ups: 4,7 kOhm ist der klassische Startwert fuer 100 kHz bei mittlerer Buskapazitaet. Berechne R_min aus max. Senkstrom und R_max aus Anstiegszeit: R_max <= t_r / (0,847 * C_bus). Ein langer Bus mit 200 pF und 1 us Anstieg braucht R <= ~5,9 kOhm.
  • Clock-Stretching: Slaves duerfen SCL tief halten. Dein Master muss das koennen, sonst haengt ein langsamer Sensor den Bus auf.
  • Bus-Lock-Recovery: wird ein Slave mitten in der Uebertragung resettet, kann er SCL tief einfrieren. Recovery toggelt SCL (9 Pulse), bis er freigibt, dann STOP. Einbauen in den Treiber.
  • Adresskonflikte: zwei Sensoren mit derselben fixen Adresse brauchen einen Mux (z.B. TCA9548A) oder Pin-Strap-Variante.

SPI-Details, die beissen

  • CS-Timing: CS assert, Setup vor Takt, Hold nach letztem Bit. Viele Flashes brauchen CS hoch zwischen Kommandos, sonst bleiben sie in einem Zustand.
  • Mode (CPOL/CPHA): falsch und jedes Byte ist verschoben. Pro Device dokumentieren.
  • DMA: SPI bei 8 MHz bewegt 1 MB/s; mit CPU-gepokten Bytes verbrennst du beide Kerne. Nutze DMA mit Ringpuffer fuers Streaming (Sensor-Fusion, Audio).
  • MISO-Konflikt: nur das gewaehlte Device treibt MISO; verdrahteter CS laesst zwei Devices kaempfen.

UART-Details, die beissen

  • Baud-Abweichung: 2% ist die uebliche Toleranz; ein RC-Oszillator des Moduls bei 3% korrumpiert bei 115200. Kristall nutzen oder niedrigere Baud akzeptieren.
  • Flusskontrolle: RTS/CTS aktivieren, bevor du hohen Durchsatz traust, sonst verlierst du Bytes unter Last.
  • Overrun: leert die ISR die FIFO nicht schnell genug, erhoehe den FIFO-Trigger oder gehe zu DMA.

Interrupt-Latenz-Budget

Von einer Pin-Aenderung bis deine ISR laeuft:

  • SoC-Wake aus Low-Power: 1-10 us (je nach Retention-State)
  • ISR-Eintritt + Prolog: < 1 us
  • Kritische Sektion: der Killer. Ein langer disable_irq()-Block verzoegert jede andere Interrupt. Kritische Sektionen auf Mikrosekunden halten; Arbeit an eine Task verlagern.

Auf einem nRF52840 mit 64 MHz feuert eine saubere ISR in wenigen Mikrosekunden. Eine 5-ms-kritische Sektion in einer Log-Funktion kann eine 1-kHz-Abtast-Deadline sprengen.

Clock-Gating und Peripherie-Leistung

Unbenutzte Peripherie zieht selbst im Idle uA. Ein UART bei 3 uA aktiv, ADC-Referenz 10 uA, uebriger Timer 2 uA – das sind 15 uA reine Verschwendung an einem Tag, der 5 uA sippt. Deaktiviere ungenutzte Peripherie und gate den HF-Takt, wenn die Radio idle ist.

Treiber-Architektur

Bevorzuge eine geschichtete, nicht-blockierende Struktur:

<h1>pseudo: nicht-blockierendes I2C-Lesen mit DMA + Timeout</h1>

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


def done_cb(buf):
queue.put(("sensor", buf))   # RTOS-Task verarbeitet spaeter
  • HAL-Schicht: duenne Wrapper ueber Register, gleiche API ueber Chips.
  • Treiber-Schicht: sensor-spezifisches Init, Kalibrierung, Einheitenwandel.
  • Service-Schicht: eine RTOS-Task besitzt den Bus, serialisiert Zugriff, bietet Queue.
  • Nie blockieren in einer Interrupt; nur signalisieren.

Das bewahrt den Radio-Stack (harte Echtzeit noetig) davor, von langsamem Sensor-Lesen ausgehungert zu werden.

Level-Shifting

Ein 1,8-V-Modul, das mit einem 3,3-V-Sensor redet, braucht Level-Shifter auf jeder Leitung (oder 1,8-V-toleranten Sensor). Vergessen hier verursacht intermitterende Korruption, die am Logik-Analysator verschwindet.

Tabelle haeufiger Fehler

Symptom Wahrscheinliche Ursache
Bus friert zufaellig ein I2C-Slave tief gesperrt, keine Recovery
SPI-Lesung verschoben falsches CPOL/CPHA
UART verliert Bytes keine Flusskontrolle / kleine FIFO
Hoher Idle-Strom Peripherie nicht gegated
Deadlines verfehlt lange kritische Sektion
intermitterende Daten Level-Shifter fehlt

Fazit

Ein Bluetooth-Modul scheitert oder gelingt an den Teilen um die Radio herum. Waehle den Bus nach Speed und Pinzahl, berechne I2C-Pull-ups, achte auf SPI-CS-Timing, nutze DMA fuer Durchsatz, halte kritische Sektionen winzig und gate jede ungenutzte Peripherie. Eine saubere Treiber-Schichtung – HAL, Treiber, Service-Task, Queue – haelt den Radio-Stack echtzeitnah und deinen Firmware debugbar.