Arduino Nicla Vision

Arduino Nicla Vision là bo mạch thị giác máy kích thước 22,86 × 22,86 mm được xây dựng dựa trên vi mạch STMicroelectronics STM32H747AII6 — một SoC lõi kép kết hợp Cortex‑M7 tại 400 MHz với Cortex‑M4 tại 200 MHz. Firmware OpenMV chạy hoàn toàn trên lõi M7. Bo mạch kết hợp MCU với cảm biến CMOS màu GC2145 2 MP, IMU 6 trục LSM6DSOX, microphone MEMS MP34DT06, cảm biến đo khoảng cách thời gian bay VL53L1CB, Wi‑Fi + Bluetooth LE 5.1, và bộ sạc / đo mức pin.

Arduino Nicla Vision

Để xem datasheet đầy đủ, ảnh chụp và kích thước, hãy truy cập trang sản phẩm Arduino Nicla Vision.

Điểm nổi bật

  • STMicroelectronics STM32H747AII6 lõi kép Cortex‑M7 (400 MHz) + Cortex‑M4 (200 MHz). Firmware OpenMV chỉ chạy trên lõi M7.

  • Bộ nhớ flash nội 2 MB cộng với Bộ nhớ flash QSPI ngoài 16 MB (dùng cho ứng dụng + ROMFS).

  • SRAM nội 1 MB.

  • Bộ mã hóa/giải mã JPEG phần cứng.

  • Cảm biến CMOS màu GC2145 2 MP.

  • IMU tích hợp (gia tốc kế + con quay hồi chuyển LSM6DSOX), microphone MEMS (MP34DT06JTR), và VL53L1CB cảm biến đo khoảng cách thời gian bay (lên đến ~4 m).

  • Wi‑Fi b/g/n (2,4 GHz) + Bluetooth LE 5.1 qua module Murata 1DX (CYW4343W) — kết nối với anten đi kèm thông qua đầu nối U.FL trên bo mạch.

  • USB tốc độ cao (480 Mb/s) qua Micro USB thông qua PHY ULPI ngoài (USB3320C).

  • 13 chân I/O người dùng trên các đầu nối cạnh Arduino — bốn LPIO kỹ thuật số (D0D3), ba đầu vào analog 1,8 V (A0A2), cặp I²C SCL/SDA, và bộ tứ SPI SCLK/CIPO/COPI/CS.

  • Hỗ trợ pin — đầu nối Li‑Po ở mặt sau, bộ sạc kiểu BQ, và đồng hồ đo mức pin MAX17262 qua bus PMIC nội.

  • Đầu nối ESLOV 5 chân ở mặt sau để mở rộng I²C không cần hàn.

Cảnh báo

Các chân kỹ thuật số mặc định là 3,3 V nhưng được định tuyến qua bộ dịch mức có thể lập trình bằng phần mềm (VDDIO_EXT) — có thể cấu hình lại thành 1,8 V. Các chân analog (A0–A2) chỉ hỗ trợ 1,8 V — chúng bỏ qua bộ dịch mức và kết nối trực tiếp với MCU. Đưa 3,3 V vào A0–A2 sẽ làm hỏng SoC.

Sơ đồ chân

Arduino Nicla Vision Pinout

Tài liệu tham chiếu chân

Mười ba chân người dùng được đưa ra trên các đầu nối cạnh Arduino (J1J2). Các tín hiệu gỡ lỗi, khôi phục và PMIC bổ sung được định tuyến đến các pad kiểm tra ở mặt sau bo mạch.

Tên chân

Tham chiếu

Chức năng

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 channel 4 (J1‑8)

A1

1,8 V

ADC2 channel 2 (J1‑7)

A2

1,8 V

ADC3 channel 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

kéo xuống GND (hoặc nhấn công tắc trên bo mạch) để đặt lại bo mạch

LED_RED

3,3 V

Kênh đỏ của LED RGB (tích cực mức thấp)

LED_GREEN

3,3 V

Kênh xanh lá của LED RGB (tích cực mức thấp)

LED_BLUE

3,3 V

Kênh xanh lam của LED RGB (tích cực mức thấp)

Ghi chú

D0D3SCLK/CIPO/COPI/CS nằm sau bộ dịch mức hai chiều TXB0108 — linh kiện này chỉ hỗ trợ chế độ GPIO push‑pull, vì vậy lưu lượng bus cực hở (ví dụ: 1‑Wire bit‑bang hoặc I²C trên các chân đó) sẽ không hoạt động.

