V
Visla Hardware
Portal R&D
🧩 Moduli & Shield ⚡ Low power

Nordic Thingy:91 X

Nordic Semiconductor
nRF9151 LTE-M/NB-IoT/NR+Wi-Fi + BLE + GNSS locationingBatteria Li-Po 1350 mAh onboard
📑 Indice sezioni

Curiosity

Prototyping kit cellulare IoT battery-powered di Nordic, pensato per valutare e prototipare asset tracking e applicazioni LPWAN senza disegnare una PCB. Integra il SiP nRF9151 (MCU Cortex-M33 + modem LTE-M/NB-IoT/DECT NR+ + GNSS) come cervello, affiancato da due companion Nordic: l’nRF7002 (Wi-Fi 6 per il locationing Wi-Fi) e l’nRF5340 (board controller per USB + Bluetooth Low Energy). A bordo ci sono PMIC (nPM1300 con charging + fuel gauge, nPM6001), una suite di sensori ambientali/motion e una batteria Li-Po da 1350 mAh per il field testing. È un DEV KIT: non si commercializza come prodotto finito — serve a valutare il silicio Nordic e prototipare il firmware prima di impegnarsi su un design proprio (sul mercato si porta poi il SiP montato sulla propria PCB).

Specs tecniche

ParametroValore
SoC principaleNordic nRF9151 SiP (Cortex-M33 64 MHz, 1 MB flash / 256 KB RAM, TrustZone + CryptoCell)
Companion Wi-FinRF7002 Wi-Fi 6 (Wi-Fi locationing)
Companion BLE / controllernRF5340 (board controller USB + Bluetooth Low Energy)
PMICnPM1300 (charging + fuel gauging) · nPM6001
Connettività cellulareLTE-M · NB-IoT · DECT NR+ · banda LTE 700–2200 MHz (no 2G)
LocationingGNSS + Wi-Fi + cellular (via nRF Cloud Location Services)
Sensori onboardTemperatura · umidità · qualità aria · pressione · magnetometro · accelerometro 3 assi low-power · IMU 6 assi con giroscopio
AlimentazioneBatteria Li-Po ricaricabile 1350 mAh onboard · USB
Casi d’usoAsset tracking, prototipazione cellular IoT, field testing LPWAN
SoftwareZephyr RTOS / nRF Connect SDK
Prezzo kit~€88 (Mouser) — è il prezzo del kit, non del chip

🔌 Current measurement & debug board (inclusa)

Nella scatola è inclusa la scheda PCA64165 — “current measurement and debug board” (HW v1.1.0, prod. 2025.50), che si innesta sul connettore frontale del Thingy via FPC 20-pin. È ciò che abilita la misura dei consumi senza J-Link esterno.

Thingy:91 X current measurement & debug board PCA64165 — lato componenti: 4 MOSFET di power-domain switching, pad di misura 3V3/1V8/GPIO, header debug SWD

Lato componenti (THIS SIDE UP · CURRENT MEASUREMENT): 4 MOSFET di potenza (DPAK, siglati D1/P2/P3/…) che spezzano i singoli rail dei domini di potenza (nRF9151, nRF5340, nRF7002) per inserire la misura su ciascuno separatamente. Fila di pad di misura etichettati 3V3 · 1V8 · 18 · 19 · 21 · 22 · 23 · 24 · 25 · GND (rail + trace GPIO) + header debug SWD/trace (destra).

Thingy:91 X current measurement & debug board PCA64165 — lato saldature con logo Nordic, etichetta PCA64165 v1.1.0 2025.50, FPC arancione 20-pin

Lato saldature: logo Nordic + scritta “Thingy:91 X current measurement and debug board”, etichetta PCA64165 · v1.1.0 · 2025.50, marcature UL (E207844, 94V-0) e RoHS. L’FPC arancione 20-pin si innesta sul fronte del Thingy.

