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
| Parametro | Valore |
|---|---|
| SoC principale | Nordic nRF9151 SiP (Cortex-M33 64 MHz, 1 MB flash / 256 KB RAM, TrustZone + CryptoCell) |
| Companion Wi-Fi | nRF7002 Wi-Fi 6 (Wi-Fi locationing) |
| Companion BLE / controller | nRF5340 (board controller USB + Bluetooth Low Energy) |
| PMIC | nPM1300 (charging + fuel gauging) · nPM6001 |
| Connettività cellulare | LTE-M · NB-IoT · DECT NR+ · banda LTE 700–2200 MHz (no 2G) |
| Locationing | GNSS + Wi-Fi + cellular (via nRF Cloud Location Services) |
| Sensori onboard | Temperatura · umidità · qualità aria · pressione · magnetometro · accelerometro 3 assi low-power · IMU 6 assi con giroscopio |
| Alimentazione | Batteria Li-Po ricaricabile 1350 mAh onboard · USB |
| Casi d’uso | Asset tracking, prototipazione cellular IoT, field testing LPWAN |
| Software | Zephyr 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.
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).
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.
🔌 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
🔧 Flash + J-Link SWD — scoperte dal bench (18–19 lug 2026)
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.
✅ Flashare l’nRF91 via USB (SENZA J-Link)
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
.hexfirmato (nonmerged.hex→ “wrong magic”; non.zip→ col traitmodemlo 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 pyserialdtr=rts=True. - Il
.printksulla 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.
🎯 J-Link SWD — i 4 pad che FUNZIONANO (dopo ore)
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 conoscenRF9151_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):
- 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).
- 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).
| Firmware | Cosa fa | Stato | Link |
|---|---|---|---|
| gps-i2c-test | Standalone: 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-test | Standalone 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-iniziale | Backup 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
resetvia 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
- 💻 Firmware Visla — gps-i2c-test (lettore NMEA SAM-M10Q via I2C, GitHub) — legge la posizione dal GPS dedicato sul Qwiic
- 💻 Firmware Visla — visla-mqtt (ATT + MQTT broker Visla + SAM-M10Q, GitHub) — pubblica la posizione su
mqtt.vislagps.com - 🏭 Nordic Thingy:91 X
- 🛒 Thingy:91 X (Mouser, ~€88)
- 🛠️ nRF Connect SDK (Zephyr)
- 🟢 nrfconnect/Asset-Tracker-Template ⭐ (firmware asset-tracker ufficiale, esempio cloud MQTT)
- 🧠 Vai alla chip card nRF9151 — il SiP che sta sul kit