Arduino Nicla Vision¶
Arduino Nicla Vision 是一款 22.86 × 22.86 mm 的機器視覺開發板,以意法半導體(STMicroelectronics)的 STM32H747AII6 為核心——這是一顆雙核心 SoC,結合了 400 MHz 的 Cortex‑M7 與 200 MHz 的 Cortex‑M4。OpenMV 韌體完全執行於 M7 核心上。該開發板將 MCU 與 GC2145 2 MP 彩色 CMOS 感測器、LSM6DSOX 六軸 IMU、MP34DT06 MEMS 麥克風、VL53L1CB 飛時測距儀(time‑of‑flight)、Wi‑Fi + Bluetooth LE 5.1,以及電池充電器/電量計搭配在一起。
完整的資料手冊、照片與尺寸請參見 Arduino Nicla Vision 產品頁面。
重點特色¶
意法半導體 STM32H747AII6 雙核心 Cortex‑M7(400 MHz)+ Cortex‑M4(200 MHz)。OpenMV 韌體僅執行於 M7 核心上。
2 MB 內部快閃記憶體 外加 16 MB 外部 QSPI 快閃記憶體(用於應用程式 + ROMFS)。
1 MB 內部 SRAM。
硬體 JPEG 編碼器/解碼器。
GC2145 2 MP 彩色 CMOS 感測器。
內建 IMU(LSM6DSOX 加速度計 + 陀螺儀)、MEMS 麥克風(MP34DT06JTR),以及 VL53L1CB 飛時測距儀(最遠約 4 m)。
Wi‑Fi b/g/n(2.4 GHz)+ Bluetooth LE 5.1,透過 Murata 1DX(CYW4343W)模組提供——經由板載 U.FL 連接器 連接所附的天線。
高速 USB(480 Mb/s),透過外部 ULPI PHY(USB3320C)經由 Micro USB 連接。
Arduino 邊緣排針上的 13 個使用者 I/O 接腳——四個數位 LPIO(
D0–D3)、三個 1.8 V 類比輸入(A0–A2)、SCL/SDAI²C 接腳對,以及SCLK/CIPO/COPI/CSSPI 四接腳組。電池支援——背面的 Li‑Po 連接器、BQ 系列充電器,以及透過內部 PMIC 匯流排存取的 MAX17262 電量計。
背面的 5 接腳 ESLOV 連接器,供免焊接 I²C 擴充使用。
警告
使用者 數位接腳預設為 3.3 V,但會經由可由軟體規劃的電平轉換器(VDDIO_EXT)路由,可重新設定為 1.8 V。類比接腳(A0–A2)僅支援 1.8 V——它們繞過電平轉換器,直接連接到 MCU。將 3.3 V 灌入 A0–A2 會損壞 SoC。
接腳配置¶
接腳參考¶
Arduino 邊緣排針(J1 與 J2)上共露出十三個使用者接腳。額外的除錯、復原與 PMIC 訊號則路由至開發板背面的測試焊盤。
接腳名稱 |
參考 |
功能 |
|---|---|---|
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 通道 4(J1‑8) |
A1 |
1.8 V |
ADC2 通道 2(J1‑7) |
A2 |
1.8 V |
ADC3 通道 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 |
拉至 GND(或按下板載開關)以重置開發板 |
LED_RED |
3.3 V |
RGB LED 紅色通道(低電位有效) |
LED_GREEN |
3.3 V |
RGB LED 綠色通道(低電位有效) |
LED_BLUE |
3.3 V |
RGB LED 藍色通道(低電位有效) |
備註
D0–D3 以及 SCLK/CIPO/COPI/CS 位於 TXB0108 雙向電平轉換器之後——該元件僅支援 推挽式(push‑pull) GPIO 驅動,因此開汲極(open‑drain)匯流排傳輸(例如在這些接腳上以軟體模擬的 1‑Wire 或 I²C)將無法運作。
SCL/SDA 位於另一顆 NTS0304 轉換器之後,該轉換器同時支援 推挽式與開汲極 驅動,這也是為什麼 I²C 1 能在那裡運作的原因。
兩顆轉換器都以 VDDIO_EXT(預設為板載 PMIC 提供的 3.3 V)為參考,且相較於直接的 GPIO,其驅動能力有限——它們是為訊號電平而非功率負載所設計的。
電源接腳¶
邊緣排針接腳:
VIN(J2‑9)——主要的 3.6 – 5 V 系統電源軌。PMIC 由此取得輸入。
VDDIO_EXT(J2‑7)——電平轉換器電源軌的 輸出,1.8 V 或 3.3 V(預設為 3.3 V)。可用此電源為連接至 LPIO/SPI/I²C 接腳的外部 1.8 V 或 3.3 V 周邊裝置供電,使其與排針使用相同的邏輯電平。
VBAT(J3‑2)——Li‑Po 電池輸入。板載 PMIC 會由 VIN 為電芯充電,並透過電量計回報充電狀態。
NTC(J3‑1)——選用的 Li‑Po 熱敏電阻輸入。
GND(J2‑6)——共同接地。
NC(J2‑8)——未連接。
開發板背面的測試焊盤:
+3V3——主要的 3.3 V 電源軌。
D_P / D_N——USB 高速資料對(PHY 之後)。
USB 與 ESLOV 連接器都會透過一對 LM66100 理想二極體(每個來源各一顆)饋入 VIN,因此任一供電來源都能單獨為開發板供電,且兩者絕不會互相回灌。若你在 J2‑9 從外部驅動 VIN,則以該供電為優先——一旦外部電源軌升高,二極體便會停止從 USB / ESLOV 導通。
因此,開發板可透過下列任一途徑供電:
Micro USB——透過 USB 側的理想二極體將 5 V 灌入 VIN。
ESLOV 連接器——在 J5 的
VESLOV接腳上最高 5 V,透過 ESLOV 側的理想二極體路由至 VIN(參見 ESLOV 連接器)。VIN 接腳(J2‑9)——直接驅動穩壓後的 3.6 – 5 V 供電。
Li‑Po 電池——連接至背面的 J4 電池連接器,或 連接至 J3 / J2‑6 上的 VBAT/GND/NTC 焊盤。請勿同時連接兩顆電池。
ESLOV 連接器¶
開發板背面的 J5 是一個 5 接腳 Molex 免焊接 ESLOV 連接器:
接腳 |
名稱 |
功能 |
|---|---|---|
J5‑1 |
VESLOV |
電源輸入(≤ 5 V)——透過 LM66100 理想二極體與 |
J5‑2 |
INT |
|
J5‑3 |
SCL_EXT |
與 J2 |
J5‑4 |
SDA_EXT |
與 J2 |
J5‑5 |
GND |
共同接地 |
ESLOV 的 SCL_EXT/SDA_EXT 與 J2 的 SCL/SDA 是相同的接腳——同一條 I²C 1 匯流排露出於兩個連接器上。
小訣竅
使用 電池續航估算工具 來推估在給定的活動/深度睡眠工作週期下,Nicla Vision 能以電池運作多久。
復原與除錯接腳¶
RESET——既是開發板頂部的瞬時開關,也是接到 SoC NRST 線的焊盤(J3‑4 / 測試焊盤 P5)。拉至 GND 即可重置。
Nicla Vision 採用 Arduino 標準的 雙擊重置(double‑tap reset) 進入 Arduino 的開機載入程式——快速按下重置按鈕兩次,開發板便會列舉為 DFU 裝置。OpenMV IDE 會使用此模式重新燒錄韌體。
STM32 SWD 訊號透過兩個 J2 排針之間的一排測試焊盤露出於開發板背面。將 2.54 mm(100‑mil) 排針焊接至這些焊盤,即可連接 ST‑LINK 或 J‑Link 轉接器:
P1 / P2——位於 PF0(SDA)與 PF1(SCL)上的內部 PMIC I²C 匯流排。在 Nicla Vision 上這是
machine.I2C(2),承載 PMIC、電量計與 ToF 的傳輸。P3——TMS / SWDIO(PA13)
P4——TCK / SWCLK(PA14)
P5——NRST
P6——TDO / SWO(PB3)
P7——+1V8 電源軌(SoC 的 I/O 供電——也是除錯轉接器的正確參考電平)。
P8——
VOTP_PMIC——僅供工廠燒錄使用。必須保持未連接。
所有除錯訊號都以 1.8 V 為參考——此開發板上 STM32H747 的 I/O 環由 +1V8 電源軌供電。連接前請將除錯轉接器設定為 1.8 V 邏輯電平。
板載周邊裝置¶
LED¶
Nicla Vision 具有單一使用者 RGB LED,可透過 machine.LED 以軟體控制:
from machine import LED
LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()
開發板側面另有一顆 DL2 CHARGE LED,直接接到 PMIC 的 CHGB 輸出——當 Li‑Po 電池正由 USB / ESLOV / VIN 充電時它會亮起,且無法由使用者控制。
相機感測器¶
GC2145 透過 csi --- 相機感測器 模組驅動:
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()
當你要求較小的框架尺寸時,GC2145 驅動程式會從感測器裁切出按比例縮小的讀出視窗——預設情況下,讀出到輸出的降取樣比率上限為 3x,以維持影格率。csi.IOCTL_SET_FOV_WIDE 會將該上限提高至 5x,這表示驅動程式在串流小解析度時會從感測器更廣的區域擷取。其結果是在小框架尺寸下視野明顯更廣,但代價是犧牲部分吞吐量:
cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE) # returns the current setting
M4 核心¶
Cortex‑M4 核心透過 openamp 露出,供處理器間通訊使用。OpenMV 韌體僅執行於 M7 上;M4 本身沒有自己的 MicroPython 執行環境,因此要使用它就必須建置一份獨立的 C 韌體映像,並透過 openamp.RemoteProc 從檔案系統載入。在 openamp_vuart 儲存庫中提供了預先建置、實作虛擬 UART 端點的範例韌體——依照其 README 建置 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)
實務上,最好將此項支援視為 openamp 介面的示範,而非可運作的雙核心平台——M4 無法獨立於 M7 之外被重置,因此停止 M4 會強制整個系統重新開機。
麥克風¶
板載的 MP34DT06JTR PDM 麥克風透過 audio --- 音訊模組 經由 STM32 的 DFSDM 周邊裝置擷取。每個緩衝區會以帶正負號的 16 位元 PCM bytearray 形式抵達,可直接送入 ulab/numpy 進行 DSP——例如一個簡單的響度偵測器:
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¶
板載的 LSM6DSOX 加速度計 + 陀螺儀透過 imu --- 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)
IMU 接線至一條專用的內部 SPI 匯流排(SPI5),因此不會與排針上引出的使用者 SPI4 產生衝突。
飛時測距儀¶
板載的 ST VL53L1CB 飛時測距儀位於內部 PMIC I²C 匯流排(I²C 2)上。使用凍結的 vl53l1x --- VL53L1X ToF 距離感測器驅動程式 驅動程式可取得最遠約 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)
電池電量計¶
Maxim MAX17262 ModelGauge m5 電量計會追蹤 Li‑Po 電池的電壓、電流、溫度與充電狀態。它位於 I²C 2 上,位址為 0x36。
MAX17262 具備 內部 電流感測功能,因此電流暫存器會直接以微安培讀出,無需套用外部 Rsense 係數。讀取電量計是無害的——出貨時並未隨附驅動程式,但 MAX17262 資料手冊 中記載的暫存器可直接讀取:
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 為帶正負號的二補數:充電時為正,放電時為負。TTE 僅在電流為負時才有意義;TTF 則僅在電流為正時才有意義。
電源管理 IC¶
NXP MC34PF1550A0EP PMIC 負責 Nicla Vision 上的每一個穩壓器——+3V3 主電源軌、+1V8 SoC 核心/ I/O 電源軌、供給電平轉換器的 VDDIO_EXT,以及 Li‑Po 充電器。它位於 I²C 2 上,位址為 0x08。
警告
讀取 PMIC 暫存器沒有問題;但寫入則很危險。 錯誤設定降壓穩壓器或充電器設定可能會永久損壞開發板、電池,或兩者皆損。除非你完全清楚自己在做什麼,否則請將 PMIC 視為唯讀。
PMIC 能告訴你而電量計無法提供、最有用的資訊就是 充電器狀態機——開發板目前是以 USB / ESLOV / VIN 運作、Li‑Po 處於充電週期的哪個階段,以及充電器是否處於熱保護或看門狗故障。充電器暫存器位於 PF1550 主 I²C 位址空間中偏移 0x80 處(參見 PF1550 資料手冊 第 22.2 節),因此舉例來說,位於充電器位址 0x04 的 CHG_INT_OK 是從 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)
資料手冊中其他值得一看的唯讀暫存器(皆位於充電器偏移 0x80):0x80 CHG_INT(鎖存的充電器中斷——故障旗標)、0x86 VBUS_SNS(包含 OVLO / UVLO / DPM 的多位元 VBUS 狀態),以及 0x88 BATT_SNS(電池存在與否及過電流狀態)。
Wi‑Fi¶
板載的 Murata 1DX(CYW4343W)透過 network --- 網路設定 以工作站(station)介面露出。在啟動無線電之前,請先將所附天線連接至板載 U.FL 連接器:
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¶
同一顆 Murata 1DX 也會露出 Bluetooth LE 5.1。使用 aioble --- 非同步 BLE 以利於 asyncio 的 BLE——例如以周邊裝置身分廣播並等待中央裝置連接:
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())
匯流排參考¶
GPIO¶
使用 machine.Pin 來讀取或驅動任何絲印標示的接腳。輸出為 3.3 V CMOS(預設 VDDIO_EXT),且電平轉換器會將每支接腳的驅動能力限制在數毫安培——它們是為訊號電平而非功率負載所設計的。
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())
任何輸入接腳也都能在邊緣轉態時觸發中斷:
def handler(pin):
print("triggered:", pin)
Pin("D1", Pin.IN, Pin.PULL_UP).irq(
handler, Pin.IRQ_FALLING | Pin.IRQ_RISING,
)
UART¶
匯流排 |
TX |
RX |
|---|---|---|
UART4 |
SDA |
SCL |
from machine import UART
uart = UART(4, baudrate=115200)
uart.write("hello")
uart.read(5)
備註
UART4 與 I²C 1 共用接腳——相同的 SDA/SCL 焊盤同時承載這兩條匯流排。在這些接腳上請擇一使用 UART 或 I²C,不可兩者並用。
D1/D2 的絲印也標示為 UART_TX/UART_RX,但在此韌體上這些接腳是路由至 LPUART1,而非 machine.UART。machine.UART(1) 本身保留給晶片內建的 Bluetooth 控制器,無法在排針上存取。
I²C¶
匯流排 |
SCL |
SDA |
|---|---|---|
I2C1 |
SCL |
SDA |
from machine import I2C
i2c = I2C(1, freq=400_000)
i2c.scan()
i2c.writeto(0x76, b"hi")
J2 上的 SCL/SDA 焊盤與 ESLOV 連接器的 SCL_EXT/SDA_EXT 接腳都落在同一條 I²C 1 匯流排上——ESLOV 接腳配置請參見上方的 ESLOV 連接器。
相同的硬體也可透過 machine.I2CTarget 以目標(從屬)模式使用,將一塊記憶體區域露出給另一個 I²C 控制器:
from machine import I2CTarget
buf = bytearray(32)
target = I2CTarget(1, addr=0x42, mem=buf)
SPI¶
匯流排 |
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 在 A0、A1 與 A2 上露出三個 12 位元 ADC 通道。三者皆以 1.8 V 為參考——read_u16 會在接腳的 0–1.8 V 範圍內回傳 0–65535:
from machine import ADC
import time
adc = ADC("A0")
while True:
voltage = adc.read_u16() * 1.8 / 65535
print(voltage)
time.sleep_ms(100)
警告
Nicla Vision 的 ADC 輸入以 1.8 V 為參考(且 SoC 前方沒有電平轉換器)。灌入 3.3 V 訊號會使轉換器飽和,並可能損壞接腳——較高的電壓請在外部分壓降低。
PWM¶
接腳 |
計時器/通道 |
|---|---|
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 |
透過 machine.PWM 驅動其中任一者:
from machine import Pin, PWM
pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)
備註
有數支接腳共用 TIM1 通道:
TIM1 CH2 位於
D1與CS上。TIM1 CH3 位於
D2與CIPO上;SCLK輸出同一通道的反相互補訊號(TIM1 CH3N)。TIM1 CH4 僅位於
COPI上。
每個計時器通道請只挑選一個使用者。SPI 四接腳(SCLK/CIPO/COPI/CS)在 machine.SPI(4) 使用它們的同時,也無法以 PWM 驅動。
軟體模擬匯流排¶
若你需要額外的匯流排,machine.SoftI2C 與 machine.SoftSPI 可在任何 GPIO 上運作。
熱感測器(外接)¶
韌體內含 fir --- 熱感測器驅動程式 (fir == far infrared,遠紅外線) 驅動程式,供外部接線的熱成像儀使用:
MLX90621——16 × 4 紅外線陣列
MLX90640——32 × 24 紅外線陣列
MLX90641——16 × 12 紅外線陣列
AMG8833——8 × 8 紅外線陣列
將模組接線至開發板的 I²C 匯流排,並以 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())
fir 驅動程式只透過 I²C 1 與感測器通訊——請將模組接線至絲印標示的 SCL / SDA 焊盤。
計時¶
time¶
time 模組涵蓋阻塞式延遲、單調遞增的計時刻度,以及經過時間的測量:
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)
虛擬計時器¶
machine.Timer 可在不佔用硬體計時器插槽的情況下排程週期性或單次回呼函式。傳入 -1 作為 id 即可使用虛擬(軟體)計時器:
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"))
週期值以毫秒為單位。呼叫 deinit() 可停止並釋放該插槽。
即時時鐘¶
machine.RTC 能在多次重置之間維持壁鐘時間:
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())
看門狗¶
machine.WDT 會在應用程式當機時重置開發板。一旦啟動便無法停止或重新設定——請在主迴圈中定期餵食它:
from machine import WDT
wdt = WDT(timeout=5_000) # 5 second window
while True:
# ...do work...
wdt.feed()
開機與執行階段資訊¶
韌體更新(DFU)¶
Nicla Vision 採用 Arduino 標準的 雙擊重置(double‑tap reset) 進入 Arduino 的開機載入程式。快速按下重置按鈕兩次——開發板會透過 USB 重新列舉為 DFU 裝置,OpenMV IDE 便可燒錄新的韌體映像。
執行中的指令碼可透過呼叫 machine.bootloader() 隨時重新進入開機載入程式:
import machine
machine.bootloader()
檔案系統與開機順序¶
Nicla Vision 韌體在開機時最多會掛載兩個檔案系統:
內部快閃記憶體——一律掛載於
/flash。預設存放main.py與README.txt;於最初的第一次開機時建立。ROMFS——唯讀、記憶體映射的檔案系統,位於
/rom,由 MicroPython 在啟動時自動掛載。
掛載完成後,工作目錄會設定為 /flash。直譯器接著會從該目錄執行指令碼:
boot.py會在 每一次 軟重置時執行(冷開機、從 REPL 按下Ctrl‑D,或每當執行中的指令碼返回時)。main.py僅在冷開機時 執行,緊接在boot.py之後。後續的軟重置會重新執行boot.py,但會直接落到 REPL——要重新執行main.py就必須完全重置開發板。
剛燒錄好的開發板上隨附的預設 main.py 只會閃爍使用者 RGB LED 的 藍色 通道作為心跳訊號(兩次短脈衝、短暫間隔),讓你即使未連接任何主機,也能判斷韌體是否乾淨地完成開機。
sys.path 會擴充以納入兩個檔案系統及其 lib/ 子目錄,因此可匯入的模組可存放於 /flash/lib 或 /rom/lib。
透過 USB 連接時,/flash 也會在主機上列舉為一個 USB 大容量儲存裝置磁碟,讓你能直接編輯 boot.py、main.py 與任何其他檔案。在重置相機前請先退出該磁碟,讓主機把它快取的寫入內容刷新出去。
備註
由於作業系統將該磁碟視為被動的區塊裝置,相機上執行的程式碼所建立或修改的檔案,要等到主機重新掛載磁碟後才會顯示出來。若作業系統與相機同時寫入相同的檔案系統,作業系統會勝出並覆寫相機所做的變更。對於指令碼寫回的任何資料,請使用 SD 卡,並在從主機讀取那些檔案前重新掛載。
備註
當主機正在從 USB 大容量儲存磁碟讀取或寫入時,使用者 RGB LED 的 紅色 通道可能會短暫亮起——這是韌體驅動的活動指示,並非故障。
儲存空間大小¶
Nicla Vision 出貨時具備:
/flash——11 MB FAT 檔案系統,可讀寫。/rom——4 MB 唯讀、記憶體映射的 ROMFS,用於配送可受惠於零複製 mmap 存取的指令碼與 ML 模型。
硬性故障指示¶
若使用者 RGB LED 快速循環顯示所有色彩——快到看起來比較像是 閃爍的白色 LED 而非各個分明的色相——則表示韌體遇到了無法復原的硬性故障(hard fault)。請重新燒錄韌體以復原;若重新燒錄仍無效,開發板可能已實體損壞。
軟體函式庫¶
完整的模組清單請參見 函式庫索引——其中包括哪些模組是 Nicla Vision 建置版本所獨有的。