SCL/SDA nằm sau bộ dịch mức NTS0304 riêng biệt hỗ trợ cả chế độ push‑pull và cực hở, đó là lý do tại sao I²C 1 hoạt động ở đó.

Cả hai bộ dịch mức đều tham chiếu đến VDDIO_EXT (mặc định 3,3 V từ PMIC trên bo mạch), và cường độ dẫn của chúng bị giới hạn so với GPIO trực tiếp — chúng được thiết kế cho tải mức tín hiệu chứ không phải tải công suất.

Chân nguồn

Các chân đầu nối cạnh:

  • VIN (J2‑9) — ray hệ thống chính 3,6 – 5 V. PMIC lấy đầu vào từ đây.

  • VDDIO_EXT (J2‑7) — đầu ra của ray bộ dịch mức, 1,8 V hoặc 3,3 V (mặc định 3,3 V). Dùng để cấp nguồn cho các ngoại vi 1,8 V hoặc 3,3 V ngoài kết nối với các chân LPIO/SPI/I²C để chúng dùng cùng mức logic với các đầu nối.

  • VBAT (J3‑2) — Đầu vào pin Li‑Po. PMIC trên bo mạch sạc pin từ VIN và báo cáo trạng thái sạc qua đồng hồ đo mức pin.

  • NTC (J3‑1) — Đầu vào thermistor Li‑Po tùy chọn.

  • GND (J2‑6) — mát chung.

  • NC (J2‑8) — không kết nối.

Các pad kiểm tra ở mặt sau bo mạch:

  • +3V3 — ray 3,3 V chính.

  • D_P / D_N — cặp dữ liệu USB tốc độ cao (sau PHY).

USB và đầu nối ESLOV đều cấp nguồn VIN qua một cặp diode lý tưởng LM66100 (một cái mỗi nguồn), nên cả hai nguồn đều có thể cấp nguồn cho bo mạch độc lập và không bao giờ back-drive nhau. Nếu bạn cấp VIN bên ngoài trên J2‑9, điều đó sẽ được ưu tiên — các diode đơn giản ngừng dẫn từ USB / ESLOV khi ray ngoài tăng cao hơn.

Do đó bo mạch có thể được cấp nguồn qua bất kỳ đường dẫn nào trong số này:

  • Micro USB — 5 V vào VIN qua diode lý tưởng phía USB.

  • Đầu nối ESLOV — lên đến 5 V trên chân VESLOV của J5, định tuyến vào VIN qua diode lý tưởng phía ESLOV (xem Đầu nối ESLOV).

  • Chân VIN (J2‑9) — cấp nguồn 3,6 – 5 V đã điều chỉnh trực tiếp.

  • Pin Li‑Po — kết nối vào đầu nối pin J4 ở mặt sau hoặc vào các pad VBAT/GND/NTC trên J3 / J2‑6. Không kết nối hai pin đồng thời.

Đầu nối ESLOV

J5 ở mặt sau bo mạch là đầu nối ESLOV Molex không cần hàn 5 chân:

Chân

Tên

Chức năng

J5‑1

VESLOV

đầu vào nguồn (≤ 5 V) — OR'd vào VIN qua diode lý tưởng LM66100

J5‑2

INT

đầu vào ngắt ngoài trên PD9

J5‑3

SCL_EXT

dùng chung với pad SCL của J2 — cùng bus I²C 1 với đầu nối người dùng

J5‑4

SDA_EXT

dùng chung với pad SDA của J2 — cùng bus I²C 1 với đầu nối người dùng

J5‑5

GND

mát chung

SCL_EXT/SDA_EXT của ESLOV và SCL/SDA của J2 là cùng một chân — một bus I²C 1 được đưa ra trên hai đầu nối.

Mẹo

Dùng công cụ ước tính thời lượng pin để mô phỏng thời gian Nicla Vision chạy trên pin với chu kỳ hoạt động / ngủ sâu nhất định.

Chân khôi phục và gỡ lỗi

  • RESET — cả công tắc nhấn tức thời ở trên bo mạch và pad (J3‑4 / test pad P5) nối với đường NRST của SoC. Kéo xuống GND để đặt lại.