Debug board PCA64165 — pad through-hole: GND, P0.21-25, P0.18-19, 1V8, 3V3 + jumper current-measurement P1/P2/P3/P6

🔌 Pad accessibili (per I/O esterno): la colonna di fori espone GPIO liberi del nRF9151 + rail: GND · 21 · 22 · 23 · 24 · 25 · 19 · 18 · 1V8 · 3V3 (= P0.21/22/23/24/25/19/18 + 1.8V + 3.3V). I jumper a sinistra (P1/P2/P3/P6) sono i selettori di corrente per i domini di potenza.

💡 Uso per GPS dedicato via UART (workaround alla coesistenza): dato che il Thingy lavora a 1.8V e i sensori esterni a 3.3V, il connettore di espansione I2C passa per un level shifter (U24) che si è bloccato col SAM-M10Q (lockup del bus). Soluzione pulita usando questi pad: alimentare il GPS a 1V8 (così la sua UART è 1.8V = stesso livello del nRF9151, niente level shifter) e collegare P0.21→RX-GPS, P0.22←TX-GPS, GND. Poi UART + driver u-blox Zephyr. Vedi test-moduli/nordic-thingy91x/.

⚠️ La board fornisce i punti di misura + il debug, ma la lettura µA vera la fa il PPK2 (venduto a parte): qui si interrompe il rail e ci si attacca il Power Profiler Kit II. Per una prima stima a costo zero c’è il fuel gauge nPM1300 via firmware.

🧪 Note dal bench Visla

  • Kit ideale per testare l’Asset-Tracker-Template di Nordic: il firmware ufficiale nrfconnect/Asset-Tracker-Template (zbus + state machine SMF, moduli Location/Cloud/Power-PSM/FOTA già pronti) gira nativamente su Thingy:91 X — è il banco di prova prima di qualsiasi PCB
  • Puntarlo al broker MQTT su GKE: il template ha un modulo cloud MQTT d’esempio (overlay-mqtt) → si swappa il modulo per parlare con il backend Visla invece di nRF Cloud, validando l’intero path senza riscrivere l’app
  • Tutto onboard per la valutazione: SiP + Wi-Fi + BLE + GNSS + sensori + batteria 1350 mAh = si valuta locationing multi-tecnologia e autonomia reale senza saldare nulla
  • Out-of-box validato (22 giu 2026, Orvieto): device sano, aggancia Vodafone IT (rete 22210, SIM Onomondo), e dà la localizzazione a gradini stesso punto/stesso istante — single-cell 503 m, Wi-Fi 19 m, GNSS 6 m. Strategia Tag: cell/Wi-Fi per il 95% del tempo, GNSS solo on-demand (vedi scheda progetto)
  • ⚠️ È un kit di valutazione, non un prodotto: il MCU del Visla Tag è già stato deciso su Nordic (nRF52840 prototipo → nRF54L15 prodotto); qui si valuta se il nRF9151 (SiP unico modem+GNSS) può sostituire SIM7080G + MAX-M10S separati (vedi chip card nRF9151)
  • ⚠️ Per i µA reali serve il PPK2: il FNB58 non scende sotto ~100 µA, quindi PSM/deep-sleep del nRF9151 vanno misurati con il Power Profiler Kit II, non sul banco USB standard

Marathon di bench per flashare l’nRF9151 e agganciare il J-Link. Tutto in test-moduli/nordic-thingy91x/ (workspace NCS v3.2.4 in firmware-custom/ncs-workspace/). Sintesi delle scoperte, per non ripartire da zero.

L’nRF5340 fa da debugger/bridge integrato → si flasha via USB, il J-Link non serve per il lavoro normale:

nrfutil device program --firmware <app>/zephyr/zephyr.signed.hex \
  --serial-number THINGY91X_... --options target=nRF91
  • ⚠️ Solo target _ns (thingy91x/nrf9151/ns): il build secure (thingy91x/nrf9151) non boota via serial-recovery (layout MCUboot ≠ fabbrica) → per il secure serve il J-Link.
  • Il .hex firmato (non merged.hex → “wrong magic”; non .zip → col trait modem lo scambia per upgrade modem).
  • ⚠️ Il J-Link collegato al Mac “maschera” il Thingy a nrfutil (vede solo il J-Link) → per flashare via USB, stacca il cavo USB del J-Link dal Mac.
  • Ripristino fabbrica: firmware-iniziale/hello.nrfcloud...nrf91-update-signed.bin (riaccende il PMIC completo).

🖥️ Console seriale

  • Console = uart0 @ 115200 → bridge nRF53 → /dev/cu.usbmodem*1102 (vcom0). uart1 @ 1M (trace). Leggere con pyserial dtr=rts=True.
  • Il .printk sulla seriale sostituisce il debug a breakpoint per il 95% dei casi → per test/sviluppo l’USB basta, il J-Link serve solo per debug live (RTT, breakpoint), backup flash, recover APPROTECT.

Aggancio riuscito (Found SW-DP 0x6BA02477 · Core found · Cortex-M33 identified) con questi test point (SW2 su nRF91):

⚫ GND   → TP15
🔴 VTref → TP18 (1V8, ~1.8V)   ⚠️⚠️ SOLO 1.8V — MAI TP19 (3.3V)!
🟢 SWCLK → TP27  (= P8 pin 4)
🟡 SWDIO → TP29  (= P8 pin 2)
  • ⚠️⚠️ VTref DEVE essere 1.8V (TP18), NON 3.3V (TP19). Il chip lavora a 1.8V: coi 3.3V si sovra-pilotano SWDIO/SWCLK (ha agganciato lo stesso, ma è fuori spec e rischioso). TP19 = da NON usare per VTref.
  • ⚠️ Il rail 1V8_SW (TP18) è acceso solo se il firmware configura il PMIC — col nostro firmware minimo era 0V; col factory hello.nrfcloud è ~1.8V. Se TP18=0, VTref non c’è.
  • Device J-Link: usare Cortex-M33 (il DLL V9.24a non conosce nRF9151_xxAA). J-Link firmware vecchio (2023) → warning cache, ma funziona.
  • SW2 su nRF91 (non nRF53!). Su nRF53 il J-Link disturba il bridge USB → il Thingy sparisce da USB (fix: power-cycle).

🔑 La lezione vera: era il CONTATTO

VTref/GND leggevano bene, ma SWDIO/SWCLK coi fili appoggiati sui pad 1.27mm non facevano contatto → 100 tentativi a vuoto, poi ha agganciato appena il contatto è stato solido. Conferma dal DevZone Nordic: stesso errore “powering up sys and debug regions failed” = saldature/GND instabili. → SALDARE i fili su TP27/TP29 (o cavo a nastro 1.27mm) per un contatto permanente. Pinout P8 = ARM Cortex 10-pin standard (pin1=VTref, 2=SWDIO, 3=GND, 4=SWCLK, 10=nRESET).

🔌 Connettori

  • P1 = espansione Qwiic (I2C su i2c2, via level shifter U24 1.8↔3.3V) — SDA=P0.09, SCL=P0.08.
  • P8 = SWD 2×5 1.27mm (i pin nudi, difficili coi fili volanti).
  • P9 = card-edge per la debug/current board (SWD anche lì, header 2×5 keyed più comodo).

🛰️ GPS SAM-M10Q via I2C — FUNZIONA (fix completo!)

Il SAM-M10Q (u-blox M10) su Qwiic/i2c2 legge la posizione end-to-end ✅. Firmware gps-i2c-test (src/main.c): abilita exp_board_enable (P0.03 = load switch 3.3V + level shifter U24), scansiona il bus, e legge lo stream NMEA dal registro DDC 0xFF dell’u-blox (indirizzo 0x42), ricompone le frasi e parsa lat/lon dalla $GxGGA.

