Arduino Nicla Vision¶
L’Arduino Nicla Vision è una scheda per visione artificiale di 22,86 × 22,86 mm costruita attorno allo STMicroelectronics STM32H747AII6 — un SoC dual‑core che combina un Cortex‑M7 a 400 MHz con un Cortex‑M4 a 200 MHz. Il firmware OpenMV gira interamente sul core M7. La scheda abbina al MCU il sensore CMOS a colori GC2145 da 2 MP, una IMU a 6 assi LSM6DSOX, un microfono MEMS MP34DT06, un telemetro time‑of‑flight VL53L1CB, Wi‑Fi + Bluetooth LE 5.1 e un caricabatterie / fuel gauge.
Per il datasheet completo, le foto e le dimensioni consulta la pagina prodotto dell’Arduino Nicla Vision.
Punti salienti¶
STMicroelectronics STM32H747AII6 dual Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Il firmware OpenMV gira solo sul core M7.
2 MB di flash interna più 16 MB di flash QSPI esterna (usata per l’applicazione + ROMFS).
1 MB di SRAM interna.
Encoder/decoder JPEG hardware.
Sensore CMOS a colori GC2145 da 2 MP.
IMU integrata (accelerometro + giroscopio LSM6DSOX), microfono MEMS (MP34DT06JTR) e telemetro time‑of‑flight VL53L1CB (fino a ~4 m).
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 tramite il modulo Murata 1DX (CYW4343W) — si collega all’antenna fornita tramite un connettore U.FL integrato.
USB ad alta velocità (480 Mb/s) su Micro USB tramite un PHY ULPI esterno (USB3320C).
13 pin di I/O utente sui connettori a pettine Arduino — quattro LPIO digitali (
D0–D3), tre ingressi analogici a 1,8 V (A0–A2), la coppia I²CSCL/SDAe il quartetto SPISCLK/CIPO/COPI/CS.Supporto batteria — connettore Li‑Po sul retro, caricabatterie in stile BQ e fuel gauge MAX17262 sul bus PMIC interno.
Connettore ESLOV a 5 pin sul retro per l’espansione I²C senza saldatura.
Avvertimento
I pin digitali utente sono a 3,3 V per impostazione predefinita ma instradati attraverso level shifter programmabili via software (VDDIO_EXT) che possono essere riconfigurati a 1,8 V. I pin analogici (A0–A2) sono solo a 1,8 V — bypassano i level shifter e si collegano direttamente al MCU. Applicare 3,3 V su A0–A2 danneggerà il SoC.
Pinout¶
Riferimento dei pin¶
Tredici pin utente sono esposti sui connettori a pettine Arduino (J1 e J2). Ulteriori segnali di debug, recovery e PMIC sono instradati a piazzole di test sul retro della scheda.
Nome del pin |
Riferimento |
Funzione |
|---|---|---|
D0 |
3,3 V |
GPIO / LPIO0 (J1‑1) |
D1 |
3,3 V |
LPUART1 TX / TIM1 CH2 / LPIO1 (J2‑3) |
D2 |
3,3 V |
LPUART1 RX / TIM1 CH3 / LPIO2 (J2‑4) |
D3 |
3,3 V |
GPIO / LPIO3 (J2‑5) |
A0 |
1,8 V |
ADC1 canale 4 (J1‑8) |
A1 |
1,8 V |
ADC2 canale 2 (J1‑7) |
A2 |
1,8 V |
ADC3 canale 5 (J1‑2) |
SCL |
3,3 V |
I2C1 SCL / UART4 RX / TIM4 CH3 (J2‑2) |
SDA |
3,3 V |
I2C1 SDA / UART4 TX / TIM4 CH4 (J2‑1) |
SCLK |
3,3 V |
SPI4 SCK / TIM1 CH3N (J1‑6) |
CIPO |
3,3 V |
SPI4 MISO / TIM1 CH3 (J1‑5) |
COPI |
3,3 V |
SPI4 MOSI / TIM1 CH4 (J1‑4) |
CS |
3,3 V |
SPI4 NSS / TIM1 CH2 (J1‑3) |
RESET |
3,3 V |
collega a GND (o premi l’interruttore integrato) per resettare la scheda |
LED_RED |
3,3 V |
canale rosso del LED RGB (attivo basso) |
LED_GREEN |
3,3 V |
canale verde del LED RGB (attivo basso) |
LED_BLUE |
3,3 V |
canale blu del LED RGB (attivo basso) |
Nota
D0–D3 e SCLK/CIPO/COPI/CS si trovano dietro il level shifter bidirezionale TXB0108 — quel componente supporta solo la pilotaggio GPIO push‑pull, quindi il traffico di bus open‑drain (ad esempio un 1‑Wire o un I²C bit‑banged su quei pin) non funzionerà.
SCL/SDA si trovano dietro un separato shifter NTS0304 che supporta sia il pilotaggio push‑pull che open‑drain, motivo per cui l’I²C 1 funziona lì.
Entrambi gli shifter sono riferiti a VDDIO_EXT (3,3 V per impostazione predefinita dal PMIC integrato) e la loro capacità di pilotaggio è limitata rispetto a un GPIO diretto — sono progettati per carichi di livello di segnale piuttosto che di potenza.
Pin di alimentazione¶
Pin dei connettori a pettine:
VIN (J2‑9) — linea di sistema principale 3,6 – 5 V. Il PMIC prende qui il suo ingresso.
VDDIO_EXT (J2‑7) — uscita della linea dei level shifter, 1,8 V o 3,3 V (3,3 V per impostazione predefinita). Usala per alimentare periferiche esterne a 1,8 V o 3,3 V collegate ai pin LPIO/SPI/I²C così che parlino lo stesso livello logico dei connettori.
VBAT (J3‑2) — ingresso batteria Li‑Po. Il PMIC integrato carica la cella da VIN e riporta lo stato di carica tramite il fuel gauge.
NTC (J3‑1) — ingresso opzionale per termistore Li‑Po.
GND (J2‑6) — massa comune.
NC (J2‑8) — non collegato.
Piazzole di test sul retro della scheda:
+3V3 — linea principale a 3,3 V.
D_P / D_N — coppia di dati USB ad alta velocità (post‑PHY).
L’USB e il connettore ESLOV alimentano entrambi VIN attraverso una coppia di diodi ideali LM66100 (uno per sorgente), così che ciascuna alimentazione possa alimentare la scheda da sola e le due non si pilotino mai a vicenda all’indietro. Se piloti VIN esternamente su J2‑9, quello ha la precedenza — i diodi smettono semplicemente di condurre da USB / ESLOV una volta che la linea esterna sale più in alto.
La scheda può quindi essere alimentata attraverso una qualsiasi di queste vie:
Micro USB — 5 V su VIN attraverso il diodo ideale lato USB.
Connettore ESLOV — fino a 5 V sul pin
VESLOVdi J5, instradato in VIN attraverso il diodo ideale lato ESLOV (vedi Connettore ESLOV).Pin VIN (J2‑9) — piloti direttamente un’alimentazione regolata a 3,6 – 5 V.
Batteria Li‑Po — collega al connettore batteria J4 sul retro oppure alle piazzole VBAT/GND/NTC su J3 / J2‑6. Non collegare due batterie contemporaneamente.
Connettore ESLOV¶
J5 sul retro della scheda è un connettore ESLOV Molex a 5 pin senza saldatura:
Pin |
Nome |
Funzione |
|---|---|---|
J5‑1 |
VESLOV |
ingresso di alimentazione (≤ 5 V) — combinato in OR su |
J5‑2 |
INT |
ingresso di interrupt esterno su |
J5‑3 |
SCL_EXT |
condiviso con la piazzola |
J5‑4 |
SDA_EXT |
condiviso con la piazzola |
J5‑5 |
GND |
massa comune |
Gli SCL_EXT/SDA_EXT dell’ESLOV e gli SCL/SDA di J2 sono gli stessi pin — un unico bus I²C 1 esposto su due connettori.
Suggerimento
Usa lo stimatore di durata della batteria per modellare per quanto tempo la Nicla Vision funzionerà a batteria per un dato ciclo di lavoro attivo / deep‑sleep.
Pin di recovery e debug¶
RESET — sia un interruttore momentaneo sulla parte superiore della scheda sia una piazzola (J3‑4 / piazzola di test P5) collegata alla linea NRST del SoC. Collega a GND per resettare.
La Nicla Vision usa il double‑tap reset standard di Arduino per entrare nel bootloader di Arduino — premi rapidamente il pulsante di reset due volte e la scheda si enumera come dispositivo DFU. OpenMV IDE usa questa modalità per riflashare il firmware.
I segnali SWD dell’STM32 sono esposti sul retro della scheda attraverso una fila di piazzole di test tra i due connettori J2. Salda un pettine da 2,54 mm (100 mil) in esse per collegare un adattatore ST‑LINK o J‑Link:
P1 / P2 — bus I²C del PMIC interno su PF0 (SDA) e PF1 (SCL). Questo è
machine.I2C(2)sulla Nicla Vision e trasporta il traffico del PMIC, del fuel gauge e del ToF.P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — linea +1V8 (l’alimentazione di I/O del SoC — anche il riferimento corretto per l’adattatore di debug).
P8 —
VOTP_PMIC— solo programmazione di fabbrica. Deve essere lasciato non collegato.
Tutti i segnali di debug sono riferiti a 1,8 V — l’anello di I/O dell’STM32H747 su questa scheda funziona dalla linea +1V8. Imposta il tuo adattatore di debug per logica a 1,8 V prima di collegarlo.
Periferiche integrate¶
LED¶
La Nicla Vision ha un singolo LED RGB utente, controllabile via software tramite machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
Un LED separato DL2 CHARGE sul lato della scheda è cablato direttamente all’uscita CHGB del PMIC — si accende mentre una batteria Li‑Po viene caricata da USB / ESLOV / VIN e non è controllabile dall’utente.
Sensore camera¶
Il GC2145 è pilotato attraverso il modulo csi — sensori camera
import csi
cam = csi.CSI()
cam.reset()
cam.pixformat(csi.RGB565)
cam.framesize(csi.QVGA)
cam.snapshot(time=2000) # let auto‑exposure settle
while True:
img = cam.snapshot()
Quando richiedi un framesize piccolo, il driver del GC2145 ritaglia una finestra di lettura proporzionalmente piccola dal sensore — per impostazione predefinita il rapporto di downscale dalla lettura all’uscita è limitato a 3x per mantenere alto il frame rate. csi.IOCTL_SET_FOV_WIDE alza tale limite a 5x, il che significa che il driver preleva da un’area più ampia del sensore quando trasmette in streaming risoluzioni piccole. Il risultato è un campo visivo notevolmente più ampio ai framesize piccoli, a costo di un po” di throughput:
cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE) # returns the current setting
Core M4¶
Il core Cortex‑M4 è esposto attraverso openamp per la comunicazione tra processori. Il firmware OpenMV gira solo sull’M7; l’M4 non ha un proprio runtime MicroPython, quindi usarlo significa compilare una immagine firmware C separata e caricarla dal filesystem tramite openamp.RemoteProc. Un firmware di esempio precompilato che implementa un endpoint UART virtuale è disponibile nel repository openamp_vuart — segui il suo README per compilare vuart.elf
import openamp
import time
def ept_recv_callback(src_addr, data):
print("Received:", data.decode())
ept = openamp.Endpoint("vuart-channel", callback=ept_recv_callback)
rproc = openamp.RemoteProc("vuart.elf")
rproc.start()
count = 0
while True:
if ept.is_ready():
ept.send("Hello World %d!" % count, timeout=1000)
count += 1
time.sleep_ms(1000)
In pratica è meglio considerare questo supporto come una dimostrazione dell’interfaccia openamp piuttosto che come una piattaforma dual‑core funzionante — l’M4 non può essere resettato indipendentemente dall’M7, quindi fermare l’M4 forza un riavvio completo del sistema.
Microfono¶
Il microfono PDM MP34DT06JTR integrato è catturato tramite audio — Modulo Audio sulla periferica DFSDM dell’STM32. Ogni buffer arriva come un bytearray PCM a 16 bit con segno, pronto per essere passato a ulab/numpy per il DSP — per esempio, un semplice rilevatore di volume:
import audio
from ulab import numpy as np
def loudness(pcmbuf):
samples = np.array(np.frombuffer(pcmbuf, dtype=np.int16), dtype=np.float)
rms = np.sqrt(np.mean(samples ** 2))
if rms > 10000:
print("Loud!", int(rms))
audio.init(channels=1, frequency=16000, gain_db=24)
audio.start_streaming(loudness)
while True:
pass
IMU¶
L’accelerometro + giroscopio LSM6DSOX integrato è esposto attraverso imu — sensore imu
import imu
import time
while True:
print(imu.acceleration_mg()) # (x, y, z) in milli‑g
print(imu.angular_rate_mdps()) # (x, y, z) in milli‑deg/s
time.sleep_ms(100)
L’IMU è cablata a un bus SPI interno dedicato (SPI5) così da non entrare in conflitto con l’SPI4 utente esposto sui connettori.
Telemetro time‑of‑flight¶
Il telemetro time‑of‑flight ST VL53L1CB integrato si trova sul bus I²C del PMIC interno (I²C 2). Usa il driver congelato vl53l1x — Driver del sensore di distanza ToF VL53L1X per ottenere letture di distanza fino a ~4 m:
import time
from machine import I2C
import vl53l1x
bus = I2C(2) # internal bus (PMIC / fuel gauge / ToF)
tof = vl53l1x.VL53L1X(bus)
while True:
print("Distance:", tof.read(), "mm")
time.sleep_ms(100)
Fuel gauge della batteria¶
Il fuel gauge Maxim MAX17262 ModelGauge m5 traccia la tensione, la corrente, la temperatura e lo stato di carica della batteria Li‑Po. Si trova sull”I²C 2 all’indirizzo 0x36.
Il MAX17262 ha il rilevamento di corrente interno, quindi il registro della corrente fornisce direttamente la lettura in microampere senza alcun fattore Rsense esterno da applicare. Leggere il fuel gauge è innocuo — non viene fornito alcun driver, ma i registri documentati nel datasheet del MAX17262 possono essere letti direttamente:
import time
import struct
from machine import I2C
FUEL_GAUGE = 0x36 # MAX17262
def read_reg(bus, addr, reg):
return struct.unpack("<H", bus.readfrom_mem(addr, reg, 2))[0]
def read_signed(bus, addr, reg):
v = read_reg(bus, addr, reg)
return v - 0x10000 if v & 0x8000 else v
bus = I2C(2)
while True:
# 0x05 RepCap — remaining capacity, raw × 0.5 mAh
rep_cap = read_reg(bus, FUEL_GAUGE, 0x05) * 0.5
# 0x06 RepSOC — state of charge, raw / 256 %
soc = read_reg(bus, FUEL_GAUGE, 0x06) / 256
# 0x08 Temp — die temperature, signed, raw / 256 °C
temp = read_signed(bus, FUEL_GAUGE, 0x08) / 256
# 0x09 VCell — battery voltage, raw × 78.125 µV
vcell = read_reg(bus, FUEL_GAUGE, 0x09) * 78.125 / 1_000_000
# 0x0A Current — signed, raw × 156.25 µA
current = read_signed(bus, FUEL_GAUGE, 0x0A) * 156.25 / 1000
# 0x0B AvgCurrent — averaged current
avg_curr = read_signed(bus, FUEL_GAUGE, 0x0B) * 156.25 / 1000
# 0x10 FullCapRep — learned full capacity, raw × 0.5 mAh
full_cap = read_reg(bus, FUEL_GAUGE, 0x10) * 0.5
# 0x11 TTE — time-to-empty (valid while discharging), raw × 5.625 s
tte_s = read_reg(bus, FUEL_GAUGE, 0x11) * 5.625
# 0x20 TTF — time-to-full (valid while charging), raw × 5.625 s
ttf_s = read_reg(bus, FUEL_GAUGE, 0x20) * 5.625
# 0x17 Cycles — charge-cycle counter, 1% per LSB
cycles = read_reg(bus, FUEL_GAUGE, 0x17) / 100
print("V: %.3f V" % vcell)
print("Capacity: %.1f / %.1f mAh (%.1f %%)" % (rep_cap, full_cap, soc))
print("Temp: %.1f C" % temp)
print("Current: %.1f mA (avg %.1f mA)" % (current, avg_curr))
print("TTE: %.0f s TTF: %.0f s" % (tte_s, ttf_s))
print("Cycles: %.2f" % cycles)
print()
time.sleep_ms(1000)
Current è in complemento a due con segno: positivo durante la carica, negativo durante la scarica. TTE è significativo solo quando la corrente è negativa; TTF solo quando la corrente è positiva.
IC di gestione dell’alimentazione¶
Il PMIC NXP MC34PF1550A0EP gestisce ogni regolatore sulla Nicla Vision — la linea principale +3V3, la linea +1V8 del core / I/O del SoC, VDDIO_EXT ai level shifter e il caricabatterie Li‑Po. Si trova sull”I²C 2 all’indirizzo 0x08.
Avvertimento
Leggere i registri del PMIC va bene; scriverci è pericoloso. Configurare male un regolatore buck o un’impostazione del caricabatterie può danneggiare permanentemente la scheda, la batteria o entrambe. Tratta il PMIC come di sola lettura a meno che tu non sappia esattamente cosa stai facendo.
La cosa più utile che il PMIC ti dice e che il fuel gauge non può è la macchina a stati del caricabatterie — se la scheda sta attualmente funzionando da USB / ESLOV / VIN, in quale fase del ciclo di carica si trova la Li‑Po e se il caricabatterie è in un guasto termico o di watchdog. I registri del caricabatterie risiedono a un offset di 0x80 nello spazio di indirizzi I²C principale del PF1550 (vedi §22.2 del datasheet del PF1550), quindi per esempio CHG_INT_OK all’indirizzo del caricabatterie 0x04 viene letto dal registro PMIC 0x84
import time
from machine import I2C
PMIC = 0x08
# Charger state machine (low nibble of CHG_SNS, register 0x87)
CHG_STATES = {
0x0: "precharge",
0x1: "fast charge (constant current)",
0x2: "fast charge (constant voltage)",
0x3: "end of charge",
0x4: "done",
0x6: "timer fault",
0x7: "thermistor suspend",
0x8: "off — input invalid or charger disabled",
0x9: "battery overvoltage",
0xA: "thermal shutdown",
0xC: "linear mode (not charging)",
}
bus = I2C(2)
while True:
# 0x84 CHG_INT_OK — single-bit indicators
ok = bus.readfrom_mem(PMIC, 0x84, 1)[0]
vbus_ok = bool(ok & (1 << 5)) # bit 5 — VBUS valid (USB/ESLOV/VIN)
bat_ok = bool(ok & (1 << 2)) # bit 2 — battery OK
chg_ok = bool(ok & (1 << 3)) # bit 3 — charger actively charging
thm_ok = bool(ok & (1 << 7)) # bit 7 — thermistor in normal range
# 0x87 CHG_SNS — charger state + thermal regulation flag
chg_sns = bus.readfrom_mem(PMIC, 0x87, 1)[0]
state = CHG_STATES.get(chg_sns & 0x0F, "reserved")
treg = bool(chg_sns & (1 << 7)) # thermal regulation active
print("VBUS valid: ", vbus_ok)
print("battery OK: ", bat_ok)
print("charger active: ", chg_ok)
print("thermistor normal: ", thm_ok)
print("thermal reg active: ", treg)
print("state: ", state)
print()
time.sleep_ms(1000)
Altri registri di sola lettura che vale la pena consultare nel datasheet (tutti all’offset del caricabatterie 0x80): 0x80 CHG_INT (interrupt del caricabatterie latched — flag di guasto), 0x86 VBUS_SNS (lo stato VBUS multi‑bit incluso OVLO / UVLO / DPM) e 0x88 BATT_SNS (presenza della batteria e stato di sovracorrente).
Wi‑Fi¶
Il Murata 1DX (CYW4343W) integrato è esposto tramite network — configurazione di rete come interfaccia station. Collega l’antenna fornita al connettore U.FL integrato prima di attivare la radio:
import network, time
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
while not wlan.isconnected():
time.sleep(1)
print("Wi‑Fi IP:", wlan.ipconfig("addr4")[0])
Bluetooth¶
Lo stesso Murata 1DX espone anche il Bluetooth LE 5.1. Usa aioble — BLE asincrono per BLE adatto ad asyncio — per esempio, annunciarsi come periferica e attendere che un central si connetta:
import asyncio
import aioble
async def run():
while True:
conn = await aioble.advertise(250_000, name="Nicla-Vision")
print("Connected:", conn.device)
await conn.disconnected()
asyncio.run(run())
Riferimento dei bus¶
GPIO¶
Usa machine.Pin per leggere o pilotare uno qualsiasi dei pin serigrafati. Le uscite sono CMOS a 3,3 V (VDDIO_EXT predefinito) e i level shifter limitano la capacità di pilotaggio per pin a pochi milliampere — sono progettati per carichi di livello di segnale piuttosto che di potenza.
from machine import Pin
out = Pin("D0", Pin.OUT)
out.on()
out.off()
out.value(1)
inp = Pin("D1", Pin.IN, Pin.PULL_UP)
print(inp.value())
Qualsiasi pin di ingresso può anche far scattare un interrupt sulle transizioni di fronte:
def handler(pin):
print("triggered:", pin)
Pin("D1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Bus |
TX |
RX |
|---|---|---|
UART4 |
SDA |
SCL |
from machine import UART
uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)
Nota
UART4 condivide i suoi pin con l”I²C 1 — le stesse piazzole SDA/SCL trasportano entrambi i bus. Scegli UART o I²C, non entrambi, su quei pin.
La serigrafia D1/D2 riporta anche UART_TX/UART_RX, ma su questo firmware quei pin sono instradati a LPUART1, non a machine.UART. machine.UART(1) stesso è riservato al controller Bluetooth on‑chip e non è accessibile sui connettori.
I²C¶
Bus |
SCL |
SDA |
|---|---|---|
I2C1 |
SCL |
SDA |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
Le piazzole SCL/SDA su J2 e i pin SCL_EXT/SDA_EXT del connettore ESLOV terminano sullo stesso bus I²C 1 — vedi Connettore ESLOV sopra per il pinout dell’ESLOV.
Lo stesso hardware può anche essere usato in modalità target (slave) tramite machine.I2CTarget per esporre una regione di memoria a un altro controller I²C:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
Bus |
MOSI |
MISO |
SCK |
CS |
|---|---|---|---|---|
SPI4 |
COPI |
CIPO |
SCLK |
CS |
from machine import SPI
from machine import Pin
spi = SPI(4, baudrate=10_000_000)
cs = Pin("CS", Pin.OUT, value=1) # CS is not driven by the SPI peripheral
cs.value(0)
spi.write(b"hello")
cs.value(1)
ADC¶
La Nicla Vision espone tre canali ADC a 12 bit su A0, A1 e A2. Tutti e tre sono riferiti a 1,8 V — read_u16 restituisce 0–65535 su 0–1,8 V al pin:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
Avvertimento
Gli ingressi ADC della Nicla Vision sono riferiti a 1,8 V (e non hanno alcun level shifter davanti al SoC). Pilotare un segnale a 3,3 V saturerà il convertitore e potrebbe danneggiare il pin — riduci esternamente le tensioni più alte tramite un partitore.
PWM¶
Pin |
Timer / canale |
|---|---|
D1 |
TIM1 CH2 |
D2 |
TIM1 CH3 |
SCL |
TIM4 CH3, TIM16 CH1 |
SDA |
TIM4 CH4, TIM17 CH1 |
SCLK |
TIM1 CH3N |
CIPO |
TIM1 CH3 |
COPI |
TIM1 CH4 |
CS |
TIM1 CH2 |
Pilota uno qualsiasi di essi tramite machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)
Nota
Diversi pin condividono canali TIM1:
TIM1 CH2 è su
D1eCS.TIM1 CH3 è su
D2eCIPO;SCLKemette il complemento invertito (TIM1 CH3N) dello stesso canale.TIM1 CH4 è su
COPIda solo.
Scegli un solo consumatore per canale timer. Anche i pin del quartetto SPI (SCLK/CIPO/COPI/CS) non possono essere pilotati in PWM mentre machine.SPI(4) li sta usando.
Bus bit‑banged via software¶
machine.SoftI2C e machine.SoftSPI funzionano su qualsiasi GPIO se ti serve un bus aggiuntivo.
Sensore termico (esterno)¶
Il firmware include il driver fir — driver del sensore termico (fir == far infrared) per imager termici cablati esternamente:
MLX90621 — array IR 16 × 4
MLX90640 — array IR 32 × 24
MLX90641 — array IR 16 × 12
AMG8833 — array IR 8 × 8
Collega il modulo al bus I²C della scheda e leggi i frame con fir.init() + fir.snapshot()
import time
import image
import fir
fir.init() # auto‑detects the sensor
clock = time.clock()
while True:
clock.tick()
try:
img = fir.snapshot(x_scale=5, y_scale=5,
color_palette=image.PALETTE_IRONBOW,
hint=image.BICUBIC,
copy_to_fb=True)
except OSError:
continue
print(clock.fps())
Il driver fir parla con il sensore solo sull”I²C 1 — collega il modulo alle piazzole serigrafate SCL / SDA.
Timing¶
time¶
Il modulo time copre i ritardi bloccanti, i tick monotoni e la misurazione del tempo trascorso:
import time
time.sleep(1) # seconds
time.sleep_ms(500)
time.sleep_us(10)
start = time.ticks_ms()
# ...do work...
elapsed = time.ticks_diff(time.ticks_ms(), start)
Timer virtuali¶
machine.Timer pianifica callback periodici o one‑shot senza consumare uno slot di timer hardware. Passa -1 come id per usare un timer virtuale (software):
from machine import Timer
one_shot = Timer(-1)
one_shot.init(period=5_000, mode=Timer.ONE_SHOT,
callback=lambda t: print("once"))
periodic = Timer(-1)
periodic.init(period=2_000, mode=Timer.PERIODIC,
callback=lambda t: print("tick"))
I valori del periodo sono in millisecondi. Chiama deinit() per fermare e rilasciare lo slot.
Real‑time clock¶
machine.RTC mantiene l’ora reale attraverso i reset:
from machine import RTC
rtc = RTC()
rtc.datetime((2026, 4, 30, 4, 12, 0, 0, 0)) # Y, M, D, weekday, h, m, s, subsec
print(rtc.datetime())
Watchdog¶
machine.WDT resetta la scheda se l’applicazione si blocca. Una volta avviato non può essere fermato né riconfigurato — alimentalo periodicamente all’interno del tuo loop principale:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Informazioni di boot e runtime¶
Aggiornamento del firmware (DFU)¶
La Nicla Vision usa il double‑tap reset standard di Arduino per entrare nel bootloader di Arduino. Premi rapidamente il pulsante di reset due volte — la scheda si rienumera su USB come dispositivo DFU e OpenMV IDE può flashare una nuova immagine firmware.
Uno script in esecuzione può rientrare nel bootloader su richiesta chiamando machine.bootloader()
import machine
machine.bootloader()
Filesystem e ordine di boot¶
Il firmware della Nicla Vision monta fino a due filesystem all’avvio:
Flash interna — sempre montata su
/flash. Contienemain.pyeREADME.txtper impostazione predefinita; creata al primissimo avvio.ROMFS — filesystem di sola lettura, mappato in memoria, su
/rommontato automaticamente da MicroPython all’avvio.
Dopo il montaggio, la directory di lavoro è impostata su /flash. L’interprete esegue quindi gli script da quella directory:
boot.pyviene eseguito a ogni soft reset (avvio a freddo,Ctrl‑Ddal REPL o ogni volta che lo script in esecuzione termina).main.pyviene eseguito solo all’avvio a freddo, subito dopoboot.py. I soft reset successivi rieseguonoboot.pyma scendono direttamente al REPL — per rieseguiremain.pydevi resettare completamente la scheda.
Il main.py predefinito fornito su una scheda appena flashata fa semplicemente lampeggiare il canale blu del LED RGB utente come battito cardiaco (due brevi impulsi, breve pausa), così puoi capire che il firmware si è avviato correttamente senza alcun host collegato.
sys.path viene esteso per includere entrambi i filesystem e le loro sottodirectory lib/, così i moduli importabili possono risiedere in /flash/lib o /rom/lib.
Quando collegata via USB, /flash si enumera anche come unità di archiviazione di massa USB sull’host, permettendoti di modificare boot.py, main.py e qualsiasi altro file direttamente. Espelli l’unità prima di resettare la camera così che l’host scarichi le sue scritture in cache.
Nota
Poiché il sistema operativo tratta l’unità come un dispositivo a blocchi passivo, i file creati o modificati dal codice in esecuzione sulla camera non compariranno finché l’host non rimonta l’unità. Se sia il sistema operativo che la camera scrivono sullo stesso filesystem contemporaneamente, vincerà il sistema operativo e sovrascriverà le modifiche fatte dalla camera. Usa la scheda SD per qualsiasi dato che lo script riscrive e rimonta prima di leggere quei file dall’host.
Nota
Il canale rosso del LED RGB utente può accendersi brevemente mentre l’host sta leggendo dall’unità di archiviazione di massa USB o scrivendo su di essa — è un indicatore di attività gestito dal firmware, non un guasto.
Dimensioni di archiviazione¶
La Nicla Vision viene fornita con:
/flash— filesystem FAT da 11 MB, lettura/scrittura./rom— ROMFS di sola lettura mappato in memoria da 4 MB, usato per fornire script e modelli ML che beneficiano dell’accesso mmap zero‑copy.
Indicatore di hard‑fault¶
Se il LED RGB utente sta ciclando rapidamente attraverso tutti i colori — abbastanza rapidamente da sembrare un LED bianco scintillante piuttosto che tinte distinte — il firmware ha incontrato un hard fault irrecuperabile. Riflasha il firmware per ripristinare; se il riflash non aiuta, la scheda potrebbe essere fisicamente danneggiata.
Librerie software¶
Consulta l”indice della libreria per l’elenco completo dei moduli — incluso quali sono esclusivi della build della Nicla Vision.