Nicla Vision dùng tính năng nhấn đúp reset tiêu chuẩn của Arduino để vào bootloader Arduino — nhấn nhanh nút reset hai lần và bo mạch sẽ liệt kê là thiết bị DFU. OpenMV IDE dùng chế độ này để nạp lại firmware.

Các tín hiệu SWD của STM32 được đưa ra ở mặt sau bo mạch qua một hàng pad kiểm tra giữa hai đầu nối J2. Hàn header 2,54 mm (100‑mil) vào đó để gắn bộ điều hợp ST‑LINK hoặc J‑Link:

  • P1 / P2 — bus I²C PMIC nội trên PF0 (SDA) và PF1 (SCL). Đây là machine.I2C(2) trên Nicla Vision và mang lưu lượng PMIC, đồng hồ đo mức pin, và ToF.

  • P3 — TMS / SWDIO (PA13)

  • P4 — TCK / SWCLK (PA14)

  • P5 — NRST

  • P6 — TDO / SWO (PB3)

  • P7 — Ray +1V8 (nguồn I/O của SoC — cũng là mức tham chiếu đúng cho bộ điều hợp gỡ lỗi).

  • P8VOTP_PMICchỉ dành cho lập trình tại nhà máy. Phải để hở.

Tất cả các tín hiệu gỡ lỗi đều tham chiếu 1,8 V — vòng I/O của STM32H747 trên bo mạch này chạy từ ray +1V8. Đặt bộ điều hợp gỡ lỗi của bạn sang logic 1,8 V trước khi kết nối.

Ngoại vi tích hợp

LED

Nicla Vision có một LED RGB người dùng duy nhất, có thể điều khiển bằng phần mềm qua machine.LED

from machine import LED

LED("LED_RED").on()
LED("LED_GREEN").on()
LED("LED_BLUE").on()

Một LED DL2 CHARGE riêng biệt ở cạnh bo mạch được nối trực tiếp với đầu ra CHGB của PMIC — nó sáng khi pin Li‑Po đang được sạc từ USB / ESLOV / VIN và không thể điều khiển bằng người dùng.

Cảm biến camera

GC2145 được điều khiển qua module csi --- cảm biến 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()

Khi bạn yêu cầu một framesize nhỏ, driver GC2145 sẽ cắt xén cửa sổ đọc nhỏ tương ứng từ cảm biến — theo mặc định tỷ lệ thu nhỏ từ readout sang output được giới hạn ở 3x để giữ tốc độ khung hình. csi.IOCTL_SET_FOV_WIDE tăng giới hạn đó lên 5x, nghĩa là driver lấy từ khu vực rộng hơn của cảm biến khi stream độ phân giải nhỏ. Kết quả là góc nhìn rõ ràng rộng hơn ở framesize nhỏ, đổi lại là giảm thông lượng:

cam.ioctl(csi.IOCTL_SET_FOV_WIDE, True)
cam.ioctl(csi.IOCTL_GET_FOV_WIDE)  # returns the current setting

Lõi M4

Lõi Cortex‑M4 được đưa ra qua openamp cho giao tiếp liên vi xử lý. Firmware OpenMV chạy trên M7 duy nhất; M4 không có runtime MicroPython riêng, vì vậy sử dụng nó nghĩa là xây dựng một firmware C riêng và tải từ hệ thống tệp qua openamp.RemoteProc. Firmware ví dụ đã được dựng sẵn triển khai endpoint UART ảo có sẵn trong repository openamp_vuart — làm theo README của nó để dựng 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)

Trong thực tế, hỗ trợ này nên được coi là bản trình diễn giao diện openamp hơn là một nền tảng lõi kép hoạt động — M4 không thể được đặt lại độc lập với M7, vì vậy dừng M4 buộc phải khởi động lại toàn hệ thống.

Microphone

Microphone PDM MP34DT06JTR tích hợp được thu âm qua audio --- Mô-đun Âm thanh trên ngoại vi DFSDM của STM32. Mỗi bộ đệm đến dưới dạng bytearray PCM 16-bit có dấu, sẵn sàng để đưa vào ulab/numpy cho DSP — ví dụ, một bộ phát hiện âm lượng đơn giản:

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