[SCAN exp-ON] 0x14 0x1d 0x42 0x6b 0x76 => 5 device  >>> SAM-M10Q 0x42 TROVATO!
$GNGGA,...,4243.04371,N,01206.46676,E,1,12,...
>>> lat=42.7174°N lon=12.1078°E · fix 3D · 12 sat (GPS+GLONASS+Galileo) · Orvieto ✅

⚠️ Lockup del bus risolto con erase+reflash pulito (via nrfutil+J-Link): un vecchio stato bloccato dell’i2c2 teneva il bus giù; dopo erase completo + flash del firmware, il bus è stabile e il SAM risponde a ogni ciclo. I 4 sensori onboard sono 0x14 0x1d 0x6b 0x76 (accel/mag/env/PMIC), il GPS è 0x42. Lettura DDC: i2c_burst_read(dev, 0x42, 0xFF, buf, 64) in loop, si scartano i byte 0xFF (idle filler).

🚨 Allarme vibrazione anti-furto (ADXL367) — FUNZIONA end-to-end

Il firmware visla-mqtt usa l’accelerometro ADXL367 low-power (onboard, 0x1d sullo stesso bus i2c2 del GPS) per un allarme anti-furto a vibrazione. Confermato end-to-end 19/07/2026: scuoti il device → alarm=vibration arriva in positions:raw sul bridge di produzione. ✅

Come rileva il movimento: accesso I2C diretto (nessun driver Zephyr), legge X/Y/Z 8-bit (reg 0x08-0x0A) ogni 300ms e calcola il delta = |Δx|+|Δy|+|Δz| vs il campione precedente. Se supera la soglia (>6, ~0.09g, sensibile) = movimento. Alimentazione dell’ADXL: rail sensori nPM1300 LDO2 (ldsw_sensors, boot-on), sempre acceso.

Logica riarmo 60s (anti-flood):

Movimento (poll 300ms, delta > soglia)
  ├─► LED verde lampeggia SEMPRE (feedback immediato, anche offline)
  └─► ≥60s dall'ultimo allarme?
        ├─ SÌ → pubblica "alarm":"vibration" + reset timer
        └─ NO → nessun allarme nuovo (solo LED)

Max 1 allarme ogni 60s: se il device resta in movimento non floppa il backend/batteria. Il primo movimento allarma subito. L’allarme viaggia in entrambi i rami di pubblicazione (posizione con fix GPS e heartbeat senza fix).

I 2 bug che lo tenevano zitto (risolti):

  1. Poll a 2s troppo lento per il delta: uno scuotimento breve inizia+finisce tra due campioni → delta=0 → perso. Fix: poll 300ms (provato affidabile nello standalone, 16/16).
  2. Accel work legata all’MQTT (partiva al connack, cancellata sui disconnect) → col segnale ballerino del banco si fermava di continuo. Fix: parte al boot (state_running_entry), gira sempre, allarme armato (latch) anche offline e spedito al primo heartbeat utile.

LED verde on-movimento: feedback visivo via canale zbus led_chan (modulo LED dell’ATT, struct led_msg — mai pilotare il LED a mano = conflitto). Indipendente dalla rete: scuoti → 3 lampeggi verdi anche con MQTT giù.

💡 Metodo di debug decisivo: firmware standalone senza modem (accel-test/, clone di gps-i2c-test) → niente cooldown 30min, console seriale attiva → si itera in 30s invece di 30min. Lì è stato provato l’ADXL (gravità z=-65, scuotimenti 16/16) e trovato il fix, poi portato su visla-mqtt. La activity-detection HW dell’ADXL (bit ACT latchato) non è servita: il delta a polling veloce basta — da riprendere per il wake-on-motion (INT1) del Tag definitivo.

💾 Firmware Visla (GitHub)

