Arduino Nicla Vision¶
Arduino Nicla Vision är ett 22,86 × 22,86 mm stort maskinseendekort byggt kring STMicroelectronics STM32H747AII6 — en SoC med dubbla kärnor som kombinerar en Cortex‑M7 på 400 MHz med en Cortex‑M4 på 200 MHz. OpenMV-firmwaren körs helt och hållet på M7-kärnan. Kortet parar MCU:n med GC2145 2 MP CMOS-färgsensor, en LSM6DSOX 6-axlig IMU, en MP34DT06 MEMS-mikrofon, en VL53L1CB time‑of‑flight-avståndsmätare, Wi‑Fi + Bluetooth LE 5.1 samt en batteriladdare/laddningsmätare.
För fullständigt datablad, bilder och mått, se produktsidan för Arduino Nicla Vision.
Höjdpunkter¶
STMicroelectronics STM32H747AII6 dubbel Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). OpenMV-firmwaren körs endast på M7-kärnan.
2 MB internt flashminne plus 16 MB externt QSPI-flashminne (används till applikationen + ROMFS).
1 MB internt SRAM.
Hårdvarubaserad JPEG-kodare/avkodare.
GC2145 2 MP CMOS-färgsensor.
Inbyggd IMU (LSM6DSOX-accelerometer + gyroskop), MEMS-mikrofon (MP34DT06JTR) och VL53L1CB time‑of‑flight-avståndsmätare (upp till ~4 m).
Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 via Murata 1DX-modulen (CYW4343W) — ansluter till den medföljande antennen via en inbyggd U.FL-kontakt.
Höghastighets-USB (480 Mb/s) över Micro USB genom en extern ULPI PHY (USB3320C).
13 användar-I/O-stift på Arduino-kantanslutningarna — fyra digitala LPIO:er (
D0–D3), tre analoga 1,8 V-ingångar (A0–A2), I²C-paretSCL/SDAoch SPI-kvartettenSCLK/CIPO/COPI/CS.Batteristöd — Li‑Po-kontakt på baksidan, laddare av BQ-typ och MAX17262-laddningsmätare över den interna PMIC-bussen.
5-stifts ESLOV-kontakt på baksidan för lödfri I²C-expansion.
Varning
Användarnas digitala stift är 3,3 V som standard men dras genom programvarustyrbara nivåomvandlare (VDDIO_EXT) som kan konfigureras om till 1,8 V. De analoga stiften (A0–A2) är endast 1,8 V — de förbigår nivåomvandlarna och ansluts direkt till MCU:n. Att mata 3,3 V in i A0–A2 skadar SoC:n.
Stiftutgång¶
Stiftreferens¶
Tretton användarstift är exponerade på Arduino-kantanslutningarna (J1 och J2). Ytterligare signaler för felsökning, återställning och PMIC dras till testytor på baksidan av kortet.
Stiftnamn |
Referens |
Funktion |
|---|---|---|
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 kanal 4 (J1‑8) |
A1 |
1,8 V |
ADC2 kanal 2 (J1‑7) |
A2 |
1,8 V |
ADC3 kanal 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 |
dra till GND (eller tryck på den inbyggda brytaren) för att återställa kortet |
LED_RED |
3,3 V |
RGB-LED röd kanal (aktiv låg) |
LED_GREEN |
3,3 V |
RGB-LED grön kanal (aktiv låg) |
LED_BLUE |
3,3 V |
RGB-LED blå kanal (aktiv låg) |
Anteckning
D0–D3 och SCLK/CIPO/COPI/CS sitter bakom den dubbelriktade nivåomvandlaren TXB0108 — den komponenten stöder endast push‑pull-GPIO-drift, så öppen-dräneringstrafik på bussen (t.ex. en bit‑bangad 1‑Wire eller I²C på dessa stift) fungerar inte.
SCL/SDA sitter bakom en separat NTS0304-omvandlare som stöder både push‑pull och öppen dränering, vilket är anledningen till att I²C 1 fungerar där.
Båda omvandlarna refererar till VDDIO_EXT (3,3 V som standard från den inbyggda PMIC:n), och deras drivstyrka är begränsad jämfört med en direkt GPIO — de är konstruerade för signalnivåer snarare än effektbelastningar.
Strömstift¶
Kantanslutningens stift:
VIN (J2‑9) — huvudsaklig 3,6–5 V systemskena. PMIC:n tar sin matning här.
VDDIO_EXT (J2‑7) — utgång för nivåomvandlarskenan, 1,8 V eller 3,3 V (3,3 V som standard). Använd den för att driva externa 1,8 V- eller 3,3 V-kringutrustningar anslutna till LPIO/SPI/I²C-stiften så att de använder samma logiknivå som anslutningarna.
VBAT (J3‑2) — Li‑Po-batteriingång. Den inbyggda PMIC:n laddar cellen från VIN och rapporterar laddningstillstånd via laddningsmätaren.
NTC (J3‑1) — valfri Li‑Po-termistoringång.
GND (J2‑6) — gemensam jord.
NC (J2‑8) — ingen anslutning.
Testytor på baksidan av kortet:
+3V3 — huvudsaklig 3,3 V-skena.
D_P / D_N — USB höghastighetsdatapar (efter PHY).
USB och ESLOV-kontakten matar båda VIN genom ett par LM66100 ideala dioder (en per källa), så endera matningen kan driva kortet på egen hand och de två återmatar aldrig varandra. Om du driver VIN externt på J2‑9 har det företräde — dioderna slutar helt enkelt att leda från USB/ESLOV när den externa skenan stiger högre.
Kortet kan därför drivas via någon av följande vägar:
Micro USB — 5 V in i VIN genom den ideala dioden på USB-sidan.
ESLOV-kontakt — upp till 5 V på
VESLOV-stiftet på J5, lett in i VIN genom den ideala dioden på ESLOV-sidan (se ESLOV-kontakt).VIN-stift (J2‑9) — driv en reglerad matning på 3,6–5 V direkt.
Li‑Po-batteri — anslut till J4-batterikontakten på baksidan eller till VBAT/GND/NTC-ytorna på J3/J2‑6. Anslut inte två batterier samtidigt.
ESLOV-kontakt¶
J5 på baksidan av kortet är en 5-stifts lödfri ESLOV-kontakt från Molex:
Stift |
Namn |
Funktion |
|---|---|---|
J5‑1 |
VESLOV |
strömingång (≤ 5 V) — OR:as in i |
J5‑2 |
INT |
extern avbrottsingång på |
J5‑3 |
SCL_EXT |
delas med J2:s |
J5‑4 |
SDA_EXT |
delas med J2:s |
J5‑5 |
GND |
gemensam jord |
ESLOV:s SCL_EXT/SDA_EXT och J2:s SCL/SDA är samma stift — en I²C 1-buss exponerad på två kontakter.
Tips
Använd uppskattaren för batterilivslängd för att modellera hur länge Nicla Vision kommer att köra på ett batteri för en given arbetscykel mellan aktiv/djupsömn.
Stift för återställning och felsökning¶
RESET — både en momentan brytare ovanpå kortet och en yta (J3‑4 / testyta P5) kopplad till SoC:ns NRST-linje. Dra till GND för att återställa.
Nicla Vision använder Arduinos standardiserade dubbeltryck-återställning för att gå in i Arduinos startladdare — tryck snabbt på återställningsknappen två gånger så räknas kortet upp som en DFU-enhet. OpenMV IDE använder detta läge för att flasha om firmwaren.
STM32:ns SWD-signaler är exponerade på baksidan av kortet genom en rad testytor mellan de två J2-anslutningarna. Löd in en 2,54 mm (100‑mil)-anslutning i dem för att koppla på en ST‑LINK- eller J‑Link-adapter:
P1 / P2 — intern PMIC I²C-buss på PF0 (SDA) och PF1 (SCL). Detta är
machine.I2C(2)på Nicla Vision och bär trafik för PMIC, laddningsmätare och ToF.P3 — TMS / SWDIO (PA13)
P4 — TCK / SWCLK (PA14)
P5 — NRST
P6 — TDO / SWO (PB3)
P7 — +1V8-skena (SoC:ns I/O-matning — även rätt referens för felsökningsadaptern).
P8 —
VOTP_PMIC— endast fabriksprogrammering. Måste lämnas oansluten.
Alla felsökningssignaler är 1,8 V-refererade — STM32H747:ns I/O-ring på detta kort drivs från +1V8-skenan. Ställ in din felsökningsadapter för 1,8 V-logik innan du ansluter.
Inbyggd kringutrustning¶
LED:ar¶
Nicla Vision har en enda RGB-LED för användaren, programvarustyrbar via machine.LED
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
En separat DL2 CHARGE-LED på sidan av kortet är kopplad direkt till PMIC:ns CHGB-utgång — den lyser medan ett Li‑Po-batteri laddas från USB/ESLOV/VIN och kan inte styras av användaren.
Kamerasensor¶
GC2145 drivs genom modulen csi — kamerasensorer
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()
När du begär en liten bildstorlek beskär GC2145-drivrutinen ett proportionellt litet utläsningsfönster från sensorn — som standard är nedskalningsförhållandet från utläsning till utdata begränsat till 3x för att hålla uppe bildrutehastigheten. csi.IOCTL_SET_FOV_WIDE höjer detta tak till 5x, vilket innebär att drivrutinen drar från ett bredare område av sensorn vid strömning av små upplösningar. Resultatet är ett märkbart bredare synfält vid små bildstorlekar, på bekostnad av en del genomströmning:
cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE) # returns the current setting
M4-kärna¶
Cortex‑M4-kärnan exponeras genom openamp för kommunikation mellan processorer. OpenMV-firmwaren körs endast på M7:an; M4:an har ingen egen MicroPython-runtime, så att använda den innebär att bygga en separat C-firmwarebild och ladda den från filsystemet via openamp.RemoteProc. Förbyggd exempel-firmware som implementerar en virtuell UART-endpunkt finns tillgänglig i förvaret openamp_vuart — följ dess README för att bygga 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)
I praktiken är detta stöd bäst att betrakta som en demonstration av openamp-gränssnittet snarare än en fungerande tvåkärnig plattform — M4:an kan inte återställas oberoende av M7:an, så att stoppa M4:an tvingar fram en fullständig omstart av systemet.
Mikrofon¶
Den inbyggda PDM-mikrofonen MP34DT06JTR fångas genom audio — Ljudmodul över STM32:ns DFSDM-kringutrustning. Varje buffert anländer som en teckenförsedd 16-bitars PCM-bytearray, redo att matas in i ulab/numpy för DSP — till exempel en enkel ljudstyrkedetektor:
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¶
Den inbyggda accelerometern + gyroskopet LSM6DSOX exponeras genom imu — imu-sensor
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)
IMU:n är kopplad till en dedikerad intern SPI-buss (SPI5) så att den inte konkurrerar med den användar-SPI4 som är utbruten på anslutningarna.
Time‑of‑flight-avståndsmätare¶
Den inbyggda ST VL53L1CB time‑of‑flight-avståndsmätaren sitter på den interna PMIC I²C-bussen (I²C 2). Använd den frysta drivrutinen vl53l1x — Drivrutin för VL53L1X ToF-avståndssensor för att få avståndsavläsningar upp till ~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)
Batteriladdningsmätare¶
Maxim MAX17262 ModelGauge m5-laddningsmätaren spårar Li‑Po-batteriets spänning, ström, temperatur och laddningstillstånd. Den sitter på I²C 2 på adress 0x36.
MAX17262 har intern strömavkänning, så strömregistret läser ut direkt i mikroampere utan någon extern Rsense-faktor att tillämpa. Att läsa laddningsmätaren är ofarligt — det finns ingen drivrutin levererad, men de register som dokumenteras i MAX17262-databladet kan läsas direkt:
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 är teckenförsedd i tvåkomplement: positiv vid laddning, negativ vid urladdning. TTE är endast meningsfull när strömmen är negativ; TTF endast när strömmen är positiv.
Strömhanterings-IC¶
NXP MC34PF1550A0EP PMIC hanterar varje regulator på Nicla Vision — +3V3-huvudskenan, +1V8-skenan för SoC-kärna/I/O, VDDIO_EXT till nivåomvandlarna och Li‑Po-laddaren. Den sitter på I²C 2 på adress 0x08.
Varning
Att läsa PMIC-register är okej; att skriva till dem är farligt. Felkonfigurering av en buck-regulator- eller laddarinställning kan permanent skada kortet, batteriet eller båda. Behandla PMIC:n som skrivskyddad om du inte exakt vet vad du gör.
Det mest användbara som PMIC:n berättar för dig och som laddningsmätaren inte kan är laddarens tillståndsmaskin — om kortet för närvarande drivs av USB/ESLOV/VIN, vilket stadium i laddningscykeln Li‑Po-batteriet är i, och om laddaren befinner sig i ett termiskt fel eller ett watchdog-fel. Laddarregistren ligger på en offset på 0x80 i PF1550:ns huvudsakliga I²C-adressrymd (se §22.2 i PF1550-databladet), så till exempel läses CHG_INT_OK på laddaradress 0x04 från PMIC-register 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)
Andra skrivskyddade register värda att titta på i databladet (alla på laddar-offset 0x80): 0x80 CHG_INT (spärrade laddaravbrott — felflaggor), 0x86 VBUS_SNS (det flerbitars VBUS-tillståndet inklusive OVLO/UVLO/DPM) och 0x88 BATT_SNS (batteriets närvaro och överströmstillstånd).
Wi‑Fi¶
Den inbyggda Murata 1DX (CYW4343W) exponeras via network — nätverkskonfiguration som ett stationsgränssnitt. Anslut den medföljande antennen till den inbyggda U.FL-kontakten innan du startar upp radion:
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¶
Samma Murata 1DX exponerar också Bluetooth LE 5.1. Använd aioble — Asynkron BLE för asyncio-vänlig BLE — till exempel att annonsera som en kringutrustning och vänta på att en central ansluter:
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())
Bussreferens¶
GPIO¶
Använd machine.Pin för att läsa eller driva något av de silktryckta stiften. Utgångar är 3,3 V CMOS (standard VDDIO_EXT) och nivåomvandlarna begränsar drivstyrkan per stift till några få milliampere — de är konstruerade för signalnivåer snarare än effektbelastningar.
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())
Vilket ingångsstift som helst kan också utlösa ett avbrott vid kanttransitioner:
def handler(pin):
print("triggered:", pin)
Pin("D1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
Buss |
TX |
RX |
|---|---|---|
UART4 |
SDA |
SCL |
from machine import UART
uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)
Anteckning
UART4 delar sina stift med I²C 1 — samma SDA/SCL-ytor bär båda bussarna. Välj UART eller I²C, inte båda, på dessa stift.
Silktrycket D1/D2 läser också UART_TX/UART_RX, men på denna firmware dras dessa stift till LPUART1, inte till machine.UART. machine.UART(1) är i sig reserverad för den inbyggda Bluetooth-styrenheten och är inte åtkomlig på anslutningarna.
I²C¶
Buss |
SCL |
SDA |
|---|---|---|
I2C1 |
SCL |
SDA |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
SCL/SDA-ytorna på J2 och ESLOV-kontaktens SCL_EXT/SDA_EXT-stift landar på samma I²C 1-buss — se ESLOV-kontakt ovan för ESLOV-stiftutgången.
Samma hårdvara kan också användas i målläge (slavläge) genom machine.I2CTarget för att exponera ett minnesområde för en annan I²C-styrenhet:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
Buss |
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¶
Nicla Vision exponerar tre 12-bitars ADC-kanaler på A0, A1 och A2. Alla tre är 1,8 V-refererade — read_u16 returnerar 0–65535 över 0–1,8 V vid stiftet:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
Varning
Nicla Visions ADC-ingångar är 1,8 V-refererade (och har ingen nivåomvandlare framför SoC:n). Att mata in en 3,3 V-signal mättar omvandlaren och kan skada stiftet — dela ner högre spänningar externt.
PWM¶
Stift |
Timer / kanal |
|---|---|
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 |
Driv någon av dem via machine.PWM
from machine import Pin, PWM
pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)
Anteckning
Flera stift delar TIM1-kanaler:
TIM1 CH2 finns på
D1ochCS.TIM1 CH3 finns på
D2ochCIPO;SCLKmatar ut det inverterade komplementet (TIM1 CH3N) av samma kanal.TIM1 CH4 finns på
COPIensam.
Välj en konsument per timerkanal. SPI-kvartettens stift (SCLK/CIPO/COPI/CS) kan inte heller PWM-drivas medan machine.SPI(4) använder dem.
Programvarubaserade bit‑bangade bussar¶
machine.SoftI2C och machine.SoftSPI fungerar på vilken GPIO som helst om du behöver en extra buss.
Värmesensor (extern)¶
Firmwaren inkluderar drivrutinen fir — drivrutin för värmesensor (fir == far infrared) för externt kopplade värmebildkameror:
MLX90621 — 16 × 4 IR-array
MLX90640 — 32 × 24 IR-array
MLX90641 — 16 × 12 IR-array
AMG8833 — 8 × 8 IR-array
Koppla modulen till kortets I²C-buss och läs bildrutor med 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())
Drivrutinen fir talar endast med sensorn över I²C 1 — koppla modulen till de silktryckta SCL/SDA-ytorna.
Tidtagning¶
time¶
Modulen time täcker blockerande fördröjningar, monotona tick och mätning av förfluten tid:
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)
Virtuella timrar¶
machine.Timer schemalägger periodiska eller engångsåteranrop utan att förbruka en hårdvarutimerplats. Skicka -1 som id för att använda en virtuell (programvarubaserad) timer:
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"))
Periodvärden anges i millisekunder. Anropa deinit() för att stoppa och frigöra platsen.
Realtidsklocka¶
machine.RTC håller väggklockstid över återställningar:
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 återställer kortet om applikationen hänger sig. När den väl har startats kan den inte stoppas eller konfigureras om — mata den periodiskt inuti din huvudloop:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
Information om uppstart och körtid¶
Firmwareuppdatering (DFU)¶
Nicla Vision använder Arduinos standardiserade dubbeltryck-återställning för att gå in i Arduinos startladdare. Tryck snabbt på återställningsknappen två gånger — kortet räknas upp på nytt över USB som en DFU-enhet och OpenMV IDE kan flasha en ny firmwarebild.
Ett körande skript kan gå in i startladdaren igen på begäran genom att anropa machine.bootloader()
import machine
machine.bootloader()
Filsystem och uppstartsordning¶
Nicla Vision-firmwaren monterar upp till två filsystem vid uppstart:
Internt flashminne — alltid monterat på
/flash. Innehållermain.pyochREADME.txtsom standard; skapas vid allra första uppstarten.ROMFS — skrivskyddat, minnesmappat filsystem på
/romsom monteras automatiskt av MicroPython vid start.
Efter monteringen sätts arbetskatalogen till /flash. Tolken kör sedan skript från den katalogen:
boot.pykörs vid varje mjuk återställning (kallstart,Ctrl‑Dfrån REPL, eller närhelst det körande skriptet returnerar).main.pykörs endast vid kallstart, omedelbart efterboot.py. Efterföljande mjuka återställningar kör omboot.pymen hoppar direkt till REPL — för att köra ommain.pymåste du återställa kortet helt.
Standard-main.py som levereras på ett nyflashat kort blinkar bara med blå kanal på användarnas RGB-LED som ett hjärtslag (två korta pulser, kort paus), så att du kan se att firmwaren startade rent utan någon ansluten värd.
sys.path utökas till att inkludera båda filsystemen och deras lib/-underkataloger, så importerbara moduler kan ligga i /flash/lib eller /rom/lib.
När den är ansluten över USB räknas /flash också upp som en USB-masslagringsenhet på värden, vilket låter dig redigera boot.py, main.py och alla andra filer direkt. Mata ut enheten innan du återställer kameran så att värden tömmer sina cachade skrivningar.
Anteckning
Eftersom operativsystemet behandlar enheten som en passiv blockenhet kommer filer som skapats eller ändrats av kod som körs på kameran inte att synas förrän värden återmonterar enheten. Om både operativsystemet och kameran skriver till samma filsystem samtidigt vinner operativsystemet och skriver över ändringar gjorda av kameran. Använd SD-kortet för all data som skriptet skriver tillbaka, och återmontera innan du läser dessa filer från värden.
Anteckning
Användarnas RGB-LED:s röda kanal kan kortvarigt tändas medan värden läser från eller skriver till USB-masslagringsenheten — detta är en firmwarestyrd aktivitetsindikator, inte ett fel.
Lagringsstorlekar¶
Nicla Vision levereras med:
/flash— 11 MB FAT-filsystem, läs/skriv./rom— 4 MB skrivskyddat minnesmappat ROMFS, används för att leverera skript och ML-modeller som drar nytta av kopieringsfri mmap-åtkomst.
Indikator för allvarligt fel (hard fault)¶
Om användarnas RGB-LED snabbt cyklar genom alla färger — tillräckligt snabbt för att det tenderar att se ut som en blinkande vit LED snarare än distinkta nyanser — har firmwaren råkat ut för ett oåterkalleligt allvarligt fel (hard fault). Flasha om firmwaren för att återställa; om omflashning inte hjälper kan kortet vara fysiskt skadat.
Programvarubibliotek¶
Se biblioteksindexet för den fullständiga listan över moduler — inklusive vilka som är unika för Nicla Vision-bygget.