Gia tốc kế + con quay hồi chuyển LSM6DSOX tích hợp được đưa ra qua imu --- cảm biến 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 được nối với bus SPI nội chuyên dụng (SPI5) nên không tranh chấp với SPI4 người dùng được đưa ra trên các đầu nối.

Cảm biến đo khoảng cách thời gian bay

Cảm biến đo khoảng cách thời gian bay ST VL53L1CB tích hợp nằm trên bus I²C PMIC nội (I²C 2). Dùng driver đóng băng vl53l1x --- Driver cảm biến đo khoảng cách ToF VL53L1X để đọc khoảng cách lên đến ~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)

Đồng hồ đo mức pin

Đồng hồ đo mức pin MAX17262 ModelGauge m5 của Maxim theo dõi điện áp, dòng điện, nhiệt độ và trạng thái sạc của pin Li‑Po. Nó nằm trên I²C 2 tại địa chỉ 0x36.

MAX17262 có cảm biến dòng điện nội bộ, vì vậy thanh ghi dòng điện đọc ra trực tiếp bằng microamp mà không cần áp dụng hệ số Rsense ngoài. Đọc đồng hồ đo mức pin là vô hại — không có driver đi kèm, nhưng các thanh ghi được ghi lại trong datasheet MAX17262 có thể được đọc trực tiếp:

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 là số bù hai's-complement có dấu: dương khi đang sạc, âm khi đang xả. TTE chỉ có ý nghĩa khi dòng điện âm; TTF chỉ khi dòng điện dương.

IC quản lý nguồn

MC34PF1550A0EP PMIC của NXP xử lý mọi bộ điều chỉnh trên Nicla Vision — ray chính +3V3, ray lõi/I/O SoC +1V8, VDDIO_EXT đến các bộ dịch mức, và bộ sạc Li‑Po. Nó nằm trên I²C 2 tại địa chỉ 0x08.

Cảnh báo

Đọc các thanh ghi PMIC là ổn; ghi vào chúng rất nguy hiểm. Cấu hình sai bộ điều chỉnh buck hoặc cài đặt bộ sạc có thể làm hỏng vĩnh viễn bo mạch, pin, hoặc cả hai. Hãy coi PMIC là chỉ đọc trừ khi bạn biết chính xác mình đang làm gì.

Điều hữu ích nhất mà PMIC cho bạn biết mà đồng hồ đo mức pin không thể là máy trạng thái bộ sạc — liệu bo mạch hiện đang chạy trên USB / ESLOV / VIN, giai đoạn nào của chu kỳ sạc mà Li‑Po đang ở, và liệu bộ sạc có đang ở trạng thái lỗi nhiệt hoặc watchdog không. Các thanh ghi bộ sạc nằm ở offset 0x80 trong không gian địa chỉ I²C chính của PF1550 (xem §22.2 của datasheet PF1550), vì vậy ví dụ CHG_INT_OK tại địa chỉ bộ sạc 0x04 được đọc từ thanh ghi 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)

Các thanh ghi chỉ đọc khác đáng xem trong datasheet (tất cả ở charger‑offset 0x80): 0x80 CHG_INT (ngắt bộ sạc đã được chốt — cờ lỗi), 0x86 VBUS_SNS (trạng thái VBUS nhiều bit bao gồm OVLO / UVLO / DPM), và 0x88 BATT_SNS (sự hiện diện pin và trạng thái quá dòng).

Wi‑Fi

Murata 1DX (CYW4343W) tích hợp được đưa ra qua network --- cấu hình mạng như một giao diện trạm. Kết nối anten đi kèm với đầu nối U.FL trên bo mạch trước khi bật 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

Cùng Murata 1DX cũng hỗ trợ Bluetooth LE 5.1. Dùng aioble --- Async BLE cho BLE thân thiện với asyncio — ví dụ, quảng bá như một ngoại vi và chờ central kết nối:

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())

Tài liệu tham chiếu bus

GPIO

Dùng machine.Pin để đọc hoặc điều khiển bất kỳ chân nào có in tên trên mạch. Đầu ra là CMOS 3,3 V (mặc định VDDIO_EXT) và các bộ dịch mức giới hạn cường độ dẫn mỗi chân ở vài milliamp — chúng được thiết kế cho tải mức tín hiệu chứ không phải tải công suất.

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())

Bất kỳ chân đầu vào nào cũng có thể kích hoạt ngắt trên các cạnh chuyển đổi:

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)

Ghi chú

UART4 dùng chung chân với I²C 1 — cùng các pad SDA/SCL mang cả hai bus. Chọn UART hoặc I²C, không chọn cả hai, trên các chân đó.

In tên D1/D2 trên mạch cũng đọc UART_TX/UART_RX, nhưng trên firmware này các chân đó được định tuyến đến LPUART1, không phải machine.UART. Bản thân machine.UART(1) được dành riêng cho bộ điều khiển Bluetooth trên chip và không thể truy cập trên các đầu nối.

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")

Các pad SCL/SDA trên J2 và các chân SCL_EXT/SDA_EXT của đầu nối ESLOV đều nằm trên cùng bus I²C 1 — xem Đầu nối ESLOV ở trên để biết sơ đồ chân ESLOV.

Phần cứng tương tự cũng có thể được dùng ở chế độ target (slave) qua machine.I2CTarget để đưa ra vùng bộ nhớ cho bộ điều khiển I²C khá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

Nicla Vision cung cấp ba kênh ADC 12‑bit trên A0, A1, và A2. Cả ba đều tham chiếu 1,8 Vread_u16 trả về 0–65535 tương ứng với 0–1,8 V tại chân:

from machine import ADC
import time

adc = ADC("A0")
while True:
    voltage = adc.read_u16() * 1.8 / 65535
    print(voltage)
    time.sleep_ms(100)

Cảnh báo

Đầu vào ADC của Nicla Vision tham chiếu 1,8 V (và không có bộ dịch mức phía trước SoC). Đưa tín hiệu 3,3 V vào sẽ bão hòa bộ chuyển đổi và có thể làm hỏng chân — chia điện áp cao hơn xuống bên ngoài.

PWM

Chân

Bộ định thời / kênh

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

Điều khiển bất kỳ chân nào trong số đó qua machine.PWM

from machine import Pin, PWM

pwm = PWM(Pin("D1"), freq=1_000, duty_u16=32768)

Ghi chú

Một số chân dùng chung kênh TIM1:

  • TIM1 CH2 nằm trên D1 CS.

  • TIM1 CH3 nằm trên D2 CIPO; SCLK xuất ra phần bù đảo ngược (TIM1 CH3N) của cùng kênh đó.

  • TIM1 CH4 chỉ nằm trên COPI.

Chọn một người dùng mỗi kênh bộ định thời. Các chân bộ tứ SPI (SCLK/CIPO/COPI/CS) cũng không thể điều khiển PWM trong khi machine.SPI(4) đang dùng chúng.

Bus bit‑bang phần mềm

machine.SoftI2Cmachine.SoftSPI hoạt động trên bất kỳ GPIO nào nếu bạn cần thêm bus.

Cảm biến nhiệt (ngoài bo mạch)

Firmware bao gồm driver fir --- trình điều khiển cảm biến nhiệt (fir == hồng ngoại xa) cho các máy ảnh nhiệt nối dây ngoài:

  • MLX90621 — mảng IR 16 × 4

  • MLX90640 — mảng IR 32 × 24

  • MLX90641 — mảng IR 16 × 12

  • AMG8833 — mảng IR 8 × 8

Nối dây module vào bus I²C của bo mạch và đọc các khung hình với 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())

Driver fir chỉ giao tiếp với cảm biến qua I²C 1 — nối dây module vào các pad SCL / SDA được in tên trên mạch.

Thời gian

time

Module time bao gồm delay chặn, ticks đơn điệu, và đo thời gian đã trôi qua:

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)

Bộ định thời ảo

machine.Timer lên lịch các hàm gọi lại định kỳ hoặc một lần mà không tiêu thụ slot bộ định thời phần cứng. Truyền -1 làm id để dùng bộ định thời ảo (phần mềm):

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"))

Giá trị chu kỳ tính bằng millisecond. Gọi deinit() để dừng và giải phóng slot.

Đồng hồ thời gian thực

machine.RTC giữ thời gian đồng hồ treo tường qua các lần đặt lại:

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 đặt lại bo mạch nếu ứng dụng bị treo. Sau khi khởi động không thể dừng hoặc cấu hình lại — cấp nó định kỳ bên trong vòng lặp chính của bạn:

from machine import WDT

wdt = WDT(timeout=5_000)   # 5 second window
while True:
    # ...do work...
    wdt.feed()

Thông tin khởi động và thời gian chạy

Cập nhật firmware (DFU)

Nicla Vision dùng tính năng nhấn đúp reset tiêu chuẩn của Arduino để vào bootloader Arduino. Nhấn nhanh nút reset hai lần — bo mạch liệt kê lại qua USB như một thiết bị DFU và OpenMV IDE có thể flash ảnh firmware mới.

Script đang chạy có thể vào lại bootloader theo yêu cầu bằng cách gọi machine.bootloader()

import machine

machine.bootloader()

Hệ thống tệp và thứ tự khởi động

Firmware Nicla Vision gắn kết tối đa hai hệ thống tệp khi khởi động:

  • Bộ nhớ flash nội — luôn được gắn kết tại /flash. Mặc định chứa main.pyREADME.txt; được tạo ngay lần khởi động đầu tiên.

  • ROMFS — hệ thống tệp chỉ đọc, ánh xạ bộ nhớ tại /rom được gắn kết tự động bởi MicroPython khi khởi động.

Sau khi gắn kết, thư mục làm việc được đặt thành /flash. Trình thông dịch sau đó chạy các tập lệnh từ thư mục đó:

  • boot.py được thực thi trên mọi lần reset mềm (khởi động lạnh, Ctrl‑D từ REPL, hoặc mỗi khi tập lệnh đang chạy trả về).

  • main.py chỉ được thực thi khi khởi động lạnh, ngay sau boot.py. Các lần reset mềm tiếp theo chạy lại boot.py nhưng đi thẳng đến REPL — để chạy lại main.py bạn phải đặt lại bo mạch hoàn toàn.

main.py mặc định được tải trên bo mạch vừa được flash chỉ nhấp nháy kênh xanh lam của LED RGB người dùng như nhịp tim (hai xung ngắn, khoảng nghỉ ngắn), để bạn biết firmware đã khởi động sạch mà không cần kết nối máy chủ.

sys.path được mở rộng để bao gồm cả hai hệ thống tệp và các thư mục con lib/ của chúng, vì vậy các module có thể nhập được có thể nằm trong /flash/lib hoặc /rom/lib.

Khi kết nối qua USB, /flash cũng liệt kê như ổ đĩa USB mass‑storage trên máy chủ, cho phép bạn chỉnh sửa boot.py, main.py, và bất kỳ tệp nào khác trực tiếp. Eject ổ đĩa trước khi đặt lại camera để máy chủ xả các ghi cache của nó.

Ghi chú

Vì hệ điều hành coi ổ đĩa như một thiết bị khối thụ động, các tệp được tạo hoặc sửa đổi bởi code chạy trên camera sẽ không hiển thị cho đến khi máy chủ gắn kết lại ổ đĩa. Nếu cả hệ điều hành và camera ghi vào cùng hệ thống tệp cùng lúc, hệ điều hành sẽ thắng và ghi đè các thay đổi do camera thực hiện. Dùng thẻ SD cho bất kỳ dữ liệu nào mà tập lệnh ghi lại, và gắn kết lại trước khi đọc các tệp đó từ máy chủ.

Ghi chú

Kênh đỏ của LED RGB người dùng có thể sáng lên trong thời gian ngắn khi máy chủ đang đọc hoặc ghi vào ổ đĩa USB mass‑storage — đây là chỉ báo hoạt động do firmware điều khiển, không phải lỗi.

Kích thước bộ nhớ

Nicla Vision được trang bị:

  • /flash — Hệ thống tệp FAT 11 MB, đọc/ghi.

  • /rom — ROMFS chỉ đọc, ánh xạ bộ nhớ 4 MB, dùng để tải script và mô hình ML hưởng lợi từ truy cập mmap zero-copy.

Chỉ báo hard‑fault

Nếu LED RGB người dùng đang chuyển đổi nhanh qua tất cả các màu — đủ nhanh để có xu hướng trông như LED trắng nhấp nháy hơn là các màu riêng biệt — firmware đã gặp lỗi cứng không thể phục hồi. Flash lại firmware để khôi phục; nếu flash lại không giúp được, bo mạch có thể bị hư hỏng vật lý.

Thư viện phần mềm

Xem chỉ mục thư viện để biết danh sách đầy đủ các module — bao gồm những module duy nhất cho bản build Nicla Vision.