Tutti in test-moduli/nordic-thingy91x/firmware-custom/. Workspace NCS in ncs-workspace/ (gitignored — si ricrea con run_west.sh).

FirmwareCosa faStatoLink
gps-i2c-testStandalone: legge lo stream NMEA del SAM-M10Q via I2C (DDC reg 0xFF), parsa $GxGGA → lat/lon, output su seriale + LED. Base per capire il GPS dedicato.✅ fix reale Orvieto (12 sat)📂 src/main.c
accel-testStandalone SENZA modem (niente cooldown): legge l’ADXL367 (0x1d) via I2C, stampa X/Y/Z + delta su seriale, LED verde su movimento. Banco di debug per l’allarme vibrazione.✅ gravità + 16/16 scuotimenti📂 src/main.c
visla-mqtt (v1.8)Il firmware “serio” completo: Asset-Tracker-Template + patch MQTT broker Visla + SAM-M10Q + allarme vibrazione ADXL367. LTE (1NCE) → MQTT TLS mqtt.vislagps.com:8883 → pubblica posizione su visla/<IMEI>/pos (valid:true lat/lon). GPS dedicato → niente coesistenza LTE. Anti-furto: poll ADXL367 (0x1d) ogni 300ms, delta > soglia → "alarm":"vibration" (in posizione e heartbeat), riarmo 60s, LED verde on-movimento. Accel decouplata dall’MQTT (parte al boot, gira anche offline).✅ posizione + allarme end-to-end sul backend📂 cartella · 🔧 patch
firmware-inizialeBackup firmware di fabbrica (hello.nrfcloud nRF91 + connectivity-bridge nRF53) per ripristino via nrfutil.ripristino📂 cartella

Build & flash (workspace NCS v3.2.4):

# via USB (senza J-Link): stacca il cavo USB del J-Link, poi
nrfutil device program --firmware <build>/merged.hex --serial-number THINGY91X_... --options target=nRF91
# via J-Link (nrfutil, NON JLinkExe grezzo che fallisce sull'algo flash nRF9151):
nrfutil device program --firmware <build>/merged.hex --serial-number <SN-J-Link>

⚠️ Gotchas

  • ⏱️ Reset-loop cooldown del modem (30 min di blocco LTE!): il firmware del modem nRF9151 conta i reset ravvicinati. Se ne rileva troppi (tipico al banco: tanti reset via J-Link/nrfutil per debug/flash), scatta la protezione “The modem has detected a reset loop. LTE network attach is now restricted for the next 30 minutes”non aggancia più la rete per 30 min. È una protezione (gli operatori penalizzano i device che si riattaccano in loop), non un guasto. Cura: smettere di resettare e aspettare ~30 min (ogni nuovo reset riazzera il timer). In produzione, con firmware stabile, non succede. Al banco: fare meno reset possibile, e sapere che dopo tanti flash il modem “dorme”.
  • Non commercializzabile: il Thingy:91 X (come l’nRF9151 DK) è un dev kit, non si rivende come prodotto finito — si commercializza il SiP sulla propria PCB
  • Toolchain Zephyr / nRF Connect SDK: niente Arduino IDE, niente portabilità degli sketch ESP-IDF/Arduino Visla — curva di apprendimento reale (zbus, Kconfig, devicetree, west), anche se l’Asset-Tracker-Template la dimezza
  • nRF Cloud vs backend proprio: il default del template è nRF Cloud (CoAP, location services); per usare il broker MQTT su GKE bisogna swappare il modulo cloud e gestirsi l’A-GPS (o tenere nRF Cloud solo per l’assist GNSS)
  • Tre chip Nordic per il full stack: cellular + Wi-Fi + BLE significano nRF9151 + nRF7002 + nRF5340 — sul kit è tutto integrato, ma su una PCB propria è complessità in più rispetto a un singolo ESP32-S3 che fa Wi-Fi + BLE

🔗 